first version of charm

This commit is contained in:
yolanda.robla@canonical.com
2013-02-12 14:53:39 +01:00
commit 36a0f02471
13 changed files with 434 additions and 0 deletions

16
config.yaml Normal file
View 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
View 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/>.

View File

@@ -0,0 +1,5 @@
import os
import uuid
NOVA_CONF="/etc/nova/nova.conf"
CEILOMETER_COMPUTE_SERVICES = ['ceilometer-agent-compute']

View File

@@ -0,0 +1 @@
hooks.py

23
hooks/hooks.py Executable file
View 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
View File

@@ -0,0 +1 @@
hooks.py

1
hooks/lib/__init__.py Normal file
View File

@@ -0,0 +1 @@

View 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
View 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
View 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
View 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
View 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.

1
revision Normal file
View File

@@ -0,0 +1 @@
1