/usr/lib/python2.7/dist-packages/deployer/service.py is in juju-deployer 0.3.6-0ubuntu2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | from feedback import Feedback
class Service(object):
def __init__(self, name, svc_data):
self.svc_data = svc_data
self.name = name
def __repr__(self):
return "<Service %s>" % (self.name)
@property
def annotations(self):
a = self.svc_data.get('annotations')
if a is None:
return a
# core annotations only supports string key / values
d = {}
for k, v in a.items():
d[str(k)] = str(v)
return d
@property
def config(self):
return self.svc_data.get('options', None)
@property
def constraints(self):
return self.svc_data.get('constraints', None)
@property
def num_units(self):
return int(self.svc_data.get('num_units', 1))
@property
def unit_placement(self):
# Separate checks to support machine 0 placement.
value = self.svc_data.get('to')
if value is None:
value = self.svc_data.get('force-machine')
if value is not None and not isinstance(value, list):
value = [value]
return value and map(str, value) or []
@property
def expose(self):
return self.svc_data.get('expose', False)
class ServiceUnitPlacement(object):
def __init__(self, service, deployment, status):
self.service = service
self.deployment = deployment
self.status = status
@staticmethod
def _format_placement(machine, container=None):
if container:
return "%s:%s" % (container, machine)
else:
return machine
def validate(self):
feedback = Feedback()
unit_placement = self.service.unit_placement
if unit_placement is None:
return feedback
if not isinstance(unit_placement, list):
unit_placement = [unit_placement]
unit_placement = map(str, unit_placement)
services = dict([(s.name, s) for s in self.deployment.get_services()])
for idx, p in enumerate(unit_placement):
if ':' in p:
container, p = p.split(':')
if container not in ('lxc', 'kvm'):
feedback.error(
"Invalid service:%s placement: %s" % (
self.service.name, unit_placement[idx]))
if '=' in p:
p, u_idx = p.split("=")
if not u_idx.isdigit():
feedback.error(
"Invalid service:%s placement: %s",
self.service.name, unit_placement[idx])
if p.isdigit() and p == '0':
continue
elif p.isdigit():
feedback.error(
"Service placement to machine not supported %s to %s",
self.service.name, unit_placement[idx])
elif p in services:
if services[p].unit_placement:
feedback.error(
"Nested placement not supported %s -> %s -> %s" % (
self.service.name, p, services[p].unit_placement))
else:
feedback.error(
"Invalid service placement %s to %s" % (
self.service.name, unit_placement[idx]))
return feedback
def get(self, unit_number):
status = self.status
svc = self.service
unit_mapping = svc.unit_placement
if not unit_mapping:
return None
if len(unit_mapping) <= unit_number:
return None
unit_placement = placement = str(unit_mapping[unit_number])
container = None
u_idx = unit_number
if ':' in unit_placement:
container, placement = unit_placement.split(":")
if '=' in placement:
placement, u_idx = placement.split("=")
if placement.isdigit() and placement == "0":
return self._format_placement(placement, container)
with_service = status['services'].get(placement)
if with_service is None:
# Should be caught in validate relations but sanity check
# for concurrency.
self.deployment.log.error(
"Service %s to be deployed with non existant service %s",
svc.name, placement)
# Prefer continuing deployment with a new machine rather
# than an in-progress abort.
return None
svc_units = with_service['units']
if len(svc_units) <= unit_number:
self.deployment.log.warning(
"Service:%s deploy-with Service:%s, but no with unit found",
svc.name, placement)
return None
unit_names = svc_units.keys()
unit_names.sort()
machine = svc_units[unit_names[int(u_idx)]].get('machine')
if not machine:
self.deployment.log.warning(
"Service:%s deploy-with unit missing machine %s",
svc.name, unit_names[unit_number])
return None
return self._format_placement(machine, container)
|