From 58daf8191e3c5d48a96b745a906fb4d9fa2a72e0 Mon Sep 17 00:00:00 2001 From: Dominique Roux Date: Fri, 24 Jan 2020 13:56:08 +0100 Subject: [PATCH] refactored vm.py to create a VM --- uncloud/hack/mac.py | 14 ++++-- uncloud/hack/main.py | 6 ++- uncloud/hack/vm.py | 106 ++++++++++++++++++++++++------------------- 3 files changed, 75 insertions(+), 51 deletions(-) diff --git a/uncloud/hack/mac.py b/uncloud/hack/mac.py index 084df13..66286dd 100755 --- a/uncloud/hack/mac.py +++ b/uncloud/hack/mac.py @@ -36,7 +36,9 @@ log = logging.getLogger(__name__) class MAC(object): def __init__(self, config): self.config = config - self.db = DB(config, prefix="/mac") + self.no_db = self.config.arguments['no_db'] + if not self.no_db: + self.db = DB(config, prefix="/mac") self.prefix = 0x420000000000 self._number = 0 # Not set by default @@ -47,10 +49,14 @@ class MAC(object): raise Error("Not a valid mac address: %s" % mac) def last_used_index(self): - value = self.db.get("last_used_index") - if not value: - self.db.set("last_used_index", "0") + if not self.no_db: value = self.db.get("last_used_index") + if not value: + self.db.set("last_used_index", "0") + value = self.db.get("last_used_index") + + else: + value = "0" return int(value) diff --git a/uncloud/hack/main.py b/uncloud/hack/main.py index 2981184..4778ef6 100644 --- a/uncloud/hack/main.py +++ b/uncloud/hack/main.py @@ -22,6 +22,10 @@ arg_parser.add_argument('--vni', help="VXLAN ID (decimal)", type=int) arg_parser.add_argument('--run-dns-ra', action='store_true', help="Provide router advertisements and DNS resolution via dnsmasq") arg_parser.add_argument('--use-sudo', help="Use sudo for command requiring root!", action='store_true') +arg_parser.add_argument('--memory', help="Size of memory (GB)", type=int) +arg_parser.add_argument('--cores', help="Amount of CPU cores", type=int) +arg_parser.add_argument('--no-db', help="Disable connection to etcd. For local testing only!", action='store_true') + log = logging.getLogger(__name__) @@ -33,7 +37,7 @@ def main(arguments): if arguments['create_vm']: print("Creating VM") vm = VM(config) - vm.create() + vm.commandline() if arguments['last_used_mac']: m = MAC(config) diff --git a/uncloud/hack/vm.py b/uncloud/hack/vm.py index 1a531e0..8e20e2e 100755 --- a/uncloud/hack/vm.py +++ b/uncloud/hack/vm.py @@ -29,58 +29,72 @@ from uncloud.hack.mac import MAC class VM(object): def __init__(self, config): - self.config = config - self.db = DB(config, prefix="/vm") + self.config = config + #TODO: Enable etcd lookup + self.no_db = self.config.arguments['no_db'] + if not self.no_db: + self.db = DB(self.config, prefix="/vm") - #TODO: Select generic - self.hackprefix="/home/nico/vcs/uncloud/uncloud/hack/hackcloud" #TODO: Should be removed midterm - self.qemu="/usr/bin/qemu-system-x86_64" #TODO: should be in config - self.accel="kvm" #TODO: should be config + #TODO: Select generic + #self.hackprefix="/home/nico/vcs/uncloud/uncloud/hack/hackcloud" #TODO: Should be removed midterm + self.hackprefix="/home/rouxdo/Work/ungleich/uncloud/uncloud/hack/hackcloud" #TODO: Dominique testing + self.qemu="/usr/bin/qemu-system-x86_64" #TODO: should be in config + self.accel="kvm" #TODO: should be config - self.vm = {} + self.vm = {} + #TODO: Touch later! (when necessary) + self.ifup = os.path.join(self.hackprefix, "ifup.sh") + self.ifdown = os.path.join(self.hackprefix, "ifdown.sh") - #TODO: this should be generic - self.vm['owner']="nico" #TODO: Should in config.arguments - #self.config['vni_hex'] = "{:x}".format(self.config.vni) - #self.config['bridgedev'] = "br{}".format(self.config['vni_hex']) - self.vni_hex = "{:x}".format(self.config.arguments['vni']) - self.bridgedev = "br{}".format(self.vni_hex) + def commandline(self): + """This method is used to trigger / create a vm from the cli""" + #TODO: read arguments from cli + #TODO: create etcd json object + self.vm['owner']= "nico" + self.vm['memory'] = self.config.arguments['memory'] + self.vm['cores'] = self.config.arguments['cores'] + self.vm['os_image'] = os.path.join(self.hackprefix, "alpine-virt-3.11.2-x86_64.iso") + self.create_template() + # mimics api call = this will already be in etcd + #self.vm['os_image'] = self.db.get("os_image") + self.create() + def create_template(self): + self.uuid = uuid.uuid4() + #TODO: This all should be generic + self.vm['uuid'] = str(self.uuid) + #self.vni_hex = "{:x}".format(self.config.arguments['vni']) + self.bridgedev = "br{}".format("{:x}".format(self.config.arguments['vni'])) + + #TODO: Enable sudo + if self.config.arguments['use_sudo']: + self.sudo = "sudo" + + self.mac=MAC(self.config) + self.mac.create() + self.vm['ifname'] = "uc{}".format(self.mac.to_str_format()) + + #self.vm['commandline'] = [ "{}".format(self.sudo), + self.vm['commandline'] = [ "{}".format(self.sudo), + "{}".format(self.qemu), + "-name", "uncloud-{}".format(self.vm['uuid']), + "-machine", "pc,accel={}".format(self.accel), + "-m", "{}".format(self.vm['memory']), + "-smp", "{}".format(self.vm['cores']), + "-uuid", "{}".format(self.vm['uuid']), + "-drive", "file={},media=cdrom".format(self.vm['os_image']), + "-netdev", "tap,id=netmain,script={},downscript={},ifname={}".format(self.ifup, self.ifdown, self.mac), + "-device", "virtio-net-pci,netdev=netmain,id=net0,mac={}".format(self.mac) + ] - #TODO: Touch later! (when necessary) - self.ifup = os.path.join(self.hackprefix, "ifup.sh") - self.ifdown = os.path.join(self.hackprefix, "ifdown.sh") def create(self): - self.uuid = uuid.uuid4() - #TODO: This all should be generic - 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") + if not self.no_db: + self.db.set(str(self.vm['uuid']), + self.vm, + as_json=True) - self.mac=MAC(self.config) - self.mac.create() - self.vm['ifname'] = "uc{}".format(self.mac.to_str_format()) - - self.vm['commandline' ] = [ "sudo", - "{}".format(self.qemu), - "-name", "uncloud-{}".format(self.vm['uuid']), - "-machine", "pc,accel={}".format(self.accel), - "-m", "{}".format(self.vm['memory']), - "-smp", "{}".format(self.vm['cores']), - "-uuid", "{}".format(self.vm['uuid']), - "-drive", "file={},media=cdrom".format(self.vm['os_image']), - "-netdev", "tap,id=netmain,script={},downscript={},ifname={}".format(self.ifup, self.ifdown),self.mac, - "-device", "virtio-net-pci,netdev=netmain,id=net0,mac={}".format(self.mac) - ] - - # TODO: Add ip link command afterwards (rouxdo) - - self.db.set(str(self.vm['uuid']), - self.vm, - as_json=True) - - print(" ".join(self.vm['commandline'])) - subprocess.run(self.vm['commandline']) + print(" ".join(self.vm['commandline'])) + subprocess.run(self.vm['commandline']) #TODO: run in background + #TODO: Add interface ifname to bridge brXX (via net.py: public function add iface to bridge)