Merge ~aluria/charm-openstack-service-checks/+git/charm-openstack-service-checks:bug/1835433-part2 into ~canonical-bootstack/charm-openstack-service-checks:master

Proposed by Alvaro Uria
Status: Rejected
Rejected by: Haw Loeung
Proposed branch: ~aluria/charm-openstack-service-checks/+git/charm-openstack-service-checks:bug/1835433-part2
Merge into: ~canonical-bootstack/charm-openstack-service-checks:master
Diff against target: 1781 lines (+1184/-267)
14 files modified
actions.yaml (+2/-0)
actions/create-flavor-rally (+15/-0)
config.yaml (+20/-7)
files/plugins/check_rally.py (+53/-79)
files/run_rally.py (+74/-39)
layer.yaml (+0/-7)
lib/lib_openstack_service_checks.py (+217/-100)
reactive/openstack_service_checks.py (+24/-25)
requirements.txt (+1/-0)
templates/extra_config.conf.j2 (+12/-0)
templates/rally.conf.j2 (+756/-0)
tests/unit/conftest.py (+3/-6)
tests/unit/test_lib.py (+6/-4)
wheelhouse.txt (+1/-0)
Reviewer Review Type Date Requested Status
Peter Sabaini (community) Approve
BootStack Reviewers Pending
Review via email: mp+372764@code.launchpad.net

Commit message

Improve support to rally tests

To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
Alvaro Uria (aluria) wrote :

Regarding bug 1837234 (TLS verification failure), it is still happening after this MP. I need to review it. Rally is now unconfined and update-ca-certificates was run, so there is no reason for verifications to fail. Nevertheless, configuring https_cacert with the same value as OS_CACERT doesn't fix the problem. It may be a problem on the version supported in bionic (v0.9.1).

OTOH, Xenial rally apt package is v0.1.1, which doesn't support the same commands as in v0.9.1. So the rally check is only supported in Bionic and on. Furthermore, latest versions of rally use "rally db recreate" instead of "rally-manage db recreate", which may break the charm code in the future.

Other tests around proxying, choosing custom flavor and image IDs, and cleaning the fcbtest snap and created nagiososc user are tested and work.

All tests pass except the functional test for "enable_rally", because "rally verify" uses "install" (v0.1.1) isntead of "create" (v0.9.1).

Revision history for this message
Peter Sabaini (peter-sabaini) wrote :

Hey Alvaro,

some comments inline.

I'm also getting a linter error:

./files/plugins/check_rally.py:19:1: C901 'main' is too complex (11)

Thanks,
peter.

review: Needs Fixing
Revision history for this message
Alvaro Uria (aluria) wrote :

I've tried to address all the suggestions, and have rewritten the charm code to support the new snap that we use (bsrally). Rally behind a proxy now works.

However, Rally TLS support is not there yet because of a snap bug (the charm does support its configuration):
https://forum.snapcraft.io/t/using-the-system-certificate-authorities/10732/10

Nevertheless, I think this code should be merged as the "upgrade-charm" hook will remove the "fcbtest" snap and the new one won't be installed except if "check-rally=true" (which shouldn't be done if we're using a custom CA).

Revision history for this message
Peter Sabaini (peter-sabaini) wrote :

Hey, some minor nits / comments inline, but all in all lgtm

review: Approve
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Failed to merge change (unable to merge source repository due to conflicts), setting status to needs review.

Revision history for this message
James Troup (elmo) wrote :

Setting this back to Work In Progress. Please rebase?

Unmerged commits

e5c15b7... by Alvaro Uria

Fix TLS support on rally check

d49965f... by Alvaro Uria

Fix bugs, Add the create-flavor-rally action.

 * Fix bug on run_rally.py. Confined snaps don't use /tmp but
 /tmp/snap.<snapname>. Temporary files need to prefix this path.
 * Create rally flavor unless it exists, or booting test instances will
 fail (Cirros image can be created by rally, though). This step is
 called when check-rally=true
 * Alternatively, an action has been added to verify if a flavor already
 exists or create it (1 vcpu, 64MB RAM).

8a1e0d1... by Alvaro Uria

Rewrite rally check to use bsrally snap

19fd7fc... by Alvaro Uria

Improve support to rally tests

A new nrpe check has been added, which parses the results of running a
subset of rally tests against an environment. Now rally uses the APT
package and imports a tempest repository from a maintainers fork.
 * 'check-rally' is set to false by default
 * certain OpenStack components tests can be skipped. The parameter has
 been renamed from 'skip-rally' to 'rally-skip-services'
 rally-skip-services="cinder,glance,nova,neutron" would skip all tests
 except Keystone's token issue
 * cronjob can be scheduled via 'rally-cron-schedule' config parameter
 * 'rally-flavor-id': Specify flavor for test VMs. It is important that
 no disk nor ephemeral options are set on the flavor, since tests expect
 volumes to be attached as vdb
 * 'rally-image-id': ID of the image to be used. Otherwise, rally will
 try to discover an image under a name containing "cirros" or "testvm".
 * upgrade-charm supports the transition from the fcbtest snap to the
 rally apt package (check-rally needs to be set to false).

