Write VM to etcd

This commit is contained in:
Nico Schottelius 2020-01-14 14:23:26 +01:00
parent c0e6d6a0d8
commit 1b36c2f96f
5 changed files with 93 additions and 36 deletions

View file

@ -44,7 +44,7 @@ if __name__ == '__main__':
default=os.path.expanduser('~/uncloud')) default=os.path.expanduser('~/uncloud'))
etcd_parser = argparse.ArgumentParser(add_help=False) etcd_parser = argparse.ArgumentParser(add_help=False)
etcd_parser.add_argument('--etcd-host', dest='etcd_url') etcd_parser.add_argument('--etcd-host')
etcd_parser.add_argument('--etcd-port') etcd_parser.add_argument('--etcd-port')
etcd_parser.add_argument('--etcd-ca-cert', help='CA that signed the etcd certificate') etcd_parser.add_argument('--etcd-ca-cert', help='CA that signed the etcd certificate')
etcd_parser.add_argument('--etcd-cert-cert', help='Path to client certificate') etcd_parser.add_argument('--etcd-cert-cert', help='Path to client certificate')
@ -88,7 +88,7 @@ if __name__ == '__main__':
main(arguments) main(arguments)
except UncloudException as err: except UncloudException as err:
logger.error(err) logger.error(err)
except ConnectionFailedError: # except ConnectionFailedError as err:
logger.error('Cannot connect to etcd') # logger.error('Cannot connect to etcd: {}'.format(err))
except Exception as err: except Exception as err:
logger.exception(err) logger.exception(err)

39
uncloud/hack/config.py Normal file
View file

@ -0,0 +1,39 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# 2020 Nico Schottelius (nico.schottelius at ungleich.ch)
#
# This file is part of uncloud.
#
# uncloud is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# uncloud is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with uncloud. If not, see <http://www.gnu.org/licenses/>.
#
#
class Config(object):
def __init__(self, arguments):
""" read arguments dicts as a base """
self.arguments = arguments
# Split them so *etcd_args can be used and we can
# iterate over etcd_hosts
self.etcd_hosts = [ arguments['etcd_host'] ]
self.etcd_args = {
'ca_cert': arguments['etcd_ca_cert'],
'cert_cert': arguments['etcd_cert_cert'],
'cert_key': arguments['etcd_cert_key'],
# 'user': None,
# 'password': None
}
self.etcd_prefix = '/nicohack/'

View file

