def __init__(self, **kargs): self.conn = kargs['conn'] self.objstore = kargs['objstore'] self.scanner = Scanner(self._clean_scan) self.scanner.delete() self.caps = CapabilitiesModel(**kargs) self.device = DeviceModel(**kargs) if self.conn.isQemuURI(): self._check_default_pools()
class StoragePoolsModel(object): def __init__(self, **kargs): self.conn = kargs['conn'] self.objstore = kargs['objstore'] self.scanner = Scanner(self._clean_scan) self.scanner.delete() self.caps = CapabilitiesModel(**kargs) self.device = DeviceModel(**kargs) if self.conn.isQemuURI(): self._check_default_pools() def _check_default_pools(self): pools = {} default_pool = tmpl_defaults['storagepool'] default_pool = default_pool.split('/')[-1] pools[default_pool] = {} if default_pool == 'default': pools[default_pool] = {'path': '/var/lib/libvirt/images'} if config.get("server", "create_iso_pool") == "true": pools['ISO'] = {'path': '/var/lib/kimchi/isos'} error_msg = ("Please, check the configuration in %s/template.conf to " "ensure it has a valid storage pool." % PluginPaths('kimchi').conf_dir) conn = self.conn.get() for pool_name in pools: try: pool = conn.storagePoolLookupByName(pool_name) except libvirt.libvirtError, e: pool_path = pools[pool_name].get('path') if pool_path is None: msg = "Fatal: Unable to find storage pool %s. " + error_msg wok_log.error(msg % pool_name) wok_log.error("Details: %s", e.message) sys.exit(1) # Try to create the pool pool = E.pool(E.name(pool_name), type='dir') pool.append(E.target(E.path(pool_path))) xml = ET.tostring(pool) try: pool = conn.storagePoolDefineXML(xml, 0) except libvirt.libvirtError, e: msg = "Fatal: Unable to create storage pool %s. " msg += error_msg wok_log.error(msg % pool_name) wok_log.error("Details: %s", e.message) sys.exit(1) # Build and set autostart value to pool # Ignore error as the pool was already successfully created try: # Add build step to make sure target directory created # The build process may fail when the pool directory # already exists on system pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW) pool.setAutostart(1) except: pass if pool.isActive() == 0: try: pool.create(0) except libvirt.libvirtError, e: msg = "Fatal: Unable to craete storage pool %s. " msg += error_msg wok_log.error(msg % pool_name) wok_log.error("Details: %s", e.message) sys.exit(1)
class StoragePoolsModel(object): def __init__(self, **kargs): self.conn = kargs['conn'] self.objstore = kargs['objstore'] self.scanner = Scanner(self._clean_scan) self.scanner.delete() self.caps = CapabilitiesModel(**kargs) self.device = DeviceModel(**kargs) if self.conn.isQemuURI(): self._check_default_pools() def _check_default_pools(self): pools = {} default_pool = tmpl_defaults['disks'][0]['pool']['name'] default_pool = default_pool.split('/')[-1] pools[default_pool] = {} if default_pool == 'default': pools[default_pool] = {'path': '/var/lib/libvirt/images'} if config.get('kimchi', {}).get('create_iso_pool', False): pools['ISO'] = {'path': '/var/lib/kimchi/isos'} error_msg = ("Please, check the configuration in %s/template.conf to " "ensure it has a valid storage pool." % kimchiPaths.sysconf_dir) conn = self.conn.get() for pool_name in pools: try: pool = conn.storagePoolLookupByName(pool_name) except libvirt.libvirtError, e: pool_path = pools[pool_name].get('path') if pool_path is None: msg = "Fatal: Unable to find storage pool %s. " + error_msg wok_log.error(msg % pool_name) wok_log.error("Details: %s", e.message) sys.exit(1) # Try to create the pool pool = E.pool(E.name(pool_name), type='dir') pool.append(E.target(E.path(pool_path))) xml = ET.tostring(pool) try: pool = conn.storagePoolDefineXML(xml, 0) except libvirt.libvirtError, e: msg = "Fatal: Unable to create storage pool %s. " msg += error_msg wok_log.error(msg % pool_name) wok_log.error("Details: %s", e.message) sys.exit(1) # Build and set autostart value to pool # Ignore error as the pool was already successfully created try: # Add build step to make sure target directory created # The build process may fail when the pool directory # already exists on system pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW) pool.setAutostart(1) except: pass if pool.isActive() == 0: try: pool.create(0) except libvirt.libvirtError, e: msg = "Fatal: Unable to craete storage pool %s. " msg += error_msg wok_log.error(msg % pool_name) wok_log.error("Details: %s", e.message) sys.exit(1)
class StoragePoolsModel(object): def __init__(self, **kargs): self.conn = kargs['conn'] self.objstore = kargs['objstore'] self.scanner = Scanner(self._clean_scan) self.scanner.delete() self.caps = CapabilitiesModel(**kargs) self.device = DeviceModel(**kargs) if self.conn.get() is not None: if self.conn.isQemuURI(): self._check_default_pools() def _check_default_pools(self): pools = {} # Don't create default pool if it's not # explicitly specified in template.conf if is_s390x() and 'pool' not in tmpl_defaults['disks'][0]: return default_pool = tmpl_defaults['disks'][0]['pool']['name'] default_pool = default_pool.split('/')[-1] pools[default_pool] = {} if default_pool == 'default': pools[default_pool] = {'path': '/var/lib/libvirt/images'} if config.get('kimchi', {}).get('create_iso_pool', False): pools['ISO'] = {'path': '/var/lib/kimchi/isos'} conn = self.conn.get() for pool_name in pools: error_msg = ("Storage pool %s does not exist or is not " "active. Please, check the configuration in " "%s/template.conf to ensure it lists only valid " "storage." % (pool_name, kimchiPaths.sysconf_dir)) try: pool = conn.storagePoolLookupByName(pool_name) except libvirt.libvirtError, e: pool_path = pools[pool_name].get('path') if pool_path is None: msg = "Fatal: Unable to find storage pool %s. " wok_log.error(msg % pool_name) wok_log.error("Details: %s", e.message) raise Exception(error_msg) # Try to create the pool pool = E.pool(E.name(pool_name), type='dir') pool.append(E.target(E.path(pool_path))) xml = ET.tostring(pool) try: pool = conn.storagePoolDefineXML(xml, 0) except libvirt.libvirtError, e: msg = "Fatal: Unable to create storage pool %s. " wok_log.error(msg % pool_name) wok_log.error("Details: %s", e.message) raise Exception(error_msg) # Build and set autostart value to pool # Ignore error as the pool was already successfully created try: # Add build step to make sure target directory created # The build process may fail when the pool directory # already exists on system pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW) pool.setAutostart(1) except: pass if pool.isActive() == 0: try: pool.create(0) except libvirt.libvirtError, e: msg = "Fatal: Unable to craete storage pool %s. " wok_log.error(msg % pool_name) wok_log.error("Details: %s", e.message) raise Exception(error_msg)
class StoragePoolsModel(object): def __init__(self, **kargs): self.conn = kargs['conn'] self.objstore = kargs['objstore'] self.scanner = Scanner(self._clean_scan) self.scanner.delete() self.caps = CapabilitiesModel(**kargs) self.device = DeviceModel(**kargs) if self.conn.get() is not None: if self.conn.isQemuURI(): self._check_default_pools() def _check_default_pools(self): pools = {} # Don't create default pool if it's not # explicitly specified in template.conf if is_s390x() and 'pool' not in tmpl_defaults['disks'][0]: return default_pool = tmpl_defaults['disks'][0]['pool']['name'] default_pool = default_pool.split('/')[-1] pools[default_pool] = {} if default_pool == 'default': pools[default_pool] = {'path': '/var/lib/libvirt/images'} if config.get('kimchi', {}).get('create_iso_pool', False): pools['ISO'] = {'path': '/var/lib/kimchi/isos'} conn = self.conn.get() for pool_name in pools: error_msg = ('Storage pool %s does not exist or is not ' 'active. Please, check the configuration in ' '%s/template.conf to ensure it lists only valid ' 'storage.' % (pool_name, kimchiPaths.sysconf_dir)) try: pool = conn.storagePoolLookupByName(pool_name) except libvirt.libvirtError as e: pool_path = pools[pool_name].get('path') if pool_path is None: wok_log.error( f'Fatal: Unable to find storage pool {pool_name}.') wok_log.error(f'Details: {str(e)}') raise Exception(error_msg) # Try to create the pool pool = E.pool(E.name(pool_name), type='dir') pool.append(E.target(E.path(pool_path))) xml = ET.tostring(pool) try: pool = conn.storagePoolDefineXML(xml, 0) except libvirt.libvirtError as e: wok_log.error( f'Fatal: Unable to create storage pool {pool_name}.') wok_log.error(f'Details: {str(e)}') raise Exception(error_msg) # Build and set autostart value to pool # Ignore error as the pool was already successfully created try: # Add build step to make sure target directory created # The build process may fail when the pool directory # already exists on system pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW) pool.setAutostart(1) except Exception: pass if pool.isActive() == 0: try: pool.create(0) except libvirt.libvirtError as e: wok_log.error( f'Fatal: Unable to create storage pool {pool_name}.') wok_log.error(f'Details: {str(e)}') raise Exception(error_msg) def get_list(self): try: conn = self.conn.get() names = conn.listStoragePools() names += conn.listDefinedStoragePools() return sorted(names) except libvirt.libvirtError as e: raise OperationFailed('KCHPOOL0006E', {'err': e.get_error_message()}) def _check_lvm(self, name, from_vg): vgdisplay_cmd = ['vgdisplay', name] output, error, returncode = run_command(vgdisplay_cmd) # From vgdisplay error codes: # 1 error reading VGDA # 2 volume group doesn't exist # 3 not all physical volumes of volume group online # 4 volume group not found # 5 no volume groups found at all # 6 error reading VGDA from lvmtab if from_vg and returncode in [2, 4, 5]: raise InvalidOperation('KCHPOOL0038E', {'name': name}) if not from_vg and returncode not in [2, 4, 5]: raise InvalidOperation('KCHPOOL0036E', {'name': name}) def create(self, params): task_id = None conn = self.conn.get() from_vg = params.get('source', {}).get('from_vg', False) try: name = params['name'] if name == ISO_POOL_NAME: raise InvalidOperation('KCHPOOL0031E') # The user may want to create a logical pool with the same name # used before but a volume group will already exist with this name # So check the volume group does not exist to create the pool if params['type'] == 'logical': self._check_lvm(name, from_vg) if params['type'] == 'kimchi-iso': task_id = self._do_deep_scan(params) if params['type'] == 'scsi': adapter_name = params['source']['adapter_name'] extra_params = self.device.lookup(adapter_name) # Adds name, adapter_type, wwpn and wwnn to source information params['source'].update(extra_params) params['fc_host_support'] = self.caps.fc_host_support poolDef = StoragePoolDef.create(params) poolDef.prepare(conn) xml = poolDef.xml except KeyError as item: raise MissingParameter('KCHPOOL0004E', { 'item': str(item), 'name': name }) if name in self.get_list(): raise InvalidOperation('KCHPOOL0001E', {'name': name}) try: if task_id: # Create transient pool for deep scan conn.storagePoolCreateXML(xml, 0) return name pool = conn.storagePoolDefineXML(xml, 0) except libvirt.libvirtError as e: wok_log.error(f'Problem creating Storage Pool: {str(e)}') raise OperationFailed('KCHPOOL0007E', { 'name': name, 'err': e.get_error_message() }) # Build and set autostart value to pool # Ignore error as the pool was already successfully created # The build process fails when the pool directory already exists try: if params['type'] in ['logical', 'dir', 'netfs', 'scsi']: pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW) pool.setAutostart(1) else: pool.setAutostart(0) except Exception: pass if params['type'] == 'netfs': output, error, returncode = run_command( ['setsebool', '-P', 'virt_use_nfs=1']) if error or returncode: wok_log.error('Unable to set virt_use_nfs=1. If you use ' 'SELinux, this may prevent NFS pools from ' 'being used.') return name 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 _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})
class StoragePoolsModel(object): def __init__(self, **kargs): self.conn = kargs['conn'] self.objstore = kargs['objstore'] self.scanner = Scanner(self._clean_scan) self.scanner.delete() self.caps = CapabilitiesModel(**kargs) self.device = DeviceModel(**kargs) if self.conn.get() is not None: if self.conn.isQemuURI(): self._check_default_pools() def _check_default_pools(self): pools = {} # Don't create default pool if it's not # explicitly specified in template.conf if is_s390x() and 'pool' not in tmpl_defaults['disks'][0]: return default_pool = tmpl_defaults['disks'][0]['pool']['name'] default_pool = default_pool.split('/')[-1] pools[default_pool] = {} if default_pool == 'default': pools[default_pool] = {'path': '/var/lib/libvirt/images'} if config.get('kimchi', {}).get('create_iso_pool', False): pools['ISO'] = {'path': '/var/lib/kimchi/isos'} conn = self.conn.get() for pool_name in pools: error_msg = ( 'Storage pool %s does not exist or is not ' 'active. Please, check the configuration in ' '%s/template.conf to ensure it lists only valid ' 'storage.' % (pool_name, kimchiPaths.sysconf_dir) ) try: pool = conn.storagePoolLookupByName(pool_name) except libvirt.libvirtError as e: pool_path = pools[pool_name].get('path') if pool_path is None: wok_log.error( f'Fatal: Unable to find storage pool {pool_name}.') wok_log.error(f'Details: {str(e)}') raise Exception(error_msg) # Try to create the pool pool = E.pool(E.name(pool_name), type='dir') pool.append(E.target(E.path(pool_path))) xml = ET.tostring(pool) try: pool = conn.storagePoolDefineXML(xml, 0) except libvirt.libvirtError as e: wok_log.error( f'Fatal: Unable to create storage pool {pool_name}.') wok_log.error(f'Details: {str(e)}') raise Exception(error_msg) # Build and set autostart value to pool # Ignore error as the pool was already successfully created try: # Add build step to make sure target directory created # The build process may fail when the pool directory # already exists on system pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW) pool.setAutostart(1) except Exception: pass if pool.isActive() == 0: try: pool.create(0) except libvirt.libvirtError as e: wok_log.error( f'Fatal: Unable to create storage pool {pool_name}.') wok_log.error(f'Details: {str(e)}') raise Exception(error_msg) def get_list(self): try: conn = self.conn.get() names = conn.listStoragePools() names += conn.listDefinedStoragePools() return sorted(names) except libvirt.libvirtError as e: raise OperationFailed( 'KCHPOOL0006E', {'err': e.get_error_message()}) def _check_lvm(self, name, from_vg): vgdisplay_cmd = ['vgdisplay', name] output, error, returncode = run_command(vgdisplay_cmd) # From vgdisplay error codes: # 1 error reading VGDA # 2 volume group doesn't exist # 3 not all physical volumes of volume group online # 4 volume group not found # 5 no volume groups found at all # 6 error reading VGDA from lvmtab if from_vg and returncode in [2, 4, 5]: raise InvalidOperation('KCHPOOL0038E', {'name': name}) if not from_vg and returncode not in [2, 4, 5]: raise InvalidOperation('KCHPOOL0036E', {'name': name}) def create(self, params): task_id = None conn = self.conn.get() from_vg = params.get('source', {}).get('from_vg', False) try: name = params['name'] if name == ISO_POOL_NAME: raise InvalidOperation('KCHPOOL0031E') # The user may want to create a logical pool with the same name # used before but a volume group will already exist with this name # So check the volume group does not exist to create the pool if params['type'] == 'logical': self._check_lvm(name, from_vg) if params['type'] == 'kimchi-iso': task_id = self._do_deep_scan(params) if params['type'] == 'scsi': adapter_name = params['source']['adapter_name'] extra_params = self.device.lookup(adapter_name) # Adds name, adapter_type, wwpn and wwnn to source information params['source'].update(extra_params) params['fc_host_support'] = self.caps.fc_host_support poolDef = StoragePoolDef.create(params) poolDef.prepare(conn) xml = poolDef.xml except KeyError as item: raise MissingParameter( 'KCHPOOL0004E', {'item': str(item), 'name': name}) if name in self.get_list(): raise InvalidOperation('KCHPOOL0001E', {'name': name}) try: if task_id: # Create transient pool for deep scan conn.storagePoolCreateXML(xml, 0) return name pool = conn.storagePoolDefineXML(xml, 0) except libvirt.libvirtError as e: wok_log.error(f'Problem creating Storage Pool: {str(e)}') raise OperationFailed( 'KCHPOOL0007E', {'name': name, 'err': e.get_error_message()} ) # Build and set autostart value to pool # Ignore error as the pool was already successfully created # The build process fails when the pool directory already exists try: if params['type'] in ['logical', 'dir', 'netfs', 'scsi']: pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW) pool.setAutostart(1) else: pool.setAutostart(0) except Exception: pass if params['type'] == 'netfs': output, error, returncode = run_command( ['setsebool', '-P', 'virt_use_nfs=1'] ) if error or returncode: wok_log.error( 'Unable to set virt_use_nfs=1. If you use ' 'SELinux, this may prevent NFS pools from ' 'being used.' ) return name 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 _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})