~bloodearnest/juju-deployer/annotate-branches

« back to all changes in this revision

Viewing changes to deployer/deployment.py

  • Committer: Simon Davy
  • Date: 2015-03-30 15:16:10 UTC
  • mfrom: (126.1.18 juju-deployer)
  • Revision ID: bloodearnest@gmail.com-20150330151610-ft7lwajcbnnroa39
merge upstream and fix review comments

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
 
8
8
from .charm import Charm
9
9
from .feedback import Feedback
10
 
from .service import Service, ServiceUnitPlacement
 
10
from .service import Service, ServiceUnitPlacementV3, ServiceUnitPlacementV4
11
11
from .relation import Endpoint
12
 
from .utils import path_join, yaml_dump, ErrorExit, resolve_include
 
12
from .utils import path_join, yaml_dump, ErrorExit, resolve_include, x_in_y
13
13
 
14
14
 
15
15
class Deployment(object):
16
16
 
17
17
    log = logging.getLogger("deployer.deploy")
18
18
 
19
 
    def __init__(self, name, data, include_dirs, repo_path=""):
 
19
    def __init__(self, name, data, include_dirs, repo_path="", version=3):
20
20
        self.name = name
21
21
        self.data = data
22
22
        self.include_dirs = include_dirs
23
23
        self.repo_path = repo_path
 
24
        self.version = version
 
25
        self.machines = {}
24
26
 
25
27
    @property
26
28
    def series(self):
44
46
        services = []
45
47
        for name, svc_data in self.data.get('services', {}).items():
46
48
            services.append(Service(name, svc_data))
47
 
        services.sort(self._placement_sort)
 
49
        if self.version == 3:
 
50
            # Sort unplaced units first, then sort by name for placed units.
 
51
            services.sort(key=lambda svc: (bool(svc.unit_placement), svc.name))
 
52
        else:
 
53
            services.sort(self._machines_placement_sort)
48
54
        return services
49
55
 
 
56
    def set_machines(self, machines):
 
57
        """Set a dict of machines, mapping from the names in the machine spec
 
58
        to the machine names in the environment status.
 
59
        """
 
60
        self.machines = machines
 
61
 
 
62
    def get_machines(self):
 
63
        """Return a dict mapping machine names to machine options.
 
64
 
 
65
        An empty dict is returned if no machines are defined in the
 
66
        bundle YAML.
 
67
        """
 
68
        machines = {}
 
69
        for key, machine in self.data.get('machines', {}).items():
 
70
            machines[str(key)] = machine
 
71
        return machines
 
72
 
50
73
    def get_service_names(self):
51
74
        """Return a sequence of service names for this deployment."""
52
75
        return self.data.get('services', {}).keys()
53
76
 
54
77
    @staticmethod
55
 
    def _placement_sort(svc_a, svc_b):
 
78
    def _machines_placement_sort(svc_a, svc_b):
 
79
        """Sort machines with machine placement in mind.
 
80
        
 
81
        If svc_a is colocated alongside svc_b, svc_b needs to be deployed
 
82
        first, so that it exists by the time svc_a is deployed, and vice
 
83
        versa; this sorts first based on this fact, then secondly based on
 
84
        whether or not the service has a unit placement, and then finally
 
85
        based on the name of the service.
 
86
        """
56
87
        if svc_a.unit_placement:
57
88
            if svc_b.unit_placement:
 
89
                # Check for colocation.  This naively assumes that there is no
 
90
                # circularity in placements.
 
91
                if x_in_y(svc_b, svc_a):
 
92
                    return -1
 
93
                if x_in_y(svc_a, svc_b):
 
94
                    return 1
 
95
                # If no colocation exists, simply compare names.
58
96
                return cmp(svc_a.name, svc_b.name)
59
97
            return 1
60
98
        if svc_b.unit_placement:
64
102
    def get_unit_placement(self, svc, status):
65
103
        if isinstance(svc, (str, unicode)):
66
104
            svc = self.get_service(svc)
67
 
        return ServiceUnitPlacement(svc, self, status)
 
105
        if self.version == 3:
 
106
            return ServiceUnitPlacementV3(svc, self, status)
 
107
        else:
 
108
            return ServiceUnitPlacementV4(svc, self, status,
 
109
                                          machines_map=self.machines)
68
110
 
69
111
    def get_relations(self):
70
112
        if 'relations' not in self.data:
161
203
            for svc_name, svc_data in self.data['services'].items():
162
204
                charm = self.get_charm_for(svc_name)
163
205
                if k in charm.config:
164
 
                    if 'options' not in svc_data:
 
206
                    if not svc_data.get('options'):
165
207
                        svc_data['options'] = {}
166
208
                    svc_data['options'][k] = v
167
209
                    found = True