teuthology 1.1.0__py3-none-any.whl → 1.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. scripts/describe.py +1 -0
  2. scripts/dispatcher.py +55 -26
  3. scripts/exporter.py +18 -0
  4. scripts/lock.py +1 -1
  5. scripts/node_cleanup.py +58 -0
  6. scripts/openstack.py +9 -9
  7. scripts/results.py +12 -11
  8. scripts/schedule.py +4 -0
  9. scripts/suite.py +57 -16
  10. scripts/supervisor.py +44 -0
  11. scripts/update_inventory.py +10 -4
  12. teuthology/__init__.py +24 -26
  13. teuthology/beanstalk.py +4 -3
  14. teuthology/config.py +16 -6
  15. teuthology/contextutil.py +18 -14
  16. teuthology/describe_tests.py +25 -18
  17. teuthology/dispatcher/__init__.py +210 -35
  18. teuthology/dispatcher/supervisor.py +140 -58
  19. teuthology/exceptions.py +43 -0
  20. teuthology/exporter.py +347 -0
  21. teuthology/kill.py +76 -81
  22. teuthology/lock/cli.py +3 -3
  23. teuthology/lock/ops.py +135 -61
  24. teuthology/lock/query.py +61 -44
  25. teuthology/ls.py +1 -1
  26. teuthology/misc.py +61 -75
  27. teuthology/nuke/__init__.py +12 -353
  28. teuthology/openstack/__init__.py +4 -3
  29. teuthology/openstack/openstack-centos-7.0-user-data.txt +1 -1
  30. teuthology/openstack/openstack-centos-7.1-user-data.txt +1 -1
  31. teuthology/openstack/openstack-centos-7.2-user-data.txt +1 -1
  32. teuthology/openstack/openstack-debian-8.0-user-data.txt +1 -1
  33. teuthology/openstack/openstack-opensuse-42.1-user-data.txt +1 -1
  34. teuthology/openstack/openstack-teuthology.cron +0 -1
  35. teuthology/orchestra/cluster.py +49 -7
  36. teuthology/orchestra/connection.py +16 -5
  37. teuthology/orchestra/console.py +111 -50
  38. teuthology/orchestra/daemon/cephadmunit.py +17 -4
  39. teuthology/orchestra/daemon/state.py +8 -1
  40. teuthology/orchestra/daemon/systemd.py +4 -4
  41. teuthology/orchestra/opsys.py +30 -11
  42. teuthology/orchestra/remote.py +405 -338
  43. teuthology/orchestra/run.py +3 -3
  44. teuthology/packaging.py +19 -16
  45. teuthology/provision/__init__.py +30 -10
  46. teuthology/provision/cloud/openstack.py +12 -6
  47. teuthology/provision/cloud/util.py +1 -2
  48. teuthology/provision/downburst.py +4 -3
  49. teuthology/provision/fog.py +68 -20
  50. teuthology/provision/openstack.py +5 -4
  51. teuthology/provision/pelagos.py +1 -1
  52. teuthology/repo_utils.py +43 -13
  53. teuthology/report.py +57 -35
  54. teuthology/results.py +5 -3
  55. teuthology/run.py +13 -14
  56. teuthology/run_tasks.py +27 -43
  57. teuthology/schedule.py +4 -3
  58. teuthology/scrape.py +28 -22
  59. teuthology/suite/__init__.py +74 -45
  60. teuthology/suite/build_matrix.py +34 -24
  61. teuthology/suite/fragment-merge.lua +105 -0
  62. teuthology/suite/matrix.py +31 -2
  63. teuthology/suite/merge.py +175 -0
  64. teuthology/suite/placeholder.py +6 -9
  65. teuthology/suite/run.py +175 -100
  66. teuthology/suite/util.py +64 -218
  67. teuthology/task/__init__.py +1 -1
  68. teuthology/task/ansible.py +101 -32
  69. teuthology/task/buildpackages.py +2 -2
  70. teuthology/task/ceph_ansible.py +13 -6
  71. teuthology/task/cephmetrics.py +2 -1
  72. teuthology/task/clock.py +33 -14
  73. teuthology/task/exec.py +18 -0
  74. teuthology/task/hadoop.py +2 -2
  75. teuthology/task/install/__init__.py +29 -7
  76. teuthology/task/install/bin/adjust-ulimits +16 -0
  77. teuthology/task/install/bin/daemon-helper +114 -0
  78. teuthology/task/install/bin/stdin-killer +263 -0
  79. teuthology/task/install/deb.py +1 -1
  80. teuthology/task/install/rpm.py +17 -5
  81. teuthology/task/install/util.py +3 -3
  82. teuthology/task/internal/__init__.py +41 -10
  83. teuthology/task/internal/edit_sudoers.sh +10 -0
  84. teuthology/task/internal/lock_machines.py +2 -9
  85. teuthology/task/internal/redhat.py +31 -1
  86. teuthology/task/internal/syslog.py +31 -8
  87. teuthology/task/kernel.py +152 -145
  88. teuthology/task/lockfile.py +1 -1
  89. teuthology/task/mpi.py +10 -10
  90. teuthology/task/pcp.py +1 -1
  91. teuthology/task/selinux.py +16 -8
  92. teuthology/task/ssh_keys.py +4 -4
  93. teuthology/task/tests/__init__.py +137 -77
  94. teuthology/task/tests/test_fetch_coredumps.py +116 -0
  95. teuthology/task/tests/test_run.py +4 -4
  96. teuthology/timer.py +3 -3
  97. teuthology/util/loggerfile.py +19 -0
  98. teuthology/util/scanner.py +159 -0
  99. teuthology/util/sentry.py +52 -0
  100. teuthology/util/time.py +52 -0
  101. teuthology-1.2.0.data/scripts/adjust-ulimits +16 -0
  102. teuthology-1.2.0.data/scripts/daemon-helper +114 -0
  103. teuthology-1.2.0.data/scripts/stdin-killer +263 -0
  104. teuthology-1.2.0.dist-info/METADATA +89 -0
  105. teuthology-1.2.0.dist-info/RECORD +174 -0
  106. {teuthology-1.1.0.dist-info → teuthology-1.2.0.dist-info}/WHEEL +1 -1
  107. {teuthology-1.1.0.dist-info → teuthology-1.2.0.dist-info}/entry_points.txt +3 -2
  108. scripts/nuke.py +0 -47
  109. scripts/worker.py +0 -37
  110. teuthology/nuke/actions.py +0 -456
  111. teuthology/openstack/test/__init__.py +0 -0
  112. teuthology/openstack/test/openstack-integration.py +0 -286
  113. teuthology/openstack/test/test_config.py +0 -35
  114. teuthology/openstack/test/test_openstack.py +0 -1695
  115. teuthology/orchestra/test/__init__.py +0 -0
  116. teuthology/orchestra/test/integration/__init__.py +0 -0
  117. teuthology/orchestra/test/integration/test_integration.py +0 -94
  118. teuthology/orchestra/test/test_cluster.py +0 -240
  119. teuthology/orchestra/test/test_connection.py +0 -106
  120. teuthology/orchestra/test/test_console.py +0 -217
  121. teuthology/orchestra/test/test_opsys.py +0 -404
  122. teuthology/orchestra/test/test_remote.py +0 -185
  123. teuthology/orchestra/test/test_run.py +0 -286
  124. teuthology/orchestra/test/test_systemd.py +0 -54
  125. teuthology/orchestra/test/util.py +0 -12
  126. teuthology/test/__init__.py +0 -0
  127. teuthology/test/fake_archive.py +0 -107
  128. teuthology/test/fake_fs.py +0 -92
  129. teuthology/test/integration/__init__.py +0 -0
  130. teuthology/test/integration/test_suite.py +0 -86
  131. teuthology/test/task/__init__.py +0 -205
  132. teuthology/test/task/test_ansible.py +0 -624
  133. teuthology/test/task/test_ceph_ansible.py +0 -176
  134. teuthology/test/task/test_console_log.py +0 -88
  135. teuthology/test/task/test_install.py +0 -337
  136. teuthology/test/task/test_internal.py +0 -57
  137. teuthology/test/task/test_kernel.py +0 -243
  138. teuthology/test/task/test_pcp.py +0 -379
  139. teuthology/test/task/test_selinux.py +0 -35
  140. teuthology/test/test_config.py +0 -189
  141. teuthology/test/test_contextutil.py +0 -68
  142. teuthology/test/test_describe_tests.py +0 -316
  143. teuthology/test/test_email_sleep_before_teardown.py +0 -81
  144. teuthology/test/test_exit.py +0 -97
  145. teuthology/test/test_get_distro.py +0 -47
  146. teuthology/test/test_get_distro_version.py +0 -47
  147. teuthology/test/test_get_multi_machine_types.py +0 -27
  148. teuthology/test/test_job_status.py +0 -60
  149. teuthology/test/test_ls.py +0 -48
  150. teuthology/test/test_misc.py +0 -391
  151. teuthology/test/test_nuke.py +0 -290
  152. teuthology/test/test_packaging.py +0 -763
  153. teuthology/test/test_parallel.py +0 -28
  154. teuthology/test/test_repo_utils.py +0 -225
  155. teuthology/test/test_report.py +0 -77
  156. teuthology/test/test_results.py +0 -155
  157. teuthology/test/test_run.py +0 -239
  158. teuthology/test/test_safepath.py +0 -55
  159. teuthology/test/test_schedule.py +0 -45
  160. teuthology/test/test_scrape.py +0 -167
  161. teuthology/test/test_timer.py +0 -80
  162. teuthology/test/test_vps_os_vers_parameter_checking.py +0 -84
  163. teuthology/test/test_worker.py +0 -303
  164. teuthology/worker.py +0 -354
  165. teuthology-1.1.0.dist-info/METADATA +0 -76
  166. teuthology-1.1.0.dist-info/RECORD +0 -213
  167. {teuthology-1.1.0.dist-info → teuthology-1.2.0.dist-info}/LICENSE +0 -0
  168. {teuthology-1.1.0.dist-info → teuthology-1.2.0.dist-info}/top_level.txt +0 -0
