Add configuration option for custom image properties

Added configuration for injecting default image properties using the
interoperable image import process. This change adds 1 configuration
option to the charm:
- 'custom-import-properties' to specify the desired custom properties

Note: current glance docs example shows incorrect quoting, the
implemented format in this change (no quotes) is correct. Docs fix
in: https://review.opendev.org/c/openstack/glance/+/890423

Release note: https://review.opendev.org/c/openstack/charm-guide/+/891010

Closes-Bug: 1994053
Related-Bug: 2028895
Change-Id: I9548c90e663285c6e7a70eebc8c135a5568974bc
This commit is contained in:
Rafael Lopez 2023-03-01 01:32:01 +00:00
parent fe0cfb0134
commit 0a1d645000
4 changed files with 82 additions and 4 deletions

View File

@ -556,6 +556,16 @@ options:
only supported on stein or newer. This only works on imported images
(for example using 'openstack image create --import') Does not work
on regular image uploads (like 'openstack image create')
custom-import-properties:
type: string
default:
description: |
Set custom image properties when images are imported using the
interoperable image import process. Properties and their value are
delimited by commas, and values with colons and spaces are possible.
The properties specified here will be added to the glance-api
configuration file without being validated.
Example: 'prop1:val1,prop2:val-2,prop3:val:with:colons'
s3-store-host:
type: string
default:

View File

@ -107,10 +107,44 @@ class GlanceImageImportContext(OSContextGenerator):
def __call__(self):
ctxt = {}
ctxt['image_import_plugins'] = []
if config('image-conversion'):
ctxt['image_conversion'] = config('image-conversion')
ctxt['image_import_plugins'].append('image_conversion')
if config('custom-import-properties'):
try:
self.validate_custom_import_properties()
ctxt['image_import_plugins'].append('inject_image_metadata')
ctxt['custom_import_properties'] = (
config('custom-import-properties')
)
except (ValueError):
juju_log('Unable to validate custom-import-properties ({}), '
'see config.yaml for information about valid '
'formatting'
.format(config('custom-import-properties')),
level=ERROR)
raise
return ctxt
def validate_custom_import_properties(self):
"""Check the format of 'custom-import-properties' config parameter,
it should be a string of comma delimited key:value pairs
"""
props = config('custom-import-properties')
if not isinstance(props, str):
raise ValueError('not a string')
# Empty string is valid
if props == '':
return
# Check key value pairs
props_list = props.split(',')
for prop in props_list:
if ":" not in prop:
raise ValueError('value not found for property: {}'
.format(prop))
return
class CephGlanceContext(OSContextGenerator):
interfaces = ['ceph-glance']

View File

@ -1,7 +1,13 @@
{% if image_conversion -%}
{% if image_import_plugins|length > 0 -%}
[image_import_opts]
image_import_plugins = ['image_conversion']
image_import_plugins = {{ image_import_plugins }}
{% if 'image_conversion' in image_import_plugins %}
[image_conversion]
output_format = raw
{% endif %}
{% if 'inject_image_metadata' in image_import_plugins -%}
[inject_metadata_properties]
ignore_user_roles = ""
inject = {{ custom_import_properties }}
{% endif -%}
{% endif %}

View File

@ -75,6 +75,34 @@ class TestGlanceContexts(CharmTestCase):
"/var/lib/glance/images/",
'image_size_cap': 1099511627776})
def test_glance_image_import_context(self):
config = {
'image-conversion': True,
'custom-import-properties': 'p1:v1,prop2:rng1:rng2'}
self.config.side_effect = lambda x: config[x]
self.assertEqual(contexts.GlanceImageImportContext()(),
{'image_import_plugins': [
'image_conversion',
'inject_image_metadata'],
'custom_import_properties':
'p1:v1,prop2:rng1:rng2'})
config = {
'image-conversion': False,
'custom-import-properties': ''}
self.config.side_effect = lambda x: config[x]
self.assertEqual(contexts.GlanceImageImportContext()(),
{'image_import_plugins': []})
config = {
'image-conversion': False,
'custom-import-properties': 'prop-noval'}
self.assertRaises(ValueError)
config = {
'image-conversion': False,
'custom-import-properties': 10}
self.assertRaises(ValueError)
def test_swift_not_related(self):
self.relation_ids.return_value = []
self.assertEqual(contexts.ObjectStoreContext()(), {})