<s> """<STR_LIT>""" <EOL> from xml . etree import ElementTree <EOL> import subprocess <EOL> import os <EOL> import glob <EOL> import re <EOL> import time <EOL> import libvirt <EOL> from ovs . extensions . generic . sshclient import SSHClient <EOL> from ovs . extensions . generic . system import System <EOL> from ovs . log . logHandler import LogHandler <EOL> logger = LogHandler . get ( '<STR_LIT>' , name = '<STR_LIT>' ) <EOL> ROOT_PATH = '<STR_LIT>' <EOL> RUN_PATH = '<STR_LIT>' <EOL> def _recurse ( treeitem ) : <EOL> result = { } <EOL> for key , item in treeitem . items ( ) : <EOL> result [ key ] = item <EOL> for child in treeitem . getchildren ( ) : <EOL> result [ child . tag ] = _recurse ( child ) <EOL> for key , item in child . items ( ) : <EOL> result [ child . tag ] [ key ] = item <EOL> result [ child . tag ] [ '<STR_LIT>' ] = child . text <EOL> return result <EOL> def authenticated ( function ) : <EOL> """<STR_LIT>""" <EOL> def new_function ( self , * args , ** kwargs ) : <EOL> self . __doc__ = function . __doc__ <EOL> try : <EOL> if self . _conn is None : <EOL> self . _connect ( ) <EOL> return function ( self , * args , ** kwargs ) <EOL> finally : <EOL> try : <EOL> self . _disconnect ( ) <EOL> except : <EOL> pass <EOL> return new_function <EOL> class Sdk ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , host = '<STR_LIT:127.0.0.1>' , login = '<STR_LIT:root>' ) : <EOL> logger . debug ( '<STR_LIT>' ) <EOL> self . states = { libvirt . VIR_DOMAIN_NOSTATE : '<STR_LIT>' , <EOL> libvirt . VIR_DOMAIN_RUNNING : '<STR_LIT>' , <EOL> libvirt . VIR_DOMAIN_BLOCKED : '<STR_LIT>' , <EOL> libvirt . VIR_DOMAIN_PAUSED : '<STR_LIT>' , <EOL> libvirt . VIR_DOMAIN_SHUTDOWN : '<STR_LIT>' , <EOL> libvirt . VIR_DOMAIN_SHUTOFF : '<STR_LIT>' , <EOL> libvirt . VIR_DOMAIN_CRASHED : '<STR_LIT>' } <EOL> self . libvirt = libvirt <EOL> self . host = host <EOL> self . login = login <EOL> self . _conn = None <EOL> self . ssh_client = SSHClient ( self . host , username = '<STR_LIT:root>' ) <EOL> logger . debug ( '<STR_LIT>' ) <EOL> def _connect ( self , attempt = <NUM_LIT:0> ) : <EOL> if self . _conn : <EOL> self . _disconnect ( ) <EOL> logger . debug ( '<STR_LIT>' , self . host , self . login , os . getgid ( ) , os . getuid ( ) ) <EOL> try : <EOL> if self . host . lower ( ) in [ '<STR_LIT:localhost>' , '<STR_LIT:127.0.0.1>' ] : <EOL> self . host = '<STR_LIT:127.0.0.1>' <EOL> self . _conn = self . libvirt . open ( '<STR_LIT>' ) <EOL> else : <EOL> self . _conn = self . libvirt . open ( '<STR_LIT>' . format ( self . login , self . host ) ) <EOL> except self . libvirt . libvirtError as le : <EOL> logger . error ( '<STR_LIT>' , str ( le ) , le . get_error_code ( ) ) <EOL> if attempt < <NUM_LIT:5> : <EOL> time . sleep ( <NUM_LIT:1> ) <EOL> self . _connect ( attempt + <NUM_LIT:1> ) <EOL> else : <EOL> raise <EOL> return True <EOL> def _disconnect ( self ) : <EOL> logger . debug ( '<STR_LIT>' ) <EOL> if self . _conn : <EOL> try : <EOL> self . _conn . close ( ) <EOL> except self . libvirt . libvirtError as le : <EOL> logger . error ( '<STR_LIT>' , str ( le ) , le . get_error_code ( ) ) <EOL> self . _conn = None <EOL> return True <EOL> @ authenticated <EOL> def test_connection ( self ) : <EOL> """<STR_LIT>""" <EOL> _ = self <EOL> return True <EOL> @ staticmethod <EOL> def _get_disks ( vm_object ) : <EOL> tree = ElementTree . fromstring ( vm_object . XMLDesc ( <NUM_LIT:0> ) ) <EOL> return [ _recurse ( item ) for item in tree . findall ( '<STR_LIT>' ) ] <EOL> @ staticmethod <EOL> def _get_nics ( vm_object ) : <EOL> tree = ElementTree . fromstring ( vm_object . XMLDesc ( <NUM_LIT:0> ) ) <EOL> return [ _recurse ( item ) for item in tree . findall ( '<STR_LIT>' ) ] <EOL> @ staticmethod <EOL> def _get_nova_name ( vm_object ) : <EOL> tree = ElementTree . fromstring ( vm_object . XMLDesc ( <NUM_LIT:0> ) ) <EOL> metadata = tree . findall ( '<STR_LIT>' ) [ <NUM_LIT:0> ] <EOL> nova_instance_namespace_tag = metadata . getchildren ( ) [ <NUM_LIT:0> ] . tag <EOL> nova_instance_namespace = nova_instance_namespace_tag [ nova_instance_namespace_tag . find ( '<STR_LIT:{>' ) + <NUM_LIT:1> : nova_instance_namespace_tag . find ( '<STR_LIT:}>' ) ] <EOL> instance = metadata . findall ( '<STR_LIT>' % nova_instance_namespace ) [ <NUM_LIT:0> ] <EOL> name = instance . findall ( '<STR_LIT>' % nova_instance_namespace ) [ <NUM_LIT:0> ] <EOL> return name . text <EOL> @ staticmethod <EOL> def _get_ram ( vm_object ) : <EOL> """<STR_LIT>""" <EOL> tree = ElementTree . fromstring ( vm_object . XMLDesc ( <NUM_LIT:0> ) ) <EOL> mem = tree . findall ( '<STR_LIT>' ) [ <NUM_LIT:0> ] <EOL> unit = mem . items ( ) [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] <EOL> value = mem . text <EOL> if unit == '<STR_LIT>' : <EOL> return int ( value ) <EOL> elif unit == '<STR_LIT>' : <EOL> return int ( value ) / <NUM_LIT> <EOL> elif unit == '<STR_LIT>' : <EOL> return int ( value ) * <NUM_LIT> <EOL> @ staticmethod <EOL> def _get_disk_size ( filename ) : <EOL> cmd = [ '<STR_LIT>' , '<STR_LIT:info>' , filename ] <EOL> try : <EOL> out = subprocess . check_output ( '<STR_LIT:U+0020>' . join ( cmd ) , <EOL> stderr = subprocess . STDOUT , <EOL> shell = True ) <EOL> except subprocess . CalledProcessError as cpe : <EOL> return cpe . output . strip ( ) <EOL> out = out . split ( '<STR_LIT:\n>' ) <EOL> for line in out : <EOL> if line . startswith ( '<STR_LIT>' ) : <EOL> size = line . split ( '<STR_LIT>' ) [ <NUM_LIT:1> ] . split ( '<STR_LIT:U+0020>' ) [ <NUM_LIT:0> ] <EOL> return size <EOL> return <NUM_LIT:0> <EOL> def _get_vm_pid ( self , vm_object ) : <EOL> """<STR_LIT>""" <EOL> if self . get_power_state ( vm_object . name ( ) ) == '<STR_LIT>' : <EOL> pid_path = '<STR_LIT>' . format ( RUN_PATH , vm_object . name ( ) ) <EOL> try : <EOL> with open ( pid_path , '<STR_LIT:r>' ) as pid_file : <EOL> pid = pid_file . read ( ) <EOL> return int ( pid ) <EOL> except IOError : <EOL> return '<STR_LIT>' <EOL> return '<STR_LIT>' <EOL> @ authenticated <EOL> def make_agnostic_config ( self , vm_object ) : <EOL> """<STR_LIT>""" <EOL> storage_ip = '<STR_LIT:127.0.0.1>' <EOL> regex = '<STR_LIT>' <EOL> config = { '<STR_LIT>' : [ ] } <EOL> mountpoints = [ ] <EOL> order = <NUM_LIT:0> <EOL> for disk in Sdk . _get_disks ( vm_object ) : <EOL> if disk [ '<STR_LIT>' ] == '<STR_LIT>' : <EOL> continue <EOL> if '<STR_LIT:file>' in disk [ '<STR_LIT:source>' ] : <EOL> backingfilename = disk [ '<STR_LIT:source>' ] [ '<STR_LIT:file>' ] <EOL> elif '<STR_LIT>' in disk [ '<STR_LIT:source>' ] : <EOL> backingfilename = disk [ '<STR_LIT:source>' ] [ '<STR_LIT>' ] <EOL> else : <EOL> continue <EOL> match = re . search ( regex , backingfilename ) <EOL> if match is None : <EOL> continue <EOL> mountpoint = '<STR_LIT>' . format ( match . group ( <NUM_LIT:1> ) ) <EOL> filename = backingfilename . replace ( mountpoint , '<STR_LIT>' ) . strip ( '<STR_LIT:/>' ) <EOL> diskname = filename . split ( '<STR_LIT:/>' ) [ - <NUM_LIT:1> ] . split ( '<STR_LIT:.>' ) [ <NUM_LIT:0> ] <EOL> config [ '<STR_LIT>' ] . append ( { '<STR_LIT:filename>' : filename , <EOL> '<STR_LIT>' : filename , <EOL> '<STR_LIT>' : mountpoint , <EOL> '<STR_LIT:name>' : diskname , <EOL> '<STR_LIT>' : order } ) <EOL> order += <NUM_LIT:1> <EOL> mountpoints . append ( mountpoint ) <EOL> if self . ssh_client is None : <EOL> self . ssh_client = SSHClient ( self . host , username = '<STR_LIT:root>' ) <EOL> vm_filename = self . ssh_client . run ( "<STR_LIT>" . format ( vm_object . UUIDString ( ) , ROOT_PATH ) ) <EOL> vm_filename = vm_filename . strip ( ) . split ( '<STR_LIT:/>' ) [ - <NUM_LIT:1> ] <EOL> vm_location = System . get_my_machine_id ( self . ssh_client ) <EOL> vm_datastore = None <EOL> possible_datastores = self . ssh_client . run ( "<STR_LIT>" . format ( vm_filename ) ) . split ( '<STR_LIT:\n>' ) <EOL> for datastore in possible_datastores : <EOL> if '<STR_LIT>' . format ( vm_location , vm_filename ) in datastore . strip ( ) : <EOL> for mountpoint in mountpoints : <EOL> if mountpoint in datastore . strip ( ) : <EOL> vm_datastore = mountpoint <EOL> try : <EOL> config [ '<STR_LIT:name>' ] = self . _get_nova_name ( vm_object ) <EOL> except Exception as ex : <EOL> logger . debug ( '<STR_LIT>' . format ( ex ) ) <EOL> config [ '<STR_LIT:name>' ] = vm_object . name ( ) <EOL> config [ '<STR_LIT:id>' ] = str ( vm_object . UUIDString ( ) ) <EOL> config [ '<STR_LIT>' ] = { '<STR_LIT:filename>' : '<STR_LIT>' . format ( vm_location , vm_filename ) , <EOL> '<STR_LIT>' : vm_datastore } <EOL> config [ '<STR_LIT>' ] = dict ( ( mountpoint , '<STR_LIT>' . format ( storage_ip , mountpoint ) ) for mountpoint in mountpoints ) <EOL> return config <EOL> @ authenticated <EOL> def get_power_state ( self , vmid ) : <EOL> """<STR_LIT>""" <EOL> vm = self . get_vm_object ( vmid ) <EOL> state = vm . info ( ) [ <NUM_LIT:0> ] <EOL> return self . states . get ( state , '<STR_LIT>' ) <EOL> @ authenticated <EOL> def get_vm_object ( self , vmid ) : <EOL> """<STR_LIT>""" <EOL> func = '<STR_LIT>' <EOL> try : <EOL> import uuid <EOL> uuid . UUID ( vmid ) <EOL> except ValueError : <EOL> func = '<STR_LIT>' <EOL> try : <EOL> return getattr ( self . _conn , func ) ( vmid ) <EOL> except self . libvirt . libvirtError as le : <EOL> logger . error ( str ( le ) ) <EOL> try : <EOL> self . _connect ( ) <EOL> return getattr ( self . _conn , func ) ( vmid ) <EOL> except self . libvirt . libvirtError as le : <EOL> logger . error ( str ( le ) ) <EOL> raise RuntimeError ( '<STR_LIT>' . format ( vmid ) ) <EOL> def get_vm_object_by_filename ( self , filename ) : <EOL> """<STR_LIT>""" <EOL> vmid = filename . split ( '<STR_LIT:/>' ) [ - <NUM_LIT:1> ] . replace ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> return self . get_vm_object ( vmid ) <EOL> @ authenticated <EOL> def get_vms ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _conn . listAllDomains ( ) <EOL> def shutdown ( self , vmid ) : <EOL> """<STR_LIT>""" <EOL> vm_object = self . get_vm_object ( vmid ) <EOL> vm_object . shutdown ( ) <EOL> return self . get_power_state ( vmid ) <EOL> @ authenticated <EOL> def delete_vm ( self , vmid , devicename , disks_info ) : <EOL> """<STR_LIT>""" <EOL> if self . ssh_client is None : <EOL> self . ssh_client = SSHClient ( self . host , username = '<STR_LIT:root>' ) <EOL> vm_object = None <EOL> try : <EOL> vm_object = self . get_vm_object ( vmid ) <EOL> except Exception as ex : <EOL> logger . error ( '<STR_LIT>' . format ( ex ) ) <EOL> found_files = self . find_devicename ( devicename ) <EOL> if found_files is not None : <EOL> for found_file in found_files : <EOL> self . ssh_client . file_delete ( found_file ) <EOL> logger . info ( '<STR_LIT>' . format ( found_file ) ) <EOL> if vm_object : <EOL> found_file = '<STR_LIT>' <EOL> for disk in self . _get_disks ( vm_object ) : <EOL> if disk [ '<STR_LIT>' ] == '<STR_LIT>' : <EOL> continue <EOL> if '<STR_LIT:file>' in disk [ '<STR_LIT:source>' ] : <EOL> found_file = disk [ '<STR_LIT:source>' ] [ '<STR_LIT:file>' ] <EOL> elif '<STR_LIT>' in disk [ '<STR_LIT:source>' ] : <EOL> found_file = disk [ '<STR_LIT:source>' ] [ '<STR_LIT>' ] <EOL> if found_file and os . path . exists ( found_file ) and os . path . isfile ( found_file ) : <EOL> self . ssh_client . file_delete ( found_file ) <EOL> logger . info ( '<STR_LIT>' . format ( found_file ) ) <EOL> vm_object . undefine ( ) <EOL> elif disks_info : <EOL> for path , devicename in disks_info : <EOL> found_file = '<STR_LIT>' . format ( path , devicename ) <EOL> if os . path . exists ( found_file ) and os . path . isfile ( found_file ) : <EOL> self . ssh_client . file_delete ( found_file ) <EOL> logger . info ( '<STR_LIT>' . format ( found_file ) ) <EOL> return True <EOL> def power_on ( self , vmid ) : <EOL> """<STR_LIT>""" <EOL> vm_object = self . get_vm_object ( vmid ) <EOL> vm_object . create ( ) <EOL> return self . get_power_state ( vmid ) <EOL> def find_devicename ( self , devicename ) : <EOL> """<STR_LIT>""" <EOL> _ = self <EOL> file_matcher = '<STR_LIT>' . format ( devicename ) <EOL> matches = [ ] <EOL> for found_file in glob . glob ( file_matcher ) : <EOL> if os . path . exists ( found_file ) and os . path . isfile ( found_file ) : <EOL> matches . append ( found_file ) <EOL> return matches if matches else None <EOL> def is_datastore_available ( self , mountpoint ) : <EOL> """<STR_LIT>""" <EOL> if self . ssh_client is None : <EOL> self . ssh_client = SSHClient ( self . host , username = '<STR_LIT:root>' ) <EOL> return self . ssh_client . run ( "<STR_LIT>" . format ( mountpoint ) ) == '<STR_LIT:yes>' <EOL> @ authenticated <EOL> def clone_vm ( self , vmid , name , disks , mountpoint ) : <EOL> """<STR_LIT>""" <EOL> source_vm = self . get_vm_object ( vmid ) <EOL> return self . create_vm_from_template ( name , source_vm , disks , mountpoint ) <EOL> def create_volume ( self , location , size ) : <EOL> """<STR_LIT>""" <EOL> if self . ssh_client . file_exists ( location ) : <EOL> raise RuntimeError ( '<STR_LIT>' % location ) <EOL> command = '<STR_LIT>' . format ( size , location ) <EOL> output = self . ssh_client . run ( command ) <EOL> if not self . ssh_client . file_exists ( location ) : <EOL> raise RuntimeError ( '<STR_LIT>' % ( location , output ) ) <EOL> logger . info ( '<STR_LIT>' . format ( command , output ) ) <EOL> def delete_volume ( self , location ) : <EOL> """<STR_LIT>""" <EOL> if not self . ssh_client . file_exists ( location ) : <EOL> logger . error ( '<STR_LIT>' % location ) <EOL> return <EOL> command = '<STR_LIT>' . format ( location ) <EOL> output = self . ssh_client . run ( command ) <EOL> logger . info ( '<STR_LIT>' . format ( command , output ) ) <EOL> if self . ssh_client . file_exists ( location ) : <EOL> raise RuntimeError ( '<STR_LIT>' % ( location , output ) ) <EOL> def extend_volume ( self , location , size ) : <EOL> """<STR_LIT>""" <EOL> if not self . ssh_client . file_exists ( location ) : <EOL> raise RuntimeError ( '<STR_LIT>' % location ) <EOL> command = '<STR_LIT>' . format ( size , location ) <EOL> output = self . ssh_client . run ( command ) <EOL> logger . info ( '<STR_LIT>' . format ( command , output ) ) <EOL> @ authenticated <EOL> def create_vm_from_template ( self , name , source_vm , disks , mountpoint ) : <EOL> """<STR_LIT>""" <EOL> vm_disks = [ ] <EOL> if hasattr ( source_vm , '<STR_LIT>' ) : <EOL> vcpus = source_vm . config . hardware . numCPU <EOL> ram = source_vm . config . hardware . memoryMB <EOL> elif isinstance ( source_vm , self . libvirt . virDomain ) : <EOL> vcpus = source_vm . info ( ) [ <NUM_LIT:3> ] <EOL> ram = Sdk . _get_ram ( source_vm ) <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' . format ( source_vm , type ( source_vm ) ) ) <EOL> networks = [ ] <EOL> for nic in Sdk . _get_nics ( source_vm ) : <EOL> if nic . get ( '<STR_LIT:type>' , None ) == '<STR_LIT>' : <EOL> source = nic . get ( '<STR_LIT:source>' , { } ) . get ( '<STR_LIT>' , '<STR_LIT:default>' ) <EOL> model = nic . get ( '<STR_LIT>' , { } ) . get ( '<STR_LIT:type>' , '<STR_LIT>' ) <EOL> networks . append ( ( '<STR_LIT>' . format ( source ) , '<STR_LIT>' , '<STR_LIT>' . format ( model ) ) ) <EOL> for disk in disks : <EOL> vm_disks . append ( ( '<STR_LIT>' . format ( mountpoint . strip ( '<STR_LIT:/>' ) , disk [ '<STR_LIT>' ] . strip ( '<STR_LIT:/>' ) ) , '<STR_LIT>' ) ) <EOL> self . _vm_create ( name = name , <EOL> vcpus = vcpus , <EOL> ram = int ( ram ) , <EOL> disks = vm_disks , <EOL> networks = networks ) <EOL> try : <EOL> return self . get_vm_object ( name ) . UUIDString ( ) <EOL> except self . libvirt . libvirtError as le : <EOL> logger . error ( str ( le ) ) <EOL> try : <EOL> self . _connect ( ) <EOL> return self . get_vm_object ( name ) . UUIDString ( ) <EOL> except self . libvirt . libvirtError as le : <EOL> logger . error ( str ( le ) ) <EOL> raise RuntimeError ( '<STR_LIT>' . format ( name ) ) <EOL> def _vm_create ( self , name , vcpus , ram , disks , <EOL> cdrom_iso = None , os_type = None , os_variant = None , vnc_listen = '<STR_LIT>' , <EOL> networks = None , start = False ) : <EOL> """<STR_LIT>""" <EOL> if networks is None : <EOL> networks = [ ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) ] <EOL> command = '<STR_LIT>' <EOL> options = [ '<STR_LIT>' . format ( self . login , self . host ) , <EOL> '<STR_LIT>' . format ( name ) , <EOL> '<STR_LIT>' . format ( vcpus ) , <EOL> '<STR_LIT>' . format ( ram ) , <EOL> '<STR_LIT>' . format ( vnc_listen ) ] <EOL> for disk in disks : <EOL> if len ( disk ) == <NUM_LIT:2> : <EOL> options . append ( '<STR_LIT>' . format ( * disk ) ) <EOL> else : <EOL> options . append ( '<STR_LIT>' . format ( * disk ) ) <EOL> if cdrom_iso is None : <EOL> options . append ( '<STR_LIT>' ) <EOL> else : <EOL> options . append ( '<STR_LIT>' . format ( cdrom_iso ) ) <EOL> if os_type is not None : <EOL> options . append ( '<STR_LIT>' . format ( os_type ) ) <EOL> if os_variant is not None : <EOL> options . append ( '<STR_LIT>' . format ( os_variant ) ) <EOL> if networks is None or networks == [ ] : <EOL> options . append ( '<STR_LIT>' ) <EOL> else : <EOL> for network in networks : <EOL> options . append ( '<STR_LIT>' . format ( '<STR_LIT:U+002C>' . join ( network ) ) ) <EOL> if self . ssh_client is None : <EOL> self . ssh_client = SSHClient ( self . host , username = '<STR_LIT:root>' ) <EOL> self . ssh_client . run ( '<STR_LIT>' . format ( command , '<STR_LIT:U+0020>' . join ( options ) ) ) <EOL> if start is False : <EOL> self . ssh_client . run ( '<STR_LIT>' . format ( name ) ) </s>
