Exemple #1
0
    def test_crt_cfg_drv_vopt(self, mock_ccdi, mock_upl, mock_getsize,
                              mock_attach, mock_ntf, mock_name):
        # Mock Returns
        cfg_dr_builder = m.ConfigDrivePowerVM(self.apt)
        cfg_dr_builder.vios_uuid = 'vios_uuid'
        mock_instance = mock.MagicMock()
        mock_instance.uuid = uuidsentinel.inst_id
        mock_upl.return_value = 'vopt', 'f_uuid'
        fh = mock_ntf.return_value.__enter__.return_value
        fh.name = 'iso_path'
        mock_name.return_value = 'fake-name'

        # Run
        cfg_dr_builder.create_cfg_drv_vopt(mock_instance, 'files', 'netinfo',
                                           'fake_lpar', admin_pass='******')
        mock_ntf.assert_called_once_with(mode='rb')
        mock_ccdi.assert_called_once_with(cfg_dr_builder, mock_instance,
                                          'files', 'netinfo', 'iso_path',
                                          admin_pass='******')
        mock_getsize.assert_called_once_with('iso_path')
        mock_upl.assert_called_once_with(self.apt, 'vios_uuid', fh,
                                         'fake-name',
                                         mock_getsize.return_value)
        mock_attach.assert_called_once_with(mock_instance, 'fake_lpar',
                                            'vopt', None)
    def check_source(self, context, block_device_info, vol_drvs):
        """Check the source host

        Here we check the source host to see if it's capable of migrating
        the instance to the destination host.  There may be conditions
        that can only be checked on the source side.

        Also, get the instance ready for the migration by removing any
        virtual optical devices attached to the LPAR.

        :param context: security context
        :param block_device_info: result of _get_instance_block_device_info
        :param vol_drvs: volume drivers for the attached volumes
        :returns: a dict containing migration info
        """

        lpar_w = vm.get_instance_wrapper(self.drvr.adapter, self.instance,
                                         self.drvr.host_uuid)
        self.lpar_w = lpar_w

        LOG.debug('Dest Migration data: %s' % self.dest_data)

        # Only 'migrate_data' is sent to the destination on prelive call.
        mig_data = {'public_key': mgmt_task.get_public_key(self.drvr.adapter)}
        self.src_data['migrate_data'] = mig_data
        LOG.debug('Src Migration data: %s' % self.src_data)

        # Check proc compatability modes
        if (lpar_w.proc_compat_mode and lpar_w.proc_compat_mode
                not in self.dest_data['dest_proc_compat'].split(',')):
            raise LiveMigrationProcCompat(
                name=self.instance.name,
                mode=lpar_w.proc_compat_mode,
                modes=', '.join(self.dest_data['dest_proc_compat'].split(',')))

        # Check if VM is ready for migration
        self._check_migration_ready(lpar_w, self.drvr.host_wrapper)

        if lpar_w.migration_state != 'Not_Migrating':
            raise LiveMigrationInvalidState(name=self.instance.name,
                                            state=lpar_w.migration_state)

        # Check the number of migrations for capacity
        _verify_migration_capacity(self.drvr.host_wrapper, self.instance)

        # Get the 'source' pre-migration data for the volume drivers.  Should
        # automatically update the mig_data dictionary as needed.
        for vol_drv in vol_drvs:
            vol_drv.pre_live_migration_on_source(mig_data)

        # Remove the VOpt devices
        LOG.debug('Removing VOpt.', instance=self.instance)
        media.ConfigDrivePowerVM(self.drvr.adapter,
                                 self.drvr.host_uuid).dlt_vopt(lpar_w.uuid)
        LOG.debug('Removing VOpt finished.', instance=self.instance)

        # Ensure the vterm is non-active
        vterm.close_vterm(self.drvr.adapter, lpar_w.uuid)

        return self.src_data