@@ -142,7 +142,7 @@ def _remove(ctx, config, remote, debs):
142
142
  run.Raw('|'),
143
143
  # Any package that is unpacked or half-installed and also requires
144
144
  # reinstallation
145
- 'grep', '^.\(U\|H\)R',
145
+ 'grep', r'^.\(U\|H\)R',
146
146
  run.Raw('|'),
147
147
  'awk', '{print $2}',
148
148
  run.Raw('|'),
@@ -145,16 +145,19 @@ def _downgrade_packages(ctx, remote, pkgs, pkg_version, config):
145
145
  remote.run(args='sudo yum -y downgrade {}'.format(' '.join(pkgs_opt)))
146
146
  return [pkg for pkg in pkgs if pkg not in downgrade_pkgs]
147
147
 
148
- def _retry_if_503_in_output(remote, args):
148
+ def _retry_if_failures_are_recoverable(remote, args):
149
149
  # wait at most 5 minutes
150
150
  with safe_while(sleep=10, tries=30) as proceed:
151
151
  while proceed():
152
152
  stdout = StringIO()
153
+ stderr = StringIO()
153
154
  try:
154
- return remote.run(args=args, stdout=stdout)
155
+ return remote.run(args=args, stderr=stderr, stdout=stdout)
155
156
  except run.CommandFailedError:
