~thedac/charms/trusty/glance/workload-status

« back to all changes in this revision

Viewing changes to hooks/lib/utils.py

  • Committer: Andres Rodriguez
  • Date: 2013-06-20 16:48:47 UTC
  • mto: (29.2.187 glance)
  • mto: This revision was merged to the branch mainline in revision 37.
  • Revision ID: andreserl@ubuntu.com-20130620164847-ywboj1uileex4msj
remove hooks/lib

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#
2
 
# Copyright 2012 Canonical Ltd.
3
 
#
4
 
# This file is sourced from lp:openstack-charm-helpers
5
 
#
6
 
# Authors:
7
 
#  James Page <james.page@ubuntu.com>
8
 
#  Paul Collins <paul.collins@canonical.com>
9
 
#  Adam Gandelman <adamg@ubuntu.com>
10
 
#
11
 
 
12
 
import json
13
 
import os
14
 
import subprocess
15
 
import socket
16
 
import sys
17
 
 
18
 
 
19
 
def do_hooks(hooks):
20
 
    hook = os.path.basename(sys.argv[0])
21
 
 
22
 
    try:
23
 
        hook_func = hooks[hook]
24
 
    except KeyError:
25
 
        juju_log('INFO',
26
 
                 "This charm doesn't know how to handle '{}'.".format(hook))
27
 
    else:
28
 
        hook_func()
29
 
 
30
 
 
31
 
def install(*pkgs):
32
 
    cmd = [
33
 
        'apt-get',
34
 
        '-y',
35
 
        'install'
36
 
          ]
37
 
    for pkg in pkgs:
38
 
        cmd.append(pkg)
39
 
    subprocess.check_call(cmd)
40
 
 
41
 
TEMPLATES_DIR = 'templates'
42
 
 
43
 
try:
44
 
    import jinja2
45
 
except ImportError:
46
 
    install('python-jinja2')
47
 
    import jinja2
48
 
 
49
 
try:
50
 
    import dns.resolver
51
 
except ImportError:
52
 
    install('python-dnspython')
53
 
    import dns.resolver
54
 
 
55
 
 
56
 
def render_template(template_name, context, template_dir=TEMPLATES_DIR):
57
 
    templates = jinja2.Environment(
58
 
                    loader=jinja2.FileSystemLoader(template_dir)
59
 
                    )
60
 
    template = templates.get_template(template_name)
61
 
    return template.render(context)
62
 
 
63
 
CLOUD_ARCHIVE = \
64
 
""" # Ubuntu Cloud Archive
65
 
deb http://ubuntu-cloud.archive.canonical.com/ubuntu {} main
66
 
"""
67
 
 
68
 
CLOUD_ARCHIVE_POCKETS = {
69
 
    'folsom': 'precise-updates/folsom',
70
 
    'folsom/updates': 'precise-updates/folsom',
71
 
    'folsom/proposed': 'precise-proposed/folsom',
72
 
    'grizzly': 'precise-updates/grizzly',
73
 
    'grizzly/updates': 'precise-updates/grizzly',
74
 
    'grizzly/proposed': 'precise-proposed/grizzly'
75
 
    }
76
 
 
77
 
 
78
 
def configure_source():
79
 
    source = str(config_get('openstack-origin'))
80
 
    if not source:
81
 
        return
82
 
    if source.startswith('ppa:'):
83
 
        cmd = [
84
 
            'add-apt-repository',
85
 
            source
86
 
            ]
87
 
        subprocess.check_call(cmd)
88
 
    if source.startswith('cloud:'):
89
 
        # CA values should be formatted as cloud:ubuntu-openstack/pocket, eg:
90
 
        #   cloud:precise-folsom/updates or cloud:precise-folsom/proposed
91
 
        install('ubuntu-cloud-keyring')
92
 
        pocket = source.split(':')[1]
93
 
        pocket = pocket.split('-')[1]