Exemple #3
0
 def test_crt_cfg_dr_iso(self, mock_mkdrv, mock_meta):
     """Validates that the image creation method works."""
     cfg_dr_builder = m.ConfigDrivePowerVM(self.apt)
     mock_instance = mock.MagicMock()
     mock_instance.name = 'fake-instance'
     mock_instance.uuid = '1e46bbfd-73b6-3c2a-aeab-a1d3f065e92f'
     mock_files = mock.MagicMock()
     mock_net = mock.MagicMock()
     iso_path, file_name = cfg_dr_builder._create_cfg_dr_iso(
         mock_instance, mock_files, mock_net)
     self.assertEqual('cfg_fake_instance.iso', file_name)
     self.assertEqual('/tmp/cfgdrv/cfg_fake_instance.iso', iso_path)
     # Make sure the length is limited properly
     mock_instance.name = 'fake-instance-with-name-that-is-too-long'
     iso_path, file_name = cfg_dr_builder._create_cfg_dr_iso(
         mock_instance, mock_files, mock_net)
     self.assertEqual('cfg_fake_instance_with_name_that_.iso', file_name)
     self.assertEqual('/tmp/cfgdrv/cfg_fake_instance_with_name_that_.iso',
                      iso_path)
     self.assertTrue(self.validate_vopt.called)
     # Test retry vopt create
     mock_mkdrv.reset_mock()
     mock_mkdrv.side_effect = [OSError, mock_mkdrv]
     mock_instance.name = 'fake-instance-2'
     iso_path, file_name = cfg_dr_builder._create_cfg_dr_iso(
         mock_instance, mock_files, mock_net)
     self.assertEqual('cfg_fake_instance_2.iso', file_name)
     self.assertEqual('/tmp/cfgdrv/cfg_fake_instance_2.iso', iso_path)
     self.assertTrue(self.validate_vopt.called)
     self.assertEqual(mock_mkdrv.call_count, 2)
Exemple #4
0
 def test_validate_opt_vg(self):
     self.apt.read.side_effect = [self.vio_feed, self.vol_grp_resp]
     vg_update = self.vol_grp_resp.feed.entries[0]
     self.apt.update_by_path.return_value = vg_update
     cfg_dr_builder = m.ConfigDrivePowerVM(self.apt, 'fake_host')
     self.assertEqual('1e46bbfd-73b6-3c2a-aeab-a1d3f065e92f',
                      cfg_dr_builder.vg_uuid)
Exemple #5
0
    def test_dlt_vopt_no_map(self, mock_vop_valid, mock_vm_id, rm_vg_stor):
        feed = [pvm_vios.VIOS.wrap(self.vio_to_vg)]
        ft_fx = pvm_fx.FeedTaskFx(feed)
        self.useFixture(ft_fx)

        # Set up the mock data.
        self.apt.read.side_effect = [self.vio_to_vg, self.vg_to_vio]
        mock_vm_id.return_value = '2'

        def validate_remove_stor(vg_w, vopts=None):
            vopts = {} if vopts is None else vopts
            self.assertIsInstance(vg_w, pvm_stor.VG)
            self.assertEqual(1, len(vopts))
            self.assertIsInstance(vopts[0], pvm_stor.VOptMedia)

        rm_vg_stor.side_effect = validate_remove_stor

        # Count the number of SCSI mappings beforehand
        num_maps_before = len(feed[0].scsi_mappings)

        # Invoke the operation
        cfg_dr = m.ConfigDrivePowerVM(self.apt, 'fake_host')
        cfg_dr.vios_uuid = feed[0].uuid
        cfg_dr.dlt_vopt('2', remove_mappings=False)

        # The storage should have been removed
        self.assertTrue(rm_vg_stor.called)

        # The mappings should have changed
        self.assertTrue(ft_fx.patchers['update'].mock.called)
        # But the number should be the same (the vopt mapping was replaced)
        self.assertEqual(num_maps_before, len(feed[0].scsi_mappings))
