Files
charm-glance/hooks/glance_utils.py
James Page 5263434412 [yolanda] Add postgresql support
Refactor templates for includes
2014-03-31 12:29:37 +01:00

237 lines
7.3 KiB
Python
Executable File

#!/usr/bin/python
import os
import subprocess
import glance_contexts
from collections import OrderedDict
from charmhelpers.fetch import (
apt_upgrade,
apt_update,
apt_install, )
from charmhelpers.core.hookenv import (
config,
log,
relation_ids,
service_name)
from charmhelpers.core.host import (
mkdir,
service_stop,
service_start
)
from charmhelpers.contrib.openstack import (
templating,
context, )
from charmhelpers.contrib.hahelpers.cluster import (
eligible_leader,
)
from charmhelpers.contrib.storage.linux.ceph import (
create_pool as ceph_create_pool,
pool_exists as ceph_pool_exists)
from charmhelpers.contrib.openstack.alternatives import install_alternative
from charmhelpers.contrib.openstack.utils import (
get_os_codename_install_source,
get_os_codename_package,
configure_installation_source)
CLUSTER_RES = "res_glance_vip"
PACKAGES = [
"apache2", "glance", "python-mysqldb", "python-swift",
"python-psycopg2", "python-keystone", "uuid", "haproxy", ]
SERVICES = [
"glance-api", "glance-registry", ]
CHARM = "glance"
GLANCE_CONF_DIR = "/etc/glance"
GLANCE_REGISTRY_CONF = "%s/glance-registry.conf" % GLANCE_CONF_DIR
GLANCE_REGISTRY_PASTE_INI = "%s/glance-registry-paste.ini" % GLANCE_CONF_DIR
GLANCE_API_CONF = "%s/glance-api.conf" % GLANCE_CONF_DIR
GLANCE_API_PASTE_INI = "%s/glance-api-paste.ini" % GLANCE_CONF_DIR
CEPH_CONF = "/etc/ceph/ceph.conf"
CHARM_CEPH_CONF = '/var/lib/charm/{}/ceph.conf'
HAPROXY_CONF = "/etc/haproxy/haproxy.cfg"
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/'
def ceph_config_file():
return CHARM_CEPH_CONF.format(service_name())
CONFIG_FILES = OrderedDict([
(GLANCE_REGISTRY_CONF, {
'hook_contexts': [context.SharedDBContext(ssl_dir=GLANCE_CONF_DIR),
context.PostgresqlDBContext(),
context.IdentityServiceContext(),
context.SyslogContext()],
'services': ['glance-registry']
}),
(GLANCE_API_CONF, {
'hook_contexts': [context.SharedDBContext(ssl_dir=GLANCE_CONF_DIR),
context.AMQPContext(ssl_dir=GLANCE_CONF_DIR),
context.PostgresqlDBContext(),
context.IdentityServiceContext(),
glance_contexts.CephGlanceContext(),
glance_contexts.ObjectStoreContext(),
glance_contexts.HAProxyContext(),
context.SyslogContext()],
'services': ['glance-api']
}),
(GLANCE_API_PASTE_INI, {
'hook_contexts': [context.IdentityServiceContext()],
'services': ['glance-api']
}),
(GLANCE_REGISTRY_PASTE_INI, {
'hook_contexts': [context.IdentityServiceContext()],
'services': ['glance-registry']
}),
(ceph_config_file(), {
'hook_contexts': [context.CephContext()],
'services': ['glance-api', 'glance-registry']
}),
(HAPROXY_CONF, {
'hook_contexts': [context.HAProxyContext(),
glance_contexts.HAProxyContext()],
'services': ['haproxy'],
}),
(HTTPS_APACHE_CONF, {
'hook_contexts': [glance_contexts.ApacheSSLContext()],
'services': ['apache2'],
}),
(HTTPS_APACHE_24_CONF, {
'hook_contexts': [glance_contexts.ApacheSSLContext()],
'services': ['apache2'],
})
])
def register_configs():
# Register config files with their respective contexts.
# Regstration of some configs may not be required depending on
# existing of certain relations.
release = get_os_codename_package('glance-common', fatal=False) or 'essex'
configs = templating.OSConfigRenderer(templates_dir=TEMPLATES,
openstack_release=release)
confs = [GLANCE_REGISTRY_CONF,
GLANCE_API_CONF,
GLANCE_API_PASTE_INI,
GLANCE_REGISTRY_PASTE_INI,
HAPROXY_CONF]
if relation_ids('ceph'):
mkdir(os.path.dirname(ceph_config_file()))
mkdir(os.path.dirname(CEPH_CONF))
# Install ceph config as an alternative for co-location with
# ceph and ceph-osd charms - glance ceph.conf will be
# lower priority that both of these but thats OK
if not os.path.exists(ceph_config_file()):
# touch file for pre-templated generation
open(ceph_config_file(), 'w').close()
install_alternative(os.path.basename(CEPH_CONF),
CEPH_CONF, ceph_config_file())
confs.append(ceph_config_file())
for conf in confs:
configs.register(conf, CONFIG_FILES[conf]['hook_contexts'])
if os.path.exists('/etc/apache2/conf-available'):
configs.register(HTTPS_APACHE_24_CONF,
CONFIG_FILES[HTTPS_APACHE_24_CONF]['hook_contexts'])
else:
configs.register(HTTPS_APACHE_CONF,
CONFIG_FILES[HTTPS_APACHE_CONF]['hook_contexts'])
return configs
def migrate_database():
'''Runs glance-manage to initialize a new database
or migrate existing
'''
cmd = ['glance-manage', 'db_sync']
subprocess.check_call(cmd)
def ensure_ceph_pool(service, replicas):
'''Creates a ceph pool for service
if one does not exist
'''
# TODO(Ditto about moving somewhere sharable.)
if not ceph_pool_exists(service=service, name=service):
ceph_create_pool(service=service, name=service, replicas=replicas)
def do_openstack_upgrade(configs):
"""Perform an uprade of cinder. Takes care of upgrading
packages, rewriting configs + database migration and potentially
any other post-upgrade actions.
:param configs: The charms main OSConfigRenderer object.
"""
new_src = config('openstack-origin')
new_os_rel = get_os_codename_install_source(new_src)
log('Performing OpenStack upgrade to %s.' % (new_os_rel))
configure_installation_source(new_src)
dpkg_opts = [
'--option', 'Dpkg::Options::=--force-confnew',
'--option', 'Dpkg::Options::=--force-confdef',
]
apt_update()
apt_upgrade(options=dpkg_opts, fatal=True, dist=True)
apt_install(PACKAGES, fatal=True)
# set CONFIGS to load templates from new release and regenerate config
configs.set_release(openstack_release=new_os_rel)
configs.write_all()
[service_stop(s) for s in services()]
if eligible_leader(CLUSTER_RES):
migrate_database()
[service_start(s) for s in services()]
def restart_map():
'''Determine the correct resource map to be passed to
charmhelpers.core.restart_on_change() based on the services configured.
:returns: dict: A dictionary mapping config file to lists of services
that should be restarted when file changes.
'''
_map = []
for f, ctxt in CONFIG_FILES.iteritems():
svcs = []
for svc in ctxt['services']:
svcs.append(svc)
if svcs:
_map.append((f, svcs))
return OrderedDict(_map)
def services():
''' Returns a list of services associate with this charm '''
_services = []
for v in restart_map().values():
_services = _services + v
return list(set(_services))