Add v2 glance image props
Added properties, supported by glanceclient v2: architecture kernel_id os_distro ramdisk_id and also owner property, supported by glanceclient v1. Closes-Bug: #1606150 Change-Id: I15b9295f631615c1d98d7872fb973d5e8ca226da
This commit is contained in:
parent
0a8d40d909
commit
652a1a8b33
|
@ -30,13 +30,18 @@ class GlanceImage(resource.Resource):
|
|||
|
||||
PROPERTIES = (
|
||||
NAME, IMAGE_ID, IS_PUBLIC, MIN_DISK, MIN_RAM, PROTECTED,
|
||||
DISK_FORMAT, CONTAINER_FORMAT, LOCATION, TAGS, EXTRA_PROPERTIES
|
||||
DISK_FORMAT, CONTAINER_FORMAT, LOCATION, TAGS, EXTRA_PROPERTIES,
|
||||
ARCHITECTURE, KERNEL_ID, OS_DISTRO, OWNER, RAMDISK_ID
|
||||
) = (
|
||||
'name', 'id', 'is_public', 'min_disk', 'min_ram', 'protected',
|
||||
'disk_format', 'container_format', 'location', 'tags',
|
||||
'extra_properties'
|
||||
'extra_properties', 'architecture', 'kernel_id', 'os_distro',
|
||||
'owner', 'ramdisk_id'
|
||||
)
|
||||
|
||||
glance_id_pattern = ('^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}'
|
||||
'-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$')
|
||||
|
||||
properties_schema = {
|
||||
NAME: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
|
@ -118,6 +123,45 @@ class GlanceImage(resource.Resource):
|
|||
update_allowed=True,
|
||||
default={},
|
||||
support_status=support.SupportStatus(version='7.0.0')
|
||||
),
|
||||
ARCHITECTURE: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('Operating system architecture.'),
|
||||
update_allowed=True,
|
||||
support_status=support.SupportStatus(version='7.0.0')
|
||||
),
|
||||
KERNEL_ID: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('ID of image stored in Glance that should be used as '
|
||||
'the kernel when booting an AMI-style image.'),
|
||||
update_allowed=True,
|
||||
support_status=support.SupportStatus(version='7.0.0'),
|
||||
constraints=[
|
||||
constraints.AllowedPattern(glance_id_pattern)
|
||||
]
|
||||
),
|
||||
OS_DISTRO: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('The common name of the operating system distribution '
|
||||
'in lowercase.'),
|
||||
update_allowed=True,
|
||||
support_status=support.SupportStatus(version='7.0.0')
|
||||
),
|
||||
OWNER: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('Owner of the image.'),
|
||||
update_allowed=True,
|
||||
support_status=support.SupportStatus(version='7.0.0')
|
||||
),
|
||||
RAMDISK_ID: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('ID of image stored in Glance that should be used as '
|
||||
'the ramdisk when booting an AMI-style image.'),
|
||||
update_allowed=True,
|
||||
support_status=support.SupportStatus(version='7.0.0'),
|
||||
constraints=[
|
||||
constraints.AllowedPattern(glance_id_pattern)
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -131,9 +175,24 @@ class GlanceImage(resource.Resource):
|
|||
|
||||
tags = args.pop(self.TAGS, [])
|
||||
args['properties'] = args.pop(self.EXTRA_PROPERTIES, {})
|
||||
architecture = args.pop(self.ARCHITECTURE, None)
|
||||
kernel_id = args.pop(self.KERNEL_ID, None)
|
||||
os_distro = args.pop(self.OS_DISTRO, None)
|
||||
ramdisk_id = args.pop(self.RAMDISK_ID, None)
|
||||
|
||||
image_id = self.client().images.create(**args).id
|
||||
self.resource_id_set(image_id)
|
||||
|
||||
v2_images = self.client(version=self.client_plugin().V2).images
|
||||
if architecture is not None:
|
||||
v2_images.update(image_id, architecture=architecture)
|
||||
if kernel_id is not None:
|
||||
v2_images.update(image_id, kernel_id=kernel_id)
|
||||
if os_distro is not None:
|
||||
v2_images.update(image_id, os_distro=os_distro)
|
||||
if ramdisk_id is not None:
|
||||
v2_images.update(image_id, ramdisk_id=ramdisk_id)
|
||||
|
||||
for tag in tags:
|
||||
self.client(
|
||||
version=self.client_plugin().V2).image_tags.update(
|
||||
|
@ -149,7 +208,7 @@ class GlanceImage(resource.Resource):
|
|||
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
|
||||
if prop_diff and self.TAGS in prop_diff:
|
||||
existing_tags = self.properties.get(self.TAGS) or []
|
||||
diff_tags = prop_diff[self.TAGS] or []
|
||||
diff_tags = prop_diff.pop(self.TAGS) or []
|
||||
|
||||
new_tags = set(diff_tags) - set(existing_tags)
|
||||
for tag in new_tags:
|
||||
|
@ -166,18 +225,20 @@ class GlanceImage(resource.Resource):
|
|||
self.resource_id,
|
||||
tag)
|
||||
|
||||
v2_images = self.client(version=self.client_plugin().V2).images
|
||||
|
||||
if self.EXTRA_PROPERTIES in prop_diff:
|
||||
old_properties = self.properties.get(self.EXTRA_PROPERTIES) or {}
|
||||
new_properties = prop_diff[self.EXTRA_PROPERTIES]
|
||||
new_properties = prop_diff.pop(self.EXTRA_PROPERTIES)
|
||||
prop_diff.update(new_properties)
|
||||
remove_props = list(set(old_properties) - set(new_properties))
|
||||
|
||||
# Though remove_props defaults to None within the glanceclient,
|
||||
# setting it to a list (possibly []) every time ensures only one
|
||||
# calling format to images.update
|
||||
self.client(version=self.client_plugin().V2).images.update(
|
||||
self.resource_id,
|
||||
remove_props,
|
||||
**new_properties)
|
||||
v2_images.update(self.resource_id, remove_props, **prop_diff)
|
||||
else:
|
||||
v2_images.update(self.resource_id, **prop_diff)
|
||||
|
||||
def _show_resource(self):
|
||||
if self.glance().version == 1.0:
|
||||
|
|
|
@ -38,6 +38,12 @@ resources:
|
|||
min_ram: 512
|
||||
protected: False
|
||||
location: https://launchpad.net/cirros/cirros-0.3.0-x86_64-disk.img
|
||||
location: https://launchpad.net/cirros/cirros-0.3.0-x86_64-disk.img
|
||||
architecture: test_architecture
|
||||
kernel_id: 12345678-1234-1234-1234-123456789012
|
||||
os_distro: test_distro
|
||||
owner: test_owner
|
||||
ramdisk_id: 12345678-1234-1234-1234-123456789012
|
||||
'''
|
||||
|
||||
image_template_validate = '''
|
||||
|
@ -231,11 +237,22 @@ class GlanceImageTest(common.HeatTestCase):
|
|||
min_ram=512,
|
||||
name=u'cirros_image',
|
||||
protected=False,
|
||||
owner=u'test_owner',
|
||||
properties={}
|
||||
)
|
||||
self.image_tags.update.assert_called_once_with(
|
||||
self.my_image.resource_id,
|
||||
'tag1')
|
||||
calls = [mock.call(self.my_image.resource_id,
|
||||
architecture='test_architecture'),
|
||||
mock.call(self.my_image.resource_id,
|
||||
kernel_id='12345678-1234-1234-1234-123456789012'),
|
||||
mock.call(self.my_image.resource_id,
|
||||
os_distro='test_distro'),
|
||||
mock.call(self.my_image.resource_id,
|
||||
ramdisk_id='12345678-1234-1234-1234-123456789012'),
|
||||
]
|
||||
self.images.update.assert_has_calls(calls)
|
||||
|
||||
def _handle_update_tags(self, prop_diff):
|
||||
self.my_image.handle_update(json_snippet=None,
|
||||
|
@ -251,17 +268,31 @@ class GlanceImageTest(common.HeatTestCase):
|
|||
'tag1'
|
||||
)
|
||||
|
||||
def _handle_update_properties(self, prop_diff):
|
||||
def test_image_handle_update(self):
|
||||
self.my_image.resource_id = '477e8273-60a7-4c41-b683-fdb0bc7cd151'
|
||||
prop_diff = {
|
||||
'architecture': 'test_architecture',
|
||||
'kernel_id': '12345678-1234-1234-1234-123456789012',
|
||||
'os_distro': 'test_distro',
|
||||
'owner': 'test_owner',
|
||||
'ramdisk_id': '12345678-1234-1234-1234-123456789012',
|
||||
'extra_properties': {'key1': 'value1', 'key2': 'value2'}}
|
||||
|
||||
self.my_image.handle_update(json_snippet=None,
|
||||
tmpl_diff=None,
|
||||
prop_diff=prop_diff)
|
||||
|
||||
self.images.update.assert_called_once_with(
|
||||
self.my_image.resource_id,
|
||||
[],
|
||||
**prop_diff['extra_properties'])
|
||||
architecture='test_architecture',
|
||||
kernel_id='12345678-1234-1234-1234-123456789012',
|
||||
os_distro='test_distro',
|
||||
owner='test_owner',
|
||||
ramdisk_id='12345678-1234-1234-1234-123456789012',
|
||||
key1='value1', key2='value2'
|
||||
)
|
||||
|
||||
def test_image_handle_update(self):
|
||||
def test_image_handle_update_tags(self):
|
||||
self.my_image.resource_id = '477e8273-60a7-4c41-b683-fdb0bc7cd151'
|
||||
|
||||
self.my_image.t['Properties']['tags'] = ['tag1']
|
||||
|
@ -269,9 +300,6 @@ class GlanceImageTest(common.HeatTestCase):
|
|||
|
||||
self._handle_update_tags(prop_diff)
|
||||
|
||||
prop_diff = {'extra_properties': {'key1': 'value1', 'key2': 'value2'}}
|
||||
self._handle_update_properties(prop_diff)
|
||||
|
||||
def test_image_handle_update_remove_tags(self):
|
||||
self.my_image.resource_id = '477e8273-60a7-4c41-b683-fdb0bc7cd151'
|
||||
|
||||
|
@ -339,7 +367,12 @@ class GlanceImageTest(common.HeatTestCase):
|
|||
'min_ram': 0,
|
||||
'id': '41f0e60c-ebb4-4375-a2b4-845ae8b9c995',
|
||||
'tags': [],
|
||||
'extra_properties': {}
|
||||
'extra_properties': {},
|
||||
'architecture': 'test_architecture',
|
||||
'kernel_id': '12345678-1234-1234-1234-123456789012',
|
||||
'os_distro': 'test_distro',
|
||||
'owner': 'test_owner',
|
||||
'ramdisk_id': '12345678-1234-1234-1234-123456789012'
|
||||
}
|
||||
if version == 1.0:
|
||||
image = mock.MagicMock()
|
||||
|
@ -363,7 +396,12 @@ class GlanceImageTest(common.HeatTestCase):
|
|||
'min_ram': 0,
|
||||
'id': '41f0e60c-ebb4-4375-a2b4-845ae8b9c995',
|
||||
'tags': [],
|
||||
'extra_properties': {}
|
||||
'extra_properties': {},
|
||||
'architecture': 'test_architecture',
|
||||
'kernel_id': '12345678-1234-1234-1234-123456789012',
|
||||
'os_distro': 'test_distro',
|
||||
'owner': 'test_owner',
|
||||
'ramdisk_id': '12345678-1234-1234-1234-123456789012'
|
||||
}
|
||||
if version == 1.0:
|
||||
expected.update({'location': 'stub'})
|
||||
|
|
Loading…
Reference in New Issue