156
157
  if "status code: 503" in stdout.getvalue().lower():
157
158
  continue
159
+ if "failed to download metadata for repo" in stderr.getvalue().lower():
160
+ continue
158
161
  else:
159
162
  raise
160
163
 
@@ -170,6 +173,13 @@ def _update_package_list_and_install(ctx, remote, rpm, config):
170
173
  :param rpm: list of packages names to install
171
174
  :param config: the config dict
172
175
  """
176
+
177
+ enable_coprs = config.get('enable_coprs', [])
178
+ if len(enable_coprs):
179
+ remote.run(args=['sudo', 'dnf', '-y', 'install', 'dnf-command(copr)'])
180
+ for copr in enable_coprs:
181
+ remote.run(args=['sudo', 'dnf', '-y', 'copr', 'enable', copr])
182
+
173
183
  # rpm does not force installation of a particular version of the project
174
184
  # packages, so we can put extra_system_packages together with the rest
175
185
  system_pkglist = config.get('extra_system_packages')
@@ -250,14 +260,14 @@ def _update_package_list_and_install(ctx, remote, rpm, config):
250
260
  rpm = _downgrade_packages(ctx, remote, rpm, pkg_version, config)
251
261
 
252
262
  if system_pkglist:
253
- _retry_if_503_in_output(remote,
263
+ _retry_if_failures_are_recoverable(remote,
254
264
  args='{install_cmd} {rpms}'
255
265
  .format(install_cmd=install_cmd, rpms=' '.join(rpm))
256
266
  )
257
267
  else:
258
268
  for cpack in rpm:
259
269
  if ldir:
260
- _retry_if_503_in_output(remote,
270
+ _retry_if_failures_are_recoverable(remote,
261
271
  args='''
262
272
  if test -e {pkg} ; then
263
273
  {remove_cmd} {pkg} ;
@@ -270,7 +280,7 @@ def _update_package_list_and_install(ctx, remote, rpm, config):
270
280
  pkg=os.path.join(ldir, cpack),
271
281
  cpack=cpack))
272
282
  else:
273
- _retry_if_503_in_output(remote,
283
+ _retry_if_failures_are_recoverable(remote,
274
284
  args='{install_cmd} {cpack}'
275
285
  .format(install_cmd=install_cmd, cpack=cpack)
276
286
  )
@@ -365,6 +375,8 @@ def _remove_sources_list(ctx, config, remote):
365
375
  if remote.os.name not in ['opensuse', 'sle']:
366
376
  _yum_unset_check_obsoletes(remote)
367
377
 
378
+ for copr in config.get('enable_coprs', []):
379
+ remote.run(args=['sudo', 'dnf', '-y', 'copr', 'disable', copr])
368
380
 
369
381
  def _upgrade_packages(ctx, config, remote, pkgs):
370
382
  """
