~hazmat/charms/precise/quantum-gateway/ssl-everywhere

« back to all changes in this revision

Viewing changes to hooks/lib/openstack_common.py

  • Committer: Adam Gandelman
  • Date: 2013-06-03 17:35:03 UTC
  • mfrom: (25.1.32 quantum-gateway)
  • Revision ID: adamg@canonical.com-20130603173503-qg646m67re20r3yn
Support for Grizzly. Support for HA.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
 
3
# Common python helper functions used for OpenStack charms.
 
4
 
 
5
import apt_pkg as apt
 
6
import subprocess
 
7
import os
 
8
 
 
9
CLOUD_ARCHIVE_URL = "http://ubuntu-cloud.archive.canonical.com/ubuntu"
 
10
CLOUD_ARCHIVE_KEY_ID = '5EDB1B62EC4926EA'
 
11
 
 
12
ubuntu_openstack_release = {
 
13
    'oneiric': 'diablo',
 
14
    'precise': 'essex',
 
15
    'quantal': 'folsom',
 
16
    'raring': 'grizzly',
 
17
}
 
18
 
 
19
 
 
20
openstack_codenames = {
 
21
    '2011.2': 'diablo',
 
22
    '2012.1': 'essex',
 
23
    '2012.2': 'folsom',
 
24
    '2013.1': 'grizzly',
 
25
    '2013.2': 'havana',
 
26
}
 
27
 
 
28
# The ugly duckling
 
29
swift_codenames = {
 
30
    '1.4.3': 'diablo',
 
31
    '1.4.8': 'essex',
 
32
    '1.7.4': 'folsom',
 
33
    '1.7.6': 'grizzly',
 
34
    '1.7.7': 'grizzly',
 
35
    '1.8.0': 'grizzly',
 
36
}
 
37
 
 
38
 
 
39
def juju_log(msg):
 
40
    subprocess.check_call(['juju-log', msg])
 
41
 
 
42
 
 
43
def error_out(msg):
 
44
    juju_log("FATAL ERROR: %s" % msg)
 
45
    exit(1)
 
46
 
 
47
 
 
48
def lsb_release():
 
49
    '''Return /etc/lsb-release in a dict'''
 
50
    lsb = open('/etc/lsb-release', 'r')
 
51
    d = {}
 
52
    for l in lsb:
 
53
        k, v = l.split('=')
 
54
        d[k.strip()] = v.strip()
 
55
    return d
 
56
 
 
57
 
 
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']
 
61
 
 
62
    rel = ''
 
63
    if src == 'distro':
 
64
        try:
 
65
            rel = ubuntu_openstack_release[ubuntu_rel]
 
66
        except KeyError:
 
67
            e = 'Code not derive openstack release for '\
 
68
                'this Ubuntu release: %s' % rel
 
69
            error_out(e)
 
70
        return rel
 
71
 
 
72
    if src.startswith('cloud:'):
 
73
        ca_rel = src.split(':')[1]
 
74
        ca_rel = ca_rel.split('%s-' % ubuntu_rel)[1].split('/')[0]
 
75
        return ca_rel
 
76
 
 
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():
 
80
            if v in src:
 
81
                return v
 
82
 
 
83
 
 
84
def get_os_codename_version(vers):
 
85
    '''Determine OpenStack codename from version number.'''
 
86
    try:
 
87
        return openstack_codenames[vers]
 
88
    except KeyError:
 
89
        e = 'Could not determine OpenStack codename for version %s' % vers
 
90
        error_out(e)
 
91
 
 
92
 
 
93
def get_os_version_codename(codename):
 
94
    '''Determine OpenStack version number from codename.'''
 
95
    for k, v in openstack_codenames.iteritems():
 
96
        if v == codename:
 
97
            return k
 
98
    e = 'Code not derive OpenStack version for '\
 
99
        'codename: %s' % codename
 
100
    error_out(e)
 
101
 
 
102
 
 
103
def get_os_codename_package(pkg):
 
