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.
44
69
Determine if the local branch being tested is derived from its
45
70
stable or next (dev) branch, and based on this, use the corresonding
46
71
stable or next branches for the other_services."""
47
base_charms = ['mysql', 'mongodb']
73
self.log.info('OpenStackAmuletDeployment: determine branch locations')
75
# Charms outside the lp:~openstack-charmers namespace
76
base_charms = ['mysql', 'mongodb', 'nrpe']
78
# Force these charms to current series even when using an older series.
79
# ie. Use trusty/nrpe even when series is precise, as the P charm
80
# does not possess the necessary external master config and hooks.
81
force_series_current = ['nrpe']
49
83
if self.series in ['precise', 'trusty']:
50
84
base_series = self.series
52
86
base_series = self.current_next
55
for svc in other_services:
88
for svc in other_services:
89
if svc['name'] in force_series_current:
90
base_series = self.current_next
91
# If a location has been explicitly set, use it
92
if svc.get('location'):
56
95
temp = 'lp:charms/{}/{}'
57
96
svc['location'] = temp.format(base_series,
60
for svc in other_services:
61
99
if svc['name'] in base_charms:
62
100
temp = 'lp:charms/{}/{}'
63
101
svc['location'] = temp.format(base_series,
78
119
services = other_services
79
120
services.append(this_service)
122
# Charms which should use the source config option
80
123
use_source = ['mysql', 'mongodb', 'rabbitmq-server', 'ceph',
81
'ceph-osd', 'ceph-radosgw']
82
# Most OpenStack subordinate charms do not expose an origin option
83
# as that is controlled by the principle.
84
ignore = ['cinder-ceph', 'hacluster', 'neutron-openvswitch']
124
'ceph-osd', 'ceph-radosgw', 'ceph-mon']
126
# Charms which can not use openstack-origin, ie. many subordinates
127
no_origin = ['cinder-ceph', 'hacluster', 'neutron-openvswitch', 'nrpe',
128
'openvswitch-odl', 'neutron-api-odl', 'odl-controller',
129
'cinder-backup', 'nexentaedge-data',
130
'nexentaedge-iscsi-gw', 'nexentaedge-swift-gw',
131
'cinder-nexentaedge', 'nexentaedge-mgmt']
86
133
if self.openstack:
87
134
for svc in services:
88
if svc['name'] not in use_source + ignore:
135
if svc['name'] not in use_source + no_origin:
89
136
config = {'openstack-origin': self.openstack}
90
137
self.d.configure(svc['name'], config)
93
140
for svc in services:
94
if svc['name'] in use_source and svc['name'] not in ignore:
141
if svc['name'] in use_source and svc['name'] not in no_origin:
95
142
config = {'source': self.source}
96
143
self.d.configure(svc['name'], config)
98
145
def _configure_services(self, configs):
99
146
"""Configure all of the services."""
147
self.log.info('OpenStackAmuletDeployment: configure services')
100
148
for service, config in six.iteritems(configs):
101
149
self.d.configure(service, config)
151
def _auto_wait_for_status(self, message=None, exclude_services=None,
152
include_only=None, timeout=1800):
153
"""Wait for all units to have a specific extended status, except
154
for any defined as excluded. Unless specified via message, any
155
status containing any case of 'ready' will be considered a match.
157
Examples of message usage:
159
Wait for all unit status to CONTAIN any case of 'ready' or 'ok':
160
message = re.compile('.*ready.*|.*ok.*', re.IGNORECASE)
162
Wait for all units to reach this status (exact match):
163
message = re.compile('^Unit is ready and clustered$')
165
Wait for all units to reach any one of these (exact match):
166
message = re.compile('Unit is ready|OK|Ready')
168
Wait for at least one unit to reach this status (exact match):
171
See Amulet's sentry.wait_for_messages() for message usage detail.
172
https://github.com/juju/amulet/blob/master/amulet/sentry.py
174
:param message: Expected status match
175
:param exclude_services: List of juju service names to ignore,
176
not to be used in conjuction with include_only.
177
:param include_only: List of juju service names to exclusively check,
178
not to be used in conjuction with exclude_services.
179
:param timeout: Maximum time in seconds to wait for status match
180
:returns: None. Raises if timeout is hit.
182
self.log.info('Waiting for extended status on units...')
184
all_services = self.d.services.keys()
186
if exclude_services and include_only:
187
raise ValueError('exclude_services can not be used '
191
if isinstance(message, re._pattern_type):
192
match = message.pattern
196
self.log.debug('Custom extended status wait match: '
199
self.log.debug('Default extended status wait match: contains '
200
'READY (case-insensitive)')
201
message = re.compile('.*ready.*', re.IGNORECASE)
204
self.log.debug('Excluding services from extended status match: '
205
'{}'.format(exclude_services))
207
exclude_services = []
210
services = include_only
212
services = list(set(all_services) - set(exclude_services))
214
self.log.debug('Waiting up to {}s for extended status on services: '
215
'{}'.format(timeout, services))
216
service_messages = {service: message for service in services}
217
self.d.sentry.wait_for_messages(service_messages, timeout=timeout)
103
220
def _get_openstack_release(self):
104
221
"""Get openstack release.
123
241
('trusty', 'cloud:trusty-juno'): self.trusty_juno,
124
242
('trusty', 'cloud:trusty-kilo'): self.trusty_kilo,
125
243
('trusty', 'cloud:trusty-liberty'): self.trusty_liberty,
244
('trusty', 'cloud:trusty-mitaka'): self.trusty_mitaka,
126
245
('utopic', None): self.utopic_juno,
127
246
('vivid', None): self.vivid_kilo,
128
('wily', None): self.wily_liberty}
247
('wily', None): self.wily_liberty,
248
('xenial', None): self.xenial_mitaka}
129
249
return releases[(self.series, self.openstack)]
131
251
def _get_openstack_release_string(self):