Add support for storage of images in Cinder
Glance charm allows to store images in file, ceph, swift. This changeset adds support for storage of images in Cinder for OpenStack Mitaka or later. Required dependencies are installed on relation to Cinder (inline with Ceph integration). This feature is dependent on resolution of some packaging issues in the glance-store package (see Related-Bug). Related-Bug: 1609733 Change-Id: Ib9d9f28e040b7b2eebb3f5d0ee9ff0773292bdcc
This commit is contained in:
parent
ad8888b09b
commit
fa1c1dda1c
1
hooks/cinder-volume-service-relation-broken
Symbolic link
1
hooks/cinder-volume-service-relation-broken
Symbolic link
@ -0,0 +1 @@
|
||||
glance_relations.py
|
1
hooks/cinder-volume-service-relation-joined
Symbolic link
1
hooks/cinder-volume-service-relation-joined
Symbolic link
@ -0,0 +1 @@
|
||||
glance_relations.py
|
@ -30,6 +30,10 @@ from charmhelpers.contrib.hahelpers.cluster import (
|
||||
determine_api_port,
|
||||
)
|
||||
|
||||
from charmhelpers.contrib.openstack.utils import (
|
||||
os_release
|
||||
)
|
||||
|
||||
|
||||
class CephGlanceContext(OSContextGenerator):
|
||||
interfaces = ['ceph-glance']
|
||||
@ -65,6 +69,21 @@ class ObjectStoreContext(OSContextGenerator):
|
||||
}
|
||||
|
||||
|
||||
class CinderStoreContext(OSContextGenerator):
|
||||
interfaces = ['cinder-volume-service']
|
||||
|
||||
def __call__(self):
|
||||
"""Cinder store config.
|
||||
Used to generate template context to be added to glance-api.conf in
|
||||
the presence of a 'cinder-volume-service' relation.
|
||||
"""
|
||||
if not relation_ids('cinder-volume-service'):
|
||||
return {}
|
||||
return {
|
||||
'cinder_store': True,
|
||||
}
|
||||
|
||||
|
||||
class MultiStoreContext(OSContextGenerator):
|
||||
|
||||
def __call__(self):
|
||||
@ -76,6 +95,9 @@ class MultiStoreContext(OSContextGenerator):
|
||||
for store_relation, store_type in store_mapping.iteritems():
|
||||
if relation_ids(store_relation):
|
||||
stores.append(store_type)
|
||||
if (relation_ids('cinder-volume-service') and
|
||||
os_release('glance-common') >= 'mitaka'):
|
||||
stores.append('glance.store.cinder.Store')
|
||||
return {
|
||||
'known_stores': ','.join(stores)
|
||||
}
|
||||
|
@ -88,6 +88,7 @@ from charmhelpers.contrib.openstack.utils import (
|
||||
sync_db_with_multi_ipv6_addresses,
|
||||
pausable_restart_on_change as restart_on_change,
|
||||
is_unit_paused_set,
|
||||
os_requires_version,
|
||||
)
|
||||
from charmhelpers.contrib.storage.linux.ceph import (
|
||||
send_request_if_needed,
|
||||
@ -526,7 +527,8 @@ def ha_relation_changed():
|
||||
@hooks.hook('identity-service-relation-broken',
|
||||
'object-store-relation-broken',
|
||||
'shared-db-relation-broken',
|
||||
'pgsql-db-relation-broken')
|
||||
'pgsql-db-relation-broken',
|
||||
'cinder-volume-service-relation-broken')
|
||||
def relation_broken():
|
||||
CONFIGS.write_all()
|
||||
|
||||
@ -590,6 +592,17 @@ def update_status():
|
||||
juju_log('Updating status.')
|
||||
|
||||
|
||||
@hooks.hook('cinder-volume-service-relation-joined')
|
||||
@os_requires_version('mitaka', 'glance-common')
|
||||
@restart_on_change(restart_map(), stopstart=True)
|
||||
def cinder_volume_service_relation_joined(relid=None):
|
||||
optional_packages = ["python-cinderclient",
|
||||
"python-os-brick",
|
||||
"python-oslo.rootwrap"]
|
||||
apt_install(filter_installed_packages(optional_packages), fatal=True)
|
||||
CONFIGS.write_all()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
hooks.execute(sys.argv)
|
||||
|
@ -142,8 +142,6 @@ HTTPS_APACHE_CONF = "/etc/apache2/sites-available/openstack_https_frontend"
|
||||
HTTPS_APACHE_24_CONF = "/etc/apache2/sites-available/" \
|
||||
"openstack_https_frontend.conf"
|
||||
|
||||
CONF_DIR = "/etc/glance"
|
||||
|
||||
TEMPLATES = 'templates/'
|
||||
|
||||
# The interface is said to be satisfied if anyone of the interfaces in the
|
||||
@ -182,6 +180,7 @@ CONFIG_FILES = OrderedDict([
|
||||
service_user='glance'),
|
||||
glance_contexts.CephGlanceContext(),
|
||||
glance_contexts.ObjectStoreContext(),
|
||||
glance_contexts.CinderStoreContext(),
|
||||
glance_contexts.HAProxyContext(),
|
||||
context.SyslogContext(),
|
||||
glance_contexts.LoggingConfigContext(),
|
||||
@ -396,7 +395,7 @@ def git_post_install(projects_yaml):
|
||||
src_etc = os.path.join(git_src_dir(projects_yaml, 'glance'), 'etc')
|
||||
configs = {
|
||||
'src': src_etc,
|
||||
'dest': '/etc/glance',
|
||||
'dest': GLANCE_CONF_DIR,
|
||||
}
|
||||
|
||||
if os.path.exists(configs['dest']):
|
||||
@ -418,7 +417,7 @@ def git_post_install(projects_yaml):
|
||||
bin_dir = os.path.join(git_pip_venv_dir(projects_yaml), 'bin')
|
||||
# Use systemd init units/scripts from ubuntu wily onward
|
||||
if lsb_release()['DISTRIB_RELEASE'] >= '15.10':
|
||||
templates_dir = os.path.join(charm_dir(), 'templates/git')
|
||||
templates_dir = os.path.join(charm_dir(), TEMPLATES, 'git')
|
||||
daemons = ['glance-api', 'glance-glare', 'glance-registry']
|
||||
for daemon in daemons:
|
||||
glance_context = {
|
||||
@ -437,7 +436,7 @@ def git_post_install(projects_yaml):
|
||||
'start_dir': '/var/lib/glance',
|
||||
'process_name': 'glance-api',
|
||||
'executable_name': os.path.join(bin_dir, 'glance-api'),
|
||||
'config_files': ['/etc/glance/glance-api.conf'],
|
||||
'config_files': [GLANCE_API_CONF],
|
||||
'log_file': '/var/log/glance/api.log',
|
||||
}
|
||||
|
||||
@ -448,7 +447,7 @@ def git_post_install(projects_yaml):
|
||||
'start_dir': '/var/lib/glance',
|
||||
'process_name': 'glance-registry',
|
||||
'executable_name': os.path.join(bin_dir, 'glance-registry'),
|
||||
'config_files': ['/etc/glance/glance-registry.conf'],
|
||||
'config_files': [GLANCE_REGISTRY_CONF],
|
||||
'log_file': '/var/log/glance/registry.log',
|
||||
}
|
||||
|
||||
@ -477,8 +476,10 @@ def get_optional_interfaces():
|
||||
if relation_ids('ha'):
|
||||
optional_interfaces['ha'] = ['cluster']
|
||||
|
||||
if relation_ids('ceph') or relation_ids('object-store'):
|
||||
optional_interfaces['storage-backend'] = ['ceph', 'object-store']
|
||||
if (relation_ids('ceph') or relation_ids('object-store') or
|
||||
relation_ids('cinder-volume-service')):
|
||||
optional_interfaces['storage-backend'] = ['ceph', 'object-store',
|
||||
'cinder']
|
||||
|
||||
if relation_ids('amqp'):
|
||||
optional_interfaces['messaging'] = ['amqp']
|
||||
|
@ -37,6 +37,8 @@ requires:
|
||||
ha:
|
||||
interface: hacluster
|
||||
scope: container
|
||||
cinder-volume-service:
|
||||
interface: cinder
|
||||
peers:
|
||||
cluster:
|
||||
interface: glance-ha
|
||||
|
@ -51,6 +51,8 @@ stores = {{ known_stores }}
|
||||
default_store = rbd
|
||||
{% elif swift_store -%}
|
||||
default_store = swift
|
||||
{% elif cinder_store -%}
|
||||
default_store = cinder
|
||||
{% else -%}
|
||||
default_store = file
|
||||
{% endif -%}
|
||||
|
@ -26,6 +26,7 @@ TO_PATCH = [
|
||||
'service_name',
|
||||
'determine_apache_port',
|
||||
'determine_api_port',
|
||||
'os_release',
|
||||
]
|
||||
|
||||
|
||||
@ -62,7 +63,8 @@ class TestGlanceContexts(CharmTestCase):
|
||||
'expose_image_locations': True})
|
||||
self.config.assert_called_with('expose-image-locations')
|
||||
|
||||
def test_multistore(self):
|
||||
def test_multistore_below_mitaka(self):
|
||||
self.os_release.return_value = 'liberty'
|
||||
self.relation_ids.return_value = ['random_rid']
|
||||
self.assertEquals(contexts.MultiStoreContext()(),
|
||||
{'known_stores': "glance.store.filesystem.Store,"
|
||||
@ -70,6 +72,16 @@ class TestGlanceContexts(CharmTestCase):
|
||||
"glance.store.rbd.Store,"
|
||||
"glance.store.swift.Store"})
|
||||
|
||||
def test_multistore_for_mitaka_and_upper(self):
|
||||
self.os_release.return_value = 'mitaka'
|
||||
self.relation_ids.return_value = ['random_rid']
|
||||
self.assertEquals(contexts.MultiStoreContext()(),
|
||||
{'known_stores': "glance.store.filesystem.Store,"
|
||||
"glance.store.http.Store,"
|
||||
"glance.store.rbd.Store,"
|
||||
"glance.store.swift.Store,"
|
||||
"glance.store.cinder.Store"})
|
||||
|
||||
def test_multistore_defaults(self):
|
||||
self.relation_ids.return_value = []
|
||||
self.assertEquals(contexts.MultiStoreContext()(),
|
||||
|
@ -35,9 +35,13 @@ utils.register_configs = MagicMock()
|
||||
utils.restart_map = MagicMock()
|
||||
|
||||
with patch('hooks.charmhelpers.contrib.hardening.harden.harden') as mock_dec:
|
||||
mock_dec.side_effect = (lambda *dargs, **dkwargs: lambda f:
|
||||
lambda *args, **kwargs: f(*args, **kwargs))
|
||||
import hooks.glance_relations as relations
|
||||
with patch('hooks.charmhelpers.contrib.openstack.'
|
||||
'utils.os_requires_version') as mock_os:
|
||||
mock_dec.side_effect = (lambda *dargs, **dkwargs: lambda f:
|
||||
lambda *args, **kwargs: f(*args, **kwargs))
|
||||
mock_os.side_effect = (lambda *dargs, **dkwargs: lambda f:
|
||||
lambda *args, **kwargs: f(*args, **kwargs))
|
||||
import hooks.glance_relations as relations
|
||||
|
||||
relations.hooks._config_save = False
|
||||
|
||||
@ -933,3 +937,14 @@ class GlanceRelationTests(CharmTestCase):
|
||||
def test_relation_broken(self, configs):
|
||||
relations.relation_broken()
|
||||
self.assertTrue(configs.write_all.called)
|
||||
|
||||
@patch.object(relations, 'CONFIGS')
|
||||
def test_cinder_volume_joined(self, configs):
|
||||
self.filter_installed_packages.side_effect = lambda pkgs: pkgs
|
||||
relations.cinder_volume_service_relation_joined()
|
||||
self.assertTrue(configs.write_all.called)
|
||||
self.apt_install.assert_called_with(
|
||||
["python-cinderclient",
|
||||
"python-os-brick",
|
||||
"python-oslo.rootwrap"], fatal=True
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user