28
34
that is specifically for use by OpenStack charms.
31
def __init__(self, series=None, openstack=None, source=None, stable=True):
37
def __init__(self, series=None, openstack=None, source=None,
38
stable=True, log_level=DEBUG):
32
39
"""Initialize the deployment environment."""
33
40
super(OpenStackAmuletDeployment, self).__init__(series)
41
self.log = self.get_logger(level=log_level)
42
self.log.info('OpenStackAmuletDeployment: init')
34
43
self.openstack = openstack
35
44
self.source = source
36
45
self.stable = stable
39
48
self.current_next = "trusty"
50
def get_logger(self, name="deployment-logger", level=logging.DEBUG):
51
"""Get a logger object that will log to stdout."""
53
logger = log.getLogger(name)
54
fmt = log.Formatter("%(asctime)s %(funcName)s "
55
"%(levelname)s: %(message)s")
57
handler = log.StreamHandler(stream=sys.stdout)
58
handler.setLevel(level)
59
handler.setFormatter(fmt)
61
logger.addHandler(handler)
62
logger.setLevel(level)
41
66
def _determine_branch_locations(self, other_services):
42
67
"""Determine the branch locations for the other services.
93
122
# Charms which should use the source config option
94
123
use_source = ['mysql', 'mongodb', 'rabbitmq-server', 'ceph',
95
'ceph-osd', 'ceph-radosgw']
124
'ceph-osd', 'ceph-radosgw', 'ceph-mon']
97
126
# Charms which can not use openstack-origin, ie. many subordinates
98
no_origin = ['cinder-ceph', 'hacluster', 'neutron-openvswitch', 'nrpe']
127
no_origin = ['cinder-ceph', 'hacluster', 'neutron-openvswitch', 'nrpe',
128
'openvswitch-odl', 'neutron-api-odl', 'odl-controller',
100
131
if self.openstack:
101
132
for svc in services:
112
143
def _configure_services(self, configs):
113
144
"""Configure all of the services."""
145
self.log.info('OpenStackAmuletDeployment: configure services')
114
146
for service, config in six.iteritems(configs):
115
147
self.d.configure(service, config)
149
def _auto_wait_for_status(self, message=None, exclude_services=None,
150
include_only=None, timeout=1800):
151
"""Wait for all units to have a specific extended status, except
152
for any defined as excluded. Unless specified via message, any
153
status containing any case of 'ready' will be considered a match.
155
Examples of message usage:
157
Wait for all unit status to CONTAIN any case of 'ready' or 'ok':
158
message = re.compile('.*ready.*|.*ok.*', re.IGNORECASE)
160
Wait for all units to reach this status (exact match):
161
message = re.compile('^Unit is ready and clustered$')
163
Wait for all units to reach any one of these (exact match):
164
message = re.compile('Unit is ready|OK|Ready')
166
Wait for at least one unit to reach this status (exact match):
169
See Amulet's sentry.wait_for_messages() for message usage detail.
170
https://github.com/juju/amulet/blob/master/amulet/sentry.py
172
:param message: Expected status match
173
:param exclude_services: List of juju service names to ignore,
174
not to be used in conjuction with include_only.
175
:param include_only: List of juju service names to exclusively check,
176
not to be used in conjuction with exclude_services.
177
:param timeout: Maximum time in seconds to wait for status match
178
:returns: None. Raises if timeout is hit.
180
self.log.info('Waiting for extended status on units...')
182
all_services = self.d.services.keys()
184
if exclude_services and include_only:
185
raise ValueError('exclude_services can not be used '
189
if isinstance(message, re._pattern_type):
190
match = message.pattern
194
self.log.debug('Custom extended status wait match: '
197
self.log.debug('Default extended status wait match: contains '
198
'READY (case-insensitive)')
199
message = re.compile('.*ready.*', re.IGNORECASE)
202
self.log.debug('Excluding services from extended status match: '
203
'{}'.format(exclude_services))
205
exclude_services = []
208
services = include_only
210
services = list(set(all_services) - set(exclude_services))
212
self.log.debug('Waiting up to {}s for extended status on services: '
213
'{}'.format(timeout, services))
214
service_messages = {service: message for service in services}
215
self.d.sentry.wait_for_messages(service_messages, timeout=timeout)
117
218
def _get_openstack_release(self):
118
219
"""Get openstack release.
125
226
self.precise_havana, self.precise_icehouse,
126
227
self.trusty_icehouse, self.trusty_juno, self.utopic_juno,
127
228
self.trusty_kilo, self.vivid_kilo, self.trusty_liberty,
128
self.wily_liberty) = range(12)
229
self.wily_liberty, self.trusty_mitaka,
230
self.xenial_mitaka) = range(14)
131
233
('precise', None): self.precise_essex,
137
239
('trusty', 'cloud:trusty-juno'): self.trusty_juno,
138
240
('trusty', 'cloud:trusty-kilo'): self.trusty_kilo,
139
241
('trusty', 'cloud:trusty-liberty'): self.trusty_liberty,
242
('trusty', 'cloud:trusty-mitaka'): self.trusty_mitaka,
140
243
('utopic', None): self.utopic_juno,
141
244
('vivid', None): self.vivid_kilo,
142
('wily', None): self.wily_liberty}
245
('wily', None): self.wily_liberty,
246
('xenial', None): self.xenial_mitaka}
143
247
return releases[(self.series, self.openstack)]
145
249
def _get_openstack_release_string(self):