@@ -38,7 +38,7 @@ def get_flavor(config):
38
38
  Determine the flavor to use.
39
39
  """
40
40
  config = config or dict()
41
- flavor = config.get('flavor', 'basic')
41
+ flavor = config.get('flavor', 'default')
42
42
 
43
43
  if config.get('path'):
44
44
  # local dir precludes any other flavors
@@ -81,11 +81,11 @@ def _ship_utilities(ctx):
81
81
  except IOError as e:
82
82
  log.info('Cannot ship supression file for valgrind: %s...', e.strerror)
83
83
 
84
- FILES = ['daemon-helper', 'adjust-ulimits']
84
+ FILES = ['daemon-helper', 'adjust-ulimits', 'stdin-killer']
85
85
  destdir = '/usr/bin'
86
86
  for filename in FILES:
87
87
  log.info('Shipping %r...', filename)
88
- src = os.path.join(os.path.dirname(__file__), filename)
88
+ src = os.path.join(os.path.dirname(__file__), 'bin', filename)
89
89
  dst = os.path.join(destdir, filename)
90
90
  filenames.append(dst)
91
91
  with open(src, 'rb') as f:
@@ -12,19 +12,21 @@ import shutil
12
12
  import time
13
13
  import yaml
14
14
  import subprocess
15
-
15
+ import tempfile
16
+ import re
16
17
  import humanfriendly
17
18
 
18
19
  import teuthology.lock.ops
19
- from teuthology import misc
20
- from teuthology.packaging import get_builder_project
20
+ from teuthology import misc, packaging
21
21
  from teuthology import report
22
22
  from teuthology.config import config as teuth_config
23
23
  from teuthology.exceptions import ConfigError, VersionNotFoundError
24
24
  from teuthology.job_status import get_status, set_status
25
25
  from teuthology.orchestra import cluster, remote, run
26
26
  # the below import with noqa is to workaround run.py which does not support multilevel submodule import
27
- from teuthology.task.internal.redhat import setup_cdn_repo, setup_base_repo, setup_additional_repo, setup_stage_cdn # noqa
27
+ from teuthology.task.internal.redhat import (setup_cdn_repo, setup_base_repo, # noqa
28
+ setup_additional_repo, # noqa
29
+ setup_stage_cdn, setup_container_registry) # noqa
28
30
 
29
31
  log = logging.getLogger(__name__)
30
32
 
@@ -86,7 +88,7 @@ def check_packages(ctx, config):
86
88
  # We can only do this check if there are a defined sha1 and os_type
87
89
  # in the job config.
88
90
  if os_type and sha1:
89
- package = get_builder_project()("ceph", ctx.config)
91
+ package = packaging.get_builder_project()("ceph", ctx.config)
90
92
  template = "Checking packages for os_type '{os}', " \
91
93
  "flavor '{flav}' and ceph hash '{ver}'"
92
94
  log.info(
@@ -270,7 +272,7 @@ def check_ceph_data(ctx, config):
270
272
  try:
271
273
  proc.wait()
272
274
  except run.CommandFailedError:
273
- log.error('Host %s has stale /var/lib/ceph, check lock and nuke/cleanup.', proc.remote.shortname)
275
+ log.error('Host %s has stale /var/lib/ceph!', proc.remote.shortname)
274
276
  failed = True
275
277
  if failed:
276
278
  raise RuntimeError('Stale /var/lib/ceph detected, aborting.')
@@ -315,7 +317,29 @@ def fetch_binaries_for_coredumps(path, remote):
315
317
  # Parse file output to get program, Example output:
316
318
  # 1422917770.7450.core: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, \
317
319
  # from 'radosgw --rgw-socket-path /home/ubuntu/cephtest/apache/tmp.client.0/fastcgi_soc'
318
- dump_program = dump_out.split("from '")[1].split(' ')[0]
320
+ log.info(f' core looks like: {dump_out}')
321
+
322
+ if 'gzip' in dump_out:
323
+ try:
324
+ log.info("core is compressed, try accessing gzip file ...")
325
+ with gzip.open(dump_path, 'rb') as f_in, \
326
+ tempfile.NamedTemporaryFile(mode='w+b') as f_out:
327
+ shutil.copyfileobj(f_in, f_out)
328
+ dump_info = subprocess.Popen(['file', f_out.name],
329
+ stdout=subprocess.PIPE)
330
+ dump_out = dump_info.communicate()[0].decode()
331
+ log.info(f' core looks like: {dump_out}')
332
+ except Exception as e:
333
+ log.info('Something went wrong while opening the compressed file')
334
+ log.error(e)
335
+ continue
336
+ try:
337
+ dump_program = re.findall("from '([^']+)'", dump_out)[0]
338
+ log.info(f' dump_program: {dump_program}')
339
+ except Exception as e:
340
+ log.info("core doesn't have the desired format, moving on ...")
341
+ log.error(e)
342
+ continue
319
343
 
320
344
  # Find path on remote server:
321
345
  remote_path = remote.sh(['which', dump_program]).rstrip()
@@ -441,9 +465,10 @@ def coredump(ctx, config):
441
465
  Stash a coredump of this system if an error occurs.
442
466
  """
