def __init__(self, uuid, record): self.__uuid = uuid # First check this class implements all the correct methods: for attr_ro in self.getAttrRO() + self.getAttrRW(): if not hasattr(self, "get_%s" % attr_ro): raise ImplementationError(self.getClass(), "get_%s" % attr_ro) for attr_rw in self.getAttrRW(): if not hasattr(self, "set_%s" % attr_rw): raise ImplementationError(self.getClass(), "set_%s" % attr_rw) for method in self.getMethods(): if not hasattr(self, method): raise ImplementationError(self.getClass(), method) for func in self.getFuncs(): if not hasattr(self.__class__, func): raise ImplementationError(self.getClass(), func) # Next check that the class is being created with the correct # parameters if not isinstance(record, dict): raise CreateUnspecifiedAttributeError("record", self.getClass()) for attr_inst in self.getAttrInst(): if attr_inst not in record: raise CreateUnspecifiedAttributeError(attr_inst, self.getClass()) setattr(self, attr_inst, record[attr_inst]) # Finally register it XendAPIStore.register(uuid, self.getClass(), self)
def remove_PPCI(self, pci_name): # Update lspci info PciUtil.create_lspci_info() # Remove the PPCI (domain, bus, slot, func) = PciUtil.parse_pci_name(pci_name) ppci_ref = XendPPCI.get_by_sbdf(domain, bus, slot, func) XendAPIStore.get(ppci_ref, "PPCI").destroy() self.save_PPCIs()
def get_PSCSI_HBAs(self): PSCSIs = [] uuid = self.get_uuid() for dscsi in XendAPIStore.get_all('DSCSI'): if dscsi.get_VM() == self.VM and dscsi.get_HBA() == uuid: PSCSIs.append(dscsi.get_PSCSI()) PSCSI_HBAs = [] for pscsi_uuid in PSCSIs: pscsi_HBA_uuid = XendAPIStore.get(pscsi_uuid, 'PSCSI').get_HBA() if not pscsi_HBA_uuid in PSCSI_HBAs: PSCSI_HBAs.append(pscsi_HBA_uuid) return PSCSI_HBAs
def remove_PSCSI(self, rem_HCTL): saved_pscsis = self.state_store.load_state('pscsi') if not saved_pscsis: return # Remove the PSCSI for pscsi_record in saved_pscsis.values(): if rem_HCTL == pscsi_record['physical_HCTL']: pscsi_ref = XendPSCSI.get_by_HCTL(rem_HCTL) XendAPIStore.get(pscsi_ref, "PSCSI").destroy() self.save_PSCSIs() return
def get_DSCSIs(self): DSCSIs = [] uuid = self.get_uuid() for dscsi in XendAPIStore.get_all('DSCSI'): if dscsi.get_VM() == self.VM and dscsi.get_HBA() == uuid: DSCSIs.append(dscsi.get_uuid()) return DSCSIs
def _init_networks(self): # Initialise networks # First configure ones off disk saved_networks = self.state_store.load_state('network') if saved_networks: for net_uuid, network in saved_networks.items(): try: XendNetwork.recreate(network, net_uuid) except CreateUnspecifiedAttributeError: log.warn("Error recreating network %s", net_uuid) # Next discover any existing bridges and check # they are not already configured # 'tmpbridge' is a temporary bridge created by network-bridge script. # Wait a couple of seconds for it to be renamed. for i in xrange(20): bridges = Brctl.get_state().keys() if 'tmpbridge' in bridges: time.sleep(0.1) else: break configured_bridges = [XendAPIStore.get( network_uuid, "network") .get_name_label() for network_uuid in XendNetwork.get_all()] unconfigured_bridges = [bridge for bridge in bridges if bridge not in configured_bridges] for unconfigured_bridge in unconfigured_bridges: if unconfigured_bridge != 'tmpbridge': XendNetwork.create_phy(unconfigured_bridge)
def save_PSCSI_HBAs(self): pscsi_HBA_records = dict([ (pscsi_HBA_uuid, XendAPIStore.get(pscsi_HBA_uuid, "PSCSI_HBA").get_record()) for pscsi_HBA_uuid in XendPSCSI_HBA.get_all() ]) self.state_store.save_state('pscsi_HBA', pscsi_HBA_records)
def _init_networks(self): # Initialise networks # First configure ones off disk saved_networks = self.state_store.load_state('network') if saved_networks: for net_uuid, network in saved_networks.items(): try: XendNetwork.recreate(network, net_uuid) except CreateUnspecifiedAttributeError: log.warn("Error recreating network %s", net_uuid) # Next discover any existing bridges and check # they are not already configured # 'tmpbridge' is a temporary bridge created by network-bridge script. # Wait a couple of seconds for it to be renamed. for i in xrange(20): bridges = Brctl.get_state().keys() if 'tmpbridge' in bridges: time.sleep(0.1) else: break configured_bridges = [ XendAPIStore.get(network_uuid, "network").get_name_label() for network_uuid in XendNetwork.get_all() ] unconfigured_bridges = [ bridge for bridge in bridges if bridge not in configured_bridges ] for unconfigured_bridge in unconfigured_bridges: if unconfigured_bridge != 'tmpbridge': XendNetwork.create_phy(unconfigured_bridge)
def recreate_active_pools(cls): """ Read active pool config from hypervisor and create pool instances. - Query pool ids and assigned CPUs from hypervisor. - Query additional information for any pool from xenstore. If an entry for a pool id is missing in xenstore, it will be recreated with a new uuid and generic name (this is an error case) - Create an XendCPUPool instance for any pool id Function have to be called after recreation of managed pools. """ log.debug('recreate_active_pools') for pool_rec in xc.cpupool_getinfo(): pool = pool_rec['cpupool'] # read pool data from xenstore path = XS_POOLROOT + "%s/" % pool uuid = xstransact.Read(path, 'uuid') if not uuid: # xenstore entry missing / invaild; create entry with new uuid uuid = genuuid.createString() name = "Pool-%s" % pool try: inst = XendCPUPool({'name_label': name}, uuid, False) inst.update_XS(pool) except PoolError, ex: # log error and skip domain log.error('cannot recreate pool %s; skipping (reason: %s)' \ % (name, ex)) else: (name, descr) = xstransact.Read(path, 'name', 'description') other_config = {} for key in xstransact.List(path + 'other_config'): other_config[key] = xstransact.Read(path + 'other_config/%s' % key) # check existance of pool instance inst = XendAPIStore.get(uuid, cls.getClass()) if inst: # update attributes of existing instance inst.name_label = name inst.name_description = descr inst.other_config = other_config else: # recreate instance try: inst = XendCPUPool( { 'name_label': name, 'name_description': descr, 'other_config': other_config, 'proposed_CPUs': pool_rec['cpulist'], 'ncpu': len(pool_rec['cpulist']), }, uuid, False) except PoolError, ex: # log error and skip domain log.error( 'cannot recreate pool %s; skipping (reason: %s)' \ % (name, ex))
def _get_ovs_name(self): network_refs = XendNetwork.get_all() network_names = [] for ref in network_refs: network = XendAPIStore.get(ref, "network") namelabel = network.get_name_label() network_names.append(namelabel) return network_names
def get_by_uuid(cls, uuid): # Sanity check the uuid is one of us me = XendAPIStore.get(uuid, cls.getClass()) if me is not None and me.getClass() == cls.getClass(): # In OSS, ref == uuid return uuid else: raise "Big Error.. TODO!"
def unplug(self): """Unplug the PIF from the network""" network = XendAPIStore.get(self.network, "network") bridge_name = network.get_name_label() from xen.util import Brctl Brctl.vif_bridge_rem({"bridge": bridge_name, "vif": self.get_interface_name()})
def save_cpu_pools(self): cpu_pool_records = dict([ (cpu_pool_uuid, XendAPIStore.get(cpu_pool_uuid, XendCPUPool.getClass()).get_record()) for cpu_pool_uuid in XendCPUPool.get_all_managed() ]) self.state_store.save_state(XendCPUPool.getClass(), cpu_pool_records)
def get_by_uuid(cls, uuid): # Sanity check the uuid is one of us me = XendAPIStore.get(uuid, cls.getClass()) if me is not None and me.getClass() == cls.getClass(): # In OSS, ref == uuid return uuid else: raise ValueError("Big Error.. TODO!")
def recreate_active_pools(cls): """ Read active pool config from hypervisor and create pool instances. - Query pool ids and assigned CPUs from hypervisor. - Query additional information for any pool from xenstore. If an entry for a pool id is missing in xenstore, it will be recreated with a new uuid and generic name (this is an error case) - Create an XendCPUPool instance for any pool id Function have to be called after recreation of managed pools. """ log.debug('recreate_active_pools') for pool_rec in xc.cpupool_getinfo(): pool = pool_rec['cpupool'] # read pool data from xenstore path = XS_POOLROOT + "%s/" % pool uuid = xstransact.Read(path, 'uuid') if not uuid: # xenstore entry missing / invaild; create entry with new uuid uuid = genuuid.createString() name = "Pool-%s" % pool try: inst = XendCPUPool( { 'name_label' : name }, uuid, False ) inst.update_XS(pool) except PoolError, ex: # log error and skip domain log.error('cannot recreate pool %s; skipping (reason: %s)' \ % (name, ex)) else: (name, descr) = xstransact.Read(path, 'name', 'description') other_config = {} for key in xstransact.List(path + 'other_config'): other_config[key] = xstransact.Read( path + 'other_config/%s' % key) # check existance of pool instance inst = XendAPIStore.get(uuid, cls.getClass()) if inst: # update attributes of existing instance inst.name_label = name inst.name_description = descr inst.other_config = other_config else: # recreate instance try: inst = XendCPUPool( { 'name_label' : name, 'name_description' : descr, 'other_config' : other_config, 'proposed_CPUs' : pool_rec['cpulist'], 'ncpu' : len(pool_rec['cpulist']), }, uuid, False ) except PoolError, ex: # log error and skip domain log.error( 'cannot recreate pool %s; skipping (reason: %s)' \ % (name, ex))
def __init__(self): self.host_instance = XendNode.instance() self.host_cpus = self.host_instance.get_host_cpu_refs() pif_refs = self.host_instance.get_PIF_refs() self.host_pifs = [] for pif_ref in pif_refs: pif = XendAPIStore.get(pif_ref, "PIF") self.host_pifs.append(pif)
def move_domain(cls, pool_ref, domid): cls.pool_lock.acquire() try: pool = XendAPIStore.get(pool_ref, cls.getClass()) pool_id = pool.query_pool_id() xc.cpupool_movedomain(pool_id, domid) finally: cls.pool_lock.release()
def unplug(self): """Unplug the PIF from the network""" network = XendAPIStore.get(self.network, "network") bridge_name = network.get_name_label() from xen.util import Brctl Brctl.vif_bridge_rem({ "bridge": bridge_name, "vif": self.get_interface_name() })
def _init_PIFs(self): # Initialise PIFs # First configure ones off disk saved_pifs = self.state_store.load_state('pif') if saved_pifs: for pif_uuid, pif in saved_pifs.items(): try: XendPIF.recreate(pif, pif_uuid) except CreateUnspecifiedAttributeError: log.warn("Error recreating PIF %s", pif_uuid) # Next discover any existing PIFs and check # they are not already configured configured_pifs = [XendAPIStore.get( pif_uuid, "PIF") .get_interface_name() for pif_uuid in XendPIF.get_all()] unconfigured_pifs = [(name, mtu, mac) for name, mtu, mac in linux_get_phy_ifaces() if name not in configured_pifs] # Get a mapping from interface to bridge if_to_br = dict([(i,b) for (b,ifs) in Brctl.get_state().items() for i in ifs]) for name, mtu, mac in unconfigured_pifs: # Check PIF is on bridge # if not, ignore bridge_name = if_to_br.get(name, None) if bridge_name is not None: # Translate bridge name to network uuid for network_uuid in XendNetwork.get_all(): network = XendAPIStore.get( network_uuid, 'network') if network.get_name_label() == bridge_name: XendPIF.create_phy(network_uuid, name, mac, mtu) break else: log.debug("Cannot find network for bridge %s " "when configuring PIF %s", (bridge_name, name))
def remove_PSCSI(self, rem_HCTL): saved_pscsis = self.state_store.load_state('pscsi') if not saved_pscsis: return # Remove the PSCSI for pscsi_record in saved_pscsis.values(): if rem_HCTL == pscsi_record['physical_HCTL']: pscsi_ref = XendPSCSI.get_by_HCTL(rem_HCTL) XendAPIStore.get(pscsi_ref, "PSCSI").destroy() self.save_PSCSIs() physical_host = int(rem_HCTL.split(':')[0]) pscsi_HBA_ref = XendPSCSI_HBA.get_by_physical_host(physical_host) if pscsi_HBA_ref: if not XendAPIStore.get(pscsi_HBA_ref, 'PSCSI_HBA').get_PSCSIs(): XendAPIStore.get(pscsi_HBA_ref, 'PSCSI_HBA').destroy() self.save_PSCSI_HBAs() return
def _init_PIFs(self): # Initialise PIFs # First configure ones off disk saved_pifs = self.state_store.load_state('pif') if saved_pifs: for pif_uuid, pif in saved_pifs.items(): try: XendPIF.recreate(pif, pif_uuid) except CreateUnspecifiedAttributeError: log.warn("Error recreating PIF %s", pif_uuid) # Next discover any existing PIFs and check # they are not already configured configured_pifs = [ XendAPIStore.get(pif_uuid, "PIF").get_interface_name() for pif_uuid in XendPIF.get_all() ] unconfigured_pifs = [(name, mtu, mac) for name, mtu, mac in linux_get_phy_ifaces() if name not in configured_pifs] # Get a mapping from interface to bridge if_to_br = dict([(i, b) for (b, ifs) in Brctl.get_state().items() for i in ifs]) for name, mtu, mac in unconfigured_pifs: # Check PIF is on bridge # if not, ignore bridge_name = if_to_br.get(name, None) if bridge_name is not None: # Translate bridge name to network uuid for network_uuid in XendNetwork.get_all(): network = XendAPIStore.get(network_uuid, 'network') if network.get_name_label() == bridge_name: XendPIF.create_phy(network_uuid, name, mac, mtu) break else: log.debug( "Cannot find network for bridge %s " "when configuring PIF %s", (bridge_name, name))
def autostart_pools(cls): """ Start managed pools that are marked as autostart pools. Function is called after recreation of managed domains while xend restart. """ cls.pool_lock.acquire() try: for inst in XendAPIStore.get_all(cls.getClass()): if inst.is_managed() and inst.auto_power_on and \ inst.query_pool_id() == None: inst.activate() finally: cls.pool_lock.release()
def get_by_name_label(cls, name_label): """ Query a Pool(ref) by its name. @return: ref of pool @rtype: str """ cls.pool_lock.acquire() try: return [ inst.get_uuid() for inst in XendAPIStore.get_all(cls.getClass()) if inst.name_label == name_label ] finally: cls.pool_lock.release()
def remove_PSCSI(self, rem_HCTL): saved_pscsis = self.state_store.load_state('pscsi') if not saved_pscsis: return # Remove the PSCSI for pscsi_record in saved_pscsis.values(): if rem_HCTL == pscsi_record['physical_HCTL']: pscsi_ref = XendPSCSI.get_by_HCTL(rem_HCTL) XendAPIStore.get(pscsi_ref, "PSCSI").destroy() self.save_PSCSIs() physical_host = int(rem_HCTL.split(':')[0]) pscsi_HBA_ref = XendPSCSI_HBA.get_by_physical_host( physical_host) if pscsi_HBA_ref: if not XendAPIStore.get(pscsi_HBA_ref, 'PSCSI_HBA').get_PSCSIs(): XendAPIStore.get(pscsi_HBA_ref, 'PSCSI_HBA').destroy() self.save_PSCSI_HBAs() return
def get_all_managed(cls): """ Query all managed pools. @return: uuids of all managed pools @rtype: list of str """ cls.pool_lock.acquire() try: managed_pools = [ inst.get_uuid() for inst in XendAPIStore.get_all(cls.getClass()) if inst.is_managed() ] finally: cls.pool_lock.release() return managed_pools
def __init__(self, uuid, record): self.__uuid = uuid # First check this class implements all the correct methods: for attr_ro in self.getAttrRO() + self.getAttrRW(): if not hasattr(self, "get_%s" % attr_ro): raise ImplementationError(self.getClass(), "get_%s" % attr_ro) for attr_rw in self.getAttrRW(): if not hasattr(self, "set_%s" % attr_rw): raise ImplementationError(self.getClass(), "set_%s" % attr_rw) for method in self.getMethods(): if not hasattr(self, method): raise ImplementationError(self.getClass(), method) for func in self.getFuncs(): if not hasattr(self.__class__, func): raise ImplementationError(self.getClass(), func) # Next check that the class is being created with the correct # parameters if not isinstance(record, dict): raise CreateUnspecifiedAttributeError( "record" , self.getClass()) for attr_inst in self.getAttrInst(): if attr_inst not in record: raise CreateUnspecifiedAttributeError( attr_inst, self.getClass()) setattr(self, attr_inst, record[attr_inst]) # Finally register it XendAPIStore.register(uuid, self.getClass(), self)
def lookup_pool(cls, id_or_name): """ Search XendCPUPool instance with given id_or_name. @param id_or_name: pool id or pool nameto search @type id_or_name: [int, str] @return: instane or None if not found @rtype: XendCPUPool """ pool_uuid = None try: pool_id = int(id_or_name) # pool id given ? pool_uuid = cls.query_pool_ref(pool_id) if not pool_uuid: # not found -> search name pool_uuid = cls.get_by_name_label(id_or_name) except ValueError: # pool name given pool_uuid = cls.get_by_name_label(id_or_name) if len(pool_uuid) > 0: return XendAPIStore.get(pool_uuid[0], cls.getClass()) else: return None
def create(self, dpci_struct): # Check if VM is valid xendom = XendDomain.instance() if not xendom.is_valid_vm(dpci_struct['VM']): raise InvalidHandleError('VM', dpci_struct['VM']) dom = xendom.get_vm_by_uuid(dpci_struct['VM']) # Check if PPCI is valid xennode = XendNode.instance() ppci_uuid = xennode.get_ppci_by_uuid(dpci_struct['PPCI']) if not ppci_uuid: raise InvalidHandleError('PPCI', dpci_struct['PPCI']) for existing_dpci in XendAPIStore.get_all('DPCI'): if ppci_uuid == existing_dpci.get_PPCI(): raise DirectPCIError("Device is in use") # Assign PPCI to VM try: dpci_ref = XendTask.log_progress(0, 100, dom.create_dpci, dpci_struct) except XendError, e: raise DirectPCIError("Failed to assign device")
def bridge_to_network(self, bridge): """ Determine which network a particular bridge is attached to. @param bridge The name of the bridge. If empty, the default bridge will be used instead (the first one in the list returned by brctl show); this is the behaviour of the vif-bridge script. @return The XendNetwork instance to which this bridge is attached. @raise Exception if the interface is not connected to a network. """ if not bridge: rc, bridge = commands.getstatusoutput( 'brctl show | cut -d "\n" -f 2 | cut -f 1') if rc != 0 or not bridge: raise Exception( 'Could not find default bridge, and none was specified') for network_uuid in XendNetwork.get_all(): network = XendAPIStore.get(network_uuid, "network") if network.get_name_label() == bridge: return network else: raise Exception('Cannot find network for bridge %s' % bridge)
def save_PBDs(self): pbd_records = dict([(pbd_uuid, XendAPIStore.get( pbd_uuid, "PBD").get_record()) for pbd_uuid in XendPBD.get_all()]) self.state_store.save_state('pbd', pbd_records)
def save_PIFs(self): pif_records = dict([(pif_uuid, XendAPIStore.get( pif_uuid, "PIF").get_record()) for pif_uuid in XendPIF.get_all()]) self.state_store.save_state('pif', pif_records)
def save_networks(self): net_records = dict([(network_uuid, XendAPIStore.get( network_uuid, "network").get_record()) for network_uuid in XendNetwork.get_all()]) self.state_store.save_state('network', net_records)
def get_by_VM(cls, VM_ref): result = [] for dscsi_HBA in XendAPIStore.get_all("DSCSI_HBA"): if dscsi_HBA.get_VM() == VM_ref: result.append(dscsi_HBA.get_uuid()) return result
def get_by_SR(cls, sr_ref): pbds = XendAPIStore.get_all("PBD") return [pbd.get_uuid() for pbd in pbds if pbd.get_SR() == sr_ref]
def get_by_name_label(cls, name): return [ inst.get_uuid() for inst in XendAPIStore.get_all(cls.getClass()) if inst.get_name_label() == name ]
def get_all(cls): return XendAPIStore.get_all_uuid(cls.getClass())
def save_PPCIs(self): ppci_records = dict([(ppci_uuid, XendAPIStore.get( ppci_uuid, "PPCI").get_record()) for ppci_uuid in XendPPCI.get_all()]) self.state_store.save_state('ppci', ppci_records)
def save_cpu_pools(self): cpu_pool_records = dict([(cpu_pool_uuid, XendAPIStore.get( cpu_pool_uuid, XendCPUPool.getClass()).get_record()) for cpu_pool_uuid in XendCPUPool.get_all_managed()]) self.state_store.save_state(XendCPUPool.getClass(), cpu_pool_records)
def save_PBDs(self): pbd_records = dict([(pbd_uuid, XendAPIStore.get(pbd_uuid, "PBD").get_record()) for pbd_uuid in XendPBD.get_all()]) self.state_store.save_state('pbd', pbd_records)
def save_PPCIs(self): ppci_records = dict([(ppci_uuid, XendAPIStore.get(ppci_uuid, "PPCI").get_record()) for ppci_uuid in XendPPCI.get_all()]) self.state_store.save_state('ppci', ppci_records)
def save_networks(self): net_records = dict([(network_uuid, XendAPIStore.get(network_uuid, "network").get_record()) for network_uuid in XendNetwork.get_all()]) self.state_store.save_state('network', net_records)
def save_PIFs(self): pif_records = dict([(pif_uuid, XendAPIStore.get(pif_uuid, "PIF").get_record()) for pif_uuid in XendPIF.get_all()]) self.state_store.save_state('pif', pif_records)
def get_pif_metrics(self, pif): return XendAPIStore.get(pif.get_metrics(), "PIF_metrics")
def get_vcpus_num(self, vm): return XendAPIStore.get(vm.get_metrics(),"VM_metrics").get_VCPUs_number()
def get_by_VM(cls, VM_ref): result = [] for dscsi in XendAPIStore.get_all("DSCSI"): if dscsi.get_VM() == VM_ref: result.append(dscsi.get_uuid()) return result
def save_PSCSI_HBAs(self): pscsi_HBA_records = dict([(pscsi_HBA_uuid, XendAPIStore.get( pscsi_HBA_uuid, "PSCSI_HBA").get_record()) for pscsi_HBA_uuid in XendPSCSI_HBA.get_all()]) self.state_store.save_state('pscsi_HBA', pscsi_HBA_records)
def destroy(self): XendAPIStore.deregister(self.get_uuid(), self.getClass())
def get_all_records(cls): return dict([(inst.get_uuid(), inst.get_record()) for inst in XendAPIStore.get_all(cls.getClass())])
def get_PIFs(self): pifs = XendAPIStore.get_all("PIF") return [ pif.get_uuid() for pif in pifs if pif.get_network() == self.get_uuid() ]