Exemple #6
0
    def test_attach_vopt(self, mock_validate, mock_build_map, mock_add_map):
        # to act as the feed for FeedTaskFx and FeedTask.
        feed = [pvm_vios.VIOS.wrap(self.vio_to_vg)]
        ft_fx = pvm_fx.FeedTaskFx(feed)
        self.useFixture(ft_fx)

        mock_instance = mock.MagicMock(name='fake-instance')

        cfg_dr_builder = m.ConfigDrivePowerVM(self.apt, 'fake_host')
        cfg_dr_builder.vios_uuid = feed[0].uuid
        vopt = mock.Mock()
        self.apt.read.return_value = self.vio_to_vg

        def validate_build(host_uuid, vios_w, lpar_uuid, vopt_elem):
            self.assertEqual('fake_host', host_uuid)
            self.assertIsInstance(vios_w, pvm_vios.VIOS)
            self.assertEqual('lpar_uuid', lpar_uuid)
            self.assertEqual(vopt, vopt_elem)
            return 'map'

        mock_build_map.side_effect = validate_build

        def validate_add(vios_w, mapping):
            self.assertIsInstance(vios_w, pvm_vios.VIOS)
            self.assertEqual(mapping, 'map')
            return 'added'

        mock_add_map.side_effect = validate_add

        cfg_dr_builder._attach_vopt(mock_instance, 'lpar_uuid', vopt)

        # Make sure they were called and validated
        self.assertEqual(1, mock_build_map.call_count)
        self.assertEqual(1, mock_add_map.call_count)
        self.assertEqual(1, ft_fx.patchers['update'].mock.call_count)
Exemple #7
0
 def execute(self, lpar_wrap, mgmt_cna):
     LOG.info(_LI('Creating Config Drive for instance: %s'),
              self.instance.name)
     self.mb = media.ConfigDrivePowerVM(self.adapter, self.host_uuid)
     self.mb.create_cfg_drv_vopt(self.instance, self.injected_files,
                                 self.network_info, lpar_wrap.uuid,
                                 admin_pass=self.ad_pass,
                                 mgmt_cna=mgmt_cna, stg_ftsk=self.stg_ftsk)
Exemple #8
0
    def test_sanitize_network_info(self):
        network_info = [{'type': 'lbr'}, {'type': 'pvm_sea'}, {'type': 'ovs'}]

        cfg_dr_builder = m.ConfigDrivePowerVM(self.apt)

        resp = cfg_dr_builder._sanitize_network_info(network_info)
        expected_ret = [{'type': 'vif'}, {'type': 'vif'}, {'type': 'ovs'}]
        self.assertEqual(resp, expected_ret)
Exemple #9
0
 def execute(self, lpar_wrap, mgmt_cna):
     self.mb = media.ConfigDrivePowerVM(self.adapter)
     self.mb.create_cfg_drv_vopt(self.instance,
                                 self.injected_files,
                                 self.network_info,
                                 lpar_wrap.uuid,
                                 admin_pass=self.ad_pass,
                                 mgmt_cna=mgmt_cna,
                                 stg_ftsk=self.stg_ftsk)
Exemple #10
0
    def test_get_cfg_drv_name(self):
        cfg_dr_builder = m.ConfigDrivePowerVM(self.apt)
        mock_instance = mock.MagicMock()
        mock_instance.uuid = uuidsentinel.inst_id

        # calculate expected file name
        expected_file_name = 'cfg_' + mock_instance.uuid.replace('-', '')
        allowed_len = pvm_const.MaxLen.VOPT_NAME - 4  # '.iso' is 4 chars
        expected_file_name = expected_file_name[:allowed_len] + '.iso'

        name = cfg_dr_builder.get_cfg_drv_name(mock_instance)
        self.assertEqual(name, expected_file_name)
Exemple #11
0
    def test_dlt_vopt_no_map(self, mock_execute, mock_class_feed_task,
                             mock_add_dlt_vopt_tasks, mock_find_maps):
        # Init objects to test with
        mock_feed_task = mock.MagicMock()
        mock_class_feed_task.return_value = mock_feed_task
        mock_find_maps.return_value = []

        # Invoke the operation
        cfg_dr = m.ConfigDrivePowerVM(self.apt)
        cfg_dr.dlt_vopt('2', remove_mappings=False)

        # Verify expected methods were called
        mock_add_dlt_vopt_tasks.assert_not_called()
        self.assertTrue(mock_feed_task.execute.called)
