<s> import datetime <EOL> import os <EOL> import subprocess <EOL> from time import sleep <EOL> import uuid <EOL> import xml . etree . ElementTree as ET <EOL> from django . conf import settings <EOL> from django . utils . functional import cached_property <EOL> import libvirt <EOL> import netaddr <EOL> from devops . driver . libvirt . libvirt_xml_builder import LibvirtXMLBuilder <EOL> from devops . error import DevopsError <EOL> from devops . helpers . helpers import deepgetattr <EOL> from devops . helpers . helpers import get_file_size <EOL> from devops . helpers . helpers import underscored <EOL> from devops . helpers . retry import retry <EOL> from devops . helpers import scancodes <EOL> from devops import logger <EOL> from devops . models . base import ParamField <EOL> from devops . models . base import ParamMultiField <EOL> from devops . models . driver import Driver <EOL> from devops . models . network import L2NetworkDevice <EOL> from devops . models . node import Node <EOL> from devops . models . volume import Volume <EOL> class _LibvirtManager ( object ) : <EOL> def __init__ ( self ) : <EOL> libvirt . virInitialize ( ) <EOL> self . connections = { } <EOL> def get_connection ( self , connection_string ) : <EOL> if connection_string not in self . connections : <EOL> conn = libvirt . open ( connection_string ) <EOL> self . connections [ connection_string ] = conn <EOL> else : <EOL> conn = self . connections [ connection_string ] <EOL> return conn <EOL> LibvirtManager = _LibvirtManager ( ) <EOL> class Snapshot ( object ) : <EOL> def __init__ ( self , snapshot ) : <EOL> self . _snapshot = snapshot <EOL> @ property <EOL> def xml ( self ) : <EOL> xml = self . _snapshot . getXMLDesc ( <NUM_LIT:0> ) <EOL> snapshot_xmltree = ET . fromstring ( xml ) <EOL> cpu = snapshot_xmltree . findall ( '<STR_LIT>' ) <EOL> if cpu and '<STR_LIT>' in cpu [ <NUM_LIT:0> ] . attrib : <EOL> cpu_mode = cpu [ <NUM_LIT:0> ] . get ( '<STR_LIT>' ) <EOL> if cpu_mode == '<STR_LIT>' : <EOL> domain = self . _snapshot . getDomain ( ) <EOL> domain_xml = domain . XMLDesc ( <EOL> libvirt . VIR_DOMAIN_XML_UPDATE_CPU ) <EOL> domain_xmltree = ET . fromstring ( domain_xml ) <EOL> cpu_element = domain_xmltree . find ( '<STR_LIT>' ) <EOL> domain_element = snapshot_xmltree . findall ( '<STR_LIT>' ) [ <NUM_LIT:0> ] <EOL> domain_element . remove ( domain_element . findall ( '<STR_LIT>' ) [ <NUM_LIT:0> ] ) <EOL> domain_element . append ( cpu_element ) <EOL> return ET . tostring ( snapshot_xmltree ) <EOL> @ property <EOL> def _xml_tree ( self ) : <EOL> return ET . fromstring ( self . xml ) <EOL> @ property <EOL> def children_num ( self ) : <EOL> return self . _snapshot . numChildren ( ) <EOL> @ property <EOL> def created ( self ) : <EOL> timestamp = self . _xml_tree . findall ( '<STR_LIT>' ) [ <NUM_LIT:0> ] . text <EOL> return datetime . datetime . utcfromtimestamp ( float ( timestamp ) ) <EOL> @ property <EOL> def disks ( self ) : <EOL> disks = { } <EOL> xml_snapshot_disks = self . _xml_tree . find ( '<STR_LIT>' ) <EOL> for xml_disk in xml_snapshot_disks : <EOL> if xml_disk . get ( '<STR_LIT>' ) == '<STR_LIT>' : <EOL> disks [ xml_disk . get ( '<STR_LIT:name>' ) ] = xml_disk . find ( <EOL> '<STR_LIT:source>' ) . get ( '<STR_LIT:file>' ) <EOL> return disks <EOL> @ property <EOL> def get_type ( self ) : <EOL> """<STR_LIT>""" <EOL> snap_memory = self . _xml_tree . findall ( '<STR_LIT>' ) [ <NUM_LIT:0> ] <EOL> if snap_memory . get ( '<STR_LIT>' ) == '<STR_LIT>' : <EOL> return '<STR_LIT>' <EOL> for disk in self . _xml_tree . iter ( '<STR_LIT>' ) : <EOL> if disk . get ( '<STR_LIT>' ) == '<STR_LIT>' : <EOL> return '<STR_LIT>' <EOL> return '<STR_LIT>' <EOL> @ property <EOL> def memory_file ( self ) : <EOL> return self . _xml_tree . findall ( '<STR_LIT>' ) [ <NUM_LIT:0> ] . get ( '<STR_LIT:file>' ) <EOL> @ property <EOL> def name ( self ) : <EOL> return self . _snapshot . getName ( ) <EOL> @ property <EOL> def parent ( self ) : <EOL> return self . _snapshot . getParent ( ) <EOL> @ property <EOL> def state ( self ) : <EOL> return self . _xml_tree . findall ( '<STR_LIT:state>' ) [ <NUM_LIT:0> ] . text <EOL> def delete ( self , flags ) : <EOL> return self . _snapshot . delete ( flags ) <EOL> def __repr__ ( self ) : <EOL> return "<STR_LIT>" . format ( self . __class__ . __name__ , <EOL> self . name , self . created ) <EOL> class LibvirtDriver ( Driver ) : <EOL> """<STR_LIT>""" <EOL> connection_string = ParamField ( default = "<STR_LIT>" ) <EOL> storage_pool_name = ParamField ( default = "<STR_LIT:default>" ) <EOL> stp = ParamField ( default = True ) <EOL> hpet = ParamField ( default = True ) <EOL> use_host_cpu = ParamField ( default = True ) <EOL> enable_acpi = ParamField ( default = False ) <EOL> reboot_timeout = ParamField ( ) <EOL> use_hugepages = ParamField ( default = False ) <EOL> vnc_password = ParamField ( ) <EOL> @ cached_property <EOL> def conn ( self ) : <EOL> """<STR_LIT>""" <EOL> return LibvirtManager . get_connection ( self . connection_string ) <EOL> def get_capabilities ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . capabilities <EOL> @ cached_property <EOL> @ retry ( ) <EOL> def capabilities ( self ) : <EOL> return ET . fromstring ( self . conn . getCapabilities ( ) ) <EOL> @ retry ( ) <EOL> def node_list ( self ) : <EOL> return [ item . name ( ) for item in self . conn . listAllDomains ( ) ] <EOL> @ retry ( ) <EOL> def get_allocated_networks ( self ) : <EOL> """<STR_LIT>""" <EOL> allocated_networks = [ ] <EOL> for network_name in self . conn . listDefinedNetworks ( ) : <EOL> et = ET . fromstring ( <EOL> self . conn . networkLookupByName ( network_name ) . XMLDesc ( <NUM_LIT:0> ) ) <EOL> ip = et . find ( '<STR_LIT>' ) <EOL> if ip is not None : <EOL> address = ip . get ( '<STR_LIT:address>' ) <EOL> prefix_or_netmask = ip . get ( '<STR_LIT>' ) or ip . get ( '<STR_LIT>' ) <EOL> allocated_networks . append ( netaddr . IPNetwork ( <EOL> "<STR_LIT>" . format ( address , prefix_or_netmask ) ) ) <EOL> return allocated_networks <EOL> def get_libvirt_version ( self ) : <EOL> return self . conn . getLibVersion ( ) <EOL> class LibvirtL2NetworkDevice ( L2NetworkDevice ) : <EOL> """<STR_LIT>""" <EOL> uuid = ParamField ( ) <EOL> forward = ParamMultiField ( <EOL> mode = ParamField ( <EOL> choices = ( None , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) , <EOL> ) <EOL> ) <EOL> dhcp = ParamField ( default = False ) <EOL> has_pxe_server = ParamField ( default = False ) <EOL> has_dhcp_server = ParamField ( default = False ) <EOL> tftp_root_dir = ParamField ( ) <EOL> vlan_ifaces = ParamField ( default = [ ] ) <EOL> parent_iface = ParamMultiField ( <EOL> phys_dev = ParamField ( default = None ) , <EOL> l2_net_dev = ParamField ( default = None ) , <EOL> tag = ParamField ( default = None ) , <EOL> ) <EOL> @ property <EOL> def _libvirt_network ( self ) : <EOL> try : <EOL> return self . driver . conn . networkLookupByUUIDString ( self . uuid ) <EOL> except libvirt . libvirtError : <EOL> logger . error ( "<STR_LIT>" . format ( self . uuid ) ) <EOL> return None <EOL> @ retry ( ) <EOL> def bridge_name ( self ) : <EOL> return self . _libvirt_network . bridgeName ( ) <EOL> @ retry ( ) <EOL> def network_name ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _libvirt_network . name ( ) <EOL> @ retry ( ) <EOL> def is_active ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _libvirt_network . isActive ( ) <EOL> @ retry ( ) <EOL> def define ( self ) : <EOL> network_name = underscored ( <EOL> deepgetattr ( self , '<STR_LIT>' ) , <EOL> self . name , <EOL> ) <EOL> bridge_name = '<STR_LIT>' . format ( self . id ) <EOL> for vlanid in self . vlan_ifaces : <EOL> self . iface_define ( name = bridge_name , vlanid = vlanid ) <EOL> ip_network_address = None <EOL> ip_network_prefixlen = None <EOL> dhcp_range_start = None <EOL> dhcp_range_end = None <EOL> addresses = [ ] <EOL> if self . address_pool is not None : <EOL> ip_network_address = self . address_pool . get_ip ( '<STR_LIT>' ) <EOL> if not ip_network_address : <EOL> ip_network_address = str ( self . address_pool . ip_network [ <NUM_LIT:1> ] ) <EOL> ip_network_prefixlen = str ( self . address_pool . ip_network . prefixlen ) <EOL> dhcp_range_start = self . address_pool . ip_range_start ( '<STR_LIT>' ) <EOL> dhcp_range_end = self . address_pool . ip_range_end ( '<STR_LIT>' ) <EOL> for interface in self . interfaces : <EOL> for address in interface . addresses : <EOL> ip_addr = netaddr . IPAddress ( address . ip_address ) <EOL> if ip_addr in self . address_pool . ip_network : <EOL> addresses . append ( dict ( <EOL> mac = str ( interface . mac_address ) , <EOL> ip = str ( address . ip_address ) , <EOL> name = interface . node . name <EOL> ) ) <EOL> xml = LibvirtXMLBuilder . build_network_xml ( <EOL> network_name = network_name , <EOL> bridge_name = bridge_name , <EOL> addresses = addresses , <EOL> forward = self . forward . mode , <EOL> ip_network_address = ip_network_address , <EOL> ip_network_prefixlen = ip_network_prefixlen , <EOL> dhcp_range_start = dhcp_range_start , <EOL> dhcp_range_end = dhcp_range_end , <EOL> stp = self . driver . stp , <EOL> has_pxe_server = self . has_pxe_server , <EOL> has_dhcp_server = self . has_dhcp_server , <EOL> tftp_root_dir = self . tftp_root_dir , <EOL> ) <EOL> ret = self . driver . conn . networkDefineXML ( xml ) <EOL> ret . setAutostart ( True ) <EOL> self . uuid = ret . UUIDString ( ) <EOL> super ( LibvirtL2NetworkDevice , self ) . define ( ) <EOL> def start ( self ) : <EOL> self . create ( ) <EOL> @ retry ( ) <EOL> def create ( self , * args , ** kwargs ) : <EOL> if not self . is_active ( ) : <EOL> self . _libvirt_network . create ( ) <EOL> parent_name = '<STR_LIT>' <EOL> if self . parent_iface . phys_dev is not None : <EOL> parent_name = self . parent_iface . phys_dev <EOL> elif self . parent_iface . l2_net_dev is not None : <EOL> l2_net_dev = self . group . environment . get_env_l2_network_device ( <EOL> name = self . parent_iface . l2_net_dev ) <EOL> parent_name = l2_net_dev . bridge_name ( ) <EOL> if parent_name is not '<STR_LIT>' : <EOL> if self . parent_iface . tag : <EOL> parent_iface_name = "<STR_LIT>" . format ( <EOL> parent_name , str ( self . parent_iface . tag ) ) <EOL> else : <EOL> parent_iface_name = parent_name <EOL> cmd = '<STR_LIT>' . format ( <EOL> br = self . bridge_name ( ) , iface = parent_iface_name ) <EOL> try : <EOL> subprocess . check_output ( cmd . split ( ) ) <EOL> except Exception : <EOL> pass <EOL> @ retry ( ) <EOL> def destroy ( self ) : <EOL> self . _libvirt_network . destroy ( ) <EOL> @ retry ( ) <EOL> def remove ( self , * args , ** kwargs ) : <EOL> if self . uuid : <EOL> if self . exists ( ) : <EOL> if self . is_active ( ) : <EOL> self . _libvirt_network . destroy ( ) <EOL> for vlanid in self . vlan_ifaces : <EOL> iface_name = "<STR_LIT>" . format ( self . bridge_name ( ) , <EOL> str ( vlanid ) ) <EOL> self . iface_undefine ( iface_name = iface_name ) <EOL> if self . _libvirt_network : <EOL> self . _libvirt_network . undefine ( ) <EOL> super ( LibvirtL2NetworkDevice , self ) . remove ( ) <EOL> @ retry ( ) <EOL> def exists ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> self . driver . conn . networkLookupByUUIDString ( self . uuid ) <EOL> return True <EOL> except libvirt . libvirtError as e : <EOL> if e . get_error_code ( ) == libvirt . VIR_ERR_NO_NETWORK : <EOL> return False <EOL> else : <EOL> raise <EOL> @ retry ( ) <EOL> def iface_define ( self , name , ip = None , prefix = None , vlanid = None ) : <EOL> """<STR_LIT>""" <EOL> self . driver . conn . interfaceDefineXML ( <EOL> LibvirtXMLBuilder . build_iface_xml ( name , ip , prefix , vlanid ) ) <EOL> @ retry ( ) <EOL> def iface_undefine ( self , iface_name ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> iface = self . driver . conn . interfaceLookupByName ( iface_name ) <EOL> except libvirt . libvirtError : <EOL> return None <EOL> iface . undefine ( ) <EOL> class LibvirtVolume ( Volume ) : <EOL> """<STR_LIT>""" <EOL> uuid = ParamField ( ) <EOL> capacity = ParamField ( default = None ) <EOL> format = ParamField ( default = '<STR_LIT>' , choices = ( '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> source_image = ParamField ( default = None ) <EOL> @ property <EOL> def _libvirt_volume ( self ) : <EOL> try : <EOL> return self . driver . conn . storageVolLookupByKey ( self . uuid ) <EOL> except libvirt . libvirtError : <EOL> logger . error ( "<STR_LIT>" . format ( self . uuid ) ) <EOL> return None <EOL> @ retry ( ) <EOL> def define ( self ) : <EOL> name = underscored ( <EOL> deepgetattr ( self , '<STR_LIT>' ) , <EOL> deepgetattr ( self , '<STR_LIT>' ) , <EOL> self . name , <EOL> ) <EOL> backing_store_path = None <EOL> backing_store_format = None <EOL> if self . backing_store is not None : <EOL> backing_store_path = self . backing_store . get_path ( ) <EOL> backing_store_format = self . backing_store . format <EOL> if self . source_image is not None : <EOL> capacity = get_file_size ( self . source_image ) <EOL> else : <EOL> capacity = int ( self . capacity * <NUM_LIT> ** <NUM_LIT:3> ) <EOL> pool_name = self . driver . storage_pool_name <EOL> pool = self . driver . conn . storagePoolLookupByName ( pool_name ) <EOL> xml = LibvirtXMLBuilder . build_volume_xml ( <EOL> name = name , <EOL> capacity = capacity , <EOL> format = self . format , <EOL> backing_store_path = backing_store_path , <EOL> backing_store_format = backing_store_format , <EOL> ) <EOL> libvirt_volume = pool . createXML ( xml , <NUM_LIT:0> ) <EOL> self . uuid = libvirt_volume . key ( ) <EOL> super ( LibvirtVolume , self ) . define ( ) <EOL> if self . source_image is not None : <EOL> self . upload ( self . source_image ) <EOL> @ retry ( ) <EOL> def remove ( self , * args , ** kwargs ) : <EOL> if self . uuid : <EOL> if self . exists ( ) : <EOL> self . _libvirt_volume . delete ( <NUM_LIT:0> ) <EOL> super ( LibvirtVolume , self ) . remove ( ) <EOL> @ retry ( ) <EOL> def get_capacity ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _libvirt_volume . info ( ) [ <NUM_LIT:1> ] <EOL> @ retry ( ) <EOL> def get_format ( self ) : <EOL> xml_desc = ET . fromstring ( self . _libvirt_volume . XMLDesc ( <NUM_LIT:0> ) ) <EOL> return xml_desc . find ( '<STR_LIT>' ) . get ( '<STR_LIT:type>' ) <EOL> @ retry ( ) <EOL> def get_path ( self ) : <EOL> return self . _libvirt_volume . path ( ) <EOL> def fill_from_exist ( self ) : <EOL> self . capacity = self . get_capacity ( ) <EOL> self . format = self . get_format ( ) <EOL> @ retry ( count = <NUM_LIT:2> ) <EOL> def upload ( self , path ) : <EOL> size = get_file_size ( path ) <EOL> with open ( path , '<STR_LIT:rb>' ) as fd : <EOL> stream = self . driver . conn . newStream ( <NUM_LIT:0> ) <EOL> self . _libvirt_volume . upload ( <EOL> stream = stream , offset = <NUM_LIT:0> , <EOL> length = size , flags = <NUM_LIT:0> ) <EOL> stream . sendAll ( self . chunk_render , fd ) <EOL> stream . finish ( ) <EOL> def chunk_render ( self , stream , size , fd ) : <EOL> return fd . read ( size ) <EOL> @ retry ( ) <EOL> def get_allocation ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _libvirt_volume . info ( ) [ <NUM_LIT:2> ] <EOL> @ retry ( ) <EOL> def exists ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> self . driver . conn . storageVolLookupByKey ( self . uuid ) <EOL> return True <EOL> except libvirt . libvirtError as e : <EOL> if e . get_error_code ( ) == libvirt . VIR_ERR_NO_STORAGE_VOL : <EOL> return False <EOL> else : <EOL> raise <EOL> def create_child ( self , name ) : <EOL> """<STR_LIT>""" <EOL> cls = self . driver . get_model_class ( '<STR_LIT>' ) <EOL> return cls . objects . create ( <EOL> name = name , <EOL> capacity = self . capacity , <EOL> node = self . node , <EOL> format = self . format , <EOL> backing_store = self , <EOL> ) <EOL> @ classmethod <EOL> def volume_get_predefined ( cls , uuid ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> volume = cls . objects . get ( uuid = uuid ) <EOL> except cls . DoesNotExist : <EOL> volume = cls ( uuid = uuid ) <EOL> volume . fill_from_exist ( ) <EOL> volume . save ( ) <EOL> return volume <EOL> class LibvirtNode ( Node ) : <EOL> """<STR_LIT>""" <EOL> uuid = ParamField ( ) <EOL> hypervisor = ParamField ( default = '<STR_LIT>' , choices = ( '<STR_LIT>' , '<STR_LIT:test>' ) ) <EOL> os_type = ParamField ( default = '<STR_LIT>' , choices = [ '<STR_LIT>' ] ) <EOL> architecture = ParamField ( default = '<STR_LIT>' , choices = [ '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> boot = ParamField ( default = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> vcpu = ParamField ( default = <NUM_LIT:1> ) <EOL> memory = ParamField ( default = <NUM_LIT> ) <EOL> has_vnc = ParamField ( default = True ) <EOL> bootmenu_timeout = ParamField ( default = <NUM_LIT:0> ) <EOL> numa = ParamField ( default = [ ] ) <EOL> @ property <EOL> def _libvirt_node ( self ) : <EOL> try : <EOL> return self . driver . conn . lookupByUUIDString ( self . uuid ) <EOL> except libvirt . libvirtError : <EOL> logger . error ( "<STR_LIT>" . format ( self . uuid ) ) <EOL> return None <EOL> @ retry ( ) <EOL> def get_vnc_port ( self ) : <EOL> """<STR_LIT>""" <EOL> xml_desc = ET . fromstring ( <EOL> self . _libvirt_node . XMLDesc ( <NUM_LIT:0> ) ) <EOL> vnc_element = xml_desc . find ( '<STR_LIT>' ) <EOL> if vnc_element is not None : <EOL> return vnc_element . get ( '<STR_LIT:port>' ) <EOL> @ property <EOL> def vnc_password ( self ) : <EOL> return self . driver . vnc_password <EOL> @ retry ( ) <EOL> def exists ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> self . driver . conn . lookupByUUIDString ( self . uuid ) <EOL> return True <EOL> except libvirt . libvirtError as e : <EOL> if e . get_error_code ( ) == libvirt . VIR_ERR_NO_DOMAIN : <EOL> return False <EOL> else : <EOL> raise <EOL> @ retry ( ) <EOL> def is_active ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _libvirt_node . isActive ( ) <EOL> @ retry ( ) <EOL> def send_keys ( self , keys ) : <EOL> """<STR_LIT>""" <EOL> key_codes = scancodes . from_string ( str ( keys ) ) <EOL> for key_code in key_codes : <EOL> if isinstance ( key_code [ <NUM_LIT:0> ] , str ) : <EOL> if key_code [ <NUM_LIT:0> ] == '<STR_LIT>' : <EOL> sleep ( <NUM_LIT:1> ) <EOL> continue <EOL> self . _libvirt_node . sendKey ( <NUM_LIT:0> , <NUM_LIT:0> , list ( key_code ) , len ( key_code ) , <NUM_LIT:0> ) <EOL> @ retry ( ) <EOL> def define ( self ) : <EOL> """<STR_LIT>""" <EOL> name = underscored ( <EOL> deepgetattr ( self , '<STR_LIT>' ) , <EOL> self . name , <EOL> ) <EOL> local_disk_devices = [ ] <EOL> for disk in self . disk_devices : <EOL> local_disk_devices . append ( dict ( <EOL> disk_type = disk . type , <EOL> disk_device = disk . device , <EOL> disk_volume_format = disk . volume . format , <EOL> disk_volume_path = disk . volume . get_path ( ) , <EOL> disk_bus = disk . bus , <EOL> disk_target_dev = disk . target_dev , <EOL> disk_serial = uuid . uuid4 ( ) . hex , <EOL> ) ) <EOL> local_interfaces = [ ] <EOL> for interface in self . interfaces : <EOL> if interface . type != '<STR_LIT>' : <EOL> raise NotImplementedError ( <EOL> message = '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> l2_dev = interface . l2_network_device <EOL> local_interfaces . append ( dict ( <EOL> interface_type = interface . type , <EOL> interface_mac_address = interface . mac_address , <EOL> interface_network_name = l2_dev . network_name ( ) , <EOL> interface_id = interface . id , <EOL> interface_model = interface . model , <EOL> ) ) <EOL> emulator = self . driver . get_capabilities ( ) . find ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' . format ( <EOL> self . architecture , self . hypervisor ) ) . text <EOL> node_xml = LibvirtXMLBuilder . build_node_xml ( <EOL> name = name , <EOL> hypervisor = self . hypervisor , <EOL> use_host_cpu = self . driver . use_host_cpu , <EOL> vcpu = self . vcpu , <EOL> memory = self . memory , <EOL> use_hugepages = self . driver . use_hugepages , <EOL> hpet = self . driver . hpet , <EOL> os_type = self . os_type , <EOL> architecture = self . architecture , <EOL> boot = self . boot , <EOL> reboot_timeout = self . driver . reboot_timeout , <EOL> bootmenu_timeout = self . bootmenu_timeout , <EOL> emulator = emulator , <EOL> has_vnc = self . has_vnc , <EOL> vnc_password = self . driver . vnc_password , <EOL> local_disk_devices = local_disk_devices , <EOL> interfaces = local_interfaces , <EOL> acpi = self . driver . enable_acpi , <EOL> numa = self . numa , <EOL> ) <EOL> logger . info ( node_xml ) <EOL> self . uuid = self . driver . conn . defineXML ( node_xml ) . UUIDString ( ) <EOL> super ( LibvirtNode , self ) . define ( ) <EOL> def start ( self ) : <EOL> self . create ( ) <EOL> @ retry ( ) <EOL> def create ( self , * args , ** kwargs ) : <EOL> if not self . is_active ( ) : <EOL> self . _libvirt_node . create ( ) <EOL> @ retry ( ) <EOL> def destroy ( self , * args , ** kwargs ) : <EOL> if self . is_active ( ) : <EOL> self . _libvirt_node . destroy ( ) <EOL> @ retry ( ) <EOL> def remove ( self , * args , ** kwargs ) : <EOL> if self . uuid : <EOL> if self . exists ( ) : <EOL> self . destroy ( ) <EOL> for snapshot in self . get_snapshots ( ) : <EOL> self . _delete_snapshot_files ( snapshot ) <EOL> if self . _libvirt_node : <EOL> self . _libvirt_node . undefineFlags ( <EOL> libvirt . VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA ) <EOL> super ( LibvirtNode , self ) . remove ( ) <EOL> @ retry ( ) <EOL> def suspend ( self , * args , ** kwargs ) : <EOL> if self . is_active ( ) : <EOL> self . _libvirt_node . suspend ( ) <EOL> @ retry ( ) <EOL> def resume ( self , * args , ** kwargs ) : <EOL> if self . is_active ( ) : <EOL> domain = self . _libvirt_node <EOL> if domain . info ( ) [ <NUM_LIT:0> ] == libvirt . VIR_DOMAIN_PAUSED : <EOL> domain . resume ( ) <EOL> @ retry ( ) <EOL> def reboot ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _libvirt_node . reboot ( ) <EOL> @ retry ( ) <EOL> def shutdown ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _libvirt_node . shutdown ( ) <EOL> @ retry ( ) <EOL> def reset ( self ) : <EOL> self . _libvirt_node . reset ( ) <EOL> @ retry ( ) <EOL> def has_snapshot ( self , name ) : <EOL> return name in self . _libvirt_node . snapshotListNames ( ) <EOL> def snapshot_create_child_volumes ( self , name ) : <EOL> for disk in self . disk_devices : <EOL> if disk . device == '<STR_LIT>' : <EOL> back_vol_name = disk . volume . name <EOL> back_count = <NUM_LIT:0> <EOL> disk_test = disk . volume . backing_store <EOL> while disk_test is not None : <EOL> back_count += <NUM_LIT:1> <EOL> back_vol_name = disk_test . name <EOL> disk_test = disk_test . backing_store <EOL> if back_count > <NUM_LIT> : <EOL> raise DevopsError ( <EOL> "<STR_LIT>" <EOL> . format ( back_vol_name , name ) ) <EOL> vol_child = disk . volume . create_child ( <EOL> name = '<STR_LIT>' . format ( back_vol_name , name ) , <EOL> ) <EOL> vol_child . define ( ) <EOL> disk . volume = vol_child <EOL> disk . save ( ) <EOL> def _assert_snapshot_type ( self , external = False ) : <EOL> snap_list = self . get_snapshots ( ) <EOL> if len ( snap_list ) > <NUM_LIT:0> : <EOL> snap_type = snap_list [ <NUM_LIT:0> ] . get_type <EOL> if external and snap_type == '<STR_LIT>' : <EOL> raise DevopsError ( <EOL> "<STR_LIT>" ) <EOL> if not external and snap_type == '<STR_LIT>' : <EOL> raise DevopsError ( <EOL> "<STR_LIT>" ) <EOL> def set_snapshot_current ( self , name ) : <EOL> snapshot = self . _get_snapshot ( name ) <EOL> self . _libvirt_node . snapshotCreateXML ( <EOL> snapshot . xml , <EOL> libvirt . VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE | <EOL> libvirt . VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT ) <EOL> @ retry ( ) <EOL> def snapshot ( self , name = None , force = False , description = None , <EOL> disk_only = False , external = False ) : <EOL> if self . has_snapshot ( name ) : <EOL> if force : <EOL> self . erase_snapshot ( name ) <EOL> else : <EOL> raise DevopsError ( "<STR_LIT>" <EOL> . format ( name ) ) <EOL> self . _assert_snapshot_type ( external = external ) <EOL> local_disk_devices = [ ] <EOL> if external : <EOL> if self . driver . get_libvirt_version ( ) < <NUM_LIT> : <EOL> raise DevopsError ( <EOL> "<STR_LIT>" ) <EOL> if not os . path . exists ( settings . SNAPSHOTS_EXTERNAL_DIR ) : <EOL> os . makedirs ( settings . SNAPSHOTS_EXTERNAL_DIR ) <EOL> self . snapshot_create_child_volumes ( name ) <EOL> base_memory_file = '<STR_LIT>' . format ( <EOL> settings . SNAPSHOTS_EXTERNAL_DIR , <EOL> deepgetattr ( self , '<STR_LIT>' ) , <EOL> self . name , <EOL> name ) <EOL> file_count = <NUM_LIT:0> <EOL> memory_file = base_memory_file <EOL> while os . path . exists ( memory_file ) : <EOL> memory_file = base_memory_file + '<STR_LIT:->' + str ( file_count ) <EOL> file_count += <NUM_LIT:1> <EOL> for disk in self . disk_devices : <EOL> if disk . device == '<STR_LIT>' : <EOL> local_disk_devices . append ( dict ( <EOL> disk_volume_path = disk . volume . get_path ( ) , <EOL> disk_target_dev = disk . target_dev , <EOL> ) ) <EOL> if self . is_active ( ) and not disk_only : <EOL> create_xml_flag = libvirt . VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT <EOL> else : <EOL> create_xml_flag = ( <EOL> libvirt . VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY | <EOL> libvirt . VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT <EOL> ) <EOL> else : <EOL> memory_file = '<STR_LIT>' <EOL> create_xml_flag = <NUM_LIT:0> <EOL> xml = LibvirtXMLBuilder . build_snapshot_xml ( <EOL> name = name , <EOL> description = description , <EOL> external = external , <EOL> disk_only = disk_only , <EOL> memory_file = memory_file , <EOL> domain_isactive = self . is_active ( ) , <EOL> local_disk_devices = local_disk_devices <EOL> ) <EOL> domain = self . _libvirt_node <EOL> logger . info ( xml ) <EOL> logger . info ( domain . state ( <NUM_LIT:0> ) ) <EOL> domain . snapshotCreateXML ( xml , create_xml_flag ) <EOL> if external : <EOL> self . set_snapshot_current ( name ) <EOL> logger . info ( domain . state ( <NUM_LIT:0> ) ) <EOL> def _delete_snapshot_files ( self , snapshot ) : <EOL> """<STR_LIT>""" <EOL> snap_type = snapshot . get_type <EOL> if snap_type == '<STR_LIT>' : <EOL> for snap_file in self . _get_snapshot_files ( snapshot ) : <EOL> if os . path . isfile ( snap_file ) : <EOL> try : <EOL> os . remove ( snap_file ) <EOL> logger . info ( <EOL> "<STR_LIT>" . format ( <EOL> snap_file ) ) <EOL> except Exception : <EOL> logger . info ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" . format ( <EOL> snap_file ) ) <EOL> def _get_snapshot_files ( self , snapshot ) : <EOL> """<STR_LIT>""" <EOL> snap_files = [ ] <EOL> snap_memory = snapshot . _xml_tree . findall ( '<STR_LIT>' ) [ <NUM_LIT:0> ] <EOL> if snap_memory . get ( '<STR_LIT:file>' ) is not None : <EOL> snap_files . append ( snap_memory . get ( '<STR_LIT:file>' ) ) <EOL> return snap_files <EOL> def _redefine_external_snapshot ( self , name = None ) : <EOL> snapshot = self . _get_snapshot ( name ) <EOL> logger . info ( "<STR_LIT>" . format ( <EOL> self . name , snapshot . state , name ) ) <EOL> self . destroy ( ) <EOL> xml_domain = snapshot . _xml_tree . find ( '<STR_LIT>' ) <EOL> if snapshot . children_num == <NUM_LIT:0> : <EOL> domain_disks = xml_domain . findall ( '<STR_LIT>' ) <EOL> for s_disk , s_disk_data in snapshot . disks . items ( ) : <EOL> for d_disk in domain_disks : <EOL> d_disk_dev = d_disk . find ( '<STR_LIT:target>' ) . get ( '<STR_LIT>' ) <EOL> d_disk_device = d_disk . get ( '<STR_LIT>' ) <EOL> if d_disk_dev == s_disk and d_disk_device == '<STR_LIT>' : <EOL> d_disk . find ( '<STR_LIT:source>' ) . set ( '<STR_LIT:file>' , s_disk_data ) <EOL> if snapshot . state == '<STR_LIT>' : <EOL> self . driver . conn . defineXML ( ET . tostring ( xml_domain ) ) <EOL> else : <EOL> self . driver . conn . restoreFlags ( <EOL> snapshot . memory_file , <EOL> dxml = ET . tostring ( xml_domain ) , <EOL> flags = libvirt . VIR_DOMAIN_SAVE_PAUSED ) <EOL> self . set_snapshot_current ( name ) <EOL> def _update_disks_from_snapshot ( self , name ) : <EOL> """<STR_LIT>""" <EOL> snapshot = self . _get_snapshot ( name ) <EOL> for snap_disk , snap_disk_file in snapshot . disks . items ( ) : <EOL> for disk in self . disk_devices : <EOL> if snap_disk == disk . target_dev : <EOL> if snapshot . children_num == <NUM_LIT:0> : <EOL> disk . volume = self . get_volume ( uuid = snap_disk_file ) <EOL> else : <EOL> disk . volume = self . get_volume ( <EOL> uuid = snap_disk_file ) . backing_store <EOL> disk . save ( ) <EOL> @ retry ( ) <EOL> def _node_revert_snapshot_recreate_disks ( self , name ) : <EOL> """<STR_LIT>""" <EOL> snapshot = self . _get_snapshot ( name ) <EOL> if snapshot . children_num == <NUM_LIT:0> : <EOL> for s_disk_data in snapshot . disks . values ( ) : <EOL> logger . info ( "<STR_LIT>" . format ( s_disk_data ) ) <EOL> volume = self . driver . conn . storageVolLookupByKey ( s_disk_data ) <EOL> volume_xml = volume . XMLDesc ( ) <EOL> volume_pool = volume . storagePoolLookupByVolume ( ) <EOL> volume . delete ( ) <EOL> volume_pool . createXML ( volume_xml ) <EOL> def _revert_external_snapshot ( self , name = None ) : <EOL> snapshot = self . _get_snapshot ( name ) <EOL> self . destroy ( ) <EOL> if snapshot . children_num == <NUM_LIT:0> : <EOL> logger . info ( "<STR_LIT>" ) <EOL> self . _update_disks_from_snapshot ( name ) <EOL> self . _node_revert_snapshot_recreate_disks ( name ) <EOL> self . _redefine_external_snapshot ( name = name ) <EOL> else : <EOL> revert_name = name + '<STR_LIT>' <EOL> revert_count = <NUM_LIT:0> <EOL> create_new = True <EOL> while self . has_snapshot ( revert_name ) : <EOL> snapshot_revert = self . _get_snapshot ( revert_name ) <EOL> if snapshot_revert . children_num == <NUM_LIT:0> : <EOL> logger . info ( <EOL> "<STR_LIT>" ) <EOL> self . _update_disks_from_snapshot ( revert_name ) <EOL> self . _node_revert_snapshot_recreate_disks ( revert_name ) <EOL> self . _redefine_external_snapshot ( name = revert_name ) <EOL> create_new = False <EOL> break <EOL> else : <EOL> revert_name = name + '<STR_LIT>' + str ( revert_count ) <EOL> revert_count += <NUM_LIT:1> <EOL> if create_new : <EOL> logger . info ( "<STR_LIT>" ) <EOL> self . _update_disks_from_snapshot ( name ) <EOL> self . _redefine_external_snapshot ( name = name ) <EOL> self . snapshot ( name = revert_name , external = True ) <EOL> @ retry ( ) <EOL> def revert ( self , name = None , destroy = True ) : <EOL> """<STR_LIT>""" <EOL> if destroy : <EOL> self . destroy ( ) <EOL> if self . has_snapshot ( name ) : <EOL> snapshot = self . _get_snapshot ( name ) <EOL> if snapshot . get_type == '<STR_LIT>' : <EOL> self . _revert_external_snapshot ( name ) <EOL> else : <EOL> logger . info ( "<STR_LIT>" . format ( <EOL> self . name , snapshot . state , name ) ) <EOL> self . _libvirt_node . revertToSnapshot ( snapshot . _snapshot , <NUM_LIT:0> ) <EOL> else : <EOL> raise DevopsError ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' . format ( self . name , name ) ) <EOL> def _get_snapshot ( self , name ) : <EOL> """<STR_LIT>""" <EOL> if name is None : <EOL> return Snapshot ( self . _libvirt_node . snapshotCurrent ( <NUM_LIT:0> ) ) <EOL> else : <EOL> return Snapshot ( self . _libvirt_node . snapshotLookupByName ( name , <NUM_LIT:0> ) ) <EOL> @ retry ( ) <EOL> def get_snapshots ( self ) : <EOL> """<STR_LIT>""" <EOL> snapshots = self . _libvirt_node . listAllSnapshots ( <NUM_LIT:0> ) <EOL> return [ Snapshot ( snap ) for snap in snapshots ] <EOL> @ retry ( ) <EOL> def erase_snapshot ( self , name ) : <EOL> if self . has_snapshot ( name ) : <EOL> snapshot = self . _get_snapshot ( name ) <EOL> snap_type = snapshot . get_type <EOL> if snap_type == '<STR_LIT>' : <EOL> if snapshot . children_num > <NUM_LIT:0> : <EOL> logger . error ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> return <EOL> self . destroy ( ) <EOL> xml_domain = snapshot . _xml_tree . find ( '<STR_LIT>' ) <EOL> self . driver . conn . defineXML ( ET . tostring ( xml_domain ) ) <EOL> self . _delete_snapshot_files ( snapshot ) <EOL> snapshot . delete ( <NUM_LIT:2> ) <EOL> for disk in self . disk_devices : <EOL> if disk . device == '<STR_LIT>' : <EOL> snap_disk = disk . volume <EOL> disk . volume = disk . volume . backing_store <EOL> disk . save ( ) <EOL> snap_disk . remove ( ) <EOL> else : <EOL> snapshot . delete ( <NUM_LIT:0> ) <EOL> @ retry ( ) <EOL> def set_vcpu ( self , vcpu ) : <EOL> """<STR_LIT>""" <EOL> if vcpu is not None and vcpu != self . vcpu : <EOL> self . vcpu = vcpu <EOL> domain = self . _libvirt_node <EOL> domain . setVcpusFlags ( vcpu , <NUM_LIT:4> ) <EOL> domain . setVcpusFlags ( vcpu , <NUM_LIT:2> ) <EOL> self . save ( ) <EOL> @ retry ( ) <EOL> def set_memory ( self , memory ) : <EOL> """<STR_LIT>""" <EOL> if memory is not None and memory != self . memory : <EOL> self . memory = memory <EOL> domain = self . _libvirt_node <EOL> domain . setMaxMemory ( memory * <NUM_LIT> ) <EOL> domain . setMemoryFlags ( memory * <NUM_LIT> , <NUM_LIT:2> ) <EOL> self . save ( ) <EOL> @ retry ( ) <EOL> def get_interface_target_dev ( self , mac ) : <EOL> """<STR_LIT>""" <EOL> xml_desc = ET . fromstring ( self . _libvirt_node . XMLDesc ( <NUM_LIT:0> ) ) <EOL> target = xml_desc . find ( '<STR_LIT>' % mac ) <EOL> if target is not None : <EOL> return target . get ( '<STR_LIT>' ) </s>
