Sanitize config ISO name
Previously, we were using the instance's name verbatim to generate the name of its config ISO. Since the format of the instance name is very permissive, this can lead to rejection of the name by the PowerVM REST API: Value 'Linux Test_0ce757b1_thorst_config.iso' is not facet-valid with respect to pattern '([A-Za-z0-9_\.]{1,79})' for type 'FileName.Pattern'. This change set exploits a new pypowervm utility to sanitize the instance name and combine it with the desired prefix and suffix to generate a valid config ISO name. The same is being done for an instance's boot/rescue disks and image LUs (for SSP). Change-Id: Id8a77e20ede3ec3339ef5e5910e05943683a2b6c
This commit is contained in:
parent
27a4b6b6e3
commit
a0ed70408c
|
@ -65,7 +65,8 @@ class TestSSPDiskAdapter(test.TestCase):
|
|||
super(TestSSPDiskAdapter, self).setUp()
|
||||
|
||||
class Instance(object):
|
||||
uuid = 'instance_uuid'
|
||||
uuid = 'instance-uuid'
|
||||
name = 'instance-name'
|
||||
|
||||
self.instance = Instance()
|
||||
|
||||
|
@ -275,19 +276,19 @@ class TestSSPDiskAdapter(test.TestCase):
|
|||
b1G = 1024 * 1024 * 1024
|
||||
b2G = 2 * b1G
|
||||
ssp_stor = self._get_ssp_stor()
|
||||
img = dict(id='image-id', size=b2G)
|
||||
img = dict(name='image-name', id='image-id', size=b2G)
|
||||
|
||||
def verify_upload_new_lu(vios_uuid, ssp1, stream, lu_name, f_size):
|
||||
self.assertIn(vios_uuid, ssp_stor._vios_uuids())
|
||||
self.assertEqual(ssp_stor._ssp_wrap, ssp1)
|
||||
# 'image' + '_' + s/-/_/g(image['id']), per _get_image_name
|
||||
self.assertEqual('image_image_id', lu_name)
|
||||
self.assertEqual('image_image_name', lu_name)
|
||||
self.assertEqual(b2G, f_size)
|
||||
return 'image_lu', None
|
||||
|
||||
def verify_create_lu_linked_clone(ssp1, clust1, imglu, lu_name, sz_gb):
|
||||
# 'boot'[:6] + '_' + 'instance_uuid'[:8], per _get_disk_name
|
||||
self.assertEqual('boot_instance', lu_name)
|
||||
# 'boot_' + sanitize('instance-name') _get_disk_name
|
||||
self.assertEqual('boot_instance_name', lu_name)
|
||||
self.assertEqual('image_lu', imglu)
|
||||
return ssp1, 'new_lu'
|
||||
|
||||
|
@ -304,18 +305,19 @@ class TestSSPDiskAdapter(test.TestCase):
|
|||
b1G = 1024 * 1024 * 1024
|
||||
b2G = 2 * b1G
|
||||
ssp_stor = self._get_ssp_stor()
|
||||
img = dict(id='image-id', size=b2G)
|
||||
img = dict(name='image-name', id='image-id', size=b2G)
|
||||
# Mock the 'existing' image LU
|
||||
img_lu = pvm_stg.LU.bld(None, 'image_image_id', 123,
|
||||
img_lu = pvm_stg.LU.bld(None, 'image_image_name', 123,
|
||||
typ=pvm_stg.LUType.IMAGE)
|
||||
ssp_stor._ssp_wrap.logical_units.append(img_lu)
|
||||
|
||||
class Instance(object):
|
||||
uuid = 'instance_uuid'
|
||||
uuid = 'instance-uuid'
|
||||
name = 'instance-name'
|
||||
|
||||
def verify_create_lu_linked_clone(ssp1, clust1, imglu, lu_name, sz_gb):
|
||||
# 'boot'[:6] + '_' + 'instance_uuid'[:8], per _get_disk_name
|
||||
self.assertEqual('boot_instance', lu_name)
|
||||
# 'boot_' + sanitize('instance-name') per _get_disk_name
|
||||
self.assertEqual('boot_instance_name', lu_name)
|
||||
self.assertEqual(img_lu, imglu)
|
||||
return ssp1, 'new_lu'
|
||||
|
||||
|
|
|
@ -75,13 +75,14 @@ class TestConfigDrivePowerVM(test.TestCase):
|
|||
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('fake_instance_config.iso', file_name)
|
||||
self.assertEqual('/tmp/cfgdrv/fake_instance_config.iso', iso_path)
|
||||
self.assertEqual('config_fake_instance.iso', file_name)
|
||||
self.assertEqual('/tmp/cfgdrv/config_fake_instance.iso', iso_path)
|
||||
|
||||
@mock.patch('nova_powervm.virt.powervm.media.ConfigDrivePowerVM.'
|
||||
'_create_cfg_dr_iso')
|
||||
|
|
|
@ -21,6 +21,7 @@ from oslo_utils import units
|
|||
import six
|
||||
|
||||
from nova import image
|
||||
import pypowervm.util as pvm_util
|
||||
|
||||
|
||||
class DiskType(object):
|
||||
|
@ -71,7 +72,7 @@ class DiskAdapter(object):
|
|||
|
||||
Default is to make the capacity arbitrarily large
|
||||
"""
|
||||
return (1 << 21)
|
||||
return 1 << 21
|
||||
|
||||
@property
|
||||
def capacity_used(self):
|
||||
|
@ -97,11 +98,15 @@ class DiskAdapter(object):
|
|||
|
||||
@staticmethod
|
||||
def _get_disk_name(disk_type, instance):
|
||||
return disk_type[:6] + '_' + instance.uuid[:8]
|
||||
"""Generate a name for a virtual disk associated with an instance."""
|
||||
return pvm_util.sanitize_file_name_for_api(instance.name,
|
||||
prefix=disk_type + '_')
|
||||
|
||||
@staticmethod
|
||||
def _get_image_name(image):
|
||||
return DiskType.IMAGE + '_' + image['id'].replace('-', '_')
|
||||
def _get_image_name(image_meta):
|
||||
"""Generate a name for a virtual storage copy of an image."""
|
||||
return pvm_util.sanitize_file_name_for_api(image_meta['name'],
|
||||
prefix=DiskType.IMAGE + '_')
|
||||
|
||||
@staticmethod
|
||||
def _disk_gb_to_bytes(size_gb, floor=None):
|
||||
|
@ -144,13 +149,13 @@ class DiskAdapter(object):
|
|||
"""
|
||||
pass
|
||||
|
||||
def create_disk_from_image(self, context, instance, image, disk_size,
|
||||
def create_disk_from_image(self, context, instance, image_meta, disk_size,
|
||||
image_type=DiskType.BOOT):
|
||||
"""Creates a disk and copies the specified image to it.
|
||||
|
||||
:param context: nova context used to retrieve image from glance
|
||||
:param instance: instance to create the disk for.
|
||||
:param image_id: image_id reference used to locate the image in glance
|
||||
:param image_meta: dict identifying the image in glance
|
||||
:param disk_size: The size of the disk to create in GB. If smaller
|
||||
than the image, it will be ignored (as the disk
|
||||
must be at least as big as the image). Must be an
|
||||
|
|
|
@ -25,6 +25,7 @@ from oslo_log import log as logging
|
|||
|
||||
from pypowervm.tasks import scsi_mapper as tsk_map
|
||||
from pypowervm.tasks import storage as tsk_stg
|
||||
from pypowervm import util as pvm_util
|
||||
from pypowervm.wrappers import base_partition as pvm_bp
|
||||
from pypowervm.wrappers import managed_system as pvm_ms
|
||||
from pypowervm.wrappers import storage as pvm_stg
|
||||
|
@ -102,7 +103,8 @@ class ConfigDrivePowerVM(object):
|
|||
if not os.path.exists(CONF.image_meta_local_path):
|
||||
os.mkdir(CONF.image_meta_local_path)
|
||||
|
||||
file_name = '%s_config.iso' % instance.name.replace('-', '_')
|
||||
file_name = pvm_util.sanitize_file_name_for_api(
|
||||
instance.name, prefix='config_', suffix='.iso')
|
||||
iso_path = os.path.join(CONF.image_meta_local_path, file_name)
|
||||
with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb:
|
||||
LOG.info(_LI("Config drive ISO being built for instance %(inst)s "
|
||||
|
|
Loading…
Reference in New Issue