Exemple #12
0
    def test_crt_cfg_drv_vopt(self, mock_attach, mock_upld, mock_rm, mock_size,
                              mock_validate, mock_cfg_iso):
        # Mock Returns
        mock_cfg_iso.return_value = '/tmp/cfgdrv/fake.iso', 'fake.iso'
        mock_size.return_value = 10000
        mock_upld.return_value = (mock.Mock(), None)

        # Run
        cfg_dr_builder = m.ConfigDrivePowerVM(self.apt, 'fake_host')
        cfg_dr_builder.create_cfg_drv_vopt(mock.MagicMock(), mock.MagicMock(),
                                           mock.MagicMock(), 'fake_lpar')
        self.assertTrue(mock_upld.called)
        self.assertTrue(mock_attach.called)
        mock_attach.assert_called_with(mock.ANY, 'fake_lpar', mock.ANY, None)
Exemple #13
0
    def test_mgmt_cna_to_vif(self, mock_validate):
        mock_cna = mock.MagicMock()
        mock_cna.mac = "FAD4433ED120"

        # Run
        cfg_dr_builder = m.ConfigDrivePowerVM(self.apt, 'fake_host')
        vif = cfg_dr_builder._mgmt_cna_to_vif(mock_cna)

        # Validate
        self.assertEqual(vif.get('address'), "fa:d4:43:3e:d1:20")
        self.assertEqual(vif.get('id'), 'mgmt_vif')
        self.assertIsNotNone(vif.get('network'))
        self.assertEqual(1, len(vif.get('network').get('subnets')))
        subnet = vif.get('network').get('subnets')[0]
        self.assertEqual(6, subnet.get('version'))
        self.assertEqual('fe80::/64', subnet.get('cidr'))
        ip = subnet.get('ips')[0]
        self.assertEqual('fe80::f8d4:43ff:fe3e:d120', ip.get('address'))
Exemple #14
0
 def test_crt_cfg_dr_iso(self, mock_mkdrv, mock_meta, mock_vopt_valid):
     """Validates that the image creation method works."""
     cfg_dr_builder = m.ConfigDrivePowerVM(self.apt, 'host_uuid')
     mock_instance = mock.MagicMock()
     mock_instance.name = 'fake-instance'
     mock_instance.uuid = '1e46bbfd-73b6-3c2a-aeab-a1d3f065e92f'
     mock_files = mock.MagicMock()
     mock_net = mock.MagicMock()
     iso_path, file_name = cfg_dr_builder._create_cfg_dr_iso(
         mock_instance, mock_files, mock_net)
     self.assertEqual('cfg_fake_instance.iso', file_name)
     self.assertEqual('/tmp/cfgdrv/cfg_fake_instance.iso', iso_path)
     # Make sure the length is limited properly
     mock_instance.name = 'fake-instance-with-name-that-is-too-long'
     iso_path, file_name = cfg_dr_builder._create_cfg_dr_iso(
         mock_instance, mock_files, mock_net)
     self.assertEqual('cfg_fake_instance_with_name_that_.iso', file_name)
     self.assertEqual('/tmp/cfgdrv/cfg_fake_instance_with_name_that_.iso',
                      iso_path)
Exemple #15
0
    def test_attach_vopt(self, mock_class_wrapper_task, mock_build_map,
                         mock_add_map):
        # Create objects to test with
        mock_instance = mock.MagicMock(name='fake-instance')
        cfg_dr_builder = m.ConfigDrivePowerVM(self.apt)
        vopt = mock.Mock()
        mock_vios = mock.Mock(spec=pvm_vios.VIOS)
        mock_vios.configure_mock(name='vios name')

        # Mock methods not currently under test
        mock_wrapper_task = mock.MagicMock()
        mock_class_wrapper_task.return_value = mock_wrapper_task

        def call_param(param):
            param(mock_vios)

        mock_wrapper_task.add_functor_subtask.side_effect = call_param

        def validate_build(host_uuid, vios_w, lpar_uuid, vopt_elem):
            self.assertEqual(None, host_uuid)
            self.assertIsInstance(vios_w, pvm_vios.VIOS)
            self.assertEqual('lpar_uuid', lpar_uuid)
            self.assertEqual(vopt, vopt_elem)
            return 'map'

        mock_build_map.side_effect = validate_build

        def validate_add(vios_w, mapping):
            self.assertIsInstance(vios_w, pvm_vios.VIOS)
            self.assertEqual(mapping, 'map')
            return 'added'

        mock_add_map.side_effect = validate_add

        # Run the actual test
        cfg_dr_builder._attach_vopt(mock_instance, 'lpar_uuid', vopt)

        # Make sure they were called and validated
        self.assertTrue(mock_wrapper_task.execute.called)
        self.assertEqual(1, mock_build_map.call_count)
        self.assertEqual(1, mock_add_map.call_count)
        self.assertTrue(self.validate_vopt.called)
