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:
parent
fe0cfb0134
commit
0a1d645000
10
config.yaml
10
config.yaml
|
@ -556,6 +556,16 @@ options:
|
||||||
only supported on stein or newer. This only works on imported images
|
only supported on stein or newer. This only works on imported images
|
||||||
(for example using 'openstack image create --import') Does not work
|
(for example using 'openstack image create --import') Does not work
|
||||||
on regular image uploads (like 'openstack image create')
|
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:
|
s3-store-host:
|
||||||
type: string
|
type: string
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -107,10 +107,44 @@ class GlanceImageImportContext(OSContextGenerator):
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
ctxt = {}
|
ctxt = {}
|
||||||
|
ctxt['image_import_plugins'] = []
|
||||||
if config('image-conversion'):
|
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
|
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):
|
class CephGlanceContext(OSContextGenerator):
|
||||||
interfaces = ['ceph-glance']
|
interfaces = ['ceph-glance']
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
{% if image_conversion -%}
|
{% if image_import_plugins|length > 0 -%}
|
||||||
[image_import_opts]
|
[image_import_opts]
|
||||||
image_import_plugins = ['image_conversion']
|
image_import_plugins = {{ image_import_plugins }}
|
||||||
|
{% if 'image_conversion' in image_import_plugins %}
|
||||||
[image_conversion]
|
[image_conversion]
|
||||||
output_format = raw
|
output_format = raw
|
||||||
|
{% endif %}
|
||||||
|
{% if 'inject_image_metadata' in image_import_plugins -%}
|
||||||
|
[inject_metadata_properties]
|
||||||
|
ignore_user_roles = ""
|
||||||
|
inject = {{ custom_import_properties }}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
|
{% endif %}
|
||||||
|
|
|
@ -75,6 +75,34 @@ class TestGlanceContexts(CharmTestCase):
|
||||||
"/var/lib/glance/images/",
|
"/var/lib/glance/images/",
|
||||||
'image_size_cap': 1099511627776})
|
'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):
|
def test_swift_not_related(self):
|
||||||
self.relation_ids.return_value = []
|
self.relation_ids.return_value = []
|
||||||
self.assertEqual(contexts.ObjectStoreContext()(), {})
|
self.assertEqual(contexts.ObjectStoreContext()(), {})
|
||||||
|
|
Loading…
Reference in New Issue