Example #1
0
    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
            })
Example #2
0
    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})
Example #3
0
 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
Example #4
0
 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
Example #5
0
    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
            })
Example #6
0
    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})
Example #7
0
    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))
Example #8
0
    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))
Example #9
0
    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
Example #10
0
    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