104
    '''Derive OpenStack release codename from an installed package.'''
 
105
    apt.init()
 
106
    cache = apt.Cache()
 
107
    try:
 
108
        pkg = cache[pkg]
 
109
    except:
 
110
        e = 'Could not determine version of installed package: %s' % pkg
 
111
        error_out(e)
 
112
 
 
113
    vers = apt.UpstreamVersion(pkg.current_ver.ver_str)
 
114
 
 
115
    try:
 
116
        if 'swift' in pkg.name:
 
117
            vers = vers[:5]
 
118
            return swift_codenames[vers]
 
119
        else:
 
120
            vers = vers[:6]
 
121
            return openstack_codenames[vers]
 
122
    except KeyError:
 
123
        e = 'Could not determine OpenStack codename for version %s' % vers
 
124
        error_out(e)
 
125
 
 
126
 
 
127
def get_os_version_package(pkg):
 
128
    '''Derive OpenStack version number from an installed package.'''
 
129
    codename = get_os_codename_package(pkg)
 
130
 
 
131
    if 'swift' in pkg:
 
132
        vers_map = swift_codenames
 
133
    else:
 
134
        vers_map = openstack_codenames
 
135
 
 
136
    for version, cname in vers_map.iteritems():
 
137
        if cname == codename:
 
138
            return version
 
139
    e = "Could not determine OpenStack version for package: %s" % pkg
 
140
    error_out(e)
 
141
 
 
142
 
 
143
def configure_installation_source(rel):
 
144
    '''Configure apt installation source.'''
 
145
 
 
146
    def _import_key(keyid):
 
147
        cmd = "apt-key adv --keyserver keyserver.ubuntu.com " \
 
148
              "--recv-keys %s" % keyid
 
149
        try:
 
150
            subprocess.check_call(cmd.split(' '))
 
151
        except subprocess.CalledProcessError:
 
152
            error_out("Error importing repo key %s" % keyid)
 
153
 
 
154
    if rel == 'distro':
 
155
        return
 
156
    elif rel[:4] == "ppa:":
 
157
        src = rel
 
158
        subprocess.check_call(["add-apt-repository", "-y", src])
 
159
    elif rel[:3] == "deb":
 
160
        l = len(rel.split('|'))
 
161
        if l == 2:
 
162
            src, key = rel.split('|')
 
163
            juju_log("Importing PPA key from keyserver for %s" % src)
 
164
            _import_key(key)
 
165
        elif l == 1:
 
166
            src = rel
 
167
        else:
 
168
            error_out("Invalid openstack-release: %s" % rel)
 
169
 
 
170
        with open('/etc/apt/sources.list.d/juju_deb.list', 'w') as f:
 
171
            f.write(src)
 
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]
 
177
 
 
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)
 
181
            error_out(e)
 
182
 
 
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(' '))
 
189
            return
 
190
 
 
191
        # map charm config options to actual archive pockets.
 
192
        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'
 
199
        }
 
200
 
 
201
        try:
 
202
            pocket = pockets[ca_rel]
 
203
        except KeyError:
 
204
            e = 'Invalid Cloud Archive release specified: %s' % rel
 
205
            error_out(e)
 
206
 
 
207
        src = "deb %s %s main" % (CLOUD_ARCHIVE_URL, pocket)
 
208
        _import_key(CLOUD_ARCHIVE_KEY_ID)
 
209
 
 
210
        with open('/etc/apt/sources.list.d/cloud-archive.list', 'w') as f:
 
211
            f.write(src)
 
212
    else:
 
213
        error_out("Invalid openstack-release specified: %s" % rel)
 
214
 
 
215
 
 
216
def save_script_rc(script_path="scripts/scriptrc", **env_vars):
 
217
    """
 
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
 
222
    service changes.
 
223
    """
 
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:
 
227
        rc_script.write(
 
228
            "#!/bin/bash\n")
 
229
        [rc_script.write('export %s=%s\n' % (u, p))
 
230
         for u, p in env_vars.iteritems() if u != "script_path"]