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.encode("utf-8") except KeyError, item: raise MissingParameter("KCHPOOL0004E", { 'item': str(item), '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.encode("utf-8") except KeyError, item: raise MissingParameter("KCHPOOL0004E", {'item': str(item), 'name': name})
def _nfs_status_online(self, pool, poolArgs=None): if not poolArgs: xml = pool.XMLDesc(0) pool_type = xpath_get_text(xml, "/pool/@type")[0] source = self._get_storage_source(pool_type, xml) poolArgs = {} poolArgs['name'] = pool.name() poolArgs['type'] = pool_type poolArgs['source'] = {'path': source['path'], 'host': source['addr']} conn = self.conn.get() poolDef = StoragePoolDef.create(poolArgs) try: poolDef.prepare(conn) return True except Exception: return False
def _nfs_status_online(self, pool, poolArgs=None): if not poolArgs: xml = pool.XMLDesc(0) pool_type = xpath_get_text(xml, '/pool/@type')[0] source = self._get_storage_source(pool_type, xml) poolArgs = {} poolArgs['name'] = pool.name() poolArgs['type'] = pool_type poolArgs['source'] = { 'path': source['path'], 'host': source['addr']} conn = self.conn.get() poolDef = StoragePoolDef.create(poolArgs) try: poolDef.prepare(conn) return True except Exception: return False
def create(self, params): task_id = None conn = self.conn.get() 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': vgdisplay_cmd = ['vgdisplay', name.encode('utf-8')] 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 returncode not in [2, 4, 5]: raise InvalidOperation("KCHPOOL0036E", {'name': name}) 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.encode("utf-8") except KeyError, item: raise MissingParameter("KCHPOOL0004E", { 'item': str(item), 'name': name })
def create(self, params): task_id = None conn = self.conn.get() 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': vgdisplay_cmd = ['vgdisplay', name.encode('utf-8')] 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 returncode not in [2, 4, 5]: raise InvalidOperation("KCHPOOL0036E", {'name': name}) 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.encode("utf-8") except KeyError, item: raise MissingParameter("KCHPOOL0004E", {'item': str(item), 'name': name})
def test_get_storagepool_xml(self): poolDefs = [{ 'def': { 'type': 'dir', 'name': 'unitTestDirPool', 'path': '/var/temp/images' }, 'xml': """ <pool type='dir'> <name>unitTestDirPool</name> <target> <path>/var/temp/images</path> </target> </pool> """ }, { 'def': { 'type': 'netfs', 'name': 'unitTestNFSPool', 'source': { 'host': '127.0.0.1', 'path': '/var/export' } }, 'xml': """ <pool type='netfs'> <name>unitTestNFSPool</name> <source> <host name='127.0.0.1'/> <dir path='/var/export'/> </source> <target> <path>/var/lib/kimchi/nfs_mount/unitTestNFSPool</path> </target> </pool> """ }, { 'def': { 'type': 'logical', 'name': 'unitTestLogicalPool', 'source': { 'devices': ['/dev/hda', '/dev/hdb'] } }, 'xml': """ <pool type='logical'> <name>unitTestLogicalPool</name> <source> <device path="/dev/hda" /> <device path="/dev/hdb" /> </source> <target> <path>/dev/unitTestLogicalPool</path> </target> </pool> """ }, { 'def': { 'type': 'iscsi', 'name': 'unitTestISCSIPool', 'source': { 'host': '127.0.0.1', 'target': 'iqn.2003-01.org.linux-iscsi.localhost' } }, 'xml': """ <pool type='iscsi'> <name>unitTestISCSIPool</name> <source> <host name='127.0.0.1' /> <device path='iqn.2003-01.org.linux-iscsi.localhost'/> </source> <target> <path>/dev/disk/by-id</path> </target> </pool> """ }, { 'def': { 'type': 'iscsi', 'name': 'unitTestISCSIPoolPort', 'source': { 'host': '127.0.0.1', 'port': 3266, 'target': 'iqn.2003-01.org.linux-iscsi.localhost' } }, 'xml': """ <pool type='iscsi'> <name>unitTestISCSIPoolPort</name> <source> <host name='127.0.0.1' port='3266' /> <device path='iqn.2003-01.org.linux-iscsi.localhost'/> </source> <target> <path>/dev/disk/by-id</path> </target> </pool> """ }, { 'def': { 'type': 'iscsi', 'name': 'unitTestISCSIPoolAuth', 'source': { 'host': '127.0.0.1', 'target': 'iqn.2003-01.org.linux-iscsi.localhost', 'auth': { 'username': '******', 'password': '******' } } }, 'xml': """ <pool type='iscsi'> <name>unitTestISCSIPoolAuth</name> <source> <host name='127.0.0.1' /> <device path='iqn.2003-01.org.linux-iscsi.localhost'/> <auth type='chap' username='******'> <secret type='iscsi' usage='unitTestISCSIPoolAuth'/> </auth> </source> <target> <path>/dev/disk/by-id</path> </target> </pool> """ }, { 'def': { 'type': 'scsi', 'name': 'unitTestSCSIFCPool', 'path': '/dev/disk/by-path', 'source': { 'name': 'scsi_host3', 'adapter': { 'type': 'fc_host', 'wwpn': '0123456789abcdef', 'wwnn': 'abcdef0123456789' } } }, 'xml': """ <pool type='scsi'> <name>unitTestSCSIFCPool</name> <source> <adapter type='fc_host' name='scsi_host3' wwnn='abcdef0123456789' wwpn='0123456789abcdef'></adapter> </source> <target> <path>/dev/disk/by-path</path> </target> </pool> """ }] for poolDef in poolDefs: defObj = StoragePoolDef.create(poolDef['def']) xmlStr = defObj.xml parser = ET.XMLParser(remove_blank_text=True) t1 = ET.fromstring(xmlStr, parser) t2 = ET.fromstring(poolDef['xml'], parser) self.assertEquals(ET.tostring(t1), ET.tostring(t2))
def test_get_storagepool_xml(self): poolDefs = [ {'def': {'type': 'dir', 'name': 'unitTestDirPool', 'path': '/var/temp/images'}, 'xml': """ <pool type='dir'> <name>unitTestDirPool</name> <target> <path>/var/temp/images</path> </target> </pool> """}, {'def': {'type': 'netfs', 'name': 'unitTestNFSPool', 'source': {'host': '127.0.0.1', 'path': '/var/export'}}, 'xml': """ <pool type='netfs'> <name>unitTestNFSPool</name> <source> <host name='127.0.0.1'/> <dir path='/var/export'/> </source> <target> <path>/var/lib/kimchi/nfs_mount/unitTestNFSPool</path> </target> </pool> """}, {'def': {'type': 'logical', 'name': 'unitTestLogicalPool', 'source': {'devices': ['/dev/hda', '/dev/hdb']}}, 'xml': """ <pool type='logical'> <name>unitTestLogicalPool</name> <source> <device path="/dev/hda" /> <device path="/dev/hdb" /> </source> <target> <path>/dev/unitTestLogicalPool</path> </target> </pool> """}, {'def': {'type': 'iscsi', 'name': 'unitTestISCSIPool', 'source': { 'host': '127.0.0.1', 'target': 'iqn.2003-01.org.linux-iscsi.localhost'}}, 'xml': """ <pool type='iscsi'> <name>unitTestISCSIPool</name> <source> <host name='127.0.0.1' /> <device path='iqn.2003-01.org.linux-iscsi.localhost'/> </source> <target> <path>/dev/disk/by-id</path> </target> </pool> """}, {'def': {'type': 'iscsi', 'name': 'unitTestISCSIPoolPort', 'source': { 'host': '127.0.0.1', 'port': 3266, 'target': 'iqn.2003-01.org.linux-iscsi.localhost'}}, 'xml': """ <pool type='iscsi'> <name>unitTestISCSIPoolPort</name> <source> <host name='127.0.0.1' port='3266' /> <device path='iqn.2003-01.org.linux-iscsi.localhost'/> </source> <target> <path>/dev/disk/by-id</path> </target> </pool> """}, {'def': {'type': 'iscsi', 'name': 'unitTestISCSIPoolAuth', 'source': { 'host': '127.0.0.1', 'target': 'iqn.2003-01.org.linux-iscsi.localhost', 'auth': {'username': '******', 'password': '******'}}}, 'xml': """ <pool type='iscsi'> <name>unitTestISCSIPoolAuth</name> <source> <host name='127.0.0.1' /> <device path='iqn.2003-01.org.linux-iscsi.localhost'/> <auth type='chap' username='******'> <secret type='iscsi' usage='unitTestISCSIPoolAuth'/> </auth> </source> <target> <path>/dev/disk/by-id</path> </target> </pool> """}, {'def': {'type': 'scsi', 'name': 'unitTestSCSIFCPool', 'path': '/dev/disk/by-path', 'source': { 'name': 'scsi_host3', 'adapter': { 'type': 'fc_host', 'wwpn': '0123456789abcdef', 'wwnn': 'abcdef0123456789'}}}, 'xml': """ <pool type='scsi'> <name>unitTestSCSIFCPool</name> <source> <adapter type='fc_host' name='scsi_host3' wwnn='abcdef0123456789' wwpn='0123456789abcdef'></adapter> </source> <target> <path>/dev/disk/by-path</path> </target> </pool> """}] for poolDef in poolDefs: defObj = StoragePoolDef.create(poolDef['def']) xmlStr = defObj.xml parser = ET.XMLParser(remove_blank_text=True) t1 = ET.fromstring(xmlStr, parser) t2 = ET.fromstring(poolDef['xml'], parser) self.assertEquals(ET.tostring(t1), ET.tostring(t2))
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 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