~cprov/tanuki-continuous-deployer/local-provider

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
#!/usr/bin/env python3
#
# Copyright (C) 2015 Canonical
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
import time
import sys

from ci_automation import juju


class ReallySureAboutThis(Exception):
    """Exception to request the user for confirmation of an action."""


def get_svc_status(svc, env, base_dir, **kw):
    # Figure out a status, ordinary webservices are active if they
    # have a 'website' relationship. workers, we don't know yet.
    juju_services = kw['juju_services']
    if 'worker' in svc:
        config = juju.get_config(svc, env, base_dir)
        active = config['settings']['active']['value']
        status = 'ACTIVE' if active else 'INACTIVE'
    else:
        has_website = juju_services[svc].get(
            'relations', {}).get('website')
        status = 'ACTIVE' if has_website else 'INACTIVE'
    return status


def activate_service(svc, env, base_dir, **kw):
    status = get_svc_status(svc, env, base_dir, **kw)
    if status == "ACTIVE":
        print("Service: {} already active".format(svc))
    else:
        print("Activating: {}".format(svc))
        if 'worker' in svc:
            juju.juju(["set", svc, "active=true"],
                      env_name=env, base_dir=base_dir)
        else:
            juju.juju(["add-relation", svc, "haproxy"],
                      env_name=env, base_dir=base_dir)


def deactivate_service(svc, env, base_dir, **kw):
    status = get_svc_status(svc, env, base_dir, **kw)
    if status == "INACTIVE":
        print("Service: {} already inactive".format(svc))
    else:
        print("Deactivating: {}".format(svc))
        if 'worker' in svc:
            juju.juju(["set", svc, "active=false"],
                      env_name=env, base_dir=base_dir)
        else:
            juju.juju(["remove-relation", svc, "haproxy"],
                      env_name=env, base_dir=base_dir)


def destroy_service(svc, env, base_dir, **kw):
    status = get_svc_status(svc, env, base_dir, **kw)
    if status == "ACTIVE" and not kw.get('force', False):
        raise ReallySureAboutThis("You'r requesting to destroy an ACTIVE service")
    else:
        print("Destroying: {}".format(svc))
        juju_status = juju.get_status(env, base_dir)
        juju.juju(["remove-service", svc], env_name=env, base_dir=base_dir)
        # get machines to destroy
        units = juju_status['services'][svc]['units']
        machines = [v['machine'] for v in units.values()]

        print("Waiting for {} to die".format(svc))
        # wait for destroyed service to die
        for _ in range(12):
            st = juju.get_status(env, base_dir)
            svc_st = st['services'].get(svc)
            if svc_st and svc_st.get('life') == 'dying':
                time.sleep(10)
        # sanity check, if there is still something alive, bail out
        st = juju.get_status(env, base_dir)
        if svc in st['services']:
            print("ERROR: Service '{}' is still alive".format(svc))
            sys.exit(1)

        # also remove the machines
        for machine in machines:
            print("Destroying machine {}".format(machine))
            juju.juju(['remove-machine', machine],
                      env_name=env,
                      base_dir=base_dir)