443
467
  log.info('Enabling coredump saving...')
468
+ cluster = ctx.cluster.filter(lambda r: not r.is_container)
444
469
  archive_dir = misc.get_archive_dir(ctx)
445
470
  run.wait(
446
- ctx.cluster.run(
471
+ cluster.run(
447
472
  args=[
448
473
  'install', '-d', '-m0755', '--',
449
474
  '{adir}/coredump'.format(adir=archive_dir),
@@ -462,11 +487,17 @@ def coredump(ctx, config):
462
487
  try:
463
488
  yield
464
489
  finally:
490
+ cluster = ctx.cluster.filter(lambda r: not r.is_container)
465
491
  run.wait(
466
- ctx.cluster.run(
492
+ cluster.run(
467
493
  args=[
468
494
  'sudo', 'sysctl', '-w', 'kernel.core_pattern=core',
469
495
  run.Raw('&&'),
496
+ 'sudo', 'bash', '-c',
497
+ (f'for f in `find {archive_dir}/coredump -type f`; do '
498
+ 'file $f | grep -q systemd-sysusers && rm $f || true ; '
499
+ 'done'),
500
+ run.Raw('&&'),
470
501
  # don't litter the archive dir if there were no cores dumped
471
502
  'rmdir',
472
503
  '--ignore-fail-on-non-empty',
@@ -479,7 +510,7 @@ def coredump(ctx, config):
479
510
 
480
511
  # set status = 'fail' if the dir is still there = coredumps were
481
512
  # seen
482
- for rem in ctx.cluster.remotes.keys():
513
+ for rem in cluster.remotes.keys():
483
514
  try:
484
515
  rem.sh("test -e " + archive_dir + "/coredump")
485
516
  except run.CommandFailedError:
@@ -0,0 +1,10 @@
1
+ #! /bin/sh
2
+
3
+ sudo vi -e /etc/sudoers <<EOF
4
+ g/ requiretty/s// !requiretty/
5
+ g/ !visiblepw/s// visiblepw/
6
+ w!
7
+ q
8
+ EOF
9
+ exit
10
+
@@ -4,7 +4,6 @@ import logging
4
4
  import teuthology.lock.ops
5
5
  import teuthology.lock.query
6
6
  import teuthology.lock.util
7
- from teuthology.job_status import get_status
8
7
 
9
8
  log = logging.getLogger(__name__)
10
9
 
@@ -24,13 +23,7 @@ def lock_machines(ctx, config):
24
23
  try:
25
24
  yield
26
25
  finally:
27
- # If both unlock_on_failure and nuke-on-error are set, don't unlock now
28
- # because we're just going to nuke (and unlock) later.
29
- unlock_on_failure = (
30
- ctx.config.get('unlock_on_failure', False)
31
- and not ctx.config.get('nuke-on-error', False)
32
- )
33
- if get_status(ctx.summary) == 'pass' or unlock_on_failure:
26
+ if ctx.config.get("unlock_on_failure", True):
34
27
  log.info('Unlocking machines...')
35
28
  for machine in ctx.config['targets'].keys():
36
- teuthology.lock.ops.unlock_one(ctx, machine, ctx.owner, ctx.archive)
29
+ teuthology.lock.ops.unlock_one(machine, ctx.owner, ctx.archive)
@@ -49,7 +49,7 @@ def _subscribe_stage_cdn(remote):
49
49
  cdn_config = teuthconfig.get('cdn-config', dict())
50
50
  server_url = cdn_config.get('server-url', 'subscription.rhsm.stage.redhat.com:443/subscription')
51
51
  base_url = cdn_config.get('base-url', 'https://cdn.stage.redhat.com')
52
- username = cdn_config.get('username', 'cephuser')
52
+ username = cdn_config.get('username')
53
53
  password = cdn_config.get('password')
54
54
  remote.run(
55
55
  args=[
@@ -88,6 +88,36 @@ def setup_cdn_repo(ctx, config):
88
88
  set_cdn_repo(ctx, config)
89
89
  yield
90
90
 
91
+ @contextlib.contextmanager
92
+ def setup_container_registry(ctx, config):
93
+ """
94
+ setup container registry if setup_container_registry in config
95
+
96
+ redhat:
97
+ setup_container_registry: <registry.io> # registry-name
98
+ """
99
+ if ctx.config.get('redhat').get('setup_container_registry', None):
100
+ registry = ctx.config['redhat']['setup_container_registry']
101
+
102
+ # fetch credentials from teuth_config
103
+ creds = teuthconfig.get('registries', dict()).get(registry)
104
+ if not creds:
105
+ raise ConfigError("Registry not found....")
106
+
107
+ # container-tool login
108
+ for remote in ctx.cluster.remotes.keys():
109
+ container_tool = "podman"
110
+ if remote.os.version.startswith('7'):
111
+ container_tool = "docker"
112
+
113
+ remote.run(args=[
114
+ 'sudo', container_tool,
115
+ 'login', registry,
116
+ '--username', creds['username'],
117
+ '--password', creds['password'],
118
+ ]
119
+ )
120
+ yield
91
121
 
92
122
  @contextlib.contextmanager
93
123
  def setup_additional_repo(ctx, config):
@@ -22,12 +22,17 @@ def syslog(ctx, config):
22
22
  yield
23
23
  return
24
24
 
25
+ cluster = ctx.cluster.filter(lambda r: not r.is_container)
26
+ if not len(cluster.remotes.keys()):
27
+ yield
28
+ return
29
+
25
30
  log.info('Starting syslog monitoring...')
26
31
 
27
32
  archive_dir = misc.get_archive_dir(ctx)
28
33
  log_dir = '{adir}/syslog'.format(adir=archive_dir)
29
34
  run.wait(
30
- ctx.cluster.run(
35
+ cluster.run(
31
36
  args=['mkdir', '-p', '-m0755', '--', log_dir],
32
37
  wait=False,
33
38
  )
@@ -43,7 +48,7 @@ def syslog(ctx, config):
43
48
  ]
44
49
  conf_fp = BytesIO('\n'.join(conf_lines).encode())
45
50
  try:
46
- for rem in ctx.cluster.remotes.keys():
51
+ for rem in cluster.remotes.keys():
47
52
  log_context = 'system_u:object_r:var_log_t:s0'
48
53
  for log_path in (kern_log, misc_log):
49
54
  rem.run(args=['install', '-m', '666', '/dev/null', log_path])
@@ -55,7 +60,7 @@ def syslog(ctx, config):
55
60
  )
56
61
  conf_fp.seek(0)
57
62
  run.wait(
58
- ctx.cluster.run(
63
+ cluster.run(
59
64
  args=[
60
65
  'sudo',
61
66
  'service',
@@ -70,10 +75,14 @@ def syslog(ctx, config):
70
75
 
71
76
  yield
72
77
  finally:
78
+ cluster = ctx.cluster.filter(lambda r: not r.is_container)
79
+ if not len(cluster.remotes.keys()):
80
+ return
81
+
73
82
  log.info('Shutting down syslog monitoring...')
74
83
 
75
84
  run.wait(
76
- ctx.cluster.run(
85
+ cluster.run(
77
86
  args=[
78
87
  'sudo',
79
88
  'rm',
@@ -93,13 +102,13 @@ def syslog(ctx, config):
93
102
  # flush the file fully. oh well.
94
103
 
95
104
  log.info('Checking logs for errors...')
96
- for rem in ctx.cluster.remotes.keys():
105
+ for rem in cluster.remotes.keys():
97
106
  log.debug('Checking %s', rem.name)
98
107
  stdout = rem.sh(
99
108
  [
100
109
  'egrep', '--binary-files=text',
101
110
  '\\bBUG\\b|\\bINFO\\b|\\bDEADLOCK\\b',
102
- run.Raw('{adir}/syslog/*.log'.format(adir=archive_dir)),
111
+ run.Raw(f'{archive_dir}/syslog/kern.log'),
103
112
  run.Raw('|'),
104
113
  'grep', '-v', 'task .* blocked for more than .* seconds',
105
114
  run.Raw('|'),
@@ -152,7 +161,7 @@ def syslog(ctx, config):
152
161
 
153
162
  log.info('Compressing syslogs...')
154
163
  run.wait(
155
- ctx.cluster.run(
164
+ cluster.run(
156
165
  args=[
157
166
  'find',
158
167
  '{adir}/syslog'.format(adir=archive_dir),
@@ -169,5 +178,19 @@ def syslog(ctx, config):
169
178
  '--',
170
179
  ],
171
180
  wait=False,
172
- ),
181
+ )
182
+ )
183
+
184
+ log.info('Gathering journactl -b0...')
185
+ run.wait(
186
+ cluster.run(
187
+ args=[
188
+ 'sudo', 'journalctl', '-b0',
189
+ run.Raw('|'),
190
+ 'gzip', '-9',
191
+ run.Raw('>'),
192
+ f'{archive_dir}/syslog/journalctl-b0.gz',
193
+ ],
194
+ wait=False,
195
+ )
173
196
  )