Merge "Sanitize PowerVM partition name"
This commit is contained in:
commit
f5b758827e
@ -15,6 +15,9 @@
|
||||
# under the License.
|
||||
#
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import fixtures
|
||||
import logging
|
||||
import mock
|
||||
from oslo_serialization import jsonutils
|
||||
@ -84,33 +87,31 @@ class TestPowerVMDriver(test.TestCase):
|
||||
self.vol_fix = self.useFixture(fx.VolumeAdapter())
|
||||
self.vol_drv = self.vol_fix.drv
|
||||
|
||||
self.crt_lpar_p = mock.patch('nova_powervm.virt.powervm.vm.crt_lpar')
|
||||
self.crt_lpar = self.crt_lpar_p.start()
|
||||
self.addCleanup(self.crt_lpar_p.stop)
|
||||
self.crt_lpar = self.useFixture(fixtures.MockPatch(
|
||||
'nova_powervm.virt.powervm.vm.crt_lpar')).mock
|
||||
|
||||
self.get_inst_wrap_p = mock.patch('nova_powervm.virt.powervm.vm.'
|
||||
'get_instance_wrapper')
|
||||
self.get_inst_wrap = self.get_inst_wrap_p.start()
|
||||
self.addCleanup(self.get_inst_wrap_p.stop)
|
||||
self.get_inst_wrap = self.useFixture(fixtures.MockPatch(
|
||||
'nova_powervm.virt.powervm.vm.get_instance_wrapper')).mock
|
||||
|
||||
wrap = pvm_lpar.LPAR.wrap(pvmhttp.load_pvm_resp(
|
||||
LPAR_HTTPRESP_FILE).response)[0]
|
||||
self.crt_lpar.return_value = wrap
|
||||
self.get_inst_wrap.return_value = wrap
|
||||
|
||||
self.build_tx_feed_p = mock.patch('nova_powervm.virt.powervm.vios.'
|
||||
'build_tx_feed_task')
|
||||
self.build_tx_feed = self.build_tx_feed_p.start()
|
||||
self.addCleanup(self.build_tx_feed_p.stop)
|
||||
self.build_tx_feed = self.useFixture(fixtures.MockPatch(
|
||||
'nova_powervm.virt.powervm.vios.build_tx_feed_task')).mock
|
||||
|
||||
self.useFixture(pvm_fx.FeedTaskFx([pvm_vios.VIOS.wrap(
|
||||
pvmhttp.load_pvm_resp(VIOS_HTTPRESP_FILE).response)]))
|
||||
self.stg_ftsk = pvm_tx.FeedTask('fake', pvm_vios.VIOS.getter(self.apt))
|
||||
self.build_tx_feed.return_value = self.stg_ftsk
|
||||
|
||||
scrub_stg_p = mock.patch('pypowervm.tasks.storage.'
|
||||
'add_lpar_storage_scrub_tasks')
|
||||
self.scrub_stg = scrub_stg_p.start()
|
||||
self.addCleanup(scrub_stg_p.stop)
|
||||
self.scrub_stg = self.useFixture(fixtures.MockPatch(
|
||||
'pypowervm.tasks.storage.add_lpar_storage_scrub_tasks')).mock
|
||||
|
||||
self.san_lpar_name = self.useFixture(fixtures.MockPatch(
|
||||
'pypowervm.util.sanitize_partition_name_for_api')).mock
|
||||
self.san_lpar_name.side_effect = lambda name: name
|
||||
|
||||
# Create an instance to test with
|
||||
self.inst = objects.Instance(**powervm.TEST_INST_SPAWNING)
|
||||
@ -912,19 +913,22 @@ class TestPowerVMDriver(test.TestCase):
|
||||
mock_dst_int.assert_called_with(
|
||||
'context', self.inst, block_device_info=mock_bdms,
|
||||
destroy_disks=True, shutdown=True)
|
||||
self.san_lpar_name.assert_not_called()
|
||||
|
||||
# Test delete during migrate / resize
|
||||
self.inst.task_state = task_states.RESIZE_REVERTING
|
||||
mock_getqp.return_value = ('resize_' + self.inst.name)[:31]
|
||||
mock_getqp.return_value = 'resize_' + self.inst.name
|
||||
with mock.patch.object(self.drv, '_destroy') as mock_dst_int:
|
||||
# Invoke the method.
|
||||
self.drv.destroy('context', self.inst, mock.Mock(),
|
||||
block_device_info=mock_bdms)
|
||||
# We shouldn't delete our resize_ instances
|
||||
mock_dst_int.assert_not_called()
|
||||
self.san_lpar_name.assert_called_with('resize_' + self.inst.name)
|
||||
self.san_lpar_name.reset_mock()
|
||||
|
||||
# Now test migrating...
|
||||
mock_getqp.return_value = ('migrate_' + self.inst.name)[:31]
|
||||
mock_getqp.return_value = 'migrate_' + self.inst.name
|
||||
with mock.patch.object(self.drv, '_destroy') as mock_dst_int:
|
||||
# Invoke the method.
|
||||
self.drv.destroy('context', self.inst, mock.Mock(),
|
||||
@ -1044,23 +1048,25 @@ class TestPowerVMDriver(test.TestCase):
|
||||
|
||||
# Boot disk resize
|
||||
boot_flav = objects.Flavor(vcpus=1, memory_mb=2048, root_gb=12)
|
||||
# Tasks expected to be added for resize to the same host
|
||||
# Tasks expected to be added for migrate
|
||||
expected = [
|
||||
'pwr_off_lpar',
|
||||
'extend_disk_boot',
|
||||
'disconnect_vol_*',
|
||||
'disconnect_vol_*',
|
||||
'fake',
|
||||
'rename_lpar_resize_instance-00000001',
|
||||
'rename_lpar_migrate_instance-00000001',
|
||||
]
|
||||
dest_host = host + '1'
|
||||
with fx.DriverTaskFlow() as taskflow_fix:
|
||||
self.drv.migrate_disk_and_power_off(
|
||||
'context', self.inst, host, boot_flav, 'network_info',
|
||||
'context', self.inst, dest_host, boot_flav, 'network_info',
|
||||
mock_bdms)
|
||||
taskflow_fix.assert_tasks_added(self, expected)
|
||||
# Check the size set in the resize task
|
||||
extend_task = taskflow_fix.tasks_added[1]
|
||||
self.assertEqual(extend_task.size, 12)
|
||||
self.san_lpar_name.assert_called_with('migrate_' + self.inst.name)
|
||||
|
||||
@mock.patch('nova.objects.flavor.Flavor.get_by_id')
|
||||
def test_finish_migration(self, mock_get_flv):
|
||||
@ -1098,6 +1104,7 @@ class TestPowerVMDriver(test.TestCase):
|
||||
'context', mig, self.inst, disk_info, 'network_info',
|
||||
powervm.IMAGE1, 'resize_instance', block_device_info=mock_bdms)
|
||||
taskflow_fix.assert_tasks_added(self, expected)
|
||||
self.san_lpar_name.assert_not_called()
|
||||
|
||||
# Tasks expected to be added for resize to the same host
|
||||
expected = [
|
||||
@ -1115,6 +1122,8 @@ class TestPowerVMDriver(test.TestCase):
|
||||
'context', mig_same_host, self.inst, disk_info, 'network_info',
|
||||
powervm.IMAGE1, 'resize_instance', block_device_info=mock_bdms)
|
||||
taskflow_fix.assert_tasks_added(self, expected)
|
||||
self.san_lpar_name.assert_called_with('resize_' + self.inst.name)
|
||||
self.san_lpar_name.reset_mock()
|
||||
|
||||
# Tasks expected to be added for resize to the same host, no BDMS,
|
||||
# and no power_on
|
||||
@ -1126,6 +1135,7 @@ class TestPowerVMDriver(test.TestCase):
|
||||
'context', mig_same_host, self.inst, disk_info, 'network_info',
|
||||
powervm.IMAGE1, 'resize_instance', power_on=False)
|
||||
taskflow_fix.assert_tasks_added(self, expected)
|
||||
self.san_lpar_name.assert_called_with('resize_' + self.inst.name)
|
||||
|
||||
@mock.patch('nova_powervm.virt.powervm.driver.vm')
|
||||
@mock.patch('nova_powervm.virt.powervm.tasks.vm.vm')
|
||||
|
@ -15,6 +15,9 @@
|
||||
# under the License.
|
||||
#
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import fixtures
|
||||
import logging
|
||||
import mock
|
||||
|
||||
@ -59,6 +62,10 @@ class TestVMBuilder(test.TestCase):
|
||||
self.host_w = mock.MagicMock()
|
||||
self.lpar_b = vm.VMBuilder(self.host_w, self.adpt)
|
||||
|
||||
self.san_lpar_name = self.useFixture(fixtures.MockPatch(
|
||||
'pypowervm.util.sanitize_partition_name_for_api')).mock
|
||||
self.san_lpar_name.side_effect = lambda name: name
|
||||
|
||||
def test_conf_values(self):
|
||||
# Test driver CONF values are passed to the standardizer
|
||||
self.flags(uncapped_proc_weight=75, proc_units_factor=.25,
|
||||
@ -82,6 +89,8 @@ class TestVMBuilder(test.TestCase):
|
||||
|
||||
self.assertEqual(self.lpar_b._format_flavor(instance, flavor),
|
||||
test_attrs)
|
||||
self.san_lpar_name.assert_called_with(instance.name)
|
||||
self.san_lpar_name.reset_mock()
|
||||
|
||||
# Test dedicated procs, min/max vcpu and sharing mode
|
||||
flavor.extra_specs = {'powervm:dedicated_proc': 'true',
|
||||
@ -95,24 +104,32 @@ class TestVMBuilder(test.TestCase):
|
||||
'min_vcpu': '1', 'max_vcpu': '3'})
|
||||
self.assertEqual(self.lpar_b._format_flavor(instance, flavor),
|
||||
test_attrs)
|
||||
self.san_lpar_name.assert_called_with(instance.name)
|
||||
self.san_lpar_name.reset_mock()
|
||||
|
||||
# Test shared proc sharing mode
|
||||
flavor.extra_specs = {'powervm:uncapped': 'true'}
|
||||
test_attrs = dict(lpar_attrs, **{'sharing_mode': 'uncapped'})
|
||||
self.assertEqual(self.lpar_b._format_flavor(instance, flavor),
|
||||
test_attrs)
|
||||
self.san_lpar_name.assert_called_with(instance.name)
|
||||
self.san_lpar_name.reset_mock()
|
||||
|
||||
# Test availability priority
|
||||
flavor.extra_specs = {'powervm:availability_priority': '150'}
|
||||
test_attrs = dict(lpar_attrs, **{'avail_priority': '150'})
|
||||
self.assertEqual(self.lpar_b._format_flavor(instance, flavor),
|
||||
test_attrs)
|
||||
self.san_lpar_name.assert_called_with(instance.name)
|
||||
self.san_lpar_name.reset_mock()
|
||||
|
||||
# Test processor compatibility
|
||||
flavor.extra_specs = {'powervm:processor_compatibility': 'POWER8'}
|
||||
test_attrs = dict(lpar_attrs, **{'processor_compatibility': 'POWER8'})
|
||||
self.assertEqual(self.lpar_b._format_flavor(instance, flavor),
|
||||
test_attrs)
|
||||
self.san_lpar_name.assert_called_with(instance.name)
|
||||
self.san_lpar_name.reset_mock()
|
||||
|
||||
flavor.extra_specs = {'powervm:processor_compatibility': 'POWER6+'}
|
||||
test_attrs = dict(
|
||||
@ -120,6 +137,8 @@ class TestVMBuilder(test.TestCase):
|
||||
**{'processor_compatibility': pvm_bp.LPARCompat.POWER6_PLUS})
|
||||
self.assertEqual(self.lpar_b._format_flavor(instance, flavor),
|
||||
test_attrs)
|
||||
self.san_lpar_name.assert_called_with(instance.name)
|
||||
self.san_lpar_name.reset_mock()
|
||||
|
||||
flavor.extra_specs = {'powervm:processor_compatibility':
|
||||
'POWER6+_Enhanced'}
|
||||
@ -128,6 +147,8 @@ class TestVMBuilder(test.TestCase):
|
||||
pvm_bp.LPARCompat.POWER6_PLUS_ENHANCED})
|
||||
self.assertEqual(self.lpar_b._format_flavor(instance, flavor),
|
||||
test_attrs)
|
||||
self.san_lpar_name.assert_called_with(instance.name)
|
||||
self.san_lpar_name.reset_mock()
|
||||
|
||||
# Test min, max proc units
|
||||
flavor.extra_specs = {'powervm:min_proc_units': '0.5',
|
||||
@ -136,6 +157,8 @@ class TestVMBuilder(test.TestCase):
|
||||
'max_proc_units': '2.0'})
|
||||
self.assertEqual(self.lpar_b._format_flavor(instance, flavor),
|
||||
test_attrs)
|
||||
self.san_lpar_name.assert_called_with(instance.name)
|
||||
self.san_lpar_name.reset_mock()
|
||||
|
||||
# Test min, max mem
|
||||
flavor.extra_specs = {'powervm:min_mem': '1024',
|
||||
@ -143,6 +166,7 @@ class TestVMBuilder(test.TestCase):
|
||||
test_attrs = dict(lpar_attrs, **{'min_mem': '1024', 'max_mem': '4096'})
|
||||
self.assertEqual(self.lpar_b._format_flavor(instance, flavor),
|
||||
test_attrs)
|
||||
self.san_lpar_name.assert_called_with(instance.name)
|
||||
|
||||
@mock.patch('pypowervm.wrappers.shared_proc_pool.SharedProcPool.search')
|
||||
def test_spp_pool_id(self, mock_search):
|
||||
@ -188,6 +212,10 @@ class TestVM(test.TestCase):
|
||||
traits=pvm_fx.LocalPVMTraits)).adpt
|
||||
self.apt.helpers = [pvm_log.log_helper]
|
||||
|
||||
self.san_lpar_name = self.useFixture(fixtures.MockPatch(
|
||||
'pypowervm.util.sanitize_partition_name_for_api')).mock
|
||||
self.san_lpar_name.side_effect = lambda name: name
|
||||
|
||||
lpar_http = pvmhttp.load_pvm_resp(LPAR_HTTPRESP_FILE, adapter=self.apt)
|
||||
self.assertNotEqual(lpar_http, None,
|
||||
"Could not load %s " %
|
||||
@ -341,6 +369,7 @@ class TestVM(test.TestCase):
|
||||
entry.update.assert_called_once_with()
|
||||
self.assertEqual(name, entry.name)
|
||||
self.assertEqual('NewEntry', new_entry)
|
||||
self.san_lpar_name.assert_called_with(name)
|
||||
|
||||
@mock.patch('nova_powervm.virt.powervm.vm.get_instance_wrapper')
|
||||
def test_rename(self, mock_get_inst):
|
||||
@ -353,6 +382,8 @@ class TestVM(test.TestCase):
|
||||
self.assertEqual('new_name', entry.name)
|
||||
entry.update.assert_called_once_with()
|
||||
self.assertEqual('NewEntry', new_entry)
|
||||
self.san_lpar_name.assert_called_with('new_name')
|
||||
self.san_lpar_name.reset_mock()
|
||||
|
||||
# Test optional entry parameter
|
||||
entry.reset_mock()
|
||||
@ -363,6 +394,7 @@ class TestVM(test.TestCase):
|
||||
self.assertEqual('new_name', entry.name)
|
||||
entry.update.assert_called_once_with()
|
||||
self.assertEqual('NewEntry', new_entry)
|
||||
self.san_lpar_name.assert_called_with('new_name')
|
||||
|
||||
def test_add_IBMi_attrs(self):
|
||||
inst = mock.Mock()
|
||||
|
@ -580,7 +580,7 @@ class PowerVMDriver(driver.ComputeDriver):
|
||||
:param migrate_data: implementation specific params
|
||||
"""
|
||||
if instance.task_state == task_states.RESIZE_REVERTING:
|
||||
LOG.info(_LI('Destroy called for migrated instance.'),
|
||||
LOG.info(_LI('Destroy called for migrated/resized instance.'),
|
||||
instance=instance)
|
||||
# This destroy is part of resize or migrate. It's called to
|
||||
# revert the resize/migration on the destination host.
|
||||
@ -1074,9 +1074,18 @@ class PowerVMDriver(driver.ComputeDriver):
|
||||
|
||||
return disk_info
|
||||
|
||||
def _gen_resize_name(self, instance, same_host=False):
|
||||
@staticmethod
|
||||
def _gen_resize_name(instance, same_host=False):
|
||||
"""Generate a temporary name for the source VM being resized/migrated.
|
||||
|
||||
:param instance: nova.objects.instance.Instance being migrated/resized.
|
||||
:param same_host: Boolean indicating whether this resize is being
|
||||
performed for the sake of a resize (True) or a
|
||||
migration (False).
|
||||
:return: A new name which can be assigned to the source VM.
|
||||
"""
|
||||
prefix = 'resize_' if same_host else 'migrate_'
|
||||
return (prefix + instance.name)[:31]
|
||||
return pvm_util.sanitize_partition_name_for_api(prefix + instance.name)
|
||||
|
||||
def finish_migration(self, context, migration, instance, disk_info,
|
||||
network_info, image_meta, resize_instance,
|
||||
|
@ -30,6 +30,7 @@ from pypowervm.tasks import cna
|
||||
from pypowervm.tasks import ibmi
|
||||
from pypowervm.tasks import power
|
||||
from pypowervm.tasks import vterm
|
||||
from pypowervm import util as pvm_util
|
||||
from pypowervm.utils import lpar_builder as lpar_bldr
|
||||
from pypowervm.utils import uuid as pvm_uuid
|
||||
from pypowervm.utils import validation as vldn
|
||||
@ -295,7 +296,8 @@ class VMBuilder(object):
|
||||
# The attrs are what is sent to pypowervm to convert the lpar.
|
||||
attrs = {}
|
||||
|
||||
attrs[lpar_bldr.NAME] = instance.name
|
||||
attrs[lpar_bldr.NAME] = pvm_util.sanitize_partition_name_for_api(
|
||||
instance.name)
|
||||
# The uuid is only actually set on a create of an LPAR
|
||||
attrs[lpar_bldr.UUID] = pvm_uuid.convert_uuid_to_pvm(instance.uuid)
|
||||
attrs[lpar_bldr.MEM] = flavor.memory_mb
|
||||
@ -561,7 +563,7 @@ def update(adapter, host_wrapper, instance, flavor, entry=None, name=None):
|
||||
|
||||
# Set the new name if the instance name is not desired.
|
||||
if name:
|
||||
entry.name = name
|
||||
entry.name = pvm_util.sanitize_partition_name_for_api(name)
|
||||
# Write out the new specs, return the updated version
|
||||
return entry.update()
|
||||
|
||||
@ -581,7 +583,7 @@ def rename(adapter, host_uuid, instance, name, entry=None):
|
||||
if not entry:
|
||||
entry = get_instance_wrapper(adapter, instance, host_uuid)
|
||||
|
||||
entry.name = name
|
||||
entry.name = pvm_util.sanitize_partition_name_for_api(name)
|
||||
return entry.update()
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user