94
 
        with open('/etc/apt/sources.list.d/cloud-archive.list', 'w') as apt:
95
 
            apt.write(CLOUD_ARCHIVE.format(CLOUD_ARCHIVE_POCKETS[pocket]))
96
 
    if source.startswith('deb'):
97
 
        l = len(source.split('|'))
98
 
        if l == 2:
99
 
            (apt_line, key) = source.split('|')
100
 
            cmd = [
101
 
                'apt-key',
102
 
                'adv', '--keyserver keyserver.ubuntu.com',
103
 
                '--recv-keys', key
104
 
                ]
105
 
            subprocess.check_call(cmd)
106
 
        elif l == 1:
107
 
            apt_line = source
108
 
 
109
 
        with open('/etc/apt/sources.list.d/quantum.list', 'w') as apt:
110
 
            apt.write(apt_line + "\n")
111
 
    cmd = [
112
 
        'apt-get',
113
 
        'update'
114
 
        ]
115
 
    subprocess.check_call(cmd)
116
 
 
117
 
# Protocols
118
 
TCP = 'TCP'
119
 
UDP = 'UDP'
120
 
 
121
 
 
122
 
def expose(port, protocol='TCP'):
123
 
    cmd = [
124
 
        'open-port',
125
 
        '{}/{}'.format(port, protocol)
126
 
        ]
127
 
    subprocess.check_call(cmd)
128
 
 
129
 
 
130
 
def juju_log(severity, message):
131
 
    cmd = [
132
 
        'juju-log',
133
 
        '--log-level', severity,
134
 
        message
135
 
        ]
136
 
    subprocess.check_call(cmd)
137
 
 
138
 
 
139
 
cache = {}
140
 
 
141
 
 
142
 
def cached(func):
143
 
    def wrapper(*args, **kwargs):
144
 
        global cache
145
 
        key = str((func, args, kwargs))
146
 
        try:
147
 
            return cache[key]
148
 
        except KeyError:
149
 
            res = func(*args, **kwargs)
150
 
            cache[key] = res
151
 
            return res
152
 
    return wrapper
153
 
 
154
 
 
155
 
@cached
156
 
def relation_ids(relation):
157
 
    cmd = [
158
 
        'relation-ids',
159
 
        relation
160
 
        ]
161
 
    result = str(subprocess.check_output(cmd)).split()
162
 
    if result == "":
163
 
        return None
164
 
    else:
165
 
        return result
166
 
 
167
 
 
168
 
@cached
169
 
def relation_list(rid):
170
 
    cmd = [
171
 
        'relation-list',
172
 
        '-r', rid,
173
 
        ]
174
 
    result = str(subprocess.check_output(cmd)).split()
175
 
    if result == "":
176
 
        return None
177
 
    else:
178
 
        return result
179
 
 
180
 
 
181
 
@cached
182
 
def relation_get(attribute, unit=None, rid=None):
183
 
    cmd = [
184
 
        'relation-get',
185
 
        ]
186
 
    if rid:
187
 
        cmd.append('-r')
188
 
        cmd.append(rid)
189
 
    cmd.append(attribute)
190
 
    if unit:
191
 
        cmd.append(unit)
192
 
    value = subprocess.check_output(cmd).strip()  # IGNORE:E1103
193
 
    if value == "":
194
 
        return None
195
 
    else:
196
 
        return value
197
 
 
198
 
 
199
 
@cached
200
 
def relation_get_dict(relation_id=None, remote_unit=None):
201
 
    """Obtain all relation data as dict by way of JSON"""
202
 
    cmd = [
203
 
        'relation-get', '--format=json'
204
 
        ]
205
 
    if relation_id:
206
 
        cmd.append('-r')
207
 
        cmd.append(relation_id)
208
 
    if remote_unit:
209
 
        remote_unit_orig = os.getenv('JUJU_REMOTE_UNIT', None)
210
 
        os.environ['JUJU_REMOTE_UNIT'] = remote_unit
211
 
    j = subprocess.check_output(cmd)
212
 
    if remote_unit and remote_unit_orig:
213
 
        os.environ['JUJU_REMOTE_UNIT'] = remote_unit_orig
214
 
    d = json.loads(j)
215
 
    settings = {}
216
 
    # convert unicode to strings
217
 
    for k, v in d.iteritems():
218
 
        settings[str(k)] = str(v)
219
 
    return settings
220
 
 
221
 
 
222
 
def relation_set(**kwargs):
223
 
    cmd = [
224
 
        'relation-set'
225
 
        ]
226
 
    args = []
227
 
    for k, v in kwargs.items():
228
 
        if k == 'rid':
229
 
            if v:
230
 
                cmd.append('-r')
231
 
                cmd.append(v)
232
 
        else:
233
 
            args.append('{}={}'.format(k, v))
234
 
    cmd += args
235
 
    subprocess.check_call(cmd)
236
 
 
237
 
 
238
 
@cached
239
 
def unit_get(attribute):
240
 
    cmd = [
241
 
        'unit-get',
242
 
        attribute
243
 
        ]
244
 
    value = subprocess.check_output(cmd).strip()  # IGNORE:E1103
245
 
    if value == "":
246
 
        return None
247
 
    else:
248
 
        return value
249
 
 
250
 
 
251
 
@cached
252
 
def config_get(attribute):
253
 
    cmd = [
254
 
        'config-get',
255
 
        '--format',
256
 
        'json',
257
 
        ]
258
 
    out = subprocess.check_output(cmd).strip()  # IGNORE:E1103
259
 
    cfg = json.loads(out)
260
 
 
261
 
    try:
262
 
        return cfg[attribute]
263
 
    except KeyError:
264
 
        return None
265
 
 
266
 
 
267
 
@cached
268
 
def get_unit_hostname():
269
 
    return socket.gethostname()
270
 
 
271
 
 
272
 
@cached
273
 
def get_host_ip(hostname=unit_get('private-address')):
274
 
    try:
275
 
        # Test to see if already an IPv4 address
276
 
        socket.inet_aton(hostname)
277
 
        return hostname
278
 
    except socket.error:
279
 
        answers = dns.resolver.query(hostname, 'A')
280
 
        if answers:
281
 
            return answers[0].address
282
 
    return None
283
 
 
284
 
 
285
 
def _svc_control(service, action):
286
 
    subprocess.check_call(['service', service, action])
287
 
 
288
 
 
289
 
def restart(*services):
290
 
    for service in services:
291
 
        _svc_control(service, 'restart')
292
 
 
293
 
 
294
 
def stop(*services):
295
 
    for service in services:
296
 
        _svc_control(service, 'stop')
297
 
 
298
 
 
299
 
def start(*services):
300
 
    for service in services:
301
 
        _svc_control(service, 'start')
302
 
 
303
 
 
304
 
def reload(*services):
305
 
    for service in services:
306
 
        try:
307
 
            _svc_control(service, 'reload')
308
 
        except subprocess.CalledProcessError:
309
 
            # Reload failed - either service does not support reload
310
 
            # or it was not running - restart will fixup most things
311
 
            _svc_control(service, 'restart')
312
 
 
313
 
 
314
 
def running(service):
315
 
    try:
316
 
        output = subprocess.check_output(['service', service, 'status'])
317
 
    except subprocess.CalledProcessError:
318
 
        return False
319
 
    else:
320
 
        if ("start/running" in output or
321
 
            "is running" in output):
322
 
            return True
323
 
        else:
324
 
            return False
325
 
 
326
 
 
327
 
def is_relation_made(relation, key='private-address'):
328
 
    for r_id in (relation_ids(relation) or []):
329
 
        for unit in (relation_list(r_id) or []):
330
 
            if relation_get(key, rid=r_id, unit=unit):
331
 
                return True
332
 
    return False