Exemple #16
0
    def test_add_dlt_vopt_tasks(self, mock_find_maps, mock_gen_match_func):
        # Init objects to test with
        cfg_dr = m.ConfigDrivePowerVM(self.apt)
        stg_ftsk = mock.MagicMock()
        cfg_dr.vios_uuid = 'vios_uuid'
        lpar_uuid = 'lpar_uuid'
        mock_find_maps.return_value = [mock.Mock(backing_storage='stor')]

        # Run
        cfg_dr.add_dlt_vopt_tasks(lpar_uuid, stg_ftsk)

        # Validate
        mock_gen_match_func.assert_called_with(pvm_stg.VOptMedia)
        mock_find_maps.assert_called_with(
            stg_ftsk.get_wrapper().scsi_mappings,
            client_lpar_id='2',
            match_func=mock_gen_match_func.return_value)
        self.assertTrue(stg_ftsk.add_post_execute.called)
        self.assertTrue(
            stg_ftsk.wrapper_tasks['vios_uuid'].add_functor_subtask.called)
Exemple #17
0
    def test_crt_cfg_dr_iso(self, mock_pvm_uuid, mock_mkdrv, mock_meta):
        """Validates that the image creation method works."""
        cfg_dr_builder = m.ConfigDrivePowerVM(self.apt)
        self.assertTrue(self.validate_vopt.called)
        mock_instance = mock.MagicMock()
        mock_instance.uuid = '1e46bbfd-73b6-3c2a-aeab-a1d3f065e92f'
        mock_files = mock.MagicMock()
        mock_net = mock.MagicMock()
        iso_path = '/tmp/cfgdrv.iso'
        cfg_dr_builder._create_cfg_dr_iso(mock_instance, mock_files, mock_net,
                                          iso_path)
        self.assertTrue(mock_pvm_uuid.called)
        self.assertEqual(mock_mkdrv.call_count, 1)

        # Test retry iso create
        mock_mkdrv.reset_mock()
        mock_mkdrv.side_effect = [OSError, mock_mkdrv]
        cfg_dr_builder._create_cfg_dr_iso(mock_instance, mock_files, mock_net,
                                          iso_path)
        self.assertEqual(mock_mkdrv.call_count, 2)
