first version of charm
This commit is contained in:
16
config.yaml
Normal file
16
config.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
options:
|
||||
openstack-origin:
|
||||
default: cloud:precise-folsom
|
||||
type: string
|
||||
description: |
|
||||
Repository from which to install. May be one of the following:
|
||||
distro (default), ppa:somecustom/ppa, a deb url sources entry,
|
||||
or a supported Cloud Archive release pocket.
|
||||
|
||||
Supported Cloud Archive sources include: cloud:precise-folsom,
|
||||
cloud:precise-folsom/updates, cloud:precise-folsom/staging,
|
||||
cloud:precise-folsom/proposed.
|
||||
|
||||
Note that updating this setting to a source that is known to
|
||||
provide a later version of OpenStack will trigger a software
|
||||
upgrade.
|
17
copyright
Normal file
17
copyright
Normal file
@@ -0,0 +1,17 @@
|
||||
Format: http://dep.debian.net/deps/dep5/
|
||||
|
||||
Files: *
|
||||
Copyright: Copyright 2011, Canonical Ltd., All Rights Reserved.
|
||||
License: GPL-3
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
5
hooks/ceilometer_utils.py
Normal file
5
hooks/ceilometer_utils.py
Normal file
@@ -0,0 +1,5 @@
|
||||
import os
|
||||
import uuid
|
||||
|
||||
NOVA_CONF="/etc/nova/nova.conf"
|
||||
CEILOMETER_COMPUTE_SERVICES = ['ceilometer-agent-compute']
|
1
hooks/container-relation-joined
Symbolic link
1
hooks/container-relation-joined
Symbolic link
@@ -0,0 +1 @@
|
||||
hooks.py
|
23
hooks/hooks.py
Executable file
23
hooks/hooks.py
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
import time
|
||||
import os
|
||||
import utils
|
||||
import ceilometer_utils
|
||||
|
||||
def install():
|
||||
utils.configure_source()
|
||||
packages = ['ceilometer-common', 'ceilometer-agent-compute']
|
||||
utils.install(*packages)
|
||||
|
||||
def container_joined():
|
||||
utils.modify_config_file(ceilometer_utils.NOVA_CONF)
|
||||
utils.restart(*ceilometer_utils.CEILOMETER_COMPUTE_SERVICES)
|
||||
return True
|
||||
|
||||
utils.do_hooks({
|
||||
"install": install,
|
||||
"container-relation-joined": container_joined
|
||||
})
|
||||
sys.exit(0)
|
1
hooks/install
Symbolic link
1
hooks/install
Symbolic link
@@ -0,0 +1 @@
|
||||
hooks.py
|
1
hooks/lib/__init__.py
Normal file
1
hooks/lib/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
|
192
hooks/lib/openstack_common.py
Normal file
192
hooks/lib/openstack_common.py
Normal file
@@ -0,0 +1,192 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# Common python helper functions used for OpenStack charms.
|
||||
|
||||
import subprocess
|
||||
|
||||
CLOUD_ARCHIVE_URL = "http://ubuntu-cloud.archive.canonical.com/ubuntu"
|
||||
CLOUD_ARCHIVE_KEY_ID = '5EDB1B62EC4926EA'
|
||||
|
||||
ubuntu_openstack_release = {
|
||||
'oneiric': 'diablo',
|
||||
'precise': 'essex',
|
||||
'quantal': 'folsom',
|
||||
'raring' : 'grizzly'
|
||||
}
|
||||
|
||||
|
||||
openstack_codenames = {
|
||||
'2011.2': 'diablo',
|
||||
'2012.1': 'essex',
|
||||
'2012.2': 'folsom',
|
||||
'2012.3': 'grizzly'
|
||||
}
|
||||
|
||||
|
||||
def juju_log(msg):
|
||||
subprocess.check_call(['juju-log', msg])
|
||||
|
||||
|
||||
def error_out(msg):
|
||||
juju_log("FATAL ERROR: %s" % msg)
|
||||
exit(1)
|
||||
|
||||
|
||||
def lsb_release():
|
||||
'''Return /etc/lsb-release in a dict'''
|
||||
lsb = open('/etc/lsb-release', 'r')
|
||||
d = {}
|
||||
for l in lsb:
|
||||
k, v = l.split('=')
|
||||
d[k.strip()] = v.strip()
|
||||
return d
|
||||
|
||||
|
||||
def get_os_codename_install_source(src):
|
||||
'''Derive OpenStack release codename from a given installation source.'''
|
||||
ubuntu_rel = lsb_release()['DISTRIB_CODENAME']
|
||||
|
||||
rel = ''
|
||||
if src == 'distro':
|
||||
try:
|
||||
rel = ubuntu_openstack_release[ubuntu_rel]
|
||||
except KeyError:
|
||||
e = 'Code not derive openstack release for '\
|
||||
'this Ubuntu release: %s' % rel
|
||||
error_out(e)
|
||||
return rel
|
||||
|
||||
if src.startswith('cloud:'):
|
||||
ca_rel = src.split(':')[1]
|
||||
ca_rel = ca_rel.split('%s-' % ubuntu_rel)[1].split('/')[0]
|
||||
return ca_rel
|
||||
|
||||
# Best guess match based on deb string provided
|
||||
if src.startswith('deb'):
|
||||
for k, v in openstack_codenames.iteritems():
|
||||
if v in src:
|
||||
return v
|
||||
|
||||
def get_os_codename_version(vers):
|
||||
'''Determine OpenStack codename from version number.'''
|
||||
try:
|
||||
return openstack_codenames[vers]
|
||||
except KeyError:
|
||||
e = 'Could not determine OpenStack codename for version %s' % vers
|
||||
error_out(e)
|
||||
|
||||
|
||||
def get_os_version_codename(codename):
|
||||
'''Determine OpenStack version number from codename.'''
|
||||
for k, v in openstack_codenames.iteritems():
|
||||
if v == codename:
|
||||
return k
|
||||
e = 'Code not derive OpenStack version for '\
|
||||
'codename: %s' % codename
|
||||
error_out(e)
|
||||
|
||||
|
||||
def get_os_codename_package(pkg):
|
||||
'''Derive OpenStack release codename from an installed package.'''
|
||||
cmd = ['dpkg', '-l', pkg]
|
||||
|
||||
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:
|
||||
e = 'Could not determine version of installed package: %s' % pkg
|
||||
error_out(e)
|
||||
|
||||
vers = vers[:6]
|
||||
try:
|
||||
return openstack_codenames[vers]
|
||||
except KeyError:
|
||||
e = 'Could not determine OpenStack codename for version %s' % vers
|
||||
error_out(e)
|
||||
|
||||
|
||||
def configure_installation_source(rel):
|
||||
'''Configure apt installation source.'''
|
||||
|
||||
def _import_key(id):
|
||||
cmd = "apt-key adv --keyserver keyserver.ubuntu.com " \
|
||||
"--recv-keys %s" % id
|
||||
try:
|
||||
subprocess.check_call(cmd.split(' '))
|
||||
except:
|
||||
error_out("Error importing repo key %s" % id)
|
||||
|
||||
if rel == 'distro':
|
||||
return
|
||||
elif rel[:4] == "ppa:":
|
||||
src = rel
|
||||
subprocess.check_call(["add-apt-repository", "-y", src])
|
||||
elif rel[:3] == "deb":
|
||||
l = len(rel.split('|'))
|
||||
if l == 2:
|
||||
src, key = rel.split('|')
|
||||
juju_log("Importing PPA key from keyserver for %s" % src)
|
||||
_import_key(key)
|
||||
elif l == 1:
|
||||
src = rel
|
||||
else:
|
||||
error_out("Invalid openstack-release: %s" % rel)
|
||||
|
||||
with open('/etc/apt/sources.list.d/juju_deb.list', 'w') as f:
|
||||
f.write(src)
|
||||
elif rel[:6] == 'cloud:':
|
||||
ubuntu_rel = lsb_release()['DISTRIB_CODENAME']
|
||||
rel = rel.split(':')[1]
|
||||
u_rel = rel.split('-')[0]
|
||||
ca_rel = rel.split('-')[1]
|
||||
|
||||
if u_rel != ubuntu_rel:
|
||||
e = 'Cannot install from Cloud Archive pocket %s on this Ubuntu '\
|
||||
'version (%s)' % (ca_rel, ubuntu_rel)
|
||||
error_out(e)
|
||||
|
||||
if ca_rel == 'folsom/staging':
|
||||
# staging is just a regular PPA.
|
||||
cmd = 'add-apt-repository -y ppa:ubuntu-cloud-archive/folsom-staging'
|
||||
subprocess.check_call(cmd.split(' '))
|
||||
return
|
||||
|
||||
# map charm config options to actual archive pockets.
|
||||
pockets = {
|
||||
'folsom': 'precise-updates/folsom',
|
||||
'folsom/updates': 'precise-updates/folsom',
|
||||
'folsom/proposed': 'precise-proposed/folsom'
|
||||
}
|
||||
|
||||
try:
|
||||
pocket = pockets[ca_rel]
|
||||
except KeyError:
|
||||
e = 'Invalid Cloud Archive release specified: %s' % rel
|
||||
error_out(e)
|
||||
|
||||
src = "deb %s %s main" % (CLOUD_ARCHIVE_URL, pocket)
|
||||
_import_key(CLOUD_ARCHIVE_KEY_ID)
|
||||
|
||||
with open('/etc/apt/sources.list.d/cloud-archive.list', 'w') as f:
|
||||
f.write(src)
|
||||
else:
|
||||
error_out("Invalid openstack-release specified: %s" % rel)
|
140
hooks/utils.py
Normal file
140
hooks/utils.py
Normal file
@@ -0,0 +1,140 @@
|
||||
#
|
||||
# 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
|
||||
import ConfigParser
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
def juju_log(severity, message):
|
||||
cmd = [
|
||||
'juju-log',
|
||||
'--log-level', severity,
|
||||
message
|
||||
]
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
def config_get(attribute):
|
||||
cmd = [
|
||||
'config-get',
|
||||
attribute
|
||||
]
|
||||
value = subprocess.check_output(cmd).strip() # IGNORE:E1103
|
||||
if value == "":
|
||||
return None
|
||||
else:
|
||||
return value
|
||||
|
||||
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
|
||||
|
||||
def modify_config_file(nova_conf):
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.read(nova_conf)
|
||||
juju_log("INFO", str(config.items("DEFAULT")))
|
3
local.yaml
Normal file
3
local.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
ceilometer-agent:
|
||||
openstack-origin: "ppa:openstack-ubuntu-testing/grizzly-trunk-testing"
|
||||
config-file: "/etc/nova/nova.conf"
|
17
metadata.yaml
Normal file
17
metadata.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
name: ceilometer-agent
|
||||
subordinate: true
|
||||
summary: Subordinate charm for deploying Ceilometer compute agent
|
||||
maintainer: Yolanda Robla <yolanda.robla@canonical.com>
|
||||
description: |
|
||||
Ceilometer project aims to become the infrastructure to collect measurements
|
||||
within OpenStack so that no two agents would need to be written to collect
|
||||
the same data. It's primary targets are monitoring and metering, but the
|
||||
framework should be easily expandable to collect for other needs. To that
|
||||
effect, Ceilometer should be able to share collected data with a variety of consumers.
|
||||
.
|
||||
This charm should be used in conjunction with the ceilometer and nova charm to collect
|
||||
Openstack measures.
|
||||
requires:
|
||||
container:
|
||||
interface: juju-info
|
||||
scope: container
|
17
readme
Normal file
17
readme
Normal file
@@ -0,0 +1,17 @@
|
||||
Overview
|
||||
--------
|
||||
|
||||
This charm provides the Ceilometer service for OpenStack. It is intended to
|
||||
be used alongside the other OpenStack components, starting with the Folsom
|
||||
release.
|
||||
|
||||
Ceilometer is made up of 2 separate services: an API service, and a collector
|
||||
service. This charm allows them to be deployed in different
|
||||
combination, depending on user preference and requirements.
|
||||
|
||||
This charm was developed to support deploying Folsom on both
|
||||
Ubuntu Quantal and Ubuntu Precise. Since Ceilometer is only available for
|
||||
Ubuntu 12.04 via the Ubuntu Cloud Archive, deploying this charm to a
|
||||
Precise machine will by default install Ceilometer and its dependencies from
|
||||
the Cloud Archive.
|
||||
|
Reference in New Issue
Block a user