3
# Common python helper functions used for OpenStack charms.
9
CLOUD_ARCHIVE_URL = "http://ubuntu-cloud.archive.canonical.com/ubuntu"
10
CLOUD_ARCHIVE_KEY_ID = '5EDB1B62EC4926EA'
12
ubuntu_openstack_release = {
20
openstack_codenames = {
40
subprocess.check_call(['juju-log', msg])
44
juju_log("FATAL ERROR: %s" % msg)
49
'''Return /etc/lsb-release in a dict'''
50
lsb = open('/etc/lsb-release', 'r')
54
d[k.strip()] = v.strip()
58
def get_os_codename_install_source(src):
59
'''Derive OpenStack release codename from a given installation source.'''
60
ubuntu_rel = lsb_release()['DISTRIB_CODENAME']
65
rel = ubuntu_openstack_release[ubuntu_rel]
67
e = 'Code not derive openstack release for '\
68
'this Ubuntu release: %s' % rel
72
if src.startswith('cloud:'):
73
ca_rel = src.split(':')[1]
74
ca_rel = ca_rel.split('%s-' % ubuntu_rel)[1].split('/')[0]
77
# Best guess match based on deb string provided
78
if src.startswith('deb') or src.startswith('ppa'):
79
for k, v in openstack_codenames.iteritems():
84
def get_os_codename_version(vers):
85
'''Determine OpenStack codename from version number.'''
87
return openstack_codenames[vers]
89
e = 'Could not determine OpenStack codename for version %s' % vers
93
def get_os_version_codename(codename):
94
'''Determine OpenStack version number from codename.'''
95
for k, v in openstack_codenames.iteritems():
98
e = 'Code not derive OpenStack version for '\
99
'codename: %s' % codename
103
def get_os_codename_package(pkg):
104
'''Derive OpenStack release codename from an installed package.'''
110
e = 'Could not determine version of installed package: %s' % pkg
113
vers = apt.UpstreamVersion(pkg.current_ver.ver_str)
116
if 'swift' in pkg.name:
118
return swift_codenames[vers]
121
return openstack_codenames[vers]
123
e = 'Could not determine OpenStack codename for version %s' % vers
127
def get_os_version_package(pkg):
128
'''Derive OpenStack version number from an installed package.'''
129
codename = get_os_codename_package(pkg)
132
vers_map = swift_codenames
134
vers_map = openstack_codenames
136
for version, cname in vers_map.iteritems():
137
if cname == codename:
139
e = "Could not determine OpenStack version for package: %s" % pkg
143
def configure_installation_source(rel):
144
'''Configure apt installation source.'''
146
def _import_key(keyid):
147
cmd = "apt-key adv --keyserver keyserver.ubuntu.com " \
148
"--recv-keys %s" % keyid
150
subprocess.check_call(cmd.split(' '))
151
except subprocess.CalledProcessError:
152
error_out("Error importing repo key %s" % keyid)
156
elif rel[:4] == "ppa:":
158
subprocess.check_call(["add-apt-repository", "-y", src])
159
elif rel[:3] == "deb":
160
l = len(rel.split('|'))
162
src, key = rel.split('|')
163
juju_log("Importing PPA key from keyserver for %s" % src)
168
error_out("Invalid openstack-release: %s" % rel)
170
with open('/etc/apt/sources.list.d/juju_deb.list', 'w') as f:
172
elif rel[:6] == 'cloud:':
173
ubuntu_rel = lsb_release()['DISTRIB_CODENAME']
174
rel = rel.split(':')[1]
175
u_rel = rel.split('-')[0]
176
ca_rel = rel.split('-')[1]
178
if u_rel != ubuntu_rel:
179
e = 'Cannot install from Cloud Archive pocket %s on this Ubuntu '\
180
'version (%s)' % (ca_rel, ubuntu_rel)
183
if 'staging' in ca_rel:
184
# staging is just a regular PPA.
185
os_rel = ca_rel.split('/')[0]
186
ppa = 'ppa:ubuntu-cloud-archive/%s-staging' % os_rel
187
cmd = 'add-apt-repository -y %s' % ppa
188
subprocess.check_call(cmd.split(' '))
191
# map charm config options to actual archive pockets.
193
'folsom': 'precise-updates/folsom',
194
'folsom/updates': 'precise-updates/folsom',
195
'folsom/proposed': 'precise-proposed/folsom',
196
'grizzly': 'precise-updates/grizzly',
197
'grizzly/updates': 'precise-updates/grizzly',
198
'grizzly/proposed': 'precise-proposed/grizzly'
202
pocket = pockets[ca_rel]
204
e = 'Invalid Cloud Archive release specified: %s' % rel
207
src = "deb %s %s main" % (CLOUD_ARCHIVE_URL, pocket)
208
_import_key(CLOUD_ARCHIVE_KEY_ID)
210
with open('/etc/apt/sources.list.d/cloud-archive.list', 'w') as f:
213
error_out("Invalid openstack-release specified: %s" % rel)
216
def save_script_rc(script_path="scripts/scriptrc", **env_vars):
218
Write an rc file in the charm-delivered directory containing
219
exported environment variables provided by env_vars. Any charm scripts run
220
outside the juju hook environment can source this scriptrc to obtain
221
updated config information necessary to perform health checks or
224
charm_dir = os.getenv('CHARM_DIR')
225
juju_rc_path = "%s/%s" % (charm_dir, script_path)
226
with open(juju_rc_path, 'wb') as rc_script:
229
[rc_script.write('export %s=%s\n' % (u, p))
230
for u, p in env_vars.iteritems() if u != "script_path"]