Closes-Bug: 1835433
Closes-Bug: 1841092
Closes-Bug: 1838174
Closes-Bug: 1837234

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/actions.yaml b/actions.yaml
2new file mode 100644
3index 0000000..078ad56
4--- /dev/null
5+++ b/actions.yaml
6@@ -0,0 +1,2 @@
7+create-flavor-rally:
8+ description: Creates the default flavor used by rally to boot test instances
9diff --git a/actions/create-flavor-rally b/actions/create-flavor-rally
10new file mode 100755
11index 0000000..d3ef3f8
12--- /dev/null
13+++ b/actions/create-flavor-rally
14@@ -0,0 +1,15 @@
15+#!/usr/local/sbin/charm-env python3
16+# Create the default flavor used by rally to boot test instances
17+
18+from charmhelpers.core.hookenv import (
19+ action_fail,
20+ action_set,
21+)
22+from lib_openstack_service_checks import OSCHelper
23+
24+helper = OSCHelper()
25+
26+if helper.create_flavor_rally():
27+ action_set({'status': 'Flavor available. check-rally can be enabled.'})
28+else:
29+ action_fail('Unable to create a flavor for rally.')
30diff --git a/config.yaml b/config.yaml
31index 86ade7d..08aa4f1 100644
32--- a/config.yaml
33+++ b/config.yaml
34@@ -9,19 +9,32 @@ options:
35 type: boolean
36 description: |
37 Switch to turn on or off rally checks via the fcbtest snap. By default, rally nrpe check is disabled.
38- skip-rally:
39- default: ""
40- type: string
41- description: |
42- Comma separated list of OpenStack components to not monitor. An empty string means all components will be
43- monitored (up to the number of currently supported components: Cinder, Glance, Nova, Neutron).
44- Sample: skip-rally=cinder
45 rally-cron-schedule:
46 default: "*/15 * * * *"
47 type: string
48 description: |
49 Cron schedule used to run the rally tests. Default value is every 15 minutes.
50 Furthermore, the cronjob is scheduled to time out after 13 minutes (SIGTERM) or 14 minutes (SIGKILL).
51+ rally-flavor-id:
52+ default: ""
53+ type: string
54+ description: |
55+ ID of the flavor to be used on the rally verifier tests (tempestverifier). By default, flavor discovery
56+ under the following specs (1 vcpu, 64MB RAM, 0 extra disk, 10G ephemeral disk) will happen.
57+ The alternative flavor (128MB RAM) will be used when needed (ie. resize tests).
58+ rally-image-id:
59+ default: ""
60+ type: string
61+ description: |
62+ ID of the image to be used on the rally verifier tests (tempestverifier). By default, a cirros image
63+ will be created under a name that contains "cirros" or "testvm" on it.
64+ rally-skip-services:
65+ default: ""
66+ type: string
67+ description: |
68+ Comma separated list of OpenStack components to not monitor. An empty string means all components will be
69+ monitored (up to the number of currently supported components: Cinder, Glance, Nova, Neutron).
70+ Sample: rally-skip-services=cinder
71 os-credentials:
72 default: ""
73 type: string
74diff --git a/files/plugins/check_rally.py b/files/plugins/check_rally.py
75index 0bf2dae..5c6b6f8 100755
76--- a/files/plugins/check_rally.py
77+++ b/files/plugins/check_rally.py
78@@ -1,70 +1,30 @@
79 #!/usr/bin/env python3
80-import collections
81 import os
82-import re
83 import sys
84
85 import json
86
87 # ie. {0} tempest.test.test1 ... success
88 TEMPEST_TEST_RE = r'{\d+} [.\w]+ ... (\w+)'
89-INPUT_FILE = '/home/nagiososc/rally.status'
90-
91-
92-def print_results(results):
93- status_message = collections.defaultdict(lambda: 'UNKNOWN') # 3
94- status_message.update({
95- 'success': 'OK', # 0
96- 'fail': 'CRITICAL', # 2
97- 'skip': 'WARNING', # 1
98- })
99- return_codes = {msg: code
100- for code, msg in enumerate(['OK', 'WARNING', 'CRITICAL', 'UNKNOWN'])}
101- rc = return_codes['OK']
102- summary = collections.defaultdict(lambda: 0)
103-
104- output = []
105- for result in sorted(results, key=lambda result: result['message']):
106- if result.get('message', '').startswith('CRITICAL: '):
107- # Exception caused by run_rally.py, without running 'rally verify'
108- output.append(result['message'])
109- continue
110- elif result.get('message', '').startswith('{'):
111- # only parse json lines - rest, ignore
112- test_re = re.match(TEMPEST_TEST_RE, result.get('message', ''))
113- if not test_re:
114- continue
115-
116- test_status = test_re.groups()[0]
117- output.append('{}: {}'.format(status_message[test_status],
118- result['message']))
119- summary[test_status] += 1
120-
121- # make the first line carry the worst event out of all the parsed ones
122- # ie. all ok except one critical event will return the first line (and return code)
123- # as critical
124- nagios_status = 'OK'
125- for status_msg in ['CRITICAL', 'WARNING', 'UNKNOWN', 'OK']:
126- status = [msg for msg in status_message.keys()
127- if status_message[msg] == status_msg]
128- if not status or status[0] not in summary:
129- continue
130-
131- status = status[0]
132- if summary[status] > 0:
133- rc = return_codes[status_msg]
134- nagios_status = status_msg
135- break
136-
137- if len(summary) > 0:
138- print('{}: '.format(nagios_status)
139- + ', '.join(['{}[{}]'.format(status_msg, summary[status_msg])
140- for status_msg in sorted(summary,
141- key=lambda status: summary[status],
142- reverse=True)
143- ]))
144- print('\n'.join(output))
145- return rc
146+INPUT_FILE = '/home/nagiososc/rally.status.json'
147+
148+STATUS_CODES = {
149+ 'OK': 0,
150+ 'WARNING': 1,
151+ 'CRITICAL': 2,
152+ 'UNKNOWN': 3,
153+}
154+
155+
156+def calculate_criticality(status):
157+ if status.get('failures', 0) > 0:
158+ return 'CRITICAL'
159+ elif status.get('skipped', 0) > 0:
160+ return 'WARNING'
161+ elif status.get('success', 0) > 0:
162+ return 'OK'
163+ else:
164+ return 'UNKNOWN'
165
166
167 def main(results_filename):
168@@ -73,26 +33,40 @@ def main(results_filename):
169 return 3
170
171 results = []
172- with open(results_filename, 'r') as fd:
173- for line in fd.readlines():
174- line = line.strip()
175- if not line:
176- continue
177- elif len(line) > 5 and line[-5:] == '\x1b[00m':
178- line = line[:-5]
179-
180- if not line.startswith('{'):
181- results.append({'message': line})
182- continue
183-
184- try:
185- results.append(json.loads(line))
186- except json.decoder.JSONDecodeError as error:
187- print('UNKNOWN: line[{}], error[{}]'.format(line, str(error)))
188- return 3
189-
190- rc = print_results(results)
191- return rc
192+ try:
193+ with open(results_filename, 'r') as fd:
194+ results = json.load(fd)
195+ except json.decoder.JSONDecodeError as error:
196+ print('UNKNOWN: {}'.format(str(error)))
197+ return STATUS_CODES['UNKNOWN']
198+
199+ # Internal cronjob errors (not returned by rally)
200+ for status in ['CRITICAL', 'UNKNOWN']:
201+ if status in results:
202+ print('{}: {}'.format(status, results[status]))
203+ return STATUS_CODES[status]
204+
205+ if 'verifications' not in results:
206+ print('UNKNOWN: {} is not parsable, missing "verifications" key'.format(results_filename))
207+ return STATUS_CODES['UNKNOWN']
208+
209+ verif_id = list(results['verifications'])[0]
210+ verif_summary = results['verifications'].get(verif_id, {})
211+
212+ status = {key: value for key, value in verif_summary.items()
213+ if key in ['skipped', 'success', 'failures', 'tests_duration']}
214+ status['NAGIOS_MSG'] = calculate_criticality(status)
215+
216+ testresults = []
217+ for testname in results['tests'].keys():
218+ verif_id = list(results['tests'][testname]['by_verification'].keys())[0]
219+ verif_summary = results['tests'][testname]['by_verification'].get(verif_id, {'status': 'unknown'})
220+ testresults.append('{}... {}'.format(testname, verif_summary['status']))
221+
222+ print('{NAGIOS_MSG}: success[{success}], failures[{failures}], skipped[{skipped}]...'
223+ ' tests_duration[{tests_duration}]'.format(**status))
224+ print('\n'.join(testresults))
225+ return STATUS_CODES[status['NAGIOS_MSG']]
226
227
228 if __name__ == '__main__':
229diff --git a/files/run_rally.py b/files/run_rally.py
230index c0e5655..5acbf55 100755
231--- a/files/run_rally.py
232+++ b/files/run_rally.py
233@@ -1,29 +1,18 @@
234-#!/usr/bin/env python3
235+#!/usr/local/sbin/charm-env python3
236 import datetime
237 import json
238 import os
239 import subprocess
240-import sys
241
242+from pid import PidFile, PidFileAlreadyLockedError
243 import shutil
244 import tempfile
245
246-OUTPUT_FILE = '/home/nagiososc/rally.status'
247-HISTORY_FOLDER = '/home/nagiososc/rallystatuses'
248-
249-
250-def get_backup_output_filename():
251- if not os.path.isdir(HISTORY_FOLDER):
252- os.mkdir(HISTORY_FOLDER, mode=0o755)
253-
254- weekday = datetime.datetime.today().weekday()
255- i = 0
256- statusfile = os.path.join(HISTORY_FOLDER, 'rally.status.{}.{}'.format(weekday, i))
257- while os.path.exists(statusfile):
258- i += 1
259- statusfile = os.path.join(HISTORY_FOLDER, 'rally.status.{}.{}'.format(weekday, i))
260-
261- return statusfile
262+HOME_DIR = '/home/nagiososc'
263+RALLY_CONFIGFILE = os.path.join(HOME_DIR, 'snap', 'bsrally', 'common', 'rally.conf')
264+TESTS_FILE = os.path.join(HOME_DIR, 'ostests.txt')
265+OUTPUT_FILE = os.path.join(HOME_DIR, 'rally.status.json')
266+HISTORY_FOLDER = os.path.join(HOME_DIR, 'rallystatuses')
267
268
269 def _load_envvars(novarc='/var/lib/nagios/nagios.novarc'):
270@@ -41,41 +30,87 @@ def _load_envvars(novarc='/var/lib/nagios/nagios.novarc'):
271 i += 1
272
273 os.environ['SHELL'] = '/bin/bash'
274- os.environ['HOME'] = '/home/nagiososc'
275+ os.environ['HOME'] = HOME_DIR
276 os.environ['PATH'] = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin'
277
278 return i >= 3
279
280
281-def main(testfile='/home/nagiososc/ostests.txt'):
282- if not _load_envvars():
283- print('UNKNOWN: could not load OS_ envvars')
284- sys.exit(3)
285+def get_backup_output_filename():
286+ if not os.path.isdir(HISTORY_FOLDER):
287+ os.mkdir(HISTORY_FOLDER, mode=0o755)
288+
289+ weekday = datetime.datetime.today().weekday()
290+ i = 0
291+ statusfile = os.path.join(HISTORY_FOLDER, 'rally.status.{}.{}'.format(weekday, i))
292+ while os.path.exists(statusfile):
293+ i += 1
294+ statusfile = os.path.join(HISTORY_FOLDER, 'rally.status.{}.{}'.format(weekday, i))
295+
296+ return statusfile
297+
298+
299+def log_and_backup(filename, message=None):
300+ if message:
301+ with open(filename, 'w') as fd:
302+ fd.write(message)
303+
304+ # Snaps generate "/tmp/filename" in a cage (see prefix) that we check
305+ # If the rally command is replaced by an APT pkg, no prefix will exist
306+ tmp_filename = None
307+ for prefix in ['', '/tmp/snap.bsrally']:
308+ searched_file = '{}{}'.format(prefix, filename)
309+ if os.path.exists(searched_file):
310+ tmp_filename = searched_file
311+ break
312
313+ # Unlikely, but no action would be taken if tempfile does not exist
314+ if tmp_filename is None:
315+ return
316+
317+ shutil.copy2(tmp_filename, OUTPUT_FILE)
318+ shutil.copy2(OUTPUT_FILE, get_backup_output_filename())
319+ os.unlink(tmp_filename)
320+
321+
322+def run_rally(testfile=TESTS_FILE):
323 tempoutputfile = tempfile.mktemp()
324- cmd1 = ['fcbtest.rally', 'deployment', 'use', 'snap_generated']
325- cmd2 = ['fcbtest.rally', '--use-json', 'verify', 'start', '--load-list', testfile, '--detailed']
326+
327+ if not _load_envvars():
328+ msg = {'UNKNOWN': 'could not load OS_ envvars'}
329+ log_and_backup(tempoutputfile, json.dumps(msg))
330+ return
331+
332+ rally_cmd = ['bsrally.rally', '--config-file', RALLY_CONFIGFILE]
333+ cmd1 = rally_cmd + ['deployment', 'use', 'charm_generated']
334+ cmd2 = rally_cmd + ['verify', 'start', '--load-list', testfile]
335+ cmd3 = rally_cmd + ['verify', 'report', '--to', tempoutputfile]
336 try:
337 subprocess.check_output(cmd1, stderr=subprocess.STDOUT)
338- output = subprocess.check_output(cmd2, stderr=subprocess.STDOUT)
339- with open(tempoutputfile, 'w') as fd:
340- fd.write(output.decode('utf-8'))
341- shutil.copy2(tempoutputfile, OUTPUT_FILE)
342- shutil.copy2(OUTPUT_FILE, get_backup_output_filename())
343- os.unlink(tempoutputfile)
344+ subprocess.check_output(cmd2, stderr=subprocess.STDOUT)
345+ subprocess.check_output(cmd3, stderr=subprocess.STDOUT)
346+ # File is moved from the temporary location - no further msg is recorded
347+ log_and_backup(tempoutputfile)
348 except subprocess.CalledProcessError as error:
349 msg = {
350- 'message': 'CRITICAL: fcbtest.rally command failed. {} - {}'.format(str(error), str(error.stdout)),
351+ 'CRITICAL': 'rally command failed. {} - {}'.format(str(error),
352+ str(error.stdout)),
353 }
354- with open(OUTPUT_FILE, 'w') as fd:
355- fd.write('{}\n'.format(json.dumps(msg)))
356+ log_and_backup(tempoutputfile, json.dumps(msg))
357
358 except IOError as error:
359- msg = {
360- 'message': 'CRITICAL: IOError. {}'.format(str(error)),
361- }
362- with open(OUTPUT_FILE, 'a') as fd:
363- fd.write('{}\n'.format(json.dumps(msg)))
364+ msg = {'CRITICAL': 'IOError. {}'.format(str(error))}
365+ log_and_backup(tempoutputfile, json.dumps(msg))
366+
367+
368+def main():
369+ try:
370+ with PidFile(pidname='rally', piddir='/var/lock'):
371+ run_rally()
372+ except PidFileAlreadyLockedError as error:
373+ tempoutputfile = tempfile.mktemp()
374+ msg = {'CRITICAL': 'Lock error: {}'.format(str(error))}
375+ log_and_backup(tempoutputfile, json.dumps(msg))
376
377
378 if __name__ == '__main__':
379diff --git a/layer.yaml b/layer.yaml
380index d8a972a..3741f72 100644
381--- a/layer.yaml
382+++ b/layer.yaml
383@@ -19,10 +19,3 @@ options:
384 - python3-keystoneclient
385 - python3-openstackclient
386 - python-openstackclient
387- snap:
388- fcbtest:
389- channel: stable
390- devmode: false
391- jailmode: false
392- dangerous: false
393- classic: false
394diff --git a/lib/lib_openstack_service_checks.py b/lib/lib_openstack_service_checks.py
395index fd12f51..f05a191 100644
396--- a/lib/lib_openstack_service_checks.py
397+++ b/lib/lib_openstack_service_checks.py
398@@ -1,20 +1,18 @@
399-import collections
400-import glob
401 import os
402 import pwd
403 import re
404 import subprocess
405 from urllib.parse import urlparse
406
407-import configparser
408-
409 from charmhelpers.core.templating import render
410 from charmhelpers.contrib.openstack.utils import config_flags_parser
411 from charmhelpers.core import hookenv, host, unitdata
412 from charmhelpers.contrib.charmsupport.nrpe import NRPE
413-from charms.reactive import any_file_changed
414+from charms.layer import snap
415+
416 import keystoneauth1
417 from keystoneclient import session
418+import os_client_config
419
420
421 class OSCCredentialsError(Exception):
422@@ -49,6 +47,30 @@ class OSCHelper():
423 return '/usr/local/bin/'
424
425 @property
426+ def rallyuser(self):
427+ return 'nagiososc'
428+
429+ @property
430+ def rally_home(self):
431+ return os.path.join('/home', self.rallyuser)
432+
433+ @property
434+ def rally_snap_common(self):
435+ return os.path.join(self.rally_home, 'snap', 'bsrally', 'common')
436+
437+ @property
438+ def rallydb(self):
439+ return os.path.join(self.rally_snap_common, 'rally.db')
440+
441+ @property
442+ def rally_extra_configfile(self):
443+ return os.path.join(self.rally_snap_common, 'extra_config.conf')
444+
445+ @property
446+ def rally_configfile(self):
447+ return os.path.join(self.rally_snap_common, 'rally.conf')
448+
449+ @property
450 def rally_cron_file(self):
451 return '/etc/cron.d/osc_rally'
452
453@@ -57,16 +79,9 @@ class OSCHelper():
454 return self.charm_config['check-rally']
455
456 @property
457- def skipped_rally_checks(self):
458- skipped_os_components = self.charm_config['skip-rally'].strip()
459- if not skipped_os_components:
460- return []
461-
462- # filter skip-rally input to match available (or supported) components that
463- # should be disabled
464- available_os_components = 'cinder glance nova neutron'.split()
465- return [comp.strip().lower() for comp in skipped_os_components.split(',')
466- if comp.strip().lower() in available_os_components]
467+ def is_rally_installed(self):
468+ kv = unitdata.kv()
469+ return kv.get('rallyinstalled', False)
470
471 @property
472 def rally_cron_schedule(self):
473@@ -76,6 +91,31 @@ class OSCHelper():
474 else:
475 return schedule.strip()
476
477+ @property
478+ def rally_image_id(self):
479+ return self.charm_config['rally-image-id']
480+
481+ @property
482+ def rally_flavor_id(self):
483+ return self.charm_config['rally-flavor-id']
484+
485+ @property
486+ def rally_available_os_components(self):
487+ return ['cinder', 'glance', 'nova', 'neutron']
488+
489+ @property
490+ def rally_skipped_checks(self):
491+ # Expected comma-separated value
492+ skipped_os_components = self.charm_config['rally-skip-services'].strip()
493+ if not skipped_os_components:
494+ return set()
495+
496+ # Filter rally-skip-services input to match available (and supported) components
497+ # that should be disabled
498+ return set([component.strip().lower()
499+ for component in skipped_os_components.split(',')
500+ if component.strip().lower() in self.rally_available_os_components])
501+
502 def get_os_credentials(self):
503 ident_creds = config_flags_parser(self.charm_config['os-credentials'])
504 if not ident_creds.get('auth_url'):
505@@ -361,6 +401,10 @@ class OSCHelper():
506 os.environ[key] = value
507 i += 1
508
509+ # Helps clone repo from github (tempest verifier)
510+ proxy_settings = hookenv.env_proxy_settings()
511+ os.environ.update({key: value for key, value in proxy_settings.items()})
512+
513 return i >= 3
514
515 def _run_as(self, user, user_cmd):
516@@ -383,107 +427,136 @@ class OSCHelper():
517 return True
518
519 except KeyError as error:
520- hookenv.log('_run_as - user does not exist => {}'.format(str(error)))
521+ hookenv.log('_run_as - user does not exist => {}'.format(str(error)),
522+ hookenv.ERROR)
523 return False
524 except subprocess.CalledProcessError as error:
525- hookenv.log('_run_as - cmd failed => {}'.format(str(error)))
526+ hookenv.log('_run_as - cmd failed => {}'.format(str(error)),
527+ hookenv.ERROR)
528 if error.stderr:
529- hookenv.log('_run_as stderr => {}'.format(error.stderr))
530+ hookenv.log('_run_as stderr => {}'.format(error.stderr),
531+ hookenv.ERROR)
532 if error.stdout:
533- hookenv.log('_run_as stderr => {}'.format(error.stdout))
534+ hookenv.log('_run_as stderr => {}'.format(error.stdout),
535+ hookenv.ERROR)
536 return False
537
538- @property
539- def _rallyuser(self):
540- return 'nagiososc'
541+ def add_nagios_to_rally(self, user, group):
542+ host.add_user_to_group(user, group)
543+ host.service_restart('nagios-nrpe-server')
544+
545+ def regenerate_extra_config(self):
546+ context = {
547+ 'image_ref': self.rally_image_id,
548+ 'flavor_ref': self.rally_flavor_id,
549+ }
550+ render(source='extra_config.conf.j2', target=self.rally_extra_configfile,
551+ context=context, perms=0o640, owner=self.rallyuser, group=self.rallyuser)
552+
553+ def regenerate_rally_config(self):
554+ # Render rally config file
555+ render(source='rally.conf.j2', target=self.rally_configfile,
556+ context={}, perms=0o640, owner=self.rallyuser, group=self.rallyuser)
557+
558+ def regenerate_tempest_conf(self):
559+ cmd = [
560+ 'bsrally.rally', '--config-file', self.rally_configfile,
561+ 'verify', 'configure-verifier',
562+ '--extend', self.rally_extra_configfile,
563+ '--reconfig',
564+ ]
565+ self.regenerate_extra_config()
566+ installed = self._run_as(self.rallyuser, cmd)
567+ return installed
568+
569+ def propagate_rally_cacert(self, cacert_filename):
570+ """Copies trusted_ssl_ca to rallyuser home dir (snap common folder)
571+ """
572+ if cacert_filename and os.path.exists(cacert_filename):
573+ host.rsync(cacert_filename, self.rally_snap_common)
574+ new_cacert_filename = os.path.join(
575+ self.rally_snap_common, os.path.basename(cacert_filename))
576+ os.chmod(new_cacert_filename, 0o644)
577+ os.environ['OS_CACERT'] = new_cacert_filename
578
579 def install_rally(self):
580+ # Persistent value to avoid running this process more than needed
581 kv = unitdata.kv()
582 if kv.get('rallyinstalled', False):
583 return True
584
585+ # Load OpenStack env vars (OS_*)
586 if not self._load_envvars:
587 hookenv.log('install_rally - could not load nagios.novarc')
588 return False
589
590- user = self._rallyuser
591- host.adduser(user)
592- host.mkdir(os.path.join('/home', user), owner=user, group=user, perms=0o755, force=False)
593-
594- for tool in ['rally', 'tempest']:
595- toolname = 'fcbtest.{}init'.format(tool)
596- installed = self._run_as(user, [toolname])
597+ # Create user that will run rally
598+ user = self.rallyuser
599+ user_pwd = host.adduser(user)
600+ host.mkdir(self.rally_home, owner=user, group=user, perms=0o755, force=False)
601+
602+ # rally.conf and tempest extra configs when the new verifier is created
603+ self.regenerate_rally_config()
604+ self.regenerate_extra_config()
605+
606+ # touch /path/to/rally.db so we can recreate it
607+ # (otherwise, rally db recreate will fail)
608+ if not os.path.isfile(self.rallydb):
609+ open(self.rallydb, 'a').close()
610+ os.chown(self.rallydb, user_pwd.pw_uid, user_pwd.pw_gid)
611+
612+ # Make 'snap' directory owned by the new user
613+ dir = self.rally_home
614+ for subdir in ['snap', 'bsrally']:
615+ dir = os.path.join(dir, subdir)
616+ os.chown(dir, user_pwd.pw_uid, user_pwd.pw_gid)
617+
618+ # OS_CACERT needs to point to the user home dir (snap is confined)
619+ os_cacert = os.getenv('OS_CACERT', False)
620+ self.propagate_rally_cacert(os_cacert)
621+
622+ # Initialize Rally
623+ rally_cmd = 'bsrally.rally --config-file {}'.format(self.rally_configfile)
624+ cmds = [
625+ '{} db recreate'.format(rally_cmd),
626+ '{} deployment create --fromenv --name charm_generated'.format(rally_cmd),
627+ ('{} verify create-verifier --type tempest'
628+ ' --source /snap/bsrally/current/tempest'
629+ ' --system-wide --name tempestverifier'.format(rally_cmd)
630+ ),
631+ '{} verify configure-verifier --extend {} --reconfig'.format(
632+ rally_cmd, self.rally_extra_configfile),
633+ ]
634+
635+ for cmd in cmds:
636+ installed = self._run_as(user, cmd.split())
637 if not installed:
638- hookenv.log('install_rally - could not initialize {}'.format(tool))
639+ hookenv.log('install_rally: could not initialize... {}'.format(cmd))
640 return False
641
642+ # By default, snap's rally tempdir is uid=0, chmod=700,
643+ # but cronjobs run as rallyuser
644+ tmpdir = '/tmp/snap.bsrally'
645+ if os.path.isdir(tmpdir):
646+ os.chmod(tmpdir, 0o755)
647+
648 kv.set('rallyinstalled', True)
649 return True
650
651- def _regenerate_tempest_conf(self, tempestfile):
652- config = configparser.ConfigParser()
653- config.read(tempestfile)
654- for section in config.keys():
655- for key, value in config[section].items():
656- try:
657- if section != 'DEFAULT' and key in config['DEFAULT'].keys():
658- # avoid copying the DEFAULT config options to the rest of sections
659- continue
660- except KeyError:
661- # DEFAULT section does not exist
662- pass
663-
664- # Enable Cinder, which is a default OpenStack service
665- if section == 'service_available' and key == 'cinder':
666- config[section][key] = 'True'
667-
668- with open(tempestfile, 'w') as fd:
669- config.write(fd)
670-
671- def reconfigure_tempest(self):
672- """Expects an external network already configured, and enables cinder tests
673+ def _get_rally_checks_context(self):
674+ """Returns dict with enabled/disabled OpenStack services
675
676- Sample:
677- RALLY_VERIFIER=7b9d06ef-e651-4da3-a56b-ecac67c595c5
678- RALLY_VERIFICATION=4a730963-083f-4e1e-8c55-f2b4b9c9c0ac
679- RALLY_DEPLOYMENT=a75657c6-9eea-4f00-9117-2580fe056a80
680- RALLY_ENV=a75657c6-9eea-4f00-9117-2580fe056a80
681+ Used to render ostests.txt (list of tempest tests to be run)
682 """
683- RALLY_CONF = ['/home', self._rallyuser, 'snap', 'fcbtest', 'current', '.rally']
684- rally_globalconfig = os.path.join(*RALLY_CONF, 'globals')
685- if not os.path.isfile(rally_globalconfig):
686- return False
687-
688- uuids = collections.defaultdict(lambda: '*')
689- with open(rally_globalconfig, 'r') as fd:
690- for line in fd.readlines():
691- key, value = line.strip().split('=')
692- if key in ['RALLY_VERIFIER', 'RALLY_DEPLOYMENT']:
693- uuids[key] = value
694-
695- tempest_path = os.path.join(*RALLY_CONF, 'verification',
696- 'verifier-{RALLY_VERIFIER}'.format(**uuids),
697- 'for-deployment-{RALLY_DEPLOYMENT}'.format(**uuids),
698- 'tempest.conf')
699- tempestfile = glob.glob(tempest_path)
700- if len(tempestfile) == 0:
701- # No tempest.conf file generated, yet
702- return False
703-
704- if not any_file_changed([tempestfile[0]]):
705- return False
706-
707- self._regenerate_tempest_conf(tempestfile[0])
708- return True
709-
710- def _get_rally_checks_context(self):
711- os_components_skip_list = self.skipped_rally_checks
712+ os_components_skip_list = self.rally_skipped_checks
713 ctxt = {}
714- for comp in 'cinder glance nova neutron'.split():
715- ctxt.update({comp: comp not in os_components_skip_list})
716+ ctxt = {component: component not in os_components_skip_list
717+ for component in self.rally_available_os_components}
718 return ctxt
719
720 def update_rally_checkfiles(self):
721+ """Called on upgrade-charm or on any config change
722+ """
723 if not self.is_rally_enabled:
724 return
725
726@@ -491,28 +564,39 @@ class OSCHelper():
727 rally_script = os.path.join(hookenv.charm_dir(), 'files', 'run_rally.py')
728 host.rsync(rally_script, self.scripts_dir, options=['--executability'])
729
730- ostestsfile = os.path.join('/home', self._rallyuser, 'ostests.txt')
731+ ostestsfile = os.path.join(self.rally_home, 'ostests.txt')
732 render(source='ostests.txt.j2', target=ostestsfile,
733 context=self._get_rally_checks_context(),
734- owner=self._rallyuser, group=self._rallyuser)
735+ owner=self.rallyuser, group=self.rallyuser)
736+
737+ cron_script = os.path.join(self.scripts_dir, 'run_rally.sh')
738+ cmd = os.path.join(self.scripts_dir, 'run_rally.py')
739
740+ # Bash script has ENVVARS + python script call
741 proxy_settings = hookenv.env_proxy_settings()
742+ content = ''
743 if proxy_settings:
744- content = '\n'.join(['{}={}'.format(proxy_var, proxy_var_val)
745+ content = '\n'.join(['export {}={}'.format(proxy_var, proxy_var_val)
746 for proxy_var, proxy_var_val in proxy_settings.items()])
747- else:
748- content = ''
749
750+ content += '\n{}'.format(cmd)
751+ with open(cron_script, 'w') as fd:
752+ fd.write('#!/bin/bash\n\n{}\n'.format(content))
753+ os.chmod(cron_script, mode=0o755)
754+
755+ # Cronjob runs the Bash script
756 context = {
757 'schedule': self.rally_cron_schedule,
758- 'user': self._rallyuser,
759- 'cmd': os.path.join(self.scripts_dir, 'run_rally.py'),
760+ 'user': self.rallyuser,
761+ 'cmd': cron_script,
762 }
763- content += '\n#\n{schedule} {user} timeout -k 840s -s SIGTERM 780s {cmd}'.format(**context)
764+ cron_content = '{schedule} {user} timeout -k 840s -s SIGTERM 780s {cmd}'.format(**context)
765 with open(self.rally_cron_file, 'w') as fd:
766- fd.write('# Juju generated - DO NOT EDIT\n{}\n\n'.format(content))
767+ fd.write('# Juju generated - DO NOT EDIT\n{}\n\n'.format(cron_content))
768
769 def configure_rally_check(self):
770+ """Add the nrpe check if check-rally=true
771+ """
772 kv = unitdata.kv()
773 if kv.get('rallyconfigured', False):
774 return
775@@ -528,9 +612,10 @@ class OSCHelper():
776 kv.set('rallyconfigured', True)
777
778 def remove_rally_check(self):
779- filename = self.rally_cron_file
780- if os.path.exists(filename):
781- os.unlink(filename)
782+ """Called from deploy_rally ir check-rally=false
783+ """
784+ if os.path.exists(self.rally_cron_file):
785+ os.unlink(self.rally_cron_file)
786
787 if os.path.exists('/etc/nagios/nrpe.d/check_rally.cfg'):
788 nrpe = NRPE()
789@@ -538,12 +623,44 @@ class OSCHelper():
790 nrpe.write()
791
792 def deploy_rally(self):
793+ """Installs rally or removes the nrpe check
794+ """
795 if self.is_rally_enabled:
796+ snap.install('bsrally')
797 installed = self.install_rally()
798 if not installed:
799 return False
800 self.configure_rally_check()
801+ self.create_flavor_rally()
802 else:
803 self.remove_rally_check()
804 unitdata.kv().set('rallyconfigured', False)
805 return True
806+
807+ def create_flavor_rally(self):
808+ """Searches for the default rally flavor (1 vcpu, 64MB RAM) or creates it
809+ """
810+ if not self._load_envvars:
811+ return False
812+ nova = os_client_config.make_client('compute', cloud='envvars')
813+ ref = {'OS-FLV-EXT-DATA:ephemeral': 0,
814+ 'disk': 0, 'ram': 64, 'vcpus': 1,
815+ 'os-flavor-access:is_public': True,
816+ }
817+ flavor_exists = False
818+ for flavor in nova.flavors.list():
819+ flavor_exists = all(getattr(flavor, attr) == ref[attr] for attr in ref.keys())
820+ if flavor_exists:
821+ break
822+
823+ if flavor_exists:
824+ hookenv.log('default rally flavor already exists.'
825+ ' No flavor needs to be created.')
826+ else:
827+ ref.update({'name': 'rally.tiny', 'ephemeral': 0, 'is_public': True})
828+ del ref['OS-FLV-EXT-DATA:ephemeral']
829+ del ref['os-flavor-access:is_public']
830+ nova.flavors.create(**ref)
831+ hookenv.log('flavor created to boot test instances via rally')
832+
833+ return True
834diff --git a/reactive/openstack_service_checks.py b/reactive/openstack_service_checks.py
835index b96269d..2ac4baa 100644
836--- a/reactive/openstack_service_checks.py
837+++ b/reactive/openstack_service_checks.py
838@@ -19,7 +19,8 @@ import base64
839 import subprocess
840
841 from charmhelpers.core import hookenv, host, unitdata
842-from charms.reactive import any_flags_set, clear_flag, is_flag_set, set_flag, when, when_not
843+from charms.reactive import any_flags_set, clear_flag, set_flag, when, when_not
844+from charms.layer import snap
845
846 from lib_openstack_service_checks import (
847 OSCHelper,
848@@ -31,8 +32,21 @@ CERT_FILE = '/usr/local/share/ca-certificates/openstack-service-checks.crt'
849 helper = OSCHelper()
850
851
852+@when('identity-credentials.available')
853+@when('nrpe-external-master.available')
854 @when('config.changed')
855 def config_changed():
856+ # Update Rally scripts and tempest config, if applicable
857+ if helper.is_rally_enabled and helper.is_rally_installed:
858+ if any_flags_set('config.changed.rally-skip-services',
859+ 'config.changed.rally-cron-schedule'):
860+ helper.update_rally_checkfiles()
861+
862+ if any_flags_set('config.changed.rally-flavor-id',
863+ 'config.changed.rally-image-id'):
864+ helper.regenerate_tempest_conf()
865+
866+ # Update Keystone related config
867 clear_flag('openstack-service-checks.configured')
868
869
870@@ -162,6 +176,9 @@ def render_config():
871 with open(CERT_FILE, 'w') as fd:
872 fd.write(cert_content)
873 subprocess.call(['/usr/sbin/update-ca-certificates'])
874+ creds['cacert'] = CERT_FILE
875+ if helper.is_rally_enabled and helper.is_rally_installed:
876+ helper.propagate_rally_cacert(CERT_FILE)
877
878 except subprocess.CalledProcessError as error:
879 block_tls_failure(error)
880@@ -220,27 +237,6 @@ def do_restart():
881 set_flag('openstack-service-checks.started')
882
883
884-@when('nrpe-external-master.available')
885-def do_reconfigure_nrpe():
886- os_credentials_flag = 'config.changed.os-credentials'
887- flags = ['config.changed.check_{}_urls'.format(interface) for interface in ['admin', 'internal', 'public']]
888- flags.extend(os_credentials_flag)
889-
890- if is_flag_set('config.changed'):
891- clear_flag('openstack-service-checks.configured')
892-
893- if any_flags_set(*flags):
894- if is_flag_set(os_credentials_flag):
895- clear_flag('openstack-service-checks.configured')
896- clear_flag('openstack-service-checks.endpoints.configured')
897-
898- if helper.is_rally_enabled:
899- helper.reconfigure_tempest()
900-
901- if is_flag_set('config.changed.skip-rally'):
902- helper.update_rally_checkfiles()
903-
904-
905 @when_not('nrpe-external-master.available')
906 def missing_nrpe():
907 """Avoid a user action to be missed or overwritten by another hook
908@@ -274,9 +270,12 @@ def parse_hooks():
909 if old_creds:
910 kv.unset('keystone-relation-creds')
911
912+ # Remove the rally snap (deprecated)
913+ snapname = 'fcbtest'
914+ if snap.is_installed(snapname):
915+ snap.remove(snapname)
916+ helper.deploy_rally()
917+
918 # update rally check files and plugins, which may have changed
919 helper.update_plugins()
920 helper.update_rally_checkfiles()
921-
922- # render configs again
923- do_reconfigure_nrpe()
924diff --git a/requirements.txt b/requirements.txt
925index 28ecaca..29c95c2 100644
926--- a/requirements.txt
927+++ b/requirements.txt
928@@ -1,2 +1,3 @@
929 flake8
930+os-client-config
931 pytest
932diff --git a/templates/extra_config.conf.j2 b/templates/extra_config.conf.j2
933new file mode 100644
934index 0000000..9f15bc1
935--- /dev/null
936+++ b/templates/extra_config.conf.j2
937@@ -0,0 +1,12 @@
938+{% if image_ref or flavor_ref -%}
939+[compute]
940+{%- endif %}
941+{%- if image_ref %}
942+image_ref = {{image_ref}}
943+{%- endif %}
944+{%- if flavor_ref %}
945+flavor_ref = {{flavor_ref}}
946+{%- endif %}
947+
948+[volume]
949+catalog_type = volumev3
950diff --git a/templates/rally.conf.j2 b/templates/rally.conf.j2
951new file mode 100644
952index 0000000..aa8b07a
953--- /dev/null
954+++ b/templates/rally.conf.j2
955@@ -0,0 +1,756 @@
956+[DEFAULT]
957+
958+#
959+# From oslo.log
960+#
961+
962+# If set to true, the logging level will be set to DEBUG instead of
963+# the default INFO level. (boolean value)
964+# Note: This option can be changed without restarting.
965+#debug = false
966+
967+# DEPRECATED: If set to false, the logging level will be set to
968+# WARNING instead of the default INFO level. (boolean value)
969+# This option is deprecated for removal.
970+# Its value may be silently ignored in the future.
971+#verbose = true
972+
973+# The name of a logging configuration file. This file is appended to
974+# any existing logging configuration files. For details about logging
975+# configuration files, see the Python logging module documentation.
976+# Note that when logging configuration files are used then all logging
977+# configuration is set in the configuration file and other logging
978+# configuration options are ignored (for example,
979+# logging_context_format_string). (string value)
980+# Note: This option can be changed without restarting.
981+# Deprecated group/name - [DEFAULT]/log_config
982+#log_config_append = <None>
983+
984+# Defines the format string for %%(asctime)s in log records. Default:
985+# %(default)s . This option is ignored if log_config_append is set.
986+# (string value)
987+#log_date_format = %Y-%m-%d %H:%M:%S
988+
989+# (Optional) Name of log file to send logging output to. If no default
990+# is set, logging will go to stderr as defined by use_stderr. This
991+# option is ignored if log_config_append is set. (string value)
992+# Deprecated group/name - [DEFAULT]/logfile
993+#log_file = <None>
994+log_file = rally.log
995+
996+# (Optional) The base directory used for relative log_file paths.
997+# This option is ignored if log_config_append is set. (string value)
998+# Deprecated group/name - [DEFAULT]/logdir
999+#log_dir = <None>
1000+log_dir = /home/nagiososc
1001+
1002+# Uses logging handler designed to watch file system. When log file is
1003+# moved or removed this handler will open a new log file with
1004+# specified path instantaneously. It makes sense only if log_file
1005+# option is specified and Linux platform is used. This option is
1006+# ignored if log_config_append is set. (boolean value)
1007+#watch_log_file = false
1008+
1009+# Use syslog for logging. Existing syslog format is DEPRECATED and
1010+# will be changed later to honor RFC5424. This option is ignored if
1011+# log_config_append is set. (boolean value)
1012+#use_syslog = false
1013+
1014+# Syslog facility to receive log lines. This option is ignored if
1015+# log_config_append is set. (string value)
1016+#syslog_log_facility = LOG_USER
1017+
1018+# Log output to standard error. This option is ignored if
1019+# log_config_append is set. (boolean value)
1020+#use_stderr = true
1021+
1022+# Format string to use for log messages with context. (string value)
1023+#logging_context_format_string = %(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s
1024+
1025+# Format string to use for log messages when context is undefined.
1026+# (string value)
1027+#logging_default_format_string = %(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s
1028+
1029+# Additional data to append to log message when logging level for the
1030+# message is DEBUG. (string value)
1031+#logging_debug_format_suffix = %(funcName)s %(pathname)s:%(lineno)d
1032+
1033+# Prefix each line of exception output with this format. (string
1034+# value)
1035+#logging_exception_prefix = %(asctime)s.%(msecs)03d %(process)d ERROR %(name)s %(instance)s
1036+
1037+# Defines the format string for %(user_identity)s that is used in
1038+# logging_context_format_string. (string value)
1039+#logging_user_identity_format = %(user)s %(tenant)s %(domain)s %(user_domain)s %(project_domain)s
1040+
1041+# List of package logging levels in logger=LEVEL pairs. This option is
1042+# ignored if log_config_append is set. (list value)
1043+#default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,requests.packages.urllib3.util.retry=WARN,urllib3.util.retry=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN,taskflow=WARN,keystoneauth=WARN,oslo.cache=INFO,dogpile.core.dogpile=INFO
1044+
1045+# Enables or disables publication of error events. (boolean value)
1046+#publish_errors = false
1047+
1048+# The format for an instance that is passed with the log message.
1049+# (string value)
1050+#instance_format = "[instance: %(uuid)s] "
1051+
1052+# The format for an instance UUID that is passed with the log message.
1053+# (string value)
1054+#instance_uuid_format = "[instance: %(uuid)s] "
1055+
1056+# Enables or disables fatal status of deprecations. (boolean value)
1057+#fatal_deprecations = false
1058+
1059+#
1060+# From rally
1061+#
1062+
1063+# Print debugging output only for Rally. Off-site components stay
1064+# quiet. (boolean value)
1065+#rally_debug = false
1066+
1067+# HTTP timeout for any of OpenStack service in seconds (floating point
1068+# value)
1069+#openstack_client_http_timeout = 180.0
1070+
1071+# Size of raw result chunk in iterations (integer value)
1072+# Minimum value: 1
1073+#raw_result_chunk_size = 1000
1074+
1075+
1076+[benchmark]
1077+
1078+#
1079+# From rally
1080+#
1081+
1082+# Time to sleep after creating a resource before polling for it status
1083+# (floating point value)
1084+#cinder_volume_create_prepoll_delay = 2.0
1085+
1086+# Time to wait for cinder volume to be created. (floating point value)
1087+#cinder_volume_create_timeout = 600.0
1088+
1089+# Interval between checks when waiting for volume creation. (floating
1090+# point value)
1091+#cinder_volume_create_poll_interval = 2.0
1092+
1093+# Time to wait for cinder volume to be deleted. (floating point value)
1094+#cinder_volume_delete_timeout = 600.0
1095+
1096+# Interval between checks when waiting for volume deletion. (floating
1097+# point value)
1098+#cinder_volume_delete_poll_interval = 2.0
1099+
1100+# Time to wait for cinder backup to be restored. (floating point
1101+# value)
1102+#cinder_backup_restore_timeout = 600.0
1103+
1104+# Interval between checks when waiting for backup restoring. (floating
1105+# point value)
1106+#cinder_backup_restore_poll_interval = 2.0
1107+
1108+# Time to sleep after boot before polling for status (floating point
1109+# value)
1110+#ec2_server_boot_prepoll_delay = 1.0
1111+
1112+# Server boot timeout (floating point value)
1113+#ec2_server_boot_timeout = 300.0
1114+
1115+# Server boot poll interval (floating point value)
1116+#ec2_server_boot_poll_interval = 1.0
1117+
1118+# Time to sleep after creating a resource before polling for it status
1119+# (floating point value)
1120+#glance_image_create_prepoll_delay = 2.0
1121+
1122+# Time to wait for glance image to be created. (floating point value)
1123+#glance_image_create_timeout = 120.0
1124+
1125+# Interval between checks when waiting for image creation. (floating
1126+# point value)
1127+#glance_image_create_poll_interval = 1.0
1128+
1129+# Time(in sec) to sleep after creating a resource before polling for
1130+# it status. (floating point value)
1131+#heat_stack_create_prepoll_delay = 2.0
1132+
1133+# Time(in sec) to wait for heat stack to be created. (floating point
1134+# value)
1135+#heat_stack_create_timeout = 3600.0
1136+
1137+# Time interval(in sec) between checks when waiting for stack
1138+# creation. (floating point value)
1139+#heat_stack_create_poll_interval = 1.0
1140+
1141+# Time(in sec) to wait for heat stack to be deleted. (floating point
1142+# value)
1143+#heat_stack_delete_timeout = 3600.0
1144+
1145+# Time interval(in sec) between checks when waiting for stack
1146+# deletion. (floating point value)
1147+#heat_stack_delete_poll_interval = 1.0
1148+
1149+# Time(in sec) to wait for stack to be checked. (floating point value)
1150+#heat_stack_check_timeout = 3600.0
1151+
1152+# Time interval(in sec) between checks when waiting for stack
1153+# checking. (floating point value)
1154+#heat_stack_check_poll_interval = 1.0
1155+
1156+# Time(in sec) to sleep after updating a resource before polling for
1157+# it status. (floating point value)
1158+#heat_stack_update_prepoll_delay = 2.0
1159+
1160+# Time(in sec) to wait for stack to be updated. (floating point value)
1161+#heat_stack_update_timeout = 3600.0
1162+
1163+# Time interval(in sec) between checks when waiting for stack update.
1164+# (floating point value)
1165+#heat_stack_update_poll_interval = 1.0
1166+
1167+# Time(in sec) to wait for stack to be suspended. (floating point
1168+# value)
1169+#heat_stack_suspend_timeout = 3600.0
1170+
1171+# Time interval(in sec) between checks when waiting for stack suspend.
1172+# (floating point value)
1173+#heat_stack_suspend_poll_interval = 1.0
1174+
1175+# Time(in sec) to wait for stack to be resumed. (floating point value)
1176+#heat_stack_resume_timeout = 3600.0
1177+
1178+# Time interval(in sec) between checks when waiting for stack resume.
1179+# (floating point value)
1180+#heat_stack_resume_poll_interval = 1.0
1181+
1182+# Time(in sec) to wait for stack snapshot to be created. (floating
1183+# point value)
1184+#heat_stack_snapshot_timeout = 3600.0
1185+
1186+# Time interval(in sec) between checks when waiting for stack snapshot
1187+# to be created. (floating point value)
1188+#heat_stack_snapshot_poll_interval = 1.0
1189+
1190+# Time(in sec) to wait for stack to be restored from snapshot.
1191+# (floating point value)
1192+#heat_stack_restore_timeout = 3600.0
1193+
1194+# Time interval(in sec) between checks when waiting for stack to be
1195+# restored. (floating point value)
1196+#heat_stack_restore_poll_interval = 1.0
1197+
1198+# Time (in sec) to wait for stack to scale up or down. (floating point
1199+# value)
1200+#heat_stack_scale_timeout = 3600.0
1201+
1202+# Time interval (in sec) between checks when waiting for a stack to
1203+# scale up or down. (floating point value)
1204+#heat_stack_scale_poll_interval = 1.0
1205+
1206+# Interval(in sec) between checks when waiting for node creation.
1207+# (floating point value)
1208+#ironic_node_create_poll_interval = 1.0
1209+
1210+# Time(in sec) to sleep after creating a resource before polling for
1211+# the status. (floating point value)
1212+#magnum_cluster_create_prepoll_delay = 5.0
1213+
1214+# Time(in sec) to wait for magnum cluster to be created. (floating
1215+# point value)
1216+#magnum_cluster_create_timeout = 1200.0
1217+
1218+# Time interval(in sec) between checks when waiting for cluster
1219+# creation. (floating point value)
1220+#magnum_cluster_create_poll_interval = 1.0
1221+
1222+# Delay between creating Manila share and polling for its status.
1223+# (floating point value)
1224+#manila_share_create_prepoll_delay = 2.0
1225+
1226+# Timeout for Manila share creation. (floating point value)
1227+#manila_share_create_timeout = 300.0
1228+
1229+# Interval between checks when waiting for Manila share creation.
1230+# (floating point value)
1231+#manila_share_create_poll_interval = 3.0
1232+
1233+# Timeout for Manila share deletion. (floating point value)
1234+#manila_share_delete_timeout = 180.0
1235+
1236+# Interval between checks when waiting for Manila share deletion.
1237+# (floating point value)
1238+#manila_share_delete_poll_interval = 2.0
1239+
1240+# mistral execution timeout (integer value)
1241+#mistral_execution_timeout = 200
1242+
1243+# Delay between creating Monasca metrics and polling for its elements.
1244+# (floating point value)
1245+#monasca_metric_create_prepoll_delay = 15.0
1246+
1247+# A timeout in seconds for an environment deploy (integer value)
1248+# Deprecated group/name - [benchmark]/deploy_environment_timeout
1249+#murano_deploy_environment_timeout = 1200
1250+
1251+# Deploy environment check interval in seconds (integer value)
1252+# Deprecated group/name - [benchmark]/deploy_environment_check_interval
1253+#murano_deploy_environment_check_interval = 5
1254+
1255+# Time to sleep after start before polling for status (floating point
1256+# value)
1257+#nova_server_start_prepoll_delay = 0.0
1258+
1259+# Server start timeout (floating point value)
1260+#nova_server_start_timeout = 300.0
1261+
1262+# Server start poll interval (floating point value)
1263+#nova_server_start_poll_interval = 1.0
1264+
1265+# Time to sleep after stop before polling for status (floating point
1266+# value)
1267+#nova_server_stop_prepoll_delay = 0.0
1268+
1269+# Server stop timeout (floating point value)
1270+#nova_server_stop_timeout = 300.0
1271+
1272+# Server stop poll interval (floating point value)
1273+#nova_server_stop_poll_interval = 2.0
1274+
1275+# Time to sleep after boot before polling for status (floating point
1276+# value)
1277+#nova_server_boot_prepoll_delay = 1.0
1278+
1279+# Server boot timeout (floating point value)
1280+#nova_server_boot_timeout = 300.0
1281+
1282+# Server boot poll interval (floating point value)
1283+#nova_server_boot_poll_interval = 1.0
1284+
1285+# Time to sleep after delete before polling for status (floating point
1286+# value)
1287+#nova_server_delete_prepoll_delay = 2.0
1288+
1289+# Server delete timeout (floating point value)
1290+#nova_server_delete_timeout = 300.0
1291+
1292+# Server delete poll interval (floating point value)
1293+#nova_server_delete_poll_interval = 2.0
1294+
1295+# Time to sleep after reboot before polling for status (floating point
1296+# value)
1297+#nova_server_reboot_prepoll_delay = 2.0
1298+
1299+# Server reboot timeout (floating point value)
1300+#nova_server_reboot_timeout = 300.0
1301+
1302+# Server reboot poll interval (floating point value)
1303+#nova_server_reboot_poll_interval = 2.0
1304+
1305+# Time to sleep after rebuild before polling for status (floating
1306+# point value)
1307+#nova_server_rebuild_prepoll_delay = 1.0
1308+
1309+# Server rebuild timeout (floating point value)
1310+#nova_server_rebuild_timeout = 300.0
1311+
1312+# Server rebuild poll interval (floating point value)
1313+#nova_server_rebuild_poll_interval = 1.0
1314+
1315+# Time to sleep after rescue before polling for status (floating point
1316+# value)
1317+#nova_server_rescue_prepoll_delay = 2.0
1318+
1319+# Server rescue timeout (floating point value)
1320+#nova_server_rescue_timeout = 300.0
1321+
1322+# Server rescue poll interval (floating point value)
1323+#nova_server_rescue_poll_interval = 2.0
1324+
1325+# Time to sleep after unrescue before polling for status (floating
1326+# point value)
1327+#nova_server_unrescue_prepoll_delay = 2.0
1328+
1329+# Server unrescue timeout (floating point value)
1330+#nova_server_unrescue_timeout = 300.0
1331+
1332+# Server unrescue poll interval (floating point value)
1333+#nova_server_unrescue_poll_interval = 2.0
1334+
1335+# Time to sleep after suspend before polling for status (floating
1336+# point value)
1337+#nova_server_suspend_prepoll_delay = 2.0
1338+
1339+# Server suspend timeout (floating point value)
1340+#nova_server_suspend_timeout = 300.0
1341+
1342+# Server suspend poll interval (floating point value)
1343+#nova_server_suspend_poll_interval = 2.0
1344+
1345+# Time to sleep after resume before polling for status (floating point
1346+# value)
1347+#nova_server_resume_prepoll_delay = 2.0
1348+
1349+# Server resume timeout (floating point value)
1350+#nova_server_resume_timeout = 300.0
1351+
1352+# Server resume poll interval (floating point value)
1353+#nova_server_resume_poll_interval = 2.0
1354+
1355+# Time to sleep after pause before polling for status (floating point
1356+# value)
1357+#nova_server_pause_prepoll_delay = 2.0
1358+
1359+# Server pause timeout (floating point value)
1360+#nova_server_pause_timeout = 300.0
1361+
1362+# Server pause poll interval (floating point value)
1363+#nova_server_pause_poll_interval = 2.0
1364+
1365+# Time to sleep after unpause before polling for status (floating
1366+# point value)
1367+#nova_server_unpause_prepoll_delay = 2.0
1368+
1369+# Server unpause timeout (floating point value)
1370+#nova_server_unpause_timeout = 300.0
1371+
1372+# Server unpause poll interval (floating point value)
1373+#nova_server_unpause_poll_interval = 2.0
1374+
1375+# Time to sleep after shelve before polling for status (floating point
1376+# value)
1377+#nova_server_shelve_prepoll_delay = 2.0
1378+
1379+# Server shelve timeout (floating point value)
1380+#nova_server_shelve_timeout = 300.0
1381+
1382+# Server shelve poll interval (floating point value)
1383+#nova_server_shelve_poll_interval = 2.0
1384+
1385+# Time to sleep after unshelve before polling for status (floating
1386+# point value)
1387+#nova_server_unshelve_prepoll_delay = 2.0
1388+
1389+# Server unshelve timeout (floating point value)
1390+#nova_server_unshelve_timeout = 300.0
1391+
1392+# Server unshelve poll interval (floating point value)
1393+#nova_server_unshelve_poll_interval = 2.0
1394+
1395+# Time to sleep after image_create before polling for status (floating
1396+# point value)
1397+#nova_server_image_create_prepoll_delay = 0.0
1398+
1399+# Server image_create timeout (floating point value)
1400+#nova_server_image_create_timeout = 300.0
1401+
1402+# Server image_create poll interval (floating point value)
1403+#nova_server_image_create_poll_interval = 2.0
1404+
1405+# Time to sleep after image_delete before polling for status (floating
1406+# point value)
1407+#nova_server_image_delete_prepoll_delay = 0.0
1408+
1409+# Server image_delete timeout (floating point value)
1410+#nova_server_image_delete_timeout = 300.0
1411+
1412+# Server image_delete poll interval (floating point value)
1413+#nova_server_image_delete_poll_interval = 2.0
1414+
1415+# Time to sleep after resize before polling for status (floating point
1416+# value)
1417+#nova_server_resize_prepoll_delay = 2.0
1418+
1419+# Server resize timeout (floating point value)
1420+#nova_server_resize_timeout = 400.0
1421+
1422+# Server resize poll interval (floating point value)
1423+#nova_server_resize_poll_interval = 5.0
1424+
1425+# Time to sleep after resize_confirm before polling for status
1426+# (floating point value)
1427+#nova_server_resize_confirm_prepoll_delay = 0.0
1428+
1429+# Server resize_confirm timeout (floating point value)
1430+#nova_server_resize_confirm_timeout = 200.0
1431+
1432+# Server resize_confirm poll interval (floating point value)
1433+#nova_server_resize_confirm_poll_interval = 2.0
1434+
1435+# Time to sleep after resize_revert before polling for status
1436+# (floating point value)
1437+#nova_server_resize_revert_prepoll_delay = 0.0
1438+
1439+# Server resize_revert timeout (floating point value)
1440+#nova_server_resize_revert_timeout = 200.0
1441+
1442+# Server resize_revert poll interval (floating point value)
1443+#nova_server_resize_revert_poll_interval = 2.0
1444+
1445+# Time to sleep after live_migrate before polling for status (floating
1446+# point value)
1447+#nova_server_live_migrate_prepoll_delay = 1.0
1448+
1449+# Server live_migrate timeout (floating point value)
1450+#nova_server_live_migrate_timeout = 400.0
1451+
1452+# Server live_migrate poll interval (floating point value)
1453+#nova_server_live_migrate_poll_interval = 2.0
1454+
1455+# Time to sleep after migrate before polling for status (floating
1456+# point value)
1457+#nova_server_migrate_prepoll_delay = 1.0
1458+
1459+# Server migrate timeout (floating point value)
1460+#nova_server_migrate_timeout = 400.0
1461+
1462+# Server migrate poll interval (floating point value)
1463+#nova_server_migrate_poll_interval = 2.0
1464+
1465+# Nova volume detach timeout (floating point value)
1466+#nova_detach_volume_timeout = 200.0
1467+
1468+# Nova volume detach poll interval (floating point value)
1469+#nova_detach_volume_poll_interval = 2.0
1470+
1471+# A timeout in seconds for a cluster create operation (integer value)
1472+# Deprecated group/name - [benchmark]/cluster_create_timeout
1473+#sahara_cluster_create_timeout = 1800
1474+
1475+# A timeout in seconds for a cluster delete operation (integer value)
1476+# Deprecated group/name - [benchmark]/cluster_delete_timeout
1477+#sahara_cluster_delete_timeout = 900
1478+
1479+# Cluster status polling interval in seconds (integer value)
1480+# Deprecated group/name - [benchmark]/cluster_check_interval
1481+#sahara_cluster_check_interval = 5
1482+
1483+# A timeout in seconds for a Job Execution to complete (integer value)
1484+# Deprecated group/name - [benchmark]/job_execution_timeout
1485+#sahara_job_execution_timeout = 600
1486+
1487+# Job Execution status polling interval in seconds (integer value)
1488+# Deprecated group/name - [benchmark]/job_check_interval
1489+#sahara_job_check_interval = 5
1490+
1491+# Amount of workers one proxy should serve to. (integer value)
1492+#sahara_workers_per_proxy = 20
1493+
1494+# Interval between checks when waiting for a VM to become pingable
1495+# (floating point value)
1496+#vm_ping_poll_interval = 1.0
1497+
1498+# Time to wait for a VM to become pingable (floating point value)
1499+#vm_ping_timeout = 120.0
1500+
1501+# Watcher audit launch interval (floating point value)
1502+#watcher_audit_launch_poll_interval = 2.0
1503+
1504+# Watcher audit launch timeout (integer value)
1505+#watcher_audit_launch_timeout = 300
1506+
1507+
1508+[cleanup]
1509+
1510+#
1511+# From rally
1512+#
1513+
1514+# A timeout in seconds for deleting resources (integer value)
1515+#resource_deletion_timeout = 600
1516+
1517+# Number of cleanup threads to run (integer value)
1518+#cleanup_threads = 20
1519+
1520+
1521+[database]
1522+
1523+#
1524+# From oslo.db
1525+#
1526+
1527+# DEPRECATED: The file name to use with SQLite. (string value)
1528+# Deprecated group/name - [DEFAULT]/sqlite_db
1529+# This option is deprecated for removal.
1530+# Its value may be silently ignored in the future.
1531+# Reason: Should use config option connection or slave_connection to
1532+# connect the database.
1533+#sqlite_db = oslo.sqlite
1534+
1535+# If True, SQLite uses synchronous mode. (boolean value)
1536+# Deprecated group/name - [DEFAULT]/sqlite_synchronous
1537+#sqlite_synchronous = true
1538+
1539+# The back end to use for the database. (string value)
1540+# Deprecated group/name - [DEFAULT]/db_backend
1541+#backend = sqlalchemy
1542+
1543+# The SQLAlchemy connection string to use to connect to the database.
1544+# (string value)
1545+# Deprecated group/name - [DEFAULT]/sql_connection
1546+# Deprecated group/name - [DATABASE]/sql_connection
1547+# Deprecated group/name - [sql]/connection
1548+connection=sqlite:////home/nagiososc/snap/bsrally/common/rally.db
1549+
1550+# The SQLAlchemy connection string to use to connect to the slave
1551+# database. (string value)
1552+#slave_connection = <None>
1553+
1554+# The SQL mode to be used for MySQL sessions. This option, including
1555+# the default, overrides any server-set SQL mode. To use whatever SQL
1556+# mode is set by the server configuration, set this to no value.
1557+# Example: mysql_sql_mode= (string value)
1558+#mysql_sql_mode = TRADITIONAL
1559+
1560+# Timeout before idle SQL connections are reaped. (integer value)
1561+# Deprecated group/name - [DEFAULT]/sql_idle_timeout
1562+# Deprecated group/name - [DATABASE]/sql_idle_timeout
1563+# Deprecated group/name - [sql]/idle_timeout
1564+#idle_timeout = 3600
1565+
1566+# Minimum number of SQL connections to keep open in a pool. (integer
1567+# value)
1568+# Deprecated group/name - [DEFAULT]/sql_min_pool_size
1569+# Deprecated group/name - [DATABASE]/sql_min_pool_size
1570+#min_pool_size = 1
1571+
1572+# Maximum number of SQL connections to keep open in a pool. Setting a
1573+# value of 0 indicates no limit. (integer value)
1574+# Deprecated group/name - [DEFAULT]/sql_max_pool_size
1575+# Deprecated group/name - [DATABASE]/sql_max_pool_size
1576+#max_pool_size = 5
1577+
1578+# Maximum number of database connection retries during startup. Set to
1579+# -1 to specify an infinite retry count. (integer value)
1580+# Deprecated group/name - [DEFAULT]/sql_max_retries
1581+# Deprecated group/name - [DATABASE]/sql_max_retries
1582+#max_retries = 10
1583+
1584+# Interval between retries of opening a SQL connection. (integer
1585+# value)
1586+# Deprecated group/name - [DEFAULT]/sql_retry_interval
1587+# Deprecated group/name - [DATABASE]/reconnect_interval
1588+#retry_interval = 10
1589+
1590+# If set, use this value for max_overflow with SQLAlchemy. (integer
1591+# value)
1592+# Deprecated group/name - [DEFAULT]/sql_max_overflow
1593+# Deprecated group/name - [DATABASE]/sqlalchemy_max_overflow
1594+#max_overflow = 50
1595+
1596+# Verbosity of SQL debugging information: 0=None, 100=Everything.
1597+# (integer value)
1598+# Minimum value: 0
1599+# Maximum value: 100
1600+# Deprecated group/name - [DEFAULT]/sql_connection_debug
1601+#connection_debug = 0
1602+
1603+# Add Python stack traces to SQL as comment strings. (boolean value)
1604+# Deprecated group/name - [DEFAULT]/sql_connection_trace
1605+#connection_trace = false
1606+
1607+# If set, use this value for pool_timeout with SQLAlchemy. (integer
1608+# value)
1609+# Deprecated group/name - [DATABASE]/sqlalchemy_pool_timeout
1610+#pool_timeout = <None>
1611+
1612+# Enable the experimental use of database reconnect on connection
1613+# lost. (boolean value)
1614+#use_db_reconnect = false
1615+
1616+# Seconds between retries of a database transaction. (integer value)
1617+#db_retry_interval = 1
1618+
1619+# If True, increases the interval between retries of a database
1620+# operation up to db_max_retry_interval. (boolean value)
1621+#db_inc_retry_interval = true
1622+
1623+# If db_inc_retry_interval is set, the maximum seconds between retries
1624+# of a database operation. (integer value)
1625+#db_max_retry_interval = 10
1626+
1627+# Maximum retries in case of connection error or deadlock error before
1628+# error is raised. Set to -1 to specify an infinite retry count.
1629+# (integer value)
1630+#db_max_retries = 20
1631+
1632+
1633+[roles_context]
1634+
1635+#
1636+# From rally
1637+#
1638+
1639+# How many concurrent threads to use for serving roles context
1640+# (integer value)
1641+#resource_management_workers = 30
1642+
1643+
1644+[tempest]
1645+
1646+#
1647+# From rally
1648+#
1649+
1650+# image URL (string value)
1651+#img_url = http://download.cirros-cloud.net/0.3.5/cirros-0.3.5-x86_64-disk.img
1652+
1653+# Image disk format to use when creating the image (string value)
1654+#img_disk_format = qcow2
1655+
1656+# Image container format to use when creating the image (string value)
1657+#img_container_format = bare
1658+
1659+# Regular expression for name of a public image to discover it in the
1660+# cloud and use it for the tests. Note that when Rally is searching
1661+# for the image, case insensitive matching is performed. Specify
1662+# nothing ('img_name_regex =') if you want to disable discovering. In
1663+# this case Rally will create needed resources by itself if the values
1664+# for the corresponding config options are not specified in the
1665+# Tempest config file (string value)
1666+#img_name_regex = ^.*(cirros|testvm).*$
1667+
1668+# Role required for users to be able to create Swift containers
1669+# (string value)
1670+#swift_operator_role = Member
1671+
1672+# User role that has reseller admin (string value)
1673+#swift_reseller_admin_role = ResellerAdmin
1674+
1675+# Role required for users to be able to manage Heat stacks (string
1676+# value)
1677+#heat_stack_owner_role = heat_stack_owner
1678+
1679+# Role for Heat template-defined users (string value)
1680+#heat_stack_user_role = heat_stack_user
1681+
1682+# Primary flavor RAM size used by most of the test cases (integer
1683+# value)
1684+#flavor_ref_ram = 64
1685+
1686+# Alternate reference flavor RAM size used by test that need two
1687+# flavors, like those that resize an instance (integer value)
1688+#flavor_ref_alt_ram = 128
1689+
1690+# RAM size flavor used for orchestration test cases (integer value)
1691+#heat_instance_type_ram = 64
1692+
1693+
1694+[users_context]
1695+
1696+#
1697+# From rally
1698+#
1699+
1700+# How many concurrent threads use for serving users context (integer
1701+# value)
1702+#resource_management_workers = 20
1703+
1704+# ID of domain in which projects will be created. (string value)
1705+#project_domain = default
1706+
1707+# ID of domain in which users will be created. (string value)
1708+#user_domain = default
1709+
1710+# The default role name of the keystone. (string value)
1711+#keystone_default_role = member
1712diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py
1713index 32a4af9..ce38155 100644
1714--- a/tests/unit/conftest.py
1715+++ b/tests/unit/conftest.py
1716@@ -14,13 +14,10 @@ def mock_layers(monkeypatch):
1717
1718 def options(layer):
1719 # mock options for layers here
1720- if layer == 'example-layer':
1721- options = {'port': 9999}
1722- return options
1723- else:
1724+ if layer == 'install':
1725 return None
1726
1727- monkeypatch.setattr('lib_openstack_service_checks.layer.options', options)
1728+ monkeypatch.setattr('lib_openstack_service_checks.snap', options)
1729
1730
1731 @pytest.fixture
1732@@ -66,7 +63,7 @@ def mock_unitdata_keystonecreds(monkeypatch):
1733
1734
1735 @pytest.fixture
1736-def openstackservicechecks(tmpdir, mock_hookenv_config, mock_charm_dir, monkeypatch):
1737+def openstackservicechecks(tmpdir, mock_layers, mock_hookenv_config, mock_charm_dir, monkeypatch):
1738 from lib_openstack_service_checks import OSCHelper
1739 helper = OSCHelper()
1740
1741diff --git a/tests/unit/test_lib.py b/tests/unit/test_lib.py
1742index fba093f..6f5a328 100644
1743--- a/tests/unit/test_lib.py
1744+++ b/tests/unit/test_lib.py
1745@@ -11,7 +11,9 @@ def test_openstackservicechecks_common_properties(openstackservicechecks):
1746 assert openstackservicechecks.skip_disabled == ''
1747 assert openstackservicechecks.check_dns == ''
1748 assert not openstackservicechecks.is_rally_enabled
1749- assert not openstackservicechecks.skipped_rally_checks
1750+ assert not openstackservicechecks.rally_skipped_checks
1751+ assert not openstackservicechecks.rally_image_id
1752+ assert not openstackservicechecks.rally_flavor_id
1753 assert openstackservicechecks.rally_cron_schedule == '*/15 * * * *'
1754
1755
1756@@ -47,15 +49,15 @@ def test_openstackservicechecks_get_keystone_credentials_oscredentials(
1757 assert openstackservicechecks.get_os_credentials() == expected
1758
1759
1760-@pytest.mark.parametrize('skip_rally,result', [
1761+@pytest.mark.parametrize('rally_skip_services,result', [
1762 ('nova,neutron', [True, True, False, False]),
1763 ('cinder,neutron', [False, True, True, False]),
1764 ('glance', [True, False, True, True]),
1765 ('nova neutron', [True, True, True, True]), # needs to be comma-separated
1766 ('', [True, True, True, True]),
1767 ])
1768-def test_get_rally_checks_context(skip_rally, result, openstackservicechecks):
1769- openstackservicechecks.charm_config['skip-rally'] = skip_rally
1770+def test_get_rally_checks_context(rally_skip_services, result, openstackservicechecks):
1771+ openstackservicechecks.charm_config['rally-skip-services'] = rally_skip_services
1772 expected = {comp: result[num]
1773 for num, comp in enumerate('cinder glance nova neutron'.split())}
1774 assert openstackservicechecks._get_rally_checks_context() == expected
1775diff --git a/wheelhouse.txt b/wheelhouse.txt
1776new file mode 100644
1777index 0000000..7fe681d
1778--- /dev/null
1779+++ b/wheelhouse.txt
1780@@ -0,0 +1 @@
1781+pid

Subscribers

People subscribed via source and target branches