General tidy, sort out hooks, use openstack helpers
This commit is contained in:
parent
59feb3673a
commit
e66a379d5a
|
@ -8,7 +8,7 @@ options:
|
|||
type: string
|
||||
description: "Enable verbose logging"
|
||||
openstack-origin:
|
||||
default: cloud:precise-folsom
|
||||
default: cloud:precise-grizzly
|
||||
type: string
|
||||
description: |
|
||||
Repository from which to install. May be one of the following:
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import os
|
||||
import uuid
|
||||
import ConfigParser
|
||||
import sys
|
||||
from lib.utils import juju_log
|
||||
|
||||
RABBIT_USER = "ceilometer"
|
||||
RABBIT_VHOST = "ceilometer"
|
||||
|
@ -56,6 +58,6 @@ def modify_config_file(nova_conf, values):
|
|||
config.write(f)
|
||||
|
||||
f.close()
|
||||
except IOError as e:
|
||||
except IOError:
|
||||
juju_log('ERROR', 'Error updating nova config file')
|
||||
sys.exit(1)
|
||||
|
|
|
@ -1,18 +1,14 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
import time
|
||||
import os
|
||||
import utils
|
||||
import lib.utils as utils
|
||||
import ceilometer_utils
|
||||
|
||||
|
||||
def install():
|
||||
utils.configure_source()
|
||||
utils.install(*ceilometer_utils.CEILOMETER_PACKAGES)
|
||||
|
||||
port = ceilometer_utils.CEILOMETER_PORT
|
||||
utils.expose(port)
|
||||
utils.expose(ceilometer_utils.CEILOMETER_PORT)
|
||||
|
||||
|
||||
def amqp_joined():
|
||||
|
@ -23,7 +19,7 @@ def amqp_joined():
|
|||
def amqp_changed():
|
||||
if render_ceilometer_conf():
|
||||
utils.restart(*ceilometer_utils.CEILOMETER_SERVICES)
|
||||
ceilometer_changed()
|
||||
ceilometer_joined()
|
||||
|
||||
|
||||
def db_joined():
|
||||
|
@ -33,7 +29,7 @@ def db_joined():
|
|||
def db_changed():
|
||||
if render_ceilometer_conf():
|
||||
utils.restart(*ceilometer_utils.CEILOMETER_SERVICES)
|
||||
ceilometer_changed()
|
||||
ceilometer_joined()
|
||||
|
||||
|
||||
def keystone_joined():
|
||||
|
@ -48,7 +44,7 @@ def keystone_joined():
|
|||
def keystone_changed():
|
||||
if render_ceilometer_conf():
|
||||
utils.restart(*ceilometer_utils.CEILOMETER_SERVICES)
|
||||
ceilometer_changed()
|
||||
ceilometer_joined()
|
||||
|
||||
|
||||
def get_rabbit_conf():
|
||||
|
@ -62,6 +58,10 @@ def get_rabbit_conf():
|
|||
"rabbit_password": utils.relation_get('password',
|
||||
unit, relid)
|
||||
}
|
||||
if utils.relation_get('clustered',
|
||||
unit, relid):
|
||||
conf["rabbit_host"] = utils.relation_get('vip',
|
||||
unit, relid)
|
||||
if None not in conf.itervalues():
|
||||
return conf
|
||||
return None
|
||||
|
@ -84,12 +84,15 @@ def get_keystone_conf():
|
|||
for relid in utils.relation_ids('identity-service'):
|
||||
for unit in utils.relation_list(relid):
|
||||
keystone_username = utils.relation_get('service_username',
|
||||
unit, relid)
|
||||
keystone_port = utils.relation_get('service_port', unit, relid)
|
||||
keystone_host = utils.relation_get('service_host', unit, relid)
|
||||
unit, relid)
|
||||
keystone_port = utils.relation_get('service_port',
|
||||
unit, relid)
|
||||
keystone_host = utils.relation_get('service_host',
|
||||
unit, relid)
|
||||
keystone_password = utils.relation_get('service_password',
|
||||
unit, relid)
|
||||
keystone_tenant = utils.relation_get('service_tenant', unit, relid)
|
||||
unit, relid)
|
||||
keystone_tenant = utils.relation_get('service_tenant',
|
||||
unit, relid)
|
||||
|
||||
conf = {
|
||||
"keystone_os_username": keystone_username,
|
||||
|
@ -125,29 +128,19 @@ def render_ceilometer_conf():
|
|||
|
||||
|
||||
def ceilometer_joined():
|
||||
# update metering secret
|
||||
metering_secret = ceilometer_utils.get_shared_secret()
|
||||
for relid in utils.relation_ids('ceilometer-service'):
|
||||
utils.relation_set(metering_secret=metering_secret, rid=relid)
|
||||
|
||||
|
||||
def ceilometer_changed():
|
||||
# set all relationships for ceilometer service
|
||||
context = get_rabbit_conf()
|
||||
contextdb = get_db_conf()
|
||||
contextkeystone = get_keystone_conf()
|
||||
|
||||
if context and contextdb and contextkeystone:
|
||||
context.update(contextdb)
|
||||
context.update(contextkeystone)
|
||||
context["metering_secret"] = ceilometer_utils.get_shared_secret()
|
||||
|
||||
# set all that info into ceilometer-service relationship
|
||||
for relid in utils.relation_ids('ceilometer-service'):
|
||||
for unit in utils.relation_list(relid):
|
||||
context["rid"] = relid
|
||||
utils.relation_set(**context)
|
||||
|
||||
context["rid"] = relid
|
||||
utils.relation_set(**context)
|
||||
|
||||
|
||||
utils.do_hooks({
|
||||
"install": install,
|
||||
|
@ -157,7 +150,5 @@ utils.do_hooks({
|
|||
"shared-db-relation-changed": db_changed,
|
||||
"identity-service-relation-joined": keystone_joined,
|
||||
"identity-service-relation-changed": keystone_changed,
|
||||
"ceilometer-service-relation-joined": ceilometer_joined,
|
||||
"ceilometer-service-relation-changed": ceilometer_changed
|
||||
"ceilometer-service-relation-joined": ceilometer_joined
|
||||
})
|
||||
sys.exit(0)
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
|
||||
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
# Common python helper functions used for OpenStack charms.
|
||||
|
||||
import apt_pkg as apt
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
CLOUD_ARCHIVE_URL = "http://ubuntu-cloud.archive.canonical.com/ubuntu"
|
||||
CLOUD_ARCHIVE_KEY_ID = '5EDB1B62EC4926EA'
|
||||
|
@ -11,7 +13,7 @@ ubuntu_openstack_release = {
|
|||
'oneiric': 'diablo',
|
||||
'precise': 'essex',
|
||||
'quantal': 'folsom',
|
||||
'raring': 'grizzly'
|
||||
'raring': 'grizzly',
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,7 +21,18 @@ openstack_codenames = {
|
|||
'2011.2': 'diablo',
|
||||
'2012.1': 'essex',
|
||||
'2012.2': 'folsom',
|
||||
'2012.3': 'grizzly'
|
||||
'2013.1': 'grizzly',
|
||||
'2013.2': 'havana',
|
||||
}
|
||||
|
||||
# The ugly duckling
|
||||
swift_codenames = {
|
||||
'1.4.3': 'diablo',
|
||||
'1.4.8': 'essex',
|
||||
'1.7.4': 'folsom',
|
||||
'1.7.6': 'grizzly',
|
||||
'1.7.7': 'grizzly',
|
||||
'1.8.0': 'grizzly',
|
||||
}
|
||||
|
||||
|
||||
|
@ -62,7 +75,7 @@ def get_os_codename_install_source(src):
|
|||
return ca_rel
|
||||
|
||||
# Best guess match based on deb string provided
|
||||
if src.startswith('deb'):
|
||||
if src.startswith('deb') or src.startswith('ppa'):
|
||||
for k, v in openstack_codenames.iteritems():
|
||||
if v in src:
|
||||
return v
|
||||
|
@ -89,52 +102,54 @@ def get_os_version_codename(codename):
|
|||
|
||||
def get_os_codename_package(pkg):
|
||||
'''Derive OpenStack release codename from an installed package.'''
|
||||
cmd = ['dpkg', '-l', pkg]
|
||||
|
||||
apt.init()
|
||||
cache = apt.Cache()
|
||||
try:
|
||||
output = subprocess.check_output(cmd)
|
||||
except subprocess.CalledProcessError:
|
||||
e = 'Could not derive OpenStack version from package that is not '\
|
||||
'installed; %s' % pkg
|
||||
error_out(e)
|
||||
|
||||
def _clean(line):
|
||||
line = line.split(' ')
|
||||
clean = []
|
||||
for c in line:
|
||||
if c != '':
|
||||
clean.append(c)
|
||||
return clean
|
||||
|
||||
vers = None
|
||||
for l in output.split('\n'):
|
||||
if l.startswith('ii'):
|
||||
l = _clean(l)
|
||||
if l[1] == pkg:
|
||||
vers = l[2]
|
||||
|
||||
if not vers:
|
||||
pkg = cache[pkg]
|
||||
except:
|
||||
e = 'Could not determine version of installed package: %s' % pkg
|
||||
error_out(e)
|
||||
|
||||
vers = vers[:6]
|
||||
vers = apt.UpstreamVersion(pkg.current_ver.ver_str)
|
||||
|
||||
try:
|
||||
return openstack_codenames[vers]
|
||||
if 'swift' in pkg.name:
|
||||
vers = vers[:5]
|
||||
return swift_codenames[vers]
|
||||
else:
|
||||
vers = vers[:6]
|
||||
return openstack_codenames[vers]
|
||||
except KeyError:
|
||||
e = 'Could not determine OpenStack codename for version %s' % vers
|
||||
error_out(e)
|
||||
|
||||
|
||||
def get_os_version_package(pkg):
|
||||
'''Derive OpenStack version number from an installed package.'''
|
||||
codename = get_os_codename_package(pkg)
|
||||
|
||||
if 'swift' in pkg:
|
||||
vers_map = swift_codenames
|
||||
else:
|
||||
vers_map = openstack_codenames
|
||||
|
||||
for version, cname in vers_map.iteritems():
|
||||
if cname == codename:
|
||||
return version
|
||||
e = "Could not determine OpenStack version for package: %s" % pkg
|
||||
error_out(e)
|
||||
|
||||
|
||||
def configure_installation_source(rel):
|
||||
'''Configure apt installation source.'''
|
||||
|
||||
def _import_key(id):
|
||||
def _import_key(keyid):
|
||||
cmd = "apt-key adv --keyserver keyserver.ubuntu.com " \
|
||||
"--recv-keys %s" % id
|
||||
"--recv-keys %s" % keyid
|
||||
try:
|
||||
subprocess.check_call(cmd.split(' '))
|
||||
except:
|
||||
error_out("Error importing repo key %s" % id)
|
||||
except subprocess.CalledProcessError:
|
||||
error_out("Error importing repo key %s" % keyid)
|
||||
|
||||
if rel == 'distro':
|
||||
return
|
||||
|
@ -165,10 +180,11 @@ def configure_installation_source(rel):
|
|||
'version (%s)' % (ca_rel, ubuntu_rel)
|
||||
error_out(e)
|
||||
|
||||
if ca_rel == 'folsom/staging':
|
||||
if 'staging' in ca_rel:
|
||||
# staging is just a regular PPA.
|
||||
cmd = 'add-apt-repository -y ppa:ubuntu-cloud-archive/'\
|
||||
'folsom-staging'
|
||||
os_rel = ca_rel.split('/')[0]
|
||||
ppa = 'ppa:ubuntu-cloud-archive/%s-staging' % os_rel
|
||||
cmd = 'add-apt-repository -y %s' % ppa
|
||||
subprocess.check_call(cmd.split(' '))
|
||||
return
|
||||
|
||||
|
@ -176,7 +192,10 @@ def configure_installation_source(rel):
|
|||
pockets = {
|
||||
'folsom': 'precise-updates/folsom',
|
||||
'folsom/updates': 'precise-updates/folsom',
|
||||
'folsom/proposed': 'precise-proposed/folsom'
|
||||
'folsom/proposed': 'precise-proposed/folsom',
|
||||
'grizzly': 'precise-updates/grizzly',
|
||||
'grizzly/updates': 'precise-updates/grizzly',
|
||||
'grizzly/proposed': 'precise-proposed/grizzly'
|
||||
}
|
||||
|
||||
try:
|
||||
|
@ -192,3 +211,20 @@ def configure_installation_source(rel):
|
|||
f.write(src)
|
||||
else:
|
||||
error_out("Invalid openstack-release specified: %s" % rel)
|
||||
|
||||
|
||||
def save_script_rc(script_path="scripts/scriptrc", **env_vars):
|
||||
"""
|
||||
Write an rc file in the charm-delivered directory containing
|
||||
exported environment variables provided by env_vars. Any charm scripts run
|
||||
outside the juju hook environment can source this scriptrc to obtain
|
||||
updated config information necessary to perform health checks or
|
||||
service changes.
|
||||
"""
|
||||
unit_name = os.getenv('JUJU_UNIT_NAME').replace('/', '-')
|
||||
juju_rc_path = "/var/lib/juju/units/%s/charm/%s" % (unit_name, script_path)
|
||||
with open(juju_rc_path, 'wb') as rc_script:
|
||||
rc_script.write(
|
||||
"#!/bin/bash\n")
|
||||
[rc_script.write('export %s=%s\n' % (u, p))
|
||||
for u, p in env_vars.iteritems() if u != "script_path"]
|
||||
|
|
239
hooks/utils.py
239
hooks/utils.py
|
@ -1,239 +0,0 @@
|
|||
#
|
||||
# Copyright 2012 Canonical Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# James Page <james.page@ubuntu.com>
|
||||
# Paul Collins <paul.collins@canonical.com>
|
||||
#
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import socket
|
||||
import sys
|
||||
import apt_pkg as apt
|
||||
import re
|
||||
import ceilometer_utils
|
||||
|
||||
|
||||
def do_hooks(hooks):
|
||||
hook = os.path.basename(sys.argv[0])
|
||||
|
||||
try:
|
||||
hook_func = hooks[hook]
|
||||
except KeyError:
|
||||
juju_log('INFO',
|
||||
"This charm doesn't know how to handle '{}'.".format(hook))
|
||||
else:
|
||||
hook_func()
|
||||
|
||||
|
||||
def install(*pkgs):
|
||||
cmd = [
|
||||
'apt-get',
|
||||
'-y',
|
||||
'install'
|
||||
]
|
||||
for pkg in pkgs:
|
||||
cmd.append(pkg)
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
TEMPLATES_DIR = 'templates'
|
||||
|
||||
try:
|
||||
import jinja2
|
||||
except ImportError:
|
||||
install('python-jinja2')
|
||||
import jinja2
|
||||
|
||||
|
||||
def render_template(template_name, context, template_dir=TEMPLATES_DIR):
|
||||
templates = jinja2.Environment(
|
||||
loader=jinja2.FileSystemLoader(template_dir)
|
||||
)
|
||||
template = templates.get_template(template_name)
|
||||
return template.render(context)
|
||||
|
||||
CLOUD_ARCHIVE = \
|
||||
""" # Ubuntu Cloud Archive
|
||||
deb http://ubuntu-cloud.archive.canonical.com/ubuntu {} main
|
||||
"""
|
||||
|
||||
CLOUD_ARCHIVE_POCKETS = {
|
||||
'precise-folsom': 'precise-updates/folsom',
|
||||
'precise-folsom/updates': 'precise-updates/folsom',
|
||||
'precise-folsom/proposed': 'precise-proposed/folsom',
|
||||
'precise-grizzly': 'precise-updates/grizzly',
|
||||
'precise-grizzly/updates': 'precise-updates/grizzly',
|
||||
'precise-grizzly/proposed': 'precise-proposed/grizzly'
|
||||
}
|
||||
|
||||
|
||||
def configure_source():
|
||||
source = str(config_get('openstack-origin'))
|
||||
if not source:
|
||||
return
|
||||
if source.startswith('ppa:'):
|
||||
cmd = [
|
||||
'add-apt-repository',
|
||||
source
|
||||
]
|
||||
subprocess.check_call(cmd)
|
||||
if source.startswith('cloud:'):
|
||||
install('ubuntu-cloud-keyring')
|
||||
pocket = source.split(':')[1]
|
||||
with open('/etc/apt/sources.list.d/cloud-archive.list', 'w') as apt:
|
||||
apt.write(CLOUD_ARCHIVE.format(CLOUD_ARCHIVE_POCKETS[pocket]))
|
||||
if source.startswith('deb'):
|
||||
l = len(source.split('|'))
|
||||
if l == 2:
|
||||
(apt_line, key) = source.split('|')
|
||||
cmd = [
|
||||
'apt-key',
|
||||
'adv', '--keyserver keyserver.ubuntu.com',
|
||||
'--recv-keys', key
|
||||
]
|
||||
subprocess.check_call(cmd)
|
||||
elif l == 1:
|
||||
apt_line = source
|
||||
|
||||
with open('/etc/apt/sources.list.d/ceilometer.list', 'w') as apt:
|
||||
apt.write(apt_line + "\n")
|
||||
cmd = [
|
||||
'apt-get',
|
||||
'update'
|
||||
]
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
# Protocols
|
||||
TCP = 'TCP'
|
||||
UDP = 'UDP'
|
||||
|
||||
|
||||
def expose(port, protocol='TCP'):
|
||||
cmd = [
|
||||
'open-port',
|
||||
'{}/{}'.format(port, protocol)
|
||||
]
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
def unexpose(port, protocol='TCP'):
|
||||
cmd = [
|
||||
'close-port',
|
||||
'{}/{}'.format(port, protocol)
|
||||
]
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
def juju_log(severity, message):
|
||||
cmd = [
|
||||
'juju-log',
|
||||
'--log-level', severity,
|
||||
message
|
||||
]
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
def relation_ids(relation):
|
||||
cmd = [
|
||||
'relation-ids',
|
||||
relation
|
||||
]
|
||||
return subprocess.check_output(cmd).split() # IGNORE:E1103
|
||||
|
||||
|
||||
def relation_list(rid):
|
||||
cmd = [
|
||||
'relation-list',
|
||||
'-r', rid,
|
||||
]
|
||||
return subprocess.check_output(cmd).split() # IGNORE:E1103
|
||||
|
||||
|
||||
def relation_get(attribute, unit=None, rid=None):
|
||||
cmd = [
|
||||
'relation-get',
|
||||
]
|
||||
if rid:
|
||||
cmd.append('-r')
|
||||
cmd.append(rid)
|
||||
cmd.append(attribute)
|
||||
if unit:
|
||||
cmd.append(unit)
|
||||
value = subprocess.check_output(cmd).strip() # IGNORE:E1103
|
||||
if value == "":
|
||||
return None
|
||||
else:
|
||||
return value
|
||||
|
||||
|
||||
def relation_set(**kwargs):
|
||||
cmd = [
|
||||
'relation-set'
|
||||
]
|
||||
args = []
|
||||
for k, v in kwargs.items():
|
||||
if k == 'rid':
|
||||
cmd.append('-r')
|
||||
cmd.append(v)
|
||||
else:
|
||||
args.append('{}={}'.format(k, v))
|
||||
cmd += args
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
def unit_get(attribute):
|
||||
cmd = [
|
||||
'unit-get',
|
||||
attribute
|
||||
]
|
||||
value = subprocess.check_output(cmd).strip() # IGNORE:E1103
|
||||
if value == "":
|
||||
return None
|
||||
else:
|
||||
return value
|
||||
|
||||
|
||||
def config_get(attribute):
|
||||
cmd = [
|
||||
'config-get',
|
||||
attribute
|
||||
]
|
||||
value = subprocess.check_output(cmd).strip() # IGNORE:E1103
|
||||
if value == "":
|
||||
return None
|
||||
else:
|
||||
return value
|
||||
|
||||
|
||||
def get_unit_hostname():
|
||||
return socket.gethostname()
|
||||
|
||||
|
||||
def _service_ctl(service, action):
|
||||
subprocess.check_call(['service', service, action])
|
||||
|
||||
|
||||
def restart(*services):
|
||||
for service in services:
|
||||
_service_ctl(service, 'restart')
|
||||
|
||||
|
||||
def stop(*services):
|
||||
for service in services:
|
||||
_service_ctl(service, 'stop')
|
||||
|
||||
|
||||
def start(*services):
|
||||
for service in services:
|
||||
_service_ctl(service, 'start')
|
||||
|
||||
|
||||
def get_os_version(package=None):
|
||||
apt.init()
|
||||
cache = apt.Cache()
|
||||
pkg = cache[package or 'quantum-common']
|
||||
if pkg.current_ver:
|
||||
return apt.upstream_version(pkg.current_ver.ver_str)
|
||||
else:
|
||||
return None
|
|
@ -23,3 +23,4 @@ auth_protocol = http
|
|||
admin_tenant_name = {{ keystone_os_tenant }}
|
||||
admin_user = {{ keystone_os_username }}
|
||||
admin_password = {{ keystone_os_password }}
|
||||
|
||||
|
|
Loading…
Reference in New Issue