@ -21,28 +21,31 @@
# #
import etcd3 import etcd3
import json
class DB(object): class DB(object):
def __init__(self, urls): def __init__(self, config):
self.urls = urls self.config = config
self.prefix = "/nicohack/" self.prefix= '/nicohack/'
self.connect()
def connect(self): def connect(self):
self.clients = [] self._db_clients = []
for endpoint in self.urls: for endpoint in self.config.etcd_hosts:
client = etcd3.client(host=endpoint, client = etcd3.client(host=endpoint, **self.config.etcd_args)
ca_cert="/home/nico/vcs/ungleich-dot-cdist/files/etcd/ca.pem", self._db_clients.append(client)
cert_cert="/home/nico/vcs/ungleich-dot-cdist/files/etcd/nico.pem",
cert_key="/home/nico/vcs/ungleich-dot-cdist/files/etcd/nico-key.pem")
clients.append(client)
def get_value(self, key): def get_value(self, key):
pass pass
def set_value(self, key, val): def set(self, key, value, store_as_json=False, **kwargs):
pass if store_as_json:
value = json.dumps(value)
key = "{}/{}".format(self.prefix, key)
# FIXME: iterate over clients in case of failure ?
return self._db_clients[0].put(key, value, **kwargs)
if __name__ == '__main__': if __name__ == '__main__':
endpoints = [ "https://etcd1.ungleich.ch:2379", endpoints = [ "https://etcd1.ungleich.ch:2379",

View file

@ -1,6 +1,7 @@
import argparse import argparse
from uncloud.hack.vm import VM from uncloud.hack.vm import VM
from uncloud.hack.config import Config
arg_parser = argparse.ArgumentParser('hack', add_help=False) arg_parser = argparse.ArgumentParser('hack', add_help=False)
#description="Commands that are unfinished - use at own risk") #description="Commands that are unfinished - use at own risk")
@ -9,10 +10,9 @@ arg_parser.add_argument('--create-vm', action='store_true')
def main(arguments): def main(arguments):
print(arguments) print(arguments)
config = Config(arguments)
if arguments['create_vm']: if arguments['create_vm']:
print("Creating VM") print("Creating VM")
vm = VM() vm = VM(config)
vm.create() vm.create()
#debug = arguments['debug']
#port = arguments['port']

View file

@ -24,34 +24,49 @@ import subprocess
import uuid import uuid
import os import os
class VM(object): from uncloud.hack.db import DB
def __init__(self):
self.hackprefix="/home/nico/vcs/uncloud/uncloud/hack/hackcloud"
class VM(object):
def __init__(self, config):
self.config = config
self.db = DB(config)
self.hackprefix="/home/nico/vcs/uncloud/uncloud/hack/hackcloud"
self.qemu="/usr/bin/qemu-system-x86_64" self.qemu="/usr/bin/qemu-system-x86_64"
self.vm = {}
self.accel="kvm" self.accel="kvm"
self.memory=1024
self.cores=2
self.uuid=uuid.uuid4()
# self.mac=$(./mac-gen.py) # self.mac=$(./mac-gen.py)
self.mac="42:00:00:00:00:42" self.mac="42:00:00:00:00:42"
self.owner="nico" self.owner="nico"
self.bridge="br100" self.bridge="br100"
self.os_image = os.path.join(self.hackprefix, "alpine-virt-3.11.2-x86_64.iso")
self.ifup = os.path.join(self.hackprefix, "ifup.sh") self.ifup = os.path.join(self.hackprefix, "ifup.sh")
self.ifdown = os.path.join(self.hackprefix, "ifdown.sh") self.ifdown = os.path.join(self.hackprefix, "ifdown.sh")
def create(self): self.uuid = uuid.uuid4()
p = [ "sudo", self.vm['uuid'] = str(self.uuid)
self.vm['memory']=1024
self.vm['cores']=2
self.vm['os_image'] = os.path.join(self.hackprefix, "alpine-virt-3.11.2-x86_64.iso")
self.vm['commandline' ] = [ "sudo",
"{}".format(self.qemu), "{}".format(self.qemu),
"-name", "uncloud-{}".format(self.uuid), "-name", "uncloud-{}".format(self.vm['uuid']),
"-machine", "pc,accel={}".format(self.accel), "-machine", "pc,accel={}".format(self.accel),
"-m", "{}".format(self.memory), "-m", "{}".format(self.vm['memory']),
"-smp", "{}".format(self.cores), "-smp", "{}".format(self.vm['cores']),
"-uuid", "{}".format(self.uuid), "-uuid", "{}".format(self.vm['uuid']),
"-drive", "file={},media=cdrom".format(self.os_image), "-drive", "file={},media=cdrom".format(self.vm['os_image']),
"-netdev", "tap,id=netmain,script={},downscript={}".format(self.ifup, self.ifdown), "-netdev", "tap,id=netmain,script={},downscript={}".format(self.ifup, self.ifdown),
"-device", "virtio-net-pci,netdev=netmain,id=net0,mac={}".format(self.mac) "-device", "virtio-net-pci,netdev=netmain,id=net0,mac={}".format(self.mac)
] ]
print(" ".join(p))
subprocess.run(p) def create(self):
self.db.set("vm/{}".format(str(self.vm['uuid'])),
self.vm, store_as_json=True)
print(" ".join(self.vm['commandline']))
subprocess.run(self.vm['commandline'])