forked from uncloud/uncloud
		
	Write VM to etcd
This commit is contained in:
		
					parent
					
						
							
								c0e6d6a0d8
							
						
					
				
			
			
				commit
				
					
						1b36c2f96f
					
				
			
		
					 5 changed files with 93 additions and 36 deletions
				
			
		| 
						 | 
					@ -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
									
								
							
							
						
						
									
										39
									
								
								uncloud/hack/config.py
									
										
									
									
									
										Normal 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/'
 | 
				
			||||||
| 
						 | 
					@ -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",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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']
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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'])
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue