~ev/charms/precise/ubuntu-ci-services-itself/restish-swift-support

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#!/usr/bin/env python

import os
import json
import subprocess
import sys
import time


def juju_info(msg):
    subprocess.check_call(['juju-log', '-l', 'INFO', msg])
    pass


def _config():
    output = subprocess.check_output(['config-get', '--format=json'])
    return json.loads(output)


def _relation_ids(relation_types=('db',)):
    # accept strings or iterators
    if isinstance(relation_types, basestring):
        reltypes = [relation_types, ]
    else:
        reltypes = relation_types
    relids = []
    for reltype in reltypes:
        relid_cmd_line = ['relation-ids', '--format=json', reltype]
        json_relids = subprocess.check_output(relid_cmd_line).strip()
        if json_relids:
            relids.extend(json.loads(json_relids))
    return relids


def _relation_get(key):
    return subprocess.check_output(['relation-get', key]).strip()


def _relation_set(keyvalues, relation_id=None):
    args = ['relation-set']
    if relation_id:
        args.extend(['-r', relation_id])
    args.extend(["{}={}".format(k, v or '') for k, v in keyvalues.items()])
    subprocess.check_call(args)


def _service_dir(config):
    unit = os.environ['JUJU_UNIT_NAME'].split('/')[0]
    for x in (':', '-', '/', '"', "'"):
        unit = unit.replace(x, '_')
    return os.path.join(config['install_root'], unit)


def install(config):
    pkgs = [x for x in config['packages'].split(' ') if x]
    pkgs.append('bzr')
    pkgs.append('python-pip')  # required for restish?

    juju_info('installing apt packages...')
    subprocess.check_call(['apt-get', 'install', '-y', '-q'] + pkgs)

    juju_info('installing restish...')
    restish = 'restish==%s' % config['restish_version']
    subprocess.check_call(['pip', 'install', restish])

    juju_info('grabbing service from bzr...')
    args = ['bzr', 'branch']
    rev = config.get('revno', '')
    if rev:
        args.extend(['-r', rev])
    args.append(config['branch'])
    args.append(_service_dir(config))
    subprocess.check_call(args)


def start(config):
    service = 'restish'
    conf = '/etc/init/%s.sh' % service
    if os.path.exists(conf):
        try:
            subprocess.check_call(['service', 'restart', service])
        except subprocess.CalledProcessError:
            # if it wasn't running, restart fails, so just try to start
            subprocess.check_call(['service', 'start', service])


def stop(config):
    service = 'restish'
    conf = '/etc/init/%s.sh' % service
    if os.path.exists(conf):
        subprocess.check_call(['service', 'stop', service])


def config_changed(config):
    # Trigger WSGI reloading
    for relid in _relation_ids('wsgi'):
        _relation_set({'wsgi_timestamp': time.time()}, relation_id=relid)


def website_relation_joined(config):
    host = subprocess.check_output(['unit-get', 'private-address']).strip()
    _relation_set({'port': config["port"], 'hostname': host})


def website_relation_changed(config):
    return website_relation_joined(config)


def website_relation_broken(config):
    pass


def wsgi_relation_joined(config):
    sdir = _service_dir(config)

    _relation_set({'working_dir': sdir})

    for var in config:
        if var.startswith('wsgi_') or var in ['listen_ip', 'port']:
            _relation_set({var: config[var]})

    path = config.get('python_path')
    if path:
        full_path = []
        for p in path.split(':'):
            if p[0] != '/':
                p = os.path.join(sdir, p)
            full_path.append(p)
        _relation_set({'python_path': ':'.join(full_path)})

    port = config.get('port')
    if port:
        subprocess.call(['open-port', "%s/TCP" % port])


def wsgi_relation_changed(config):
    return wsgi_relation_joined(config)


def wsgi_relation_broken(config):
    port = config.get('port')
    if port:
        subprocess.call(['close-port', "%s/TCP" % port])


def amqp_relation_joined(config):
    _relation_set({
        'username': config['amqp-user'],
        'vhost': config['amqp-vhost'],
    })


def amqp_relation_changed(config):
    with open(os.path.join(_service_dir(config), 'amqp_config.py'), 'w') as f:
        f.write('# DO NOT EDIT. Generated by restish charm hook\n')
        f.write('AMQP_USER = "%s"\n' % config['amqp-user'])
        f.write('AMQP_VHOST = "%s"\n' % config['amqp-vhost'])
        f.write('AMQP_HOST = "%s"\n' % _relation_get('private-address'))
        f.write('AMQP_PASSWORD = "%s"\n' % _relation_get('password'))


def amqp_relation_broken(config):
    os.unlink(os.path.join(_service_dir(config), 'amqp_config.py'))


def lander_jenkins_relation_joined(config):
    host = subprocess.check_output(['unit-get', 'private-address']).strip()
    _relation_set({
        'lander_api_hostname': host,
    })


def lander_jenkins_relation_changed(config):
    data = {
        "lander_username": _relation_get('username'),
        "lander_password": _relation_get('password'),
        "lander_hostname": _relation_get('hostname'),
        "lander_port": _relation_get('port'),
        "lander_master_job": _relation_get('master_job'),
        "lander_job_token": _relation_get('job_token'),
    }
    with open(os.path.join(_service_dir(config), 'lander_config.json'),
              'w') as f:
        f.write(json.dumps(data))
        f.write('\n')


def lander_jenkins_relation_broken(config):
    os.unlink(os.path.join(_service_dir(config), 'lander_config.json'))


def main():
    hook = os.path.basename(sys.argv[0])
    juju_info("Running hook: %s" % hook)

    hook_py = hook.replace('-', '_')
    funcs = globals()
    if hook_py not in funcs:
        print("Unknown hook: %s" % hook)
        return 1

    config = _config()
    try:
        return funcs[hook_py](config)
    except subprocess.CalledProcessError as e:
        juju_info('Error running: %s: %s' % (e.cmd, e.output))
        return e.returncode


if __name__ == '__main__':
    exit(main())