def create_phy(self, network_uuid, device, MAC, MTU): """ Called when a new physical PIF is found Could be a VLAN... """ # Create new uuids pif_uuid = genuuid.createString() metrics_uuid = genuuid.createString() # Create instances metrics = XendPIFMetrics(metrics_uuid, pif_uuid) # Is this a VLAN? VLANdot = device.split(".") VLANcolon = device.split(":") if len(VLANdot) > 1: VLAN = VLANdot[1] device = VLANdot[0] elif len(VLANcolon) > 1: VLAN = VLANcolon[1] device = VLANcolon[0] else: VLAN = -1 record = {"network": network_uuid, "device": device, "MAC": MAC, "MTU": MTU, "VLAN": VLAN} pif = XendPIF(record, pif_uuid, metrics_uuid) return pif_uuid
def create_phy(self, network_uuid, device, MAC, MTU): """ Called when a new physical PIF is found Could be a VLAN... """ # Create new uuids pif_uuid = genuuid.createString() metrics_uuid = genuuid.createString() # Create instances metrics = XendPIFMetrics(metrics_uuid, pif_uuid) # Is this a VLAN? VLANdot = device.split(".") VLANcolon = device.split(":") if len(VLANdot) > 1: VLAN = VLANdot[1] device = VLANdot[0] elif len(VLANcolon) > 1: VLAN = VLANcolon[1] device = VLANcolon[0] else: VLAN = -1 record = { 'network': network_uuid, 'device': device, 'MAC': MAC, 'MTU': MTU, 'VLAN': VLAN } pif = XendPIF(record, pif_uuid, metrics_uuid) return pif_uuid
def create_VLAN(self, device, network_uuid, host_ref, vlan): """Exposed via API - create a new VLAN from existing VIF""" ifs = [name for name, _, _ in linux_get_phy_ifaces()] vlan = int(vlan) # Check VLAN tag is valid if vlan < 0 or vlan >= 4096: raise VLANTagInvalid(vlan) # Check device exists if device not in ifs: raise InvalidDeviceError(device) # Check VLAN doesn't already exist if "%s.%d" % (device, vlan) in ifs: raise DeviceExistsError("%s.%d" % (device, vlan)) # Check network ref is valid from XendNetwork import XendNetwork if network_uuid not in XendNetwork.get_all(): raise InvalidHandleError("Network", network_uuid) # Check host_ref is this host import XendNode if host_ref != XendNode.instance().get_uuid(): raise InvalidHandleError("Host", host_ref) # Create the VLAN _create_VLAN(device, vlan) # Create new uuids pif_uuid = genuuid.createString() metrics_uuid = genuuid.createString() # Create the record record = { "device": device, "MAC": linux_get_mac("%s.%d" % (device, vlan)), "MTU": linux_get_mtu("%s.%d" % (device, vlan)), "network": network_uuid, "VLAN": vlan, } # Create instances metrics = XendPIFMetrics(metrics_uuid, pif_uuid) pif = XendPIF(record, pif_uuid, metrics_uuid) # Not sure if they should be created plugged or not... pif.plug() XendNode.instance().save_PIFs() return pif_uuid
def create_VLAN(self, device, network_uuid, host_ref, vlan): """Exposed via API - create a new VLAN from existing VIF""" ifs = [name for name, _, _ in linux_get_phy_ifaces()] vlan = int(vlan) # Check VLAN tag is valid if vlan < 0 or vlan >= 4096: raise VLANTagInvalid(vlan) # Check device exists if device not in ifs: raise InvalidDeviceError(device) # Check VLAN doesn't already exist if "%s.%d" % (device, vlan) in ifs: raise DeviceExistsError("%s.%d" % (device, vlan)) # Check network ref is valid from XendNetwork import XendNetwork if network_uuid not in XendNetwork.get_all(): raise InvalidHandleError("Network", network_uuid) # Check host_ref is this host import XendNode if host_ref != XendNode.instance().get_uuid(): raise InvalidHandleError("Host", host_ref) # Create the VLAN _create_VLAN(device, vlan) # Create new uuids pif_uuid = genuuid.createString() metrics_uuid = genuuid.createString() # Create the record record = { "device": device, "MAC": '', "MTU": '', "network": network_uuid, "VLAN": vlan } # Create instances metrics = XendPIFMetrics(metrics_uuid, pif_uuid) pif = XendPIF(record, pif_uuid, metrics_uuid) # Not sure if they should be created plugged or not... pif.plug() XendNode.instance().save_PIFs() return pif_uuid
def __init__(self, maxpolicies): """ Create a management class for managing the system's policies. @param maxpolicies: The max. number of policies allowed on the system (currently '1') """ self.maxpolicies = maxpolicies self.policies = {} self.xsobjs = {} act_pol_name = self.get_hv_loaded_policy_name() initialize() ref = uuid.createString() try: self.xsobjs[ref] = ACMPolicy(name=act_pol_name, ref=ref) self.policies[ref] = (act_pol_name, xsconstants.ACM_POLICY_ID) except Exception, e: log.error("Could not find XML representation of policy '%s': " "%s" % (act_pol_name, e)) rc, errors, acmpol_def = ACMPolicy.force_default_policy() if rc == xsconstants.XSERR_SUCCESS: self.xsobjs[ref] = acmpol_def self.policies[ref] = (acmpol_def.get_name(), xsconstants.ACM_POLICY_ID) log.info("Switched to DEFAULT policy.")
def __init__(self, maxpolicies): """ Create a management class for managing the system's policies. @param maxpolicies: The max. number of policies allowed on the system (currently '1') """ self.maxpolicies = maxpolicies self.policies = {} self.xsobjs = {} act_pol_name = self.get_hv_loaded_policy_name() initialize() ref = uuid.createString() try: self.xsobjs[ref] = ACMPolicy(name=act_pol_name, ref=ref) self.policies[ref] = (act_pol_name, xsconstants.ACM_POLICY_ID) except Exception, e: log.error("Could not find XML representation of policy '%s': " "%s" % (act_pol_name,e)) rc, errors, acmpol_def = ACMPolicy.force_default_policy() if rc == xsconstants.XSERR_SUCCESS: self.xsobjs[ref] = acmpol_def self.policies[ref] = (acmpol_def.get_name(), xsconstants.ACM_POLICY_ID) log.info("Switched to DEFAULT policy.")
def create_task(func, args, func_name, return_type, label, session): """Creates a new Task and registers it with the XendTaskManager. @param func: callable object XMLRPC method @type func: callable object @param args: tuple or list of arguments @type args: tuple or list @param func_name: XMLRPC method name, so we can estimate the progress @type func_name: string @return: Task UUID @rtype: string. """ task_uuid = uuid.createString() try: tasks_lock.acquire() task = XendTask(task_uuid, func, args, func_name, return_type, label, '', session) tasks[task_uuid] = task finally: tasks_lock.release() task.start() return task_uuid
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 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 login_unconditionally(self, username): """Returns a session UUID if valid. @rtype: string @return: Session UUID """ new_session = uuid.createString() self.sessions[new_session] = (username, time.time()) return new_session
def create(cls, record): """ Create a new managed pool instance. @param record: attributes of pool @type record: dict @return: uuid of created pool @rtype: str """ new_uuid = genuuid.createString() XendCPUPool(record, new_uuid) XendNode.instance().save_cpu_pools() return new_uuid
def pool_create(cls, config): try: record = sxp2map(config) if record.has_key('proposed_CPUs') and \ not isinstance(record['proposed_CPUs'], types.ListType): record['proposed_CPUs'] = [record['proposed_CPUs']] new_uuid = genuuid.createString() pool = XendCPUPool(record, new_uuid, False) pool.activate() except XendAPIError, ex: raise VmError(ex.get_api_error())
def __acm_init(self): act_pol_name = self.get_hv_loaded_policy_name() initialize() ref = uuid.createString() try: self.xsobjs[ref] = ACMPolicy(name=act_pol_name, ref=ref) self.policies[ref] = (act_pol_name, xsconstants.ACM_POLICY_ID) self.xsobjs[ref].validate_enforced_policy_hash() except Exception, e: log.error("Could not find XML representation of policy '%s': " "%s" % (act_pol_name,e)) rc, errors, acmpol_def = ACMPolicy.force_default_policy(ref) if rc == xsconstants.XSERR_SUCCESS: self.xsobjs[ref] = acmpol_def self.policies[ref] = (acmpol_def.get_name(), xsconstants.ACM_POLICY_ID) log.info("Switched to DEFAULT policy.")
def __acm_init(self): act_pol_name = self.get_hv_loaded_policy_name() initialize() ref = uuid.createString() try: self.xsobjs[ref] = ACMPolicy(name=act_pol_name, ref=ref) self.policies[ref] = (act_pol_name, xsconstants.ACM_POLICY_ID) self.xsobjs[ref].validate_enforced_policy_hash() except Exception, e: log.error("Could not find XML representation of policy '%s': " "%s" % (act_pol_name, e)) rc, errors, acmpol_def = ACMPolicy.force_default_policy(ref) if rc == xsconstants.XSERR_SUCCESS: self.xsobjs[ref] = acmpol_def self.policies[ref] = (acmpol_def.get_name(), xsconstants.ACM_POLICY_ID) log.info("Switched to DEFAULT policy.")
def create_phy(self, name): """ Called when a new bridge is found on xend start """ # Create new uuids uuid = genuuid.createString() # Create instance record = { 'name_label': name, 'name_description': '', 'other_config': {}, 'default_gateway': '', 'default_netmask': '', 'managed': False, } network = XendNetwork(record, uuid) return uuid
def create(self, record): """ Called from API, to create a new network """ # Create new uuids uuid = genuuid.createString() # Create instance (do this first, to check record) network = XendNetwork(record, uuid) # Check network doesn't already exist name_label = network.name_label if bridge_exists(name_label): del network raise UniqueNameError(name_label, "network") # Create the bridge Brctl.bridge_create(network.name_label) XendNode.instance().save_networks() return uuid
def create(cls, record): uuid = genuuid.createString() pbd = XendPBD(record, uuid) return uuid
def __add_acmpolicy_to_system(self, xmltext, flags, overwrite): errors = "" if security.on() != xsconstants.XS_POLICY_ACM: raise SecurityError(-xsconstants.XSERR_POLICY_TYPE_UNSUPPORTED) loadedpol = self.get_loaded_policy() if loadedpol: # This is meant as an update to a currently loaded policy if flags & xsconstants.XS_INST_LOAD == 0: raise SecurityError(-xsconstants.XSERR_POLICY_LOADED) # Remember old flags, so they can be restored if update fails old_flags = self.get_policy_flags(loadedpol) # Remove policy from bootloader in case of new name of policy self.rm_bootpolicy() rc, errors = loadedpol.update(xmltext) if rc == 0: irc = self.activate_xspolicy(loadedpol, flags) # policy is loaded; if setting the boot flag fails it's ok. else: old_flags = old_flags & xsconstants.XS_INST_BOOT log.info("OLD FLAGS TO RESTORE: %s" % str(old_flags)) if old_flags != 0: self.activate_xspolicy(loadedpol, xsconstants.XS_INST_BOOT) return (loadedpol, rc, errors) try: dom = minidom.parseString(xmltext.encode("utf-8")) except: raise SecurityError(-xsconstants.XSERR_BAD_XML) ref = uuid.createString() acmpol = ACMPolicy(dom=dom, ref=ref) #First some basic tests that do not modify anything: if flags & xsconstants.XS_INST_BOOT and not overwrite: filename = acmpol.get_filename(".bin","",dotted=True) if bootloader.get_default_policy != None and \ not bootloader.loads_default_policy(filename): raise SecurityError(-xsconstants.XSERR_BOOTPOLICY_INSTALLED) if not overwrite and len(self.policies) >= self.maxpolicies: raise SecurityError(-xsconstants.XSERR_BOOTPOLICY_INSTALLED) if overwrite: #This should only give one key since only one policy is #allowed. keys = self.policies.keys() for k in keys: self.rm_bootpolicy() rc = self.rm_policy_from_system(k, force=overwrite) if rc != xsconstants.XSERR_SUCCESS: raise SecurityError(rc) rc = acmpol.compile() if rc != 0: raise SecurityError(rc) if flags & xsconstants.XS_INST_LOAD: rc = acmpol.loadintohv() if rc != 0: raise SecurityError(rc) if flags & xsconstants.XS_INST_BOOT: rc = self.make_boot_policy(acmpol) if rc != 0: # If it cannot be installed due to unsupported # bootloader, let it be ok. pass if dom: new_entry = { ref : tuple([acmpol.get_name(), xsconstants.ACM_POLICY_ID]) } self.policies.update(new_entry) self.xsobjs[ref] = acmpol return (acmpol, xsconstants.XSERR_SUCCESS, errors)
def pci_convert_sxp_to_dict(dev_sxp): """Convert pci device sxp to dict @param dev_sxp: device configuration @type dev_sxp: SXP object (parsed config) @return: dev_config @rtype: dictionary """ # Parsing the device SXP's. In most cases, the SXP looks # like this: # # [device, [vif, [mac, xx:xx:xx:xx:xx:xx], [ip 1.3.4.5]]] # # However, for PCI devices it looks like this: # # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2]]] # # It seems the reasoning for this difference is because # pciif.py needs all the PCI device configurations at # the same time when creating the devices. # # To further complicate matters, Xen 2.0 configuration format # uses the following for pci device configuration: # # [device, [pci, [domain, 0], [bus, 0], [dev, 1], [func, 2]]] # For PCI device hotplug support, the SXP of PCI devices is # extendend like this: # # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2], # [vdevfn, 0]], # [state, 'Initialising']]] # # 'vdevfn' shows the virtual hotplug slot number which the PCI device # is inserted in. This is only effective for HVM domains. # # state 'Initialising' indicates that the device is being attached, # while state 'Closing' indicates that the device is being detached. # # The Dict looks like this: # # { devs: [{domain: 0, bus: 0, slot: 1, func: 2, vdevfn: 0}], # states: ['Initialising'] } dev_config = {} pci_devs = [] for pci_dev in sxp.children(dev_sxp, 'dev'): pci_dev_info = dict(pci_dev[1:]) if 'opts' in pci_dev_info: pci_dev_info['opts'] = pci_opts_list_from_sxp(pci_dev) # If necessary, initialize uuid, key, and vdevfn for each pci device if not pci_dev_info.has_key('uuid'): pci_dev_info['uuid'] = uuid.createString() if not pci_dev_info.has_key('key'): pci_dev_info['key'] = "%02x:%02x.%x" % \ (int(pci_dev_info['bus'], 16), int(pci_dev_info['slot'], 16), int(pci_dev_info['func'], 16)) if not pci_dev_info.has_key('vdevfn'): pci_dev_info['vdevfn'] = "0x%02x" % AUTO_PHP_SLOT pci_devs.append(pci_dev_info) dev_config['devs'] = pci_devs pci_states = [] for pci_state in sxp.children(dev_sxp, 'state'): try: pci_states.append(pci_state[1]) except IndexError: raise XendError("Error reading state while parsing pci sxp") dev_config['states'] = pci_states return dev_config
def __add_acmpolicy_to_system(self, xmltext, flags, overwrite): errors = "" if security.on() != xsconstants.XS_POLICY_ACM: raise SecurityError(-xsconstants.XSERR_POLICY_TYPE_UNSUPPORTED) loadedpol = self.get_loaded_policy() if loadedpol: # This is meant as an update to a currently loaded policy if flags & xsconstants.XS_INST_LOAD == 0: raise SecurityError(-xsconstants.XSERR_POLICY_LOADED) # Remember old flags, so they can be restored if update fails old_flags = self.get_policy_flags(loadedpol) # Remove policy from bootloader in case of new name of policy self.rm_bootpolicy() rc, errors = loadedpol.update(xmltext) if rc == 0: irc = self.activate_xspolicy(loadedpol, flags) # policy is loaded; if setting the boot flag fails it's ok. else: old_flags = old_flags & xsconstants.XS_INST_BOOT log.info("OLD FLAGS TO RESTORE: %s" % str(old_flags)) if old_flags != 0: self.activate_xspolicy(loadedpol, xsconstants.XS_INST_BOOT) return (loadedpol, rc, errors) try: dom = minidom.parseString(xmltext.encode("utf-8")) except: raise SecurityError(-xsconstants.XSERR_BAD_XML) ref = uuid.createString() acmpol = ACMPolicy(dom=dom, ref=ref) #First some basic tests that do not modify anything: if flags & xsconstants.XS_INST_BOOT and not overwrite: filename = acmpol.get_filename(".bin", "", dotted=True) if bootloader.get_default_policy != None and \ not bootloader.loads_default_policy(filename): raise SecurityError(-xsconstants.XSERR_BOOTPOLICY_INSTALLED) if not overwrite and len(self.policies) >= self.maxpolicies: raise SecurityError(-xsconstants.XSERR_BOOTPOLICY_INSTALLED) if overwrite: #This should only give one key since only one policy is #allowed. keys = self.policies.keys() for k in keys: self.rm_bootpolicy() rc = self.rm_policy_from_system(k, force=overwrite) if rc != xsconstants.XSERR_SUCCESS: raise SecurityError(rc) rc = acmpol.compile() if rc != 0: raise SecurityError(rc) if flags & xsconstants.XS_INST_LOAD: rc = acmpol.loadintohv() if rc != 0: raise SecurityError(rc) if flags & xsconstants.XS_INST_BOOT: rc = self.make_boot_policy(acmpol) if rc != 0: # If it cannot be installed due to unsupported # bootloader, let it be ok. pass if dom: new_entry = { ref: tuple([acmpol.get_name(), xsconstants.ACM_POLICY_ID]) } self.policies.update(new_entry) self.xsobjs[ref] = acmpol return (acmpol, xsconstants.XSERR_SUCCESS, errors)
def pci_convert_sxp_to_dict(dev_sxp): """Convert pci device sxp to dict @param dev_sxp: device configuration @type dev_sxp: SXP object (parsed config) @return: dev_config @rtype: dictionary """ # Parsing the device SXP's. In most cases, the SXP looks # like this: # # [device, [vif, [mac, xx:xx:xx:xx:xx:xx], [ip 1.3.4.5]]] # # However, for PCI devices it looks like this: # # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2]]] # # It seems the reasoning for this difference is because # pciif.py needs all the PCI device configurations at # the same time when creating the devices. # # To further complicate matters, Xen 2.0 configuration format # uses the following for pci device configuration: # # [device, [pci, [domain, 0], [bus, 0], [dev, 1], [func, 2]]] # For PCI device hotplug support, the SXP of PCI devices is # extendend like this: # # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2], # [vdevfn, 0]], # [state, 'Initialising']]] # # 'vdevfn' shows the virtual hotplug slot number which the PCI device # is inserted in. This is only effective for HVM domains. # # state 'Initialising' indicates that the device is being attached, # while state 'Closing' indicates that the device is being detached. # # The Dict looks like this: # # { devs: [{domain: 0, bus: 0, slot: 1, func: 2, vdevfn: 0}], # states: ['Initialising'] } dev_config = {} pci_devs = [] for pci_dev in sxp.children(dev_sxp, 'dev'): pci_dev_info = dict(pci_dev[1:]) if 'opts' in pci_dev_info: pci_dev_info['opts'] = pci_opts_list_from_sxp(pci_dev) # append uuid to each pci device that does't already have one. if not pci_dev_info.has_key('uuid'): dpci_uuid = pci_dev_info.get('uuid', uuid.createString()) pci_dev_info['uuid'] = dpci_uuid pci_devs.append(pci_dev_info) dev_config['devs'] = pci_devs pci_states = [] for pci_state in sxp.children(dev_sxp, 'state'): try: pci_states.append(pci_state[1]) except IndexError: raise XendError("Error reading state while parsing pci sxp") dev_config['states'] = pci_states return dev_config