193 lines
5.3 KiB
Python
193 lines
5.3 KiB
Python
#!/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)
|