<s> import json <EOL> import os <EOL> from xml . etree import ElementTree <EOL> from cloudferry . lib . utils import log <EOL> LOG = log . getLogger ( __name__ ) <EOL> nova_instances_path = "<STR_LIT>" <EOL> def instance_path ( instance_id ) : <EOL> return os . path . join ( nova_instances_path , instance_id ) <EOL> def instance_image_path ( instance_id ) : <EOL> return os . path . join ( instance_path ( instance_id ) , "<STR_LIT>" ) <EOL> def _qemu_img_rebase ( src , dst ) : <EOL> return "<STR_LIT>" . format ( src = src , dst = dst ) <EOL> class QemuBackingFileMover ( object ) : <EOL> def __init__ ( self , runner , src , instance_id ) : <EOL> self . runner = runner <EOL> self . src = src <EOL> self . dst = instance_image_path ( instance_id ) <EOL> def __enter__ ( self ) : <EOL> cmd = _qemu_img_rebase ( self . src , self . dst ) <EOL> self . runner . run ( cmd ) <EOL> return self <EOL> def __exit__ ( self , exc_type , exc_val , exc_tb ) : <EOL> cmd = _qemu_img_rebase ( self . dst , self . src ) <EOL> self . runner . run_ignoring_errors ( cmd ) <EOL> return self <EOL> class DestNovaInstanceDestroyer ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , dest_libvirt , dest_nova , libvirt_name , nova_vm_id ) : <EOL> self . dest_libvirt = dest_libvirt <EOL> self . dest_nova = dest_nova <EOL> self . libvirt_name = libvirt_name <EOL> self . nova_vm_id = nova_vm_id <EOL> def __enter__ ( self ) : <EOL> self . do ( ) <EOL> def __exit__ ( self , exc_type , exc_val , exc_tb ) : <EOL> self . undo ( ) <EOL> def do ( self ) : <EOL> self . dest_libvirt . destroy_vm ( self . libvirt_name ) <EOL> def undo ( self ) : <EOL> try : <EOL> LOG . debug ( "<STR_LIT>" , self . nova_vm_id ) <EOL> self . dest_nova . reset_state ( self . nova_vm_id ) <EOL> self . dest_nova . delete_vm_by_id ( self . nova_vm_id ) <EOL> except RuntimeError : <EOL> pass <EOL> class Libvirt ( object ) : <EOL> def __init__ ( self , remote_runner ) : <EOL> """<STR_LIT>""" <EOL> self . runner = remote_runner <EOL> def get_backing_file ( self , instance_id ) : <EOL> cmd = ( "<STR_LIT>" . format ( <EOL> image_path = instance_image_path ( instance_id ) ) ) <EOL> try : <EOL> image_info = json . loads ( self . runner . run ( cmd ) ) <EOL> return image_info [ '<STR_LIT>' ] <EOL> except ( ValueError , TypeError ) as e : <EOL> LOG . error ( "<STR_LIT>" , e ) <EOL> except KeyError : <EOL> LOG . warning ( "<STR_LIT>" , <EOL> instance_id ) <EOL> def get_xml ( self , libvirt_instance_name ) : <EOL> cmd = ( "<STR_LIT>" . format ( <EOL> inst_name = libvirt_instance_name ) ) <EOL> return LibvirtXml ( self . runner . run ( cmd ) ) <EOL> def destroy_vm ( self , libvirt_instance_name ) : <EOL> cmds = [ <EOL> "<STR_LIT>" . format ( instance = libvirt_instance_name ) , <EOL> "<STR_LIT>" . format ( instance = libvirt_instance_name ) <EOL> ] <EOL> for cmd in cmds : <EOL> self . runner . run ( cmd ) <EOL> def move_backing_file ( self , source_file , instance_id ) : <EOL> cmd = _qemu_img_rebase ( src = source_file , <EOL> dst = instance_image_path ( instance_id ) ) <EOL> self . runner . run ( cmd ) <EOL> def live_migrate ( self , libvirt_instance_name , dest_host , migration_xml ) : <EOL> cmd = ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" . format ( instance = libvirt_instance_name , <EOL> dst_host = dest_host , <EOL> migration_xml = migration_xml ) ) <EOL> self . runner . run ( cmd ) <EOL> class LibvirtDeviceInterfaceHwAddress ( object ) : <EOL> def __init__ ( self , element ) : <EOL> self . type = element . get ( '<STR_LIT:type>' ) <EOL> self . domain = element . get ( '<STR_LIT>' ) <EOL> self . bus = element . get ( '<STR_LIT>' ) <EOL> self . slot = element . get ( '<STR_LIT>' ) <EOL> self . function = element . get ( '<STR_LIT>' ) <EOL> def __repr__ ( self ) : <EOL> return "<STR_LIT>" % ( self . type , self . bus , self . slot ) <EOL> def __eq__ ( self , other ) : <EOL> return ( isinstance ( other , self . __class__ ) and <EOL> self . type == other . type and <EOL> self . domain == other . domain and <EOL> self . bus == other . bus and <EOL> self . slot == other . slot and <EOL> self . function == other . function ) <EOL> class LibvirtDeviceInterface ( object ) : <EOL> def __init__ ( self , interface ) : <EOL> """<STR_LIT>""" <EOL> self . _xml_element = interface <EOL> self . mac = interface . find ( '<STR_LIT>' ) . get ( '<STR_LIT:address>' ) <EOL> self . source_iface = interface . find ( '<STR_LIT:source>' ) . get ( '<STR_LIT>' ) <EOL> self . target_iface = interface . find ( '<STR_LIT:target>' ) . get ( '<STR_LIT>' ) <EOL> self . hw_address = LibvirtDeviceInterfaceHwAddress ( <EOL> interface . find ( '<STR_LIT:address>' ) ) <EOL> def __eq__ ( self , other ) : <EOL> return ( isinstance ( other , self . __class__ ) and <EOL> self . source_iface == other . source_iface and <EOL> self . target_iface == other . target_iface and <EOL> self . hw_address == other . hw_address ) <EOL> def __repr__ ( self ) : <EOL> return "<STR_LIT>" . format ( <EOL> mac = self . mac , src = self . source_iface , dst = self . target_iface ) <EOL> @ classmethod <EOL> def _replace_attr ( cls , element , attr , value ) : <EOL> if element . get ( attr ) != value : <EOL> element . clear ( ) <EOL> element . attrib = { attr : value } <EOL> def element ( self ) : <EOL> source = self . _xml_element . find ( '<STR_LIT:source>' ) <EOL> target = self . _xml_element . find ( '<STR_LIT:target>' ) <EOL> self . _replace_attr ( source , '<STR_LIT>' , self . source_iface ) <EOL> self . _replace_attr ( target , '<STR_LIT>' , self . target_iface ) <EOL> return self . _xml_element <EOL> class LibvirtXml ( object ) : <EOL> def __init__ ( self , contents ) : <EOL> """<STR_LIT>""" <EOL> self . _xml = ElementTree . fromstring ( contents ) <EOL> self . _interfaces = [ LibvirtDeviceInterface ( i ) <EOL> for i in self . _xml . findall ( '<STR_LIT>' ) ] <EOL> self . disk_file = self . _get ( '<STR_LIT>' , '<STR_LIT:file>' ) <EOL> self . serial_file = self . _get ( '<STR_LIT>' , '<STR_LIT:path>' ) <EOL> self . console_file = self . _get ( '<STR_LIT>' , '<STR_LIT:path>' ) <EOL> def _get ( self , element , attribute ) : <EOL> el = self . _xml . find ( element ) <EOL> if el is not None : <EOL> return el . get ( attribute ) <EOL> def _set ( self , element , attribute , value ) : <EOL> el = self . _xml . find ( element ) <EOL> if el is not None : <EOL> el . set ( attribute , value ) <EOL> @ property <EOL> def interfaces ( self ) : <EOL> return self . _interfaces <EOL> @ interfaces . setter <EOL> def interfaces ( self , other ) : <EOL> """<STR_LIT>""" <EOL> if len ( self . interfaces ) != len ( other ) : <EOL> raise RuntimeError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> for other_iface in other : <EOL> for this_iface in self . interfaces : <EOL> identical = ( this_iface . mac == other_iface . mac ) <EOL> if identical : <EOL> this_iface . source_iface = other_iface . source_iface <EOL> this_iface . target_iface = other_iface . target_iface <EOL> break <EOL> def dump ( self ) : <EOL> self . _set ( '<STR_LIT>' , '<STR_LIT:file>' , self . disk_file ) <EOL> self . _set ( '<STR_LIT>' , '<STR_LIT:path>' , self . serial_file ) <EOL> self . _set ( '<STR_LIT>' , '<STR_LIT:path>' , self . console_file ) <EOL> xml_devices = self . _xml . find ( '<STR_LIT>' ) <EOL> xml_interfaces = self . _xml . findall ( '<STR_LIT>' ) <EOL> for iface in xml_interfaces : <EOL> xml_devices . remove ( iface ) <EOL> for iface in self . _interfaces : <EOL> xml_devices . append ( iface . element ( ) ) <EOL> return ElementTree . tostring ( self . _xml ) </s>
