~barryprice/juju-deployer/LP1892423

« back to all changes in this revision

Viewing changes to deployer/env/py.py

  • Committer: Adam Gandelman
  • Date: 2013-09-03 20:44:14 UTC
  • mfrom: (69.3.45 darwin)
  • Revision ID: adamg@canonical.com-20130903204414-xsqqz2gp83dp5d2o
MergeĀ lp:juju-deployer/darwin.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import time
 
2
 
 
3
from deployer.errors import UnitErrors
 
4
from deployer.utils import ErrorExit
 
5
 
 
6
from .base import BaseEnvironment
 
7
 
 
8
 
 
9
class PyEnvironment(BaseEnvironment):
 
10
 
 
11
    def __init__(self, name, options=None):
 
12
        self.name = name
 
13
        self.options = options
 
14
 
 
15
    def add_units(self, service_name, num_units):
 
16
        params = self._named_env(["juju", "add-unit"])
 
17
        if num_units > 1:
 
18
            params.extend(["-n", str(num_units)])
 
19
        params.append(service_name)
 
20
        self._check_call(
 
21
            params, self.log, "Error adding units to %s", service_name)
 
22
 
 
23
    def add_relation(self, endpoint_a, endpoint_b):
 
24
        params = self._named_env(["juju", "add-relation"])
 
25
        params.extend([endpoint_a, endpoint_b])
 
26
        self._check_call(
 
27
            params, self.log, "Error adding relation to %s %s",
 
28
            endpoint_a, endpoint_b)
 
29
 
 
30
    def close(self):
 
31
        """ NoOp """
 
32
 
 
33
    def connect(self):
 
34
        """ NoOp """
 
35
 
 
36
    def _destroy_service(self, service_name):
 
37
        params = self._named_env(["juju", "destroy-service"])
 
38
        params.append(service_name)
 
39
        self._check_call(
 
40
            params, self.log, "Error destroying service %s" % service_name)
 
41
 
 
42
    def get_config(self, svc_name):
 
43
        params = self._named_env(["juju", "get"])
 
44
        params.append(svc_name)
 
45
        return self._check_call(
 
46
            params, self.log, "Error retrieving config for %r", svc_name)
 
47
 
 
48
    def get_constraints(self, svc_name):
 
49
        params = self._named_env(["juju", "get-constraints"])
 
50
        params.append(svc_name)
 
51
        return self._check_call(
 
52
            params, self.log, "Error retrieving constraints for %r", svc_name)
 
53
 
 
54
    def reset(self,
 
55
              terminate_machines=False,
 
56
              terminate_delay=0,
 
57
              timeout=360,
 
58
              watch=False):
 
59
        status = self.status()
 
60
        for s in status.get('services'):
 
61
            self.log.debug(" Destroying service %s", s)
 
62
            self._destroy_service(s)
 
63
        if not terminate_machines:
 
64
            return True
 
65
        for m in status.get('machines'):
 
66
            if int(m) == 0:
 
67
                continue
 
68
            self.log.debug(" Terminating machine %s", m)
 
69
            self.terminate_machine(str(m))
 
70
            if terminate_delay:
 
71
                self.log.debug("  Waiting for terminate delay")
 
72
                time.sleep(terminate_delay)
 
73
 
 
74
    def resolve_errors(self, retry_count=0, timeout=600, watch=False, delay=5):
 
75
        pass
 
76
 
 
77
    def status(self):
 
78
        return self.get_cli_status()
 
79
 
 
80
    def wait_for_units(
 
81
            self, timeout, goal_state="started", watch=False, no_exit=False):
 
82
 
 
83
        max_time = time.time() + timeout
 
84
        while max_time > time.time():
 
85
            status = self.status()
 
86
            pending = []
 
87
            error_units = self._get_units_in_error(status)
 
88
            errors = []
 
89
            for s in status.get("services", {}).values():
 
90
                for uid, u in s.get("units", {}).items():
 
91
                    state = u.get("agent-state") or "pending"
 
92
                    if uid in error_units:
 
93
                        errors.append({"name": uid,
 
94
                                       "machine": u["machine"],
 
95
                                       "agent-state": state})
 
96
                    elif state != goal_state:
 
97
                        pending.append(u)
 
98
                    for rid in u.get("relation-errors", {}).keys():
 
99
                        errors.append({"name": uid,
 
100
                                       "machine": u["machine"],
 
101
                                       "agent-state":
 
102
                                       "relation-error: %s" % rid})
 
103
                    for sid, sub in u.get("subordinates", {}).items():
 
104
                        state = sub.get("agent-state") or "pending"
 
105
                        if sid in error_units:
 
106
                            errors.append({"name": sid,
 
107
                                           "machine": u["machine"],
 
108
                                           "agent-state": state})
 
109
                        elif state != goal_state:
 
110
                            pending.append(sid)
 
111
            if not pending and not errors:
 
112
                break
 
113
            if errors:
 
114
                if no_exit:
 
115
                    raise UnitErrors(errors)
 
116
                else:
 
117
                    error_units = [
 
118
                        "unit: %s: machine: %s agent-state: %s" % (
 
119
                            u["name"], u["machine"], u["agent-state"]
 
120
                            )
 
121
                        for u in errors]
 
122
                    self.log.error(
 
123
                        "The following units had errors:\n  %s" % (
 
124
                            "   \n".join(error_units)))
 
125
                    raise ErrorExit()