Exemple #18
0
    def test_dlt_vopt(self, mock_vop_valid, mock_vm_id, rm_vg_stor):
        feed = [pvm_vios.VIOS.wrap(self.vio_to_vg)]
        ft_fx = pvm_fx.FeedTaskFx(feed)
        self.useFixture(ft_fx)

        # Set up the mock data.
        self.apt.read.side_effect = [self.vio_to_vg, self.vg_to_vio]
        mock_vm_id.return_value = '2'

        # Make sure that the first update is a VIO and doesn't have the vopt
        # mapping
        def validate_update(*kargs, **kwargs):
            vol_grp = kargs[0]
            # This is the VG update.  Make sure there are no optical medias
            # anymore.
            self.assertEqual(0, len(vol_grp.vmedia_repos[0].optical_media))
            return vol_grp.entry

        self.apt.update_by_path.side_effect = validate_update

        def validate_remove_stor(vg_w, vopts=None):
            vopts = {} if vopts is None else vopts
            self.assertIsInstance(vg_w, pvm_stor.VG)
            self.assertEqual(1, len(vopts))
            self.assertIsInstance(vopts[0], pvm_stor.VOptMedia)

        rm_vg_stor.side_effect = validate_remove_stor

        # Count the number of SCSI mappings beforehand
        num_maps_before = len(feed[0].scsi_mappings)

        # Invoke the operation
        cfg_dr = m.ConfigDrivePowerVM(self.apt, 'fake_host')
        cfg_dr.vios_uuid = feed[0].uuid
        cfg_dr.dlt_vopt('2')

        self.assertEqual(num_maps_before - 1, len(feed[0].scsi_mappings))
        self.assertTrue(ft_fx.patchers['update'].mock.called)
        self.assertTrue(rm_vg_stor.called)
    def check_source(self, context, block_device_info, vol_drvs):
        """Check the source host

        Here we check the source host to see if it's capable of migrating
        the instance to the destination host.  There may be conditions
        that can only be checked on the source side.

        Also, get the instance ready for the migration by removing any
        virtual optical devices attached to the LPAR.

        :param context: security context
        :param block_device_info: result of _get_instance_block_device_info
        :param vol_drvs: volume drivers for the attached volumes
        :returns: a PowerVMLiveMigrateData object
        """

        lpar_w = vm.get_instance_wrapper(self.drvr.adapter, self.instance)
        self.lpar_w = lpar_w

        LOG.debug('Dest Migration data: %s',
                  self.mig_data,
                  instance=self.instance)

        # Check proc compatibility modes
        if (lpar_w.proc_compat_mode and lpar_w.proc_compat_mode
                not in self.mig_data.dest_proc_compat.split(',')):
            msg = (_("Cannot migrate %(name)s because its "
                     "processor compatibility mode %(mode)s "
                     "is not in the list of modes \"%(modes)s\" "
                     "supported by the target host.") %
                   dict(name=self.instance.name,
                        mode=lpar_w.proc_compat_mode,
                        modes=', '.join(
                            self.mig_data.dest_proc_compat.split(','))))

            raise exception.MigrationPreCheckError(reason=msg)

        # Check if VM is ready for migration
        self._check_migration_ready(lpar_w, self.drvr.host_wrapper)

        if lpar_w.migration_state != 'Not_Migrating':
            msg = (_("Live migration of instance '%(name)s' failed because "
                     "the migration state is: %(state)s") %
                   dict(name=self.instance.name, state=lpar_w.migration_state))
            raise exception.MigrationPreCheckError(reason=msg)

        # Check the number of migrations for capacity
        _verify_migration_capacity(self.drvr.host_wrapper, self.instance)

        self.mig_data.public_key = mgmt_task.get_public_key(self.drvr.adapter)

        # Get the 'source' pre-migration data for the volume drivers.
        vol_data = {}
        for vol_drv in vol_drvs:
            vol_drv.pre_live_migration_on_source(vol_data)
        self.mig_data.vol_data = vol_data

        LOG.debug('Source migration data: %s',
                  self.mig_data,
                  instance=self.instance)

        # Create a FeedTask to scrub any orphaned mappings/storage associated
        # with this LPAR.  (Don't run it yet - we want to do the VOpt removal
        # within the same FeedTask.)
        stg_ftsk = stor_task.ScrubOrphanStorageForLpar(self.drvr.adapter,
                                                       lpar_w.id)
        # Add subtasks to remove the VOpt devices under the same FeedTask.
        media.ConfigDrivePowerVM(self.drvr.adapter).dlt_vopt(
            lpar_w.uuid, stg_ftsk=stg_ftsk, remove_mappings=False)
        # Now execute the FeedTask, performing both scrub and VOpt removal.
        stg_ftsk.execute()

        # Ensure the vterm is non-active
        vterm.close_vterm(self.drvr.adapter, lpar_w.uuid)

        return self.mig_data
Exemple #20
0
 def execute(self):
     media_builder = media.ConfigDrivePowerVM(self.adapter, self.host_uuid)
     media_builder.dlt_vopt(self.lpar_uuid, stg_ftsk=self.stg_ftsk)
Exemple #21
0
 def execute(self):
     media_builder = media.ConfigDrivePowerVM(self.adapter)
     media_builder.dlt_vopt(vm.get_pvm_uuid(self.instance),
                            stg_ftsk=self.stg_ftsk)