def get_ipv4_info(self, info, cfgmap): wok_log.debug('Begin get_ipv4_info') if info.__len__() != 0 and cfgmap.__len__() != 0: info[IPV4_ID] = {} ipv4_info_keys = [ BOOTPROTO, DEFROUTE, PEERROUTES, PEERDNS, IPV4_FAILURE_FATAL ] for key in ipv4_info_keys: if key in cfgmap: info[IPV4_ID][key] = cfgmap[key] if BOOTPROTO in cfgmap and (info[IPV4_ID][BOOTPROTO] == MANUAL or info[IPV4_ID][BOOTPROTO] == STATIC): info[IPV4_ID][IPV4Addresses] = \ cfgInterfacesHelper.get_ipv4_addresses(cfgmap) dnsaddresses = cfgInterfacesHelper.get_dnsv4_info(cfgmap) if len(dnsaddresses) > 0: info[IPV4_ID][DNSAddresses] = dnsaddresses # construct routeinfo. if DEVICE in cfgmap: routes = self.get_routes_map(cfgmap[DEVICE], 4) elif NAME in cfgmap: routes = self.get_routes_map(cfgmap[NAME], 4) if len(routes) > 0: info[IPV4_ID][ROUTES] = routes if len(info[IPV4_ID]) > 0: info[IPV4_ID][IPV4INIT] = CONST_YES else: info[IPV4_ID][IPV4INIT] = CONST_NO wok_log.debug('End get_ipv4_info') return info
def get_disk_xml(params): """ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> [source XML according to src_type] <target dev='%(dev)s' bus='%(bus)s'/> <readonly/> </disk> """ path = params['path'] disk_type = params.get('disk', None) if disk_type is None: disk_type = _get_disk_type(path) if len(path) > 0 else 'file' disk = E.disk(type=disk_type, device=params['type']) driver = E.driver(name='qemu', type=params['format']) try: fd = os.open(path, os.O_RDONLY | os.O_DIRECT) os.close(fd) wok_log.debug("Disk '%s' supports direct I/O. Setting cache=none" "to enable live migration" % path) except OSError, e: if e.errno == errno.EINVAL: wok_log.debug("Disk '%s' does not support direct I/O: " "'%s'. Let libvirt sets the default cache mode." % (path, e.message))
def get_basic_info(self, cfgmap): wok_log.debug('Begin get_basic_info') info = {} info[BASIC_INFO] = {} basic_info_keys = [NAME, DEVICE, ONBOOT, MACADDR, HWADDR, UUID, MTU, ZONE, TYPE] for key in basic_info_keys: if key in cfgmap: info[BASIC_INFO][key] = cfgmap[key] if SLAVE in cfgmap and CONST_YES == cfgmap[SLAVE]: info[BASIC_INFO][SLAVE] = cfgmap[SLAVE] info[BASIC_INFO][MASTER] = cfgInterfacesHelper.get_master(cfgmap) interface_type = None if TYPE in cfgmap: interface_type = cfgmap[TYPE] elif VLAN in cfgmap and CONST_YES == cfgmap[VLAN]: interface_type = IFACE_VLAN # Fix ginger issue #131 cfgInterfacesHelper.get_architecture_specific_info(info, cfgmap) if interface_type is not None: info[BASIC_INFO][TYPE] = interface_type if interface_type == IFACE_VLAN: cfgInterfacesHelper.get_vlan_info(info, cfgmap) elif interface_type == IFACE_BOND: cfgInterfacesHelper.get_bond_info(info, cfgmap) wok_log.debug('end get_basic_info') if MTU not in cfgmap: info[BASIC_INFO][MTU] = "1500" return info
def _get_deviceinfo(lscss_out, device): """ :param lscss_out: out of lscss command :param device: device id for which we need info to be returned :return: device info dict for the device from lscss output """ device_pattern = r'('+re.escape(device) + r')\s+' \ r'(\d\.\d\.[0-9a-fA-F]{4})\s+' \ r'(\w+\/\w+)\s+' \ r'(\w+\/\w+)\s' \ r'(\s{3}|yes)\s+' \ r'([0-9a-fA-F]{2})\s+' \ r'([0-9a-fA-F]{2})\s+' \ r'([0-9a-fA-F]{2})\s+' \ r'(\w+\s\w+)' if device: device = utils.get_row_data(lscss_out, HEADER_PATTERN, device_pattern) msg = 'The device is %s' % device wok_log.debug(msg) try: device_info = _format_lscss(device) return device_info except KeyError as e: wok_log.error('lscss column key not found') raise e else: return device
def get_ipv6_info(self, info, cfgmap): wok_log.debug('Begin get_ipv6_info') if info.__len__() != 0 and cfgmap.__len__() != 0: info[IPV6_ID] = {} ipv6_info_keys = [IPV6INIT, IPV6_AUTOCONF, IPV6_DEFROUTE, IPV6_PEERDNS, IPV6_PEERROUTES, IPV6_FAILURE_FATAL, DHCPV6C, IPV6_DEFAULTGW, IPV6_PRIVACY] for key in ipv6_info_keys: if key in cfgmap: info[IPV6_ID][key] = cfgmap[key] ipv6_addresses = cfgInterfacesHelper.get_ipv6_address(cfgmap) if len(ipv6_addresses): info[IPV6_ID][IPV6Addresses] = ipv6_addresses dnsaddresses = cfgInterfacesHelper.get_dnsv6_info(cfgmap) if len(dnsaddresses) > 0: info[IPV6_ID][DNSAddresses] = dnsaddresses # construct routeinfo. if DEVICE in cfgmap: routes = self.get_routes_map(cfgmap[DEVICE], 6) elif NAME in cfgmap: routes = self.get_routes_map(cfgmap[NAME], 6) if len(routes) > 0: info[IPV6_ID][ROUTES] = routes wok_log.debug('End get_ipv6_info') return info
def get_ipv4_info(self, info, cfgmap): wok_log.debug('Begin get_ipv4_info') if info.__len__() != 0 and cfgmap.__len__() != 0: info[IPV4_ID] = {} ipv4_info_keys = [BOOTPROTO, DEFROUTE, PEERROUTES, PEERDNS, IPV4_FAILURE_FATAL] for key in ipv4_info_keys: if key in cfgmap: info[IPV4_ID][key] = cfgmap[key] if BOOTPROTO in cfgmap and (info[IPV4_ID][BOOTPROTO] == MANUAL or info[IPV4_ID][BOOTPROTO] == STATIC): info[IPV4_ID][IPV4Addresses] = \ cfgInterfacesHelper.get_ipv4_addresses(cfgmap) dnsaddresses = cfgInterfacesHelper.get_dnsv4_info(cfgmap) if len(dnsaddresses) > 0: info[IPV4_ID][DNSAddresses] = dnsaddresses # construct routeinfo. if DEVICE in cfgmap: routes = self.get_routes_map(cfgmap[DEVICE], 4) elif NAME in cfgmap: routes = self.get_routes_map(cfgmap[NAME], 4) if len(routes) > 0: info[IPV4_ID][ROUTES] = routes # Fix ginger issue #110 if len(info[IPV4_ID]) > 0: info[IPV4_ID][IPV4INIT] = CONST_YES else: info[IPV4_ID][IPV4INIT] = CONST_NO wok_log.debug('End get_ipv4_info') return info
def _do_deep_scan(self, params): scan_params = dict(ignore_list=[]) scan_params['scan_path'] = params['path'] params['type'] = 'dir' for pool in self.get_list(): try: res = StoragePoolModel(conn=self.conn, objstore=self.objstore).lookup( pool ) if res['state'] == 'active': scan_params['ignore_list'].append(res['path']) except Exception as e: wok_log.debug(f'Exception {e} occured when get ignore path') params['path'] = self.scanner.scan_dir_prepare(params['name']) scan_params['pool_path'] = params['path'] task_id = AsyncTask( f'/plugins/kimchi/storagepools/{ISO_POOL_NAME}', self.scanner.start_scan, scan_params, ).id # Record scanning-task/storagepool mapping for future querying try: with self.objstore as session: session.store( 'scanning', params['name'], task_id, get_kimchi_version()) return task_id except Exception as e: raise OperationFailed('KCHPOOL0037E', {'err': e.message})
def get_basic_info(self, cfgmap): wok_log.debug('Begin get_basic_info') info = {} info[BASIC_INFO] = {} basic_info_keys = [ NAME, DEVICE, ONBOOT, MACADDR, HWADDR, UUID, MTU, ZONE, TYPE ] for key in basic_info_keys: if key in cfgmap: info[BASIC_INFO][key] = cfgmap[key] if SLAVE in cfgmap and CONST_YES == cfgmap[SLAVE]: info[BASIC_INFO][SLAVE] = cfgmap[SLAVE] info[BASIC_INFO][MASTER] = cfgInterfacesHelper.get_master(cfgmap) interface_type = None if TYPE in cfgmap: interface_type = cfgmap[TYPE] elif VLAN in cfgmap and CONST_YES == cfgmap[VLAN]: interface_type = IFACE_VLAN # Fix ginger issue #131 cfgInterfacesHelper.get_architecture_specific_info(info, cfgmap) if interface_type is not None: info[BASIC_INFO][TYPE] = interface_type if interface_type == IFACE_VLAN: cfgInterfacesHelper.get_vlan_info(info, cfgmap) elif interface_type == IFACE_BOND: cfgInterfacesHelper.get_bond_info(info, cfgmap) wok_log.debug('end get_basic_info') if MTU not in cfgmap: info[BASIC_INFO][MTU] = "1500" return info
def get_basic_info(self, cfgmap): wok_log.debug('Begin get_basic_info') info = {} info[BASIC_INFO] = {} basic_info_keys = [NAME, DEVICE, ONBOOT, MACADDR, HWADDR, UUID] for key in basic_info_keys: if key in cfgmap: info[BASIC_INFO][key] = cfgmap[key] if SLAVE in cfgmap and CONST_YES == cfgmap[SLAVE]: info[BASIC_INFO][SLAVE] = cfgmap[SLAVE] info[BASIC_INFO][MASTER] = self.get_master(cfgmap) interface_type = None if TYPE in cfgmap: interface_type = cfgmap[TYPE] elif VLAN in cfgmap and CONST_YES == cfgmap[VLAN]: interface_type = IFACE_VLAN if interface_type is not None: info[BASIC_INFO][TYPE] = interface_type if interface_type == IFACE_ETHERNET: self.get_architecture_specific_info(info, cfgmap) elif interface_type == IFACE_VLAN: self.get_vlan_info(info, cfgmap) elif interface_type == IFACE_BOND: self.get_bond_info(info, cfgmap) wok_log.debug('end get_basic_info') return info
def _get_deviceinfo(lscss_out, device): """ :param lscss_out: out of lscss command :param device: device id for which we need info to be returned :return: device info dict for the device from lscss output """ device_pattern = r'(' + re.escape(device) + r')\s+' \ r'(\d\.\d\.[0-9a-fA-F]{4})\s+' \ r'(\w+\/\w+)\s+' \ r'(\w+\/\w+)\s' \ r'(\s{3}|yes)\s+' \ r'([0-9a-fA-F]{2})\s+' \ r'([0-9a-fA-F]{2})\s+' \ r'([0-9a-fA-F]{2})\s+' \ r'(\w+\s\w+)' if device: device = utils.get_row_data(lscss_out, HEADER_PATTERN, device_pattern) msg = 'The device is %s' % device wok_log.debug(msg) try: device_info = _format_lscss(device) return device_info except KeyError as e: wok_log.error('lscss column key not found') raise e else: return device
def _do_deep_scan(self, params): scan_params = dict(ignore_list=[]) scan_params['scan_path'] = params['path'] params['type'] = 'dir' for pool in self.get_list(): try: res = StoragePoolModel(conn=self.conn, objstore=self.objstore).lookup(pool) if res['state'] == 'active': scan_params['ignore_list'].append(res['path']) except Exception as e: wok_log.debug(f'Exception {e} occured when get ignore path') params['path'] = self.scanner.scan_dir_prepare(params['name']) scan_params['pool_path'] = params['path'] task_id = AsyncTask( f'/plugins/kimchi/storagepools/{ISO_POOL_NAME}', self.scanner.start_scan, scan_params, ).id # Record scanning-task/storagepool mapping for future querying try: with self.objstore as session: session.store('scanning', params['name'], task_id, get_kimchi_version()) return task_id except Exception as e: raise OperationFailed('KCHPOOL0037E', {'err': e.message})
def get_dns_info(self, info, cfgmap): wok_log.debug('Begin get_dns_info') if DNS in cfgmap: ip = IPAddress(cfgmap[DNS]) if ip.version == 4: info[IPV4_ID][DNS] = cfgmap[DNS] elif ip.version == 6: info[IPV6_ID][DNS] = cfgmap[DNS] else: flag = 0 dnscount = 1 dnsincrmnt = DNS + str(dnscount) while flag == 0: if dnsincrmnt in cfgmap: ip = IPAddress(cfgmap[dnsincrmnt]) if ip.version == 4: info[IPV4_ID][dnsincrmnt] = cfgmap[dnsincrmnt] elif ip.version == 6: info[IPV6_ID][dnsincrmnt] = cfgmap[dnsincrmnt] dnscount = dnscount + 1 dnsincrmnt = DNS + str(dnscount) else: flag = 1 wok_log.debug('End get_dns_info') return info
def get_storagedevice(device): """ get the device info dict for the device passed as parameter. Raises exception on failure of lscss execution or device is None/blank :param device: device id for which we need info to be returned :return: device info dict """ device = _validate_device(device) if dasd_utils._is_dasdeckd_device(device) or _is_zfcp_device(device): command = [lscss, '-d', device] msg = 'The command is "%s" ' % command wok_log.debug(msg) out, err, rc = run_command(command) messge = 'The output of command "%s" is %s' % (command, out) wok_log.debug(messge) if rc: err = err.strip().replace("lscss:", '').strip() wok_log.error(err) raise OperationFailed("GS390XCMD0001E", {'command': command, 'rc': rc, 'reason': err}) if out.strip(): device_info = _get_deviceinfo(out, device) return device_info wok_log.error("lscss output is either blank or None") raise OperationFailed("GS390XCMD0001E", {'command': command, 'rc': rc, 'reason': out}) else: wok_log.error("Given device id is of type dasd-eckd or zfcp. " "Device: %s" % device) raise InvalidParameter("GS390XINVINPUT", {'reason': 'given device is not of type ' 'dasd-eckd or zfcp. ' 'Device : %s' % device})
def get_ipv6_info(self, info, cfgmap): wok_log.debug('Begin get_ipv6_info') if info.__len__() != 0 and cfgmap.__len__() != 0: info[IPV6_ID] = {} ipv6_info_keys = [ IPV6INIT, IPV6_AUTOCONF, IPV6_DEFROUTE, IPV6_PEERDNS, IPV6_PEERROUTES, IPV6_FAILURE_FATAL, DHCPV6C, IPV6_DEFAULTGW, IPV6_PRIVACY ] for key in ipv6_info_keys: if key in cfgmap: info[IPV6_ID][key] = cfgmap[key] ipv6_addresses = cfgInterfacesHelper.get_ipv6_address(cfgmap) if len(ipv6_addresses): info[IPV6_ID][IPV6Addresses] = ipv6_addresses dnsaddresses = cfgInterfacesHelper.get_dnsv6_info(cfgmap) if len(dnsaddresses) > 0: info[IPV6_ID][DNSAddresses] = dnsaddresses # construct routeinfo. if DEVICE in cfgmap: routes = self.get_routes_map(cfgmap[DEVICE], 6) elif NAME in cfgmap: routes = self.get_routes_map(cfgmap[NAME], 6) if len(routes) > 0: info[IPV6_ID][ROUTES] = routes wok_log.debug('End get_ipv6_info') return info
def _clean_scan(self, pool_name): try: conn = self.conn.get() pool = conn.storagePoolLookupByName(pool_name) pool.destroy() with self.objstore as session: session.delete('scanning', pool_name) except Exception as e: wok_log.debug(f'Exception {e} occurred when cleaning scan result')
def get_architecture_specific_info(self, info, cfgmap): wok_log.debug('Begin get_architecture_specific_info') if platform.machine() == ARCH_S390: basic_info_keys = [SUBCHANNELS, NETTYPE, PORTNAME, OPTIONS] for key in basic_info_keys: if key in cfgmap: info[BASIC_INFO][key] = cfgmap[key] wok_log.debug('End get_architecture_specific_info') return info
def get_vlan_info(self, info, cfgmap): wok_log.debug('Begin get_vlan_info') if info.__len__() != 0 and cfgmap.__len__() != 0: basic_info_keys = [VLANID, VLAN, REORDER_HDR, PHYSDEV] for key in basic_info_keys: if key in cfgmap: info[BASIC_INFO][key] = cfgmap[key] wok_log.debug('End get_vlan_info') return info
def _clean_scan(self, pool_name): try: conn = self.conn.get() pool = conn.storagePoolLookupByName(pool_name.encode("utf-8")) pool.destroy() with self.objstore as session: session.delete('scanning', pool_name) except Exception, e: err = "Exception %s occured when cleaning scan result" wok_log.debug(err % e.message)
def get_bond_info(self, info, cfgmap): wok_log.debug('Begin get_bond_info') if info.__len__() != 0 and cfgmap.__len__() != 0: basic_info_keys = [BONDING_OPTS, BONDING_MASTER] for key in basic_info_keys: if key in cfgmap: info[BASIC_INFO][key] = cfgmap[key] info[BASIC_INFO][SLAVES] = self.get_slaves(cfgmap) wok_log.debug('End get_bond_info') return info
def _do_deep_scan(self, params): scan_params = dict(ignore_list=[]) scan_params["scan_path"] = params["path"] params["type"] = "dir" for pool in self.get_list(): try: res = StoragePoolModel(conn=self.conn, objstore=self.objstore).lookup(pool) if res["state"] == "active": scan_params["ignore_list"].append(res["path"]) except Exception, e: err = "Exception %s occured when get ignore path" wok_log.debug(err % e.message)
def get_ipv4_info(self, info, cfgmap): wok_log.debug('Begin get_ipv4_info') if info.__len__() != 0 and cfgmap.__len__() != 0: info[IPV4_ID] = {} ipv4_info_keys = [ BOOTPROTO, DEFROUTE, PEERROUTES, PEERDNS, IPV4_FAILURE_FATAL, IPADDR, NETMASK, GATEWAY, PREFIX ] for key in ipv4_info_keys: if key in cfgmap: info[IPV4_ID][key] = cfgmap[key] wok_log.debug('End get_ipv4_info') return info
def swupdate(self, *name): try: swupdate = SoftwareUpdate() except: raise OperationFailed('KCHPKGUPD0004E') pkgs = swupdate.getNumOfUpdates() if pkgs == 0: raise OperationFailed('KCHPKGUPD0001E') wok_log.debug('Host is going to be updated.') taskid = add_task('/plugins/kimchi/host/swupdate', swupdate.doUpdate, self.objstore, None) return self.task.lookup(taskid)
def get_list(self, _type=None): """ :param _type: supported types are dasd-eckd, zfcp. Based on this devices will be retrieved :return: device data list. """ device_paths = [] if _type is None: device_paths.extend(utils.get_directories(syspath_eckd)) device_paths.extend(utils.get_directories(syspath_zfcp)) elif _type == DEV_TYPES[0]: device_paths = utils.get_directories(syspath_eckd) elif _type == DEV_TYPES[1]: device_paths = utils.get_directories(syspath_zfcp) else: wok_log.error("Invalid _type given. _type: %s" % _type) raise InvalidParameter("GS390XINVTYPE", {'supported_type': DEV_TYPES}) if not device_paths: return [] command = [lscss] msg = 'The command executed is "%s" ' % command wok_log.debug(msg) out, err, rc = run_command(command) if rc: err = err.strip().replace("lscss:", '').strip() wok_log.error(err) raise OperationFailed("GS390XCMD0001E", { 'command': command, 'rc': rc, 'reason': err }) device_pattern = r'(\d\.\d\.[0-9a-fA-F]{4})\s+' \ r'(\d\.\d\.[0-9a-fA-F]{4})\s+' \ r'(\w+\/\w+)\s+' \ r'(\w+\/\w+)\s' \ r'(\s{3}|yes)\s+' \ r'([0-9a-fA-F]{2})\s+' \ r'([0-9a-fA-F]{2})\s+' \ r'([0-9a-fA-F]{2})\s+' \ r'(\w+\s\w+)' devices = utils.get_rows_info(out, HEADER_PATTERN, device_pattern, unique_col='device', format_data=_format_lscss) device_data_list = _list_devicesinfo(devices, device_paths) return device_data_list
def _do_deep_scan(self, params): scan_params = dict(ignore_list=[]) scan_params['scan_path'] = params['path'] params['type'] = 'dir' for pool in self.get_list(): try: res = StoragePoolModel(conn=self.conn, objstore=self.objstore).lookup(pool) if res['state'] == 'active': scan_params['ignore_list'].append(res['path']) except Exception, e: err = "Exception %s occured when get ignore path" wok_log.debug(err % e.message)
def get_ipv6_info(self, info, cfgmap): wok_log.debug('Begin get_ipv6_info') if info.__len__() != 0 and cfgmap.__len__() != 0: info[IPV6_ID] = {} ipv6_info_keys = [ IPV6INIT, IPV6_AUTOCONF, IPV6_DEFROUTE, IPV6_PEERDNS, IPV6_PEERROUTES, IPV6_FAILURE_FATAL, DHCPV6C, IPV6ADDR, IPV6_DEFAULTGW, IPV6_PRIVACY ] for key in ipv6_info_keys: if key in cfgmap: info[IPV6_ID][key] = cfgmap[key] wok_log.debug('End get_ipv6_info') return info
def lookup(self, name): pool = self.get_storagepool(name, self.conn) info = pool.info() autostart = True if pool.autostart() else False persistent = True if pool.isPersistent() else False xml = pool.XMLDesc(0) path = xpath_get_text(xml, '/pool/target/path')[0] pool_type = xpath_get_text(xml, '/pool/@type')[0] source = self._get_storage_source(pool_type, xml) # FIXME: nfs workaround - prevent any libvirt operation # for a nfs if the corresponding NFS server is down. if pool_type == 'netfs' and not self._nfs_status_online(pool): wok_log.debug( 'NFS pool %s is offline, reason: NFS ' 'server %s is unreachable.', name, source['addr'], ) # Mark state as '4' => inaccessible. info[0] = 4 # skip calculating volumes nr_volumes = 0 else: nr_volumes = self._get_storagepool_vols_num(pool) res = { 'state': POOL_STATE_MAP[info[0]], 'path': path, 'source': source, 'type': pool_type, 'autostart': autostart, 'capacity': info[1], 'allocated': info[2], 'available': info[3], 'nr_volumes': nr_volumes, 'persistent': persistent, 'in_use': self._pool_used_by_template(name), } if not pool.isPersistent(): # Deal with deep scan generated pool try: with self.objstore as session: task_id = session.get('scanning', name) res['task_id'] = str(task_id) res['type'] = 'kimchi-iso' except NotFoundError: # User created normal pool pass return res
def swupdate(self, *name): try: swupdate = SoftwareUpdate() except: raise OperationFailed('GGBPKGUPD0004E') pkgs = swupdate.getNumOfUpdates() if pkgs == 0: wok_log.debug(messages['GGBPKGUPD0001E']) return {'message': messages['GGBPKGUPD0001E']} wok_log.debug('Host is going to be updated.') taskid = AsyncTask('/plugins/gingerbase/host/swupdate', swupdate.doUpdate).id return self.task.lookup(taskid)
def swupdate(self, *name): try: swupdate = SoftwareUpdate() except Exception: raise OperationFailed('GGBPKGUPD0004E') pkgs = swupdate.getNumOfUpdates() if pkgs == 0: wok_log.debug(messages['GGBPKGUPD0001E']) return {'message': messages['GGBPKGUPD0001E']} wok_log.debug('Host is going to be updated.') taskid = AsyncTask('/plugins/gingerbase/host/swupdate', swupdate.doUpdate).id return self.task.lookup(taskid)
def get_storagedevice(self, device): """ get the device info dict for the device passed as parameter. Raises exception on failure of lscss execution or device is None/blank :param device: device id for which we need info to be returned :return: device info dict """ if device and isinstance(device, unicode): device = device.encode('utf-8') device = str(device) device = _validate_device(device) if _is_dasdeckd_device(device) or _is_zfcp_device(device): command = [lscss, '-d', device] # Use join to handle unicode charater in device msg = 'The command is "%s" ' % ' '.join(command) wok_log.debug(msg) out, err, rc = run_command(command) messge = 'The output of command "%s" is %s' % (' '.join(command), out) wok_log.debug(messge) if rc: err = err.strip().replace("lscss:", '').strip() wok_log.error(err) raise OperationFailed("GS390XCMD0001E", { 'command': ' '.join(command), 'rc': rc, 'reason': err }) if out.strip().splitlines()[2:]: # sample command output with '-d' option when device # not found # """"" # [root@zfwpc159 ginger]# lscss -d 1530 # Device Subchan. DevType CU Type Use PIM PAM POM CHPIDs # ----------------------------------------------------------- # """"" device_info = _get_deviceinfo(out, device) return device_info wok_log.error("lscss output is either blank or None") raise OperationFailed("GS390XCMD0001E", { 'command': ' '.join(command), 'rc': rc, 'reason': out }) else: wok_log.error("Given device id is of type dasd-eckd or zfcp. " "Device: %s" % device) raise NotFoundError("GS390XSTG00023", {'device': device})
def get_list(self, _type=None): """ :param _type: supported types are dasd-eckd, zfcp. Based on this devices will be retrieved :return: device data list. """ device_paths = [] if _type is None: device_paths.extend(utils.get_directories(syspath_eckd)) device_paths.extend(utils.get_directories(syspath_zfcp)) elif _type == DEV_TYPES[0]: device_paths = utils.get_directories(syspath_eckd) elif _type == DEV_TYPES[1]: device_paths = utils.get_directories(syspath_zfcp) else: wok_log.error("Invalid _type given. _type: %s" % _type) raise InvalidParameter("GS390XINVTYPE", {'supported_type': DEV_TYPES}) if not device_paths: return [] command = [lscss] msg = 'The command executed is "%s" ' % command wok_log.debug(msg) out, err, rc = run_command(command) if rc: err = err.strip().replace("lscss:", '').strip() wok_log.error(err) raise OperationFailed("GS390XCMD0001E", {'command': command, 'rc': rc, 'reason': err}) device_pattern = r'(\d\.\d\.[0-9a-fA-F]{4})\s+' \ r'(\d\.\d\.[0-9a-fA-F]{4})\s+' \ r'(\w+\/\w+)\s+' \ r'(\w+\/\w+)\s' \ r'(\s{3}|yes)\s+' \ r'([0-9a-fA-F]{2})\s+' \ r'([0-9a-fA-F]{2})\s+' \ r'([0-9a-fA-F]{2})\s+' \ r'(\w+\s\w+)' devices = utils.get_rows_info(out, HEADER_PATTERN, device_pattern, unique_col='device', format_data=_format_lscss) device_data_list = _list_devicesinfo(devices, device_paths) return device_data_list
def clean_stale(self, window=SCAN_TTL): """ Clear scan pools generated before time window, Clear all scan pools if window is -1. """ try: now = time.time() clean_list = glob.glob("/tmp/kimchi-scan-*") for d in clean_list: transient_pool = \ os.path.basename(d).replace('kimchi-scan-', '')[0: -6] if now - os.path.getmtime(d) > window: shutil.rmtree(d) self.clean_cb(transient_pool) except OSError as e: msg = "Exception %s occured when cleaning stale pool, ignore" wok_log.debug(msg % e.message)
def upgrade(self, name): """ Execute the update of a specific package (and its dependencies, if necessary) in the system. @param: Name @return: task """ if self.host_swupdate is None: raise OperationFailed('GGBPKGUPD0004E') self.pkgs2update = self.host_swupdate.getUpdates() pkgs_list = self._resolve_dependencies(name) msg = 'The following packages will be updated: ' + ', '.join(pkgs_list) wok_log.debug(msg) taskid = AsyncTask('/plugins/gingerbase/host/packagesupdate/%s/upgrade' % name, self.host_swupdate.doUpdate, pkgs_list).id return self.task.lookup(taskid)
def lookup(self, name): pool = self.get_storagepool(name, self.conn) info = pool.info() autostart = True if pool.autostart() else False persistent = True if pool.isPersistent() else False xml = pool.XMLDesc(0) path = xpath_get_text(xml, "/pool/target/path")[0] pool_type = xpath_get_text(xml, "/pool/@type")[0] source = self._get_storage_source(pool_type, xml) # FIXME: nfs workaround - prevent any libvirt operation # for a nfs if the corresponding NFS server is down. if pool_type == "netfs" and not self._nfs_status_online(pool): wok_log.debug("NFS pool %s is offline, reason: NFS " "server %s is unreachable.", name, source["addr"]) # Mark state as '4' => inaccessible. info[0] = 4 # skip calculating volumes nr_volumes = 0 else: nr_volumes = self._get_storagepool_vols_num(pool) res = { "state": POOL_STATE_MAP[info[0]], "path": path, "source": source, "type": pool_type, "autostart": autostart, "capacity": info[1], "allocated": info[2], "available": info[3], "nr_volumes": nr_volumes, "persistent": persistent, } if not pool.isPersistent(): # Deal with deep scan generated pool try: with self.objstore as session: task_id = session.get("scanning", name) res["task_id"] = str(task_id) res["type"] = "kimchi-iso" except NotFoundError: # User created normal pool pass return res
def get_storagedevice(self, device): """ get the device info dict for the device passed as parameter. Raises exception on failure of lscss execution or device is None/blank :param device: device id for which we need info to be returned :return: device info dict """ if device and isinstance(device, unicode): device = device.encode('utf-8') device = str(device) device = _validate_device(device) if _is_dasdeckd_device(device) or _is_zfcp_device(device): command = [lscss, '-d', device] # Use join to handle unicode charater in device msg = 'The command is "%s" ' % ' '.join(command) wok_log.debug(msg) out, err, rc = run_command(command) messge = 'The output of command "%s" is %s' % (' '. join(command), out) wok_log.debug(messge) if rc: err = err.strip().replace("lscss:", '').strip() wok_log.error(err) raise OperationFailed("GS390XCMD0001E", {'command': ' '.join(command), 'rc': rc, 'reason': err}) if out.strip().splitlines()[2:]: # sample command output with '-d' option when device # not found # """"" # [root@zfwpc159 ginger]# lscss -d 1530 # Device Subchan. DevType CU Type Use PIM PAM POM CHPIDs # ----------------------------------------------------------- # """"" device_info = _get_deviceinfo(out, device) return device_info wok_log.error("lscss output is either blank or None") raise OperationFailed("GS390XCMD0001E", {'command': ' '.join(command), 'rc': rc, 'reason': out}) else: wok_log.error("Given device id is of type dasd-eckd or zfcp. " "Device: %s" % device) raise NotFoundError("GS390XSTG00023", {'device': device})
def probe(self): if not self.bootable: raise IsoFormatError('KCHISO0002E', {'filename': self.path}) matcher = Matcher(self.volume_id) for d, v, regex in iso_dir: if matcher.search(regex): distro = d if hasattr(v, '__call__'): version = v(matcher) else: version = v return (distro, version) msg = 'probe_iso: Unable to identify ISO %s with Volume ID: %s' wok_log.debug(msg, self.path, self.volume_id) return ('unknown', 'unknown')
def probe(self): if not self.bootable: raise IsoFormatError("KCHISO0002E", {'filename': self.path}) matcher = Matcher(self.volume_id) for d, v, regex in iso_dir: if matcher.search(regex): distro = d if hasattr(v, '__call__'): version = v(matcher) else: version = v return (distro, version) msg = "probe_iso: Unable to identify ISO %s with Volume ID: %s" wok_log.debug(msg, self.path, self.volume_id) return ('unknown', 'unknown')
def get_storagedevice(self, device): """ get the device info dict for the device passed as parameter. Raises exception on failure of lscss execution or device is None/blank :param device: device id for which we need info to be returned :return: device info dict """ device = _validate_device(device) if _is_dasdeckd_device(device) or _is_zfcp_device(device): command = [lscss, '-d', device] msg = 'The command is "%s" ' % command wok_log.debug(msg) out, err, rc = run_command(command) messge = 'The output of command "%s" is %s' % (command, out) wok_log.debug(messge) if rc: err = err.strip().replace("lscss:", '').strip() wok_log.error(err) raise OperationFailed("GS390XCMD0001E", { 'command': command, 'rc': rc, 'reason': err }) if out.strip(): device_info = _get_deviceinfo(out, device) return device_info wok_log.error("lscss output is either blank or None") raise OperationFailed("GS390XCMD0001E", { 'command': command, 'rc': rc, 'reason': out }) else: wok_log.error("Given device id is of type dasd-eckd or zfcp. " "Device: %s" % device) raise InvalidParameter( "GS390XINVINPUT", { 'reason': 'given device is not of type ' 'dasd-eckd or zfcp. ' 'Device : %s' % device })
def get_list(self): iso_volumes = [] conn = self.conn.get() pools = conn.listStoragePools() pools += conn.listDefinedStoragePools() for pool_name in pools: try: pool = StoragePoolModel.get_storagepool(pool_name, self.conn) pool.refresh(0) volumes = pool.listVolumes() except Exception, e: # Skip inactive pools wok_log.debug("Shallow scan: skipping pool %s because of " "error: %s", (pool_name, e.message)) continue for volume in volumes: res = self.storagevolume.lookup(pool_name, volume.decode("utf-8")) if res["format"] == "iso" and res["bootable"]: res["name"] = "%s" % volume iso_volumes.append(res)
def get_list(self): iso_volumes = [] conn = self.conn.get() pools = conn.listStoragePools() pools += conn.listDefinedStoragePools() for pool_name in pools: try: pool = StoragePoolModel.get_storagepool(pool_name, self.conn) pool.refresh(0) volumes = pool.listVolumes() except Exception, e: # Skip inactive pools wok_log.debug("Shallow scan: skipping pool %s because of " "error: %s", (pool_name, e.message)) continue for volume in volumes: res = self.storagevolume.lookup(pool_name, volume.decode("utf-8")) if res['format'] == 'iso' and res['bootable']: res['name'] = '%s' % volume iso_volumes.append(res)
def _parse_interfaces_file(iface): ifaces = [] try: content = open('/etc/network/interfaces').readlines() for line in content: if line.startswith('iface'): ifaces.append({ 'iface': line.split()[1], 'index': content.index(line) }) except IOError: wok_log.debug('Unable to get bridge information from ' '/etc/network/interfaces') return {} index = next_index = None for data in ifaces: if data['iface'] == iface: index = data['index'] next_elem = ifaces.index(data) + 1 if next_elem > len(ifaces) - 1: next_index = len(content) else: next_index = ifaces[ifaces.index(data) + 1]['index'] break if index is None or next_index is None: return {} result = {} iface_data = content[index + 1:next_index] for item in iface_data: data = item.split() result[data[0]] = data[1:] return result
def get_list(self): iso_volumes = [] conn = self.conn.get() pools = conn.listStoragePools() pools += conn.listDefinedStoragePools() for pool_name in pools: try: pool = StoragePoolModel.get_storagepool(pool_name, self.conn) pool.refresh(0) volumes = pool.listVolumes() except Exception as e: # Skip inactive pools wok_log.debug( f'Shallow scan: skipping pool {pool_name} because of ' f'error: {e}' ) continue for volume in volumes: res = self.storagevolume.lookup(pool_name, volume) if res['format'] == 'iso' and res['bootable']: res['name'] = f'{volume}' iso_volumes.append(res) return iso_volumes
def get_list(self): iso_volumes = [] conn = self.conn.get() pools = conn.listStoragePools() pools += conn.listDefinedStoragePools() for pool_name in pools: try: pool = StoragePoolModel.get_storagepool(pool_name, self.conn) pool.refresh(0) volumes = pool.listVolumes() except Exception as e: # Skip inactive pools wok_log.debug( f'Shallow scan: skipping pool {pool_name} because of ' f'error: {e}') continue for volume in volumes: res = self.storagevolume.lookup(pool_name, volume) if res['format'] == 'iso' and res['bootable']: res['name'] = f'{volume}' iso_volumes.append(res) return iso_volumes
def get_disk_xml(params): """ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> [source XML according to src_type] <target dev='%(dev)s' bus='%(bus)s'/> <readonly/> </disk> """ path = params['path'] disk_type = params.get('disk', None) if disk_type is None: disk_type = _get_disk_type(path) if len(path) > 0 else 'file' disk = E.disk(type=disk_type, device=params['type']) driver = E.driver(name='qemu', type=params['format']) try: fd = os.open(path, os.O_RDONLY | os.O_DIRECT) os.close(fd) wok_log.debug("Disk '%s' supports direct I/O. Setting cache=none" 'to enable live migration' % path) except OSError as e: if e.errno == errno.EINVAL: wok_log.debug("Disk '%s' does not support direct I/O: " "'%s'. Let libvirt sets the default cache mode." % (path, e)) else: if params['type'] != 'cdrom': driver.set('cache', 'none') if params.get('pool_type') == 'netfs': driver.set('io', 'native') disk.append(driver) # Get device name according to bus and index values dev = params.get( 'dev', (BUS_TO_DEV_MAP[params['bus']] + string.ascii_lowercase[params.get('index', 0)]), ) disk.append(E.target(dev=dev, bus=params['bus'])) if params.get('address'): # ide disk target id is always '0' disk.append( E.address( type='drive', controller=params['address']['controller'], bus=params['address']['bus'], target='0', unit=params['address']['unit'], )) if len(params['path']) == 0: return dev, ET.tostring(disk, encoding='unicode', pretty_print=True) if disk_type == 'network': """ <source protocol='%(protocol)s' name='%(url_path)s'> <host name='%(hostname)s' port='%(port)s'/> </source> """ output = urllib.parse.urlparse(params['path']) port = str(output.port or socket.getservbyname(output.scheme)) source = E.source(protocol=output.scheme, name=output.path) source.append(E.host(name=output.hostname, port=port)) else: """ <source file='%(src)s' /> """ source = E.source() source.set(DEV_TYPE_SRC_ATTR_MAP[disk_type], params['path']) disk.append(source) return dev, ET.tostring(disk, encoding='unicode', pretty_print=True)
def get_disk_xml(params): """ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> [source XML according to src_type] <target dev='%(dev)s' bus='%(bus)s'/> <readonly/> </disk> """ path = params['path'] disk_type = params.get('disk', None) if disk_type is None: disk_type = _get_disk_type(path) if len(path) > 0 else 'file' disk = E.disk(type=disk_type, device=params['type']) driver = E.driver(name='qemu', type=params['format']) try: fd = os.open(path, os.O_RDONLY | os.O_DIRECT) os.close(fd) wok_log.debug( "Disk '%s' supports direct I/O. Setting cache=none" 'to enable live migration' % path ) except OSError as e: if e.errno == errno.EINVAL: wok_log.debug( "Disk '%s' does not support direct I/O: " "'%s'. Let libvirt sets the default cache mode." % (path, e) ) else: if params['type'] != 'cdrom': driver.set('cache', 'none') if params.get('pool_type') == 'netfs': driver.set('io', 'native') disk.append(driver) # Get device name according to bus and index values dev = params.get( 'dev', ( BUS_TO_DEV_MAP[params['bus']] + string.ascii_lowercase[params.get('index', 0)] ), ) disk.append(E.target(dev=dev, bus=params['bus'])) if params.get('address'): # ide disk target id is always '0' disk.append( E.address( type='drive', controller=params['address']['controller'], bus=params['address']['bus'], target='0', unit=params['address']['unit'], ) ) if len(params['path']) == 0: return ( dev, ET.tostring(disk, encoding='utf-8', pretty_print=True).decode('utf-8'), ) if disk_type == 'network': """ <source protocol='%(protocol)s' name='%(url_path)s'> <host name='%(hostname)s' port='%(port)s'/> </source> """ output = urllib.parse.urlparse(params['path']) port = str(output.port or socket.getservbyname(output.scheme)) source = E.source(protocol=output.scheme, name=output.path) source.append(E.host(name=output.hostname, port=port)) else: """ <source file='%(src)s' /> """ source = E.source() source.set(DEV_TYPE_SRC_ATTR_MAP[disk_type], params['path']) disk.append(source) return dev, ET.tostring(disk, encoding='utf-8', pretty_print=True).decode('utf-8')