X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=osm_openvim%2Fhost_thread.py;h=ed6551fb1efc4a8f189ba149598148ed53af278b;hb=9cead2a0262deabadc900d580ef312fbc468efc0;hp=6c3c7e28308e68adcd3847d7a8a902a16528863d;hpb=c67abe2ff35fcdd5b85db97915a7833ab31beb56;p=osm%2Fopenvim.git diff --git a/osm_openvim/host_thread.py b/osm_openvim/host_thread.py index 6c3c7e2..ed6551f 100644 --- a/osm_openvim/host_thread.py +++ b/osm_openvim/host_thread.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- ## -# Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U. +# Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U. # This file is part of openvim # All Rights Reserved. # @@ -49,25 +49,25 @@ class RunCommandException(Exception): class host_thread(threading.Thread): lvirt_module = None - def __init__(self, name, host, user, db, db_lock, test, image_path, host_id, version, develop_mode, - develop_bridge_iface, password=None, keyfile = None, logger_name=None, debug=None): + def __init__(self, name, host, user, db, test, image_path, host_id, version, develop_mode, + develop_bridge_iface, password=None, keyfile = None, logger_name=None, debug=None, hypervisors=None): """Init a thread to communicate with compute node or ovs_controller. :param host_id: host identity :param name: name of the thread :param host: host ip or name to manage and user :param user, password, keyfile: user and credentials to connect to host - :param db, db_lock': database class and lock to use it in exclusion + :param db: database class, threading safe """ threading.Thread.__init__(self) self.name = name self.host = host self.user = user self.db = db - self.db_lock = db_lock self.test = test self.password = password self.keyfile = keyfile self.localinfo_dirty = False + self.connectivity = True if not test and not host_thread.lvirt_module: try: @@ -98,6 +98,14 @@ class host_thread(threading.Thread): self.pending_terminate_server =[] #list with pairs (time,server_uuid) time to send a terminate for a server being destroyed self.next_update_server_status = 0 #time when must be check servers status +####### self.hypervisor = "kvm" #hypervisor flag (default: kvm) + if hypervisors: + self.hypervisors = hypervisors + else: + self.hypervisors = "kvm" + + self.xen_hyp = True if "xen" in self.hypervisors else False + self.hostinfo = None self.queueLock = threading.Lock() @@ -106,19 +114,26 @@ class host_thread(threading.Thread): self.run_command_session = None self.error = None self.localhost = True if host == 'localhost' else False - self.lvirt_conn_uri = "qemu+ssh://{user}@{host}/system?no_tty=1&no_verify=1".format( - user=self.user, host=self.host) + + if self.xen_hyp: + self.lvirt_conn_uri = "xen+ssh://{user}@{host}/?no_tty=1&no_verify=1".format( + user=self.user, host=self.host) + else: + self.lvirt_conn_uri = "qemu+ssh://{user}@{host}/system?no_tty=1&no_verify=1".format( + user=self.user, host=self.host) if keyfile: self.lvirt_conn_uri += "&keyfile=" + keyfile + self.remote_ip = None self.local_ip = None - def run_command(self, command, keep_session=False): + def run_command(self, command, keep_session=False, ignore_exit_status=False): """Run a command passed as a str on a localhost or at remote machine. :param command: text with the command to execute. :param keep_session: if True it returns a for sending input with '.write("text\n")'. A command with keep_session=True MUST be followed by a command with keep_session=False in order to close the session and get the output + :param ignore_exit_status: Return stdout and not raise an exepction in case of error. :return: the output of the command if 'keep_session=False' or the object if 'keep_session=True' :raises: RunCommandException if command fails """ @@ -139,8 +154,14 @@ class host_thread(threading.Thread): self.run_command_session = p return p.stdin else: - output = subprocess.check_output(('bash', "-c", command)) - returncode = 0 + if not ignore_exit_status: + output = subprocess.check_output(('bash', "-c", command)) + returncode = 0 + else: + out = None + p = subprocess.Popen(('bash', "-c", command), stdout=subprocess.PIPE) + out, err = p.communicate() + return out else: if self.run_command_session: (i, o, e) = self.run_command_session @@ -156,7 +177,7 @@ class host_thread(threading.Thread): returncode = o.channel.recv_exit_status() output = o.read() outerror = e.read() - if returncode != 0: + if returncode != 0 and not ignore_exit_status: text = "run_command='{}' Error='{}'".format(command, outerror) self.logger.error(text) raise RunCommandException(text) @@ -192,25 +213,12 @@ class host_thread(threading.Thread): def check_connectivity(self): if not self.test: - # TODO change to run_command try: - if not self.ssh_conn: - self.ssh_connect() - command = 'sudo brctl show' - (_, stdout, stderr) = self.ssh_conn.exec_command(command, timeout=10) - content = stderr.read() - if len(content) > 0: - self.connectivity = False - self.logger.error("ssh conection error") - except paramiko.ssh_exception.SSHException as e: - text = e.args[0] - self.connectivity = False - self.logger.error("ssh_connect ssh Exception: " + text) - raise paramiko.ssh_exception.SSHException("ssh error conection") - except Exception as e: + self.run_command(command) + except RunCommandException as e: self.connectivity = False - raise paramiko.ssh_exception.SSHException("ssh error conection") + self.logger.error("check_connectivity Exception: " + str(e)) def load_localinfo(self): if not self.test: @@ -313,9 +321,7 @@ class host_thread(threading.Thread): self.logger.error("save_localinfo Exception: " + text) def load_servers_from_db(self): - self.db_lock.acquire() r,c = self.db.get_table(SELECT=('uuid','status', 'image_id'), FROM='instances', WHERE={'host_id': self.host_id}) - self.db_lock.release() self.server_status = {} if r<0: @@ -493,8 +499,13 @@ class host_thread(threading.Thread): bus_ide = True if bus=='ide' else False self.xml_level = 0 + hypervisor = server.get('hypervisor', 'kvm') + os_type_img = server.get('os_image_type', 'other') - text = "" + if hypervisor[:3] == 'xen': + text = "" + else: + text = "" #get topology topo = server_metadata.get('topology', None) if topo == None and 'metadata' in dev_list[0]: @@ -568,12 +579,26 @@ class host_thread(threading.Thread): if dev['type']=='cdrom' : boot_cdrom = True break - text += self.tab()+ '' + \ - self.inc_tab() + "hvm" - if boot_cdrom: - text += self.tab() + "" - text += self.tab() + "" + \ - self.dec_tab()+'' + if hypervisor == 'xenhvm': + text += self.tab()+ '' + \ + self.inc_tab() + "hvm" + text += self.tab() + "/usr/lib/xen/boot/hvmloader" + if boot_cdrom: + text += self.tab() + "" + text += self.tab() + "" + \ + self.dec_tab()+'' + elif hypervisor == 'xen-unik': + text += self.tab()+ '' + \ + self.inc_tab() + "xen" + text += self.tab() + "" + str(dev_list[0]['source file']) + "" + \ + self.dec_tab()+'' + else: + text += self.tab()+ '' + \ + self.inc_tab() + "hvm" + if boot_cdrom: + text += self.tab() + "" + text += self.tab() + "" + \ + self.dec_tab()+'' #features text += self.tab()+''+\ self.inc_tab()+'' +\ @@ -592,14 +617,29 @@ class host_thread(threading.Thread): self.tab() + "preserve" + \ self.tab() + "restart" + \ self.tab() + "restart" - text += self.tab() + "" + \ - self.inc_tab() + "/usr/libexec/qemu-kvm" + \ - self.tab() + "" +\ - self.inc_tab() + "" + \ - self.dec_tab() + "" +\ - self.tab() + "" + \ - self.inc_tab()+ "" + \ - self.dec_tab()+'' + if hypervisor == 'xenhvm': + text += self.tab() + "" + \ + self.inc_tab() + "/usr/bin/qemu-system-i386" + \ + self.tab() + "" +\ + self.inc_tab() + "" + \ + self.dec_tab() + "" +\ + self.tab() + "" + \ + self.inc_tab()+ "" + \ + self.dec_tab()+'' #In some libvirt version may be: /usr/lib64/xen/bin/qemu-dm (depends on distro) + elif hypervisor == 'xen-unik': + text += self.tab() + "" + \ + self.tab() + "" + \ + self.inc_tab()+ "" + \ + self.dec_tab()+'' + else: + text += self.tab() + "" + \ + self.inc_tab() + "/usr/libexec/qemu-kvm" + \ + self.tab() + "" +\ + self.inc_tab() + "" + \ + self.dec_tab() + "" +\ + self.tab() + "" + \ + self.inc_tab()+ "" + \ + self.dec_tab()+'' if windows_os: text += self.tab() + "" + \ self.tab() + "" + \ @@ -610,6 +650,15 @@ class host_thread(threading.Thread): self.dec_tab() + "" + \ self.tab() + "" + \ self.tab() + "" #TODO revisar + elif hypervisor == 'xen-unik': + pass + else: + text += self.tab() + "" + \ + self.tab() + "" + \ + self.tab() + "" + \ + self.tab() + "" #> self.tab()+'\n' +\ #> self.dec_tab()+'\n' +\ @@ -626,7 +675,7 @@ class host_thread(threading.Thread): vd_index = 'a' for dev in dev_list: bus_ide_dev = bus_ide - if dev['type']=='cdrom' or dev['type']=='disk': + if (dev['type']=='cdrom' or dev['type']=='disk') and hypervisor != 'xen-unik': if dev['type']=='cdrom': bus_ide_dev = True text += self.tab() + "" @@ -661,6 +710,8 @@ class host_thread(threading.Thread): dev_text = dev_text.replace('__dev__', vd_index) vd_index = chr(ord(vd_index)+1) text += dev_text + elif hypervisor == 'xen-unik': + pass else: return -1, 'Unknown device type ' + dev['type'] @@ -668,9 +719,7 @@ class host_thread(threading.Thread): bridge_interfaces = server.get('networks', []) for v in bridge_interfaces: #Get the brifge name - self.db_lock.acquire() result, content = self.db.get_table(FROM='nets', SELECT=('provider',),WHERE={'uuid':v['net_id']} ) - self.db_lock.release() if result <= 0: self.logger.error("create_xml_server ERROR %d getting nets %s", result, content) return -1, content @@ -701,6 +750,8 @@ class host_thread(threading.Thread): vlan = content[0]['provider'].replace('OVS:', '') text += self.tab() + "" + \ self.inc_tab() + "" + if hypervisor == 'xenhvm' or hypervisor == 'xen-unik': + text += self.tab() + "