teuthology 1.0.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 (172) hide show
  1. scripts/describe.py +1 -0
  2. scripts/dispatcher.py +62 -0
  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/run.py +4 -0
  9. scripts/schedule.py +4 -0
  10. scripts/suite.py +61 -16
  11. scripts/supervisor.py +44 -0
  12. scripts/update_inventory.py +10 -4
  13. scripts/wait.py +31 -0
  14. teuthology/__init__.py +24 -21
  15. teuthology/beanstalk.py +4 -3
  16. teuthology/config.py +17 -6
  17. teuthology/contextutil.py +18 -14
  18. teuthology/describe_tests.py +25 -18
  19. teuthology/dispatcher/__init__.py +365 -0
  20. teuthology/dispatcher/supervisor.py +374 -0
  21. teuthology/exceptions.py +54 -0
  22. teuthology/exporter.py +347 -0
  23. teuthology/kill.py +76 -75
  24. teuthology/lock/cli.py +16 -7
  25. teuthology/lock/ops.py +276 -70
  26. teuthology/lock/query.py +61 -44
  27. teuthology/ls.py +9 -18
  28. teuthology/misc.py +152 -137
  29. teuthology/nuke/__init__.py +12 -351
  30. teuthology/openstack/__init__.py +4 -3
  31. teuthology/openstack/openstack-centos-7.0-user-data.txt +1 -1
  32. teuthology/openstack/openstack-centos-7.1-user-data.txt +1 -1
  33. teuthology/openstack/openstack-centos-7.2-user-data.txt +1 -1
  34. teuthology/openstack/openstack-debian-8.0-user-data.txt +1 -1
  35. teuthology/openstack/openstack-opensuse-42.1-user-data.txt +1 -1
  36. teuthology/openstack/openstack-teuthology.cron +0 -1
  37. teuthology/orchestra/cluster.py +51 -9
  38. teuthology/orchestra/connection.py +23 -16
  39. teuthology/orchestra/console.py +111 -50
  40. teuthology/orchestra/daemon/cephadmunit.py +23 -5
  41. teuthology/orchestra/daemon/state.py +10 -3
  42. teuthology/orchestra/daemon/systemd.py +10 -8
  43. teuthology/orchestra/opsys.py +32 -11
  44. teuthology/orchestra/remote.py +369 -152
  45. teuthology/orchestra/run.py +21 -12
  46. teuthology/packaging.py +54 -15
  47. teuthology/provision/__init__.py +30 -10
  48. teuthology/provision/cloud/openstack.py +12 -6
  49. teuthology/provision/cloud/util.py +1 -2
  50. teuthology/provision/downburst.py +83 -29
  51. teuthology/provision/fog.py +68 -20
  52. teuthology/provision/openstack.py +5 -4
  53. teuthology/provision/pelagos.py +13 -5
  54. teuthology/repo_utils.py +91 -44
  55. teuthology/report.py +57 -35
  56. teuthology/results.py +5 -3
  57. teuthology/run.py +21 -15
  58. teuthology/run_tasks.py +114 -40
  59. teuthology/schedule.py +4 -3
  60. teuthology/scrape.py +28 -22
  61. teuthology/suite/__init__.py +75 -46
  62. teuthology/suite/build_matrix.py +34 -24
  63. teuthology/suite/fragment-merge.lua +105 -0
  64. teuthology/suite/matrix.py +31 -2
  65. teuthology/suite/merge.py +175 -0
  66. teuthology/suite/placeholder.py +8 -8
  67. teuthology/suite/run.py +204 -102
  68. teuthology/suite/util.py +67 -211
  69. teuthology/task/__init__.py +1 -1
  70. teuthology/task/ansible.py +101 -31
  71. teuthology/task/buildpackages.py +2 -2
  72. teuthology/task/ceph_ansible.py +13 -6
  73. teuthology/task/cephmetrics.py +2 -1
  74. teuthology/task/clock.py +33 -14
  75. teuthology/task/exec.py +18 -0
  76. teuthology/task/hadoop.py +2 -2
  77. teuthology/task/install/__init__.py +51 -22
  78. teuthology/task/install/bin/adjust-ulimits +16 -0
  79. teuthology/task/install/bin/daemon-helper +114 -0
  80. teuthology/task/install/bin/stdin-killer +263 -0
  81. teuthology/task/install/deb.py +24 -4
  82. teuthology/task/install/redhat.py +36 -32
  83. teuthology/task/install/rpm.py +41 -14
  84. teuthology/task/install/util.py +48 -22
  85. teuthology/task/internal/__init__.py +69 -11
  86. teuthology/task/internal/edit_sudoers.sh +10 -0
  87. teuthology/task/internal/lock_machines.py +3 -133
  88. teuthology/task/internal/redhat.py +48 -28
  89. teuthology/task/internal/syslog.py +31 -8
  90. teuthology/task/kernel.py +155 -147
  91. teuthology/task/lockfile.py +1 -1
  92. teuthology/task/mpi.py +10 -10
  93. teuthology/task/pcp.py +1 -1
  94. teuthology/task/selinux.py +17 -8
  95. teuthology/task/ssh_keys.py +6 -6
  96. teuthology/task/tests/__init__.py +137 -77
  97. teuthology/task/tests/test_fetch_coredumps.py +116 -0
  98. teuthology/task/tests/test_run.py +4 -4
  99. teuthology/timer.py +3 -3
  100. teuthology/util/loggerfile.py +19 -0
  101. teuthology/util/scanner.py +159 -0
  102. teuthology/util/sentry.py +52 -0
  103. teuthology/util/time.py +52 -0
  104. teuthology-1.2.0.data/scripts/adjust-ulimits +16 -0
  105. teuthology-1.2.0.data/scripts/daemon-helper +114 -0
  106. teuthology-1.2.0.data/scripts/stdin-killer +263 -0
  107. teuthology-1.2.0.dist-info/METADATA +89 -0
  108. teuthology-1.2.0.dist-info/RECORD +174 -0
  109. {teuthology-1.0.0.dist-info → teuthology-1.2.0.dist-info}/WHEEL +1 -1
  110. {teuthology-1.0.0.dist-info → teuthology-1.2.0.dist-info}/entry_points.txt +5 -2
  111. scripts/nuke.py +0 -45
  112. scripts/worker.py +0 -37
  113. teuthology/nuke/actions.py +0 -456
  114. teuthology/openstack/test/__init__.py +0 -0
  115. teuthology/openstack/test/openstack-integration.py +0 -286
  116. teuthology/openstack/test/test_config.py +0 -35
  117. teuthology/openstack/test/test_openstack.py +0 -1695
  118. teuthology/orchestra/test/__init__.py +0 -0
  119. teuthology/orchestra/test/integration/__init__.py +0 -0
  120. teuthology/orchestra/test/integration/test_integration.py +0 -94
  121. teuthology/orchestra/test/test_cluster.py +0 -240
  122. teuthology/orchestra/test/test_connection.py +0 -106
  123. teuthology/orchestra/test/test_console.py +0 -217
  124. teuthology/orchestra/test/test_opsys.py +0 -404
  125. teuthology/orchestra/test/test_remote.py +0 -185
  126. teuthology/orchestra/test/test_run.py +0 -286
  127. teuthology/orchestra/test/test_systemd.py +0 -54
  128. teuthology/orchestra/test/util.py +0 -12
  129. teuthology/sentry.py +0 -18
  130. teuthology/test/__init__.py +0 -0
  131. teuthology/test/fake_archive.py +0 -107
  132. teuthology/test/fake_fs.py +0 -92
  133. teuthology/test/integration/__init__.py +0 -0
  134. teuthology/test/integration/test_suite.py +0 -86
  135. teuthology/test/task/__init__.py +0 -205
  136. teuthology/test/task/test_ansible.py +0 -624
  137. teuthology/test/task/test_ceph_ansible.py +0 -176
  138. teuthology/test/task/test_console_log.py +0 -88
  139. teuthology/test/task/test_install.py +0 -337
  140. teuthology/test/task/test_internal.py +0 -57
  141. teuthology/test/task/test_kernel.py +0 -243
  142. teuthology/test/task/test_pcp.py +0 -379
  143. teuthology/test/task/test_selinux.py +0 -35
  144. teuthology/test/test_config.py +0 -189
  145. teuthology/test/test_contextutil.py +0 -68
  146. teuthology/test/test_describe_tests.py +0 -316
  147. teuthology/test/test_email_sleep_before_teardown.py +0 -81
  148. teuthology/test/test_exit.py +0 -97
  149. teuthology/test/test_get_distro.py +0 -47
  150. teuthology/test/test_get_distro_version.py +0 -47
  151. teuthology/test/test_get_multi_machine_types.py +0 -27
  152. teuthology/test/test_job_status.py +0 -60
  153. teuthology/test/test_ls.py +0 -48
  154. teuthology/test/test_misc.py +0 -368
  155. teuthology/test/test_nuke.py +0 -232
  156. teuthology/test/test_packaging.py +0 -763
  157. teuthology/test/test_parallel.py +0 -28
  158. teuthology/test/test_repo_utils.py +0 -204
  159. teuthology/test/test_report.py +0 -77
  160. teuthology/test/test_results.py +0 -155
  161. teuthology/test/test_run.py +0 -238
  162. teuthology/test/test_safepath.py +0 -55
  163. teuthology/test/test_schedule.py +0 -45
  164. teuthology/test/test_scrape.py +0 -167
  165. teuthology/test/test_timer.py +0 -80
  166. teuthology/test/test_vps_os_vers_parameter_checking.py +0 -84
  167. teuthology/test/test_worker.py +0 -303
  168. teuthology/worker.py +0 -339
  169. teuthology-1.0.0.dist-info/METADATA +0 -76
  170. teuthology-1.0.0.dist-info/RECORD +0 -210
  171. {teuthology-1.0.0.dist-info → teuthology-1.2.0.dist-info}/LICENSE +0 -0
  172. {teuthology-1.0.0.dist-info → teuthology-1.2.0.dist-info}/top_level.txt +0 -0
@@ -22,7 +22,7 @@ class CephAnsible(Task):
22
22
 
23
23
  - ceph-ansible:
24
24
  repo: {git_base}ceph-ansible.git
25
- branch: mybranch # defaults to master
25
+ branch: mybranch # defaults to main
26
26
  ansible-version: 2.4 # defaults to 2.5
27
27
  vars:
28
28
  ceph_dev: True ( default)
@@ -73,7 +73,7 @@ class CephAnsible(Task):
73
73
  if 'ceph_dev_key' not in vars:
74
74
  vars['ceph_dev_key'] = 'https://download.ceph.com/keys/autobuild.asc'
75
75
  if 'ceph_dev_branch' not in vars:
76
- vars['ceph_dev_branch'] = ctx.config.get('branch', 'master')
76
+ vars['ceph_dev_branch'] = ctx.config.get('branch', 'main')
77
77
  self.cluster_name = vars.get('cluster', 'ceph')
78
78
 
79
79
  def setup(self):
@@ -296,8 +296,11 @@ class CephAnsible(Task):
296
296
  roles = self.ctx.cluster.remotes[remote]
297
297
  dev_needed = len([role for role in roles
298
298
  if role.startswith('osd')])
299
- if teuth_config.get('ceph_ansible') and \
300
- self.ctx.machine_type in teuth_config['ceph_ansible']['has_lvm_scratch_disks']:
299
+ if (
300
+ teuth_config.get('ceph_ansible') and
301
+ hasattr(self.ctx, "machine_type") and
302
+ self.ctx.machine_type in teuth_config['ceph_ansible']['has_lvm_scratch_disks']
303
+ ):
301
304
  devices = get_file(remote, "/scratch_devs").decode().split()
302
305
  vols = []
303
306
 
@@ -375,7 +378,7 @@ class CephAnsible(Task):
375
378
  'python-dev'
376
379
  ])
377
380
  ansible_repo = self.config['repo']
378
- branch = 'master'
381
+ branch = 'main'
379
382
  if self.config.get('branch'):
380
383
  branch = self.config.get('branch')
381
384
  ansible_ver = 'ansible==2.5'
@@ -404,7 +407,6 @@ class CephAnsible(Task):
404
407
  run.Raw('cd ~/ceph-ansible'),
405
408
  run.Raw(';'),
406
409
  'virtualenv',
407
- run.Raw('--system-site-packages'),
408
410
  run.Raw('--python=python3'),
409
411
  'venv',
410
412
  run.Raw(';'),
@@ -425,6 +427,11 @@ class CephAnsible(Task):
425
427
  run.Raw('setuptools>=11.3'),
426
428
  run.Raw('notario>=0.0.13'), # FIXME: use requirements.txt
427
429
  run.Raw('netaddr'),
430
+ run.Raw('six'),
431
+ run.Raw(';'),
432
+ 'LANG=en_US.utf8',
433
+ 'pip',
434
+ 'install',
428
435
  run.Raw(ansible_ver),
429
436
  run.Raw(';'),
430
437
  run.Raw(str_args)
@@ -5,8 +5,9 @@ import time
5
5
 
6
6
  from teuthology.config import config as teuth_config
7
7
  from teuthology.exceptions import CommandFailedError
8
+ from teuthology.task.ansible import Ansible
9
+ from teuthology.util.loggerfile import LoggerFile
8
10
 
9
- from teuthology.ansible import Ansible, LoggerFile
10
11
 
11
12
  log = logging.getLogger(__name__)
12
13
 
teuthology/task/clock.py CHANGED
@@ -8,6 +8,13 @@ from teuthology.orchestra import run
8
8
 
9
9
  log = logging.getLogger(__name__)
10
10
 
11
+ def filter_out_containers(cluster):
12
+ """
13
+ Returns a cluster that excludes remotes which should skip this task.
14
+ Currently, only skips containerized remotes.
15
+ """
16
+ return cluster.filter(lambda r: not r.is_container)
17
+
11
18
  @contextlib.contextmanager
12
19
  def task(ctx, config):
13
20
  """
@@ -30,8 +37,9 @@ def task(ctx, config):
30
37
  """
31
38
 
32
39
  log.info('Syncing clocks and checking initial clock skew...')
33
- for rem in ctx.cluster.remotes.keys():
34
- rem.run(
40
+ cluster = filter_out_containers(ctx.cluster)
41
+ run.wait(
42
+ cluster.run(
35
43
  args = [
36
44
  'sudo', 'systemctl', 'stop', 'ntp.service', run.Raw('||'),
37
45
  'sudo', 'systemctl', 'stop', 'ntpd.service', run.Raw('||'),
@@ -50,22 +58,27 @@ def task(ctx, config):
50
58
  'true'
51
59
  ],
52
60
  timeout = 360,
61
+ wait=False,
53
62
  )
63
+ )
54
64
 
55
65
  try:
56
66
  yield
57
67
 
58
68
  finally:
59
69
  log.info('Checking final clock skew...')
60
- for rem in ctx.cluster.remotes.keys():
61
- rem.run(
70
+ cluster = filter_out_containers(ctx.cluster)
71
+ run.wait(
72
+ cluster.run(
62
73
  args=[
63
74
  'PATH=/usr/bin:/usr/sbin', 'ntpq', '-p', run.Raw('||'),
64
75
  'PATH=/usr/bin:/usr/sbin', 'chronyc', 'sources',
65
76
  run.Raw('||'),
66
77
  'true'
67
- ],
68
- )
78
+ ],
79
+ wait=False,
80
+ )
81
+ )
69
82
 
70
83
 
71
84
  @contextlib.contextmanager
@@ -77,27 +90,33 @@ def check(ctx, config):
77
90
  :param config: Configuration
78
91
  """
79
92
  log.info('Checking initial clock skew...')
80
- for rem in ctx.cluster.remotes.keys():
81
- rem.run(
93
+ cluster = filter_out_containers(ctx.cluster)
94
+ run.wait(
95
+ cluster.run(
82
96
  args=[
83
97
  'PATH=/usr/bin:/usr/sbin', 'ntpq', '-p', run.Raw('||'),
84
98
  'PATH=/usr/bin:/usr/sbin', 'chronyc', 'sources',
85
99
  run.Raw('||'),
86
100
  'true'
87
- ],
88
- )
101
+ ],
102
+ wait=False,
103
+ )
104
+ )
89
105
 
90
106
  try:
91
107
  yield
92
108
 
93
109
  finally:
94
110
  log.info('Checking final clock skew...')
95
- for rem in ctx.cluster.remotes.keys():
96
- rem.run(
111
+ cluster = filter_out_containers(ctx.cluster)
112
+ run.wait(
113
+ cluster.run(
97
114
  args=[
98
115
  'PATH=/usr/bin:/usr/sbin', 'ntpq', '-p', run.Raw('||'),
99
116
  'PATH=/usr/bin:/usr/sbin', 'chronyc', 'sources',
100
117
  run.Raw('||'),
101
118
  'true'
102
- ],
103
- )
119
+ ],
120
+ wait=False,
121
+ )
122
+ )
teuthology/task/exec.py CHANGED
@@ -23,6 +23,16 @@ def task(ctx, config):
23
23
  It stops and fails with the first command that does not return on success. It means
24
24
  that if the first command fails, the second won't run at all.
25
25
 
26
+ You can run a command on all hosts `all-hosts`, or all roles with `all-roles`:
27
+
28
+ tasks:
29
+ - exec:
30
+ all-hosts:
31
+ - touch /etc/passwd
32
+ - exec:
33
+ all-roles:
34
+ - pwd
35
+
26
36
  To avoid confusion it is recommended to explicitly enclose the commands in
27
37
  double quotes. For instance if the command is false (without double quotes) it will
28
38
  be interpreted as a boolean by the YAML parser.
@@ -39,6 +49,14 @@ def task(ctx, config):
39
49
  a = config['all']
40
50
  roles = teuthology.all_roles(ctx.cluster)
41
51
  config = dict((id_, a) for id_ in roles)
52
+ elif 'all-roles' in config and len(config) == 1:
53
+ a = config['all-roles']
54
+ roles = teuthology.all_roles(ctx.cluster)
55
+ config = dict((id_, a) for id_ in roles)
56
+ elif 'all-hosts' in config and len(config) == 1:
57
+ a = config['all-hosts']
58
+ roles = [roles[0] for roles in ctx.cluster.remotes.values()]
59
+ config = dict((id_, a) for id_ in roles)
42
60
 
43
61
  for role, ls in config.items():
44
62
  (remote,) = ctx.cluster.only(role).remotes.keys()
teuthology/task/hadoop.py CHANGED
@@ -259,8 +259,8 @@ def install_hadoop(ctx, config):
259
259
  format = "jar",
260
260
  dist = "precise",
261
261
  arch = "x86_64",
262
- flavor = "basic",
263
- branch = "master")
262
+ flavor = "default",
263
+ branch = "main")
264
264
 
265
265
  run.wait(
266
266
  hadoops.run(
@@ -9,6 +9,7 @@ from teuthology import misc as teuthology
9
9
  from teuthology import contextutil, packaging
10
10
  from teuthology.parallel import parallel
11
11
  from teuthology.task import ansible
12
+ from teuthology.exceptions import ConfigError
12
13
 
13
14
  from distutils.version import LooseVersion
14
15
  from teuthology.task.install.util import (
@@ -99,11 +100,13 @@ def remove_packages(ctx, config, pkgs):
99
100
  "deb": deb._remove,
100
101
  "rpm": rpm._remove,
101
102
  }
103
+ cleanup = config.get('cleanup', False)
102
104
  with parallel() as p:
103
105
  for remote in ctx.cluster.remotes.keys():
104
- system_type = teuthology.get_system_type(remote)
105
- p.spawn(remove_pkgs[
106
- system_type], ctx, config, remote, pkgs[system_type])
106
+ if not remote.is_reimageable or cleanup:
107
+ system_type = teuthology.get_system_type(remote)
108
+ p.spawn(remove_pkgs[
109
+ system_type], ctx, config, remote, pkgs[system_type])
107
110
 
108
111
 
109
112
  def remove_sources(ctx, config):
@@ -117,13 +120,15 @@ def remove_sources(ctx, config):
117
120
  'deb': deb._remove_sources_list,
118
121
  'rpm': rpm._remove_sources_list,
119
122
  }
123
+ cleanup = config.get('cleanup', False)
124
+ project = config.get('project', 'ceph')
120
125
  with parallel() as p:
121
- project = config.get('project', 'ceph')
122
- log.info("Removing {proj} sources lists".format(
123
- proj=project))
124
126
  for remote in ctx.cluster.remotes.keys():
125
- remove_fn = remove_sources_pkgs[remote.os.package_type]
126
- p.spawn(remove_fn, ctx, config, remote)
127
+ if not remote.is_reimageable or cleanup:
128
+ log.info("Removing {p} sources lists on {r}"
129
+ .format(p=project,r=remote))
130
+ remove_fn = remove_sources_pkgs[remote.os.package_type]
131
+ p.spawn(remove_fn, ctx, config, remote)
127
132
 
128
133
 
129
134
  def get_package_list(ctx, config):
@@ -278,7 +283,7 @@ def upgrade_remote_to_config(ctx, config):
278
283
  # take any remote in the dict
279
284
  remote = next(iter(remotes_dict))
280
285
  if remote in remotes:
281
- log.warn('remote %s came up twice (role %s)', remote, role)
286
+ log.warning('remote %s came up twice (role %s)', remote, role)
282
287
  continue
283
288
  remotes[remote] = config.get(role)
284
289
 
@@ -454,6 +459,12 @@ def task(ctx, config):
454
459
  are welcome to add support for other distros.
455
460
 
456
461
 
462
+ Enable Fedora copr repositories using enable_coprs:
463
+
464
+ - install:
465
+ enable_coprs: [ceph/el9]
466
+
467
+
457
468
  Overrides are project specific:
458
469
 
459
470
  overrides:
@@ -538,8 +549,8 @@ def task(ctx, config):
538
549
  sha1: 1234
539
550
 
540
551
  where sha1 matches the --ceph argument. For instance if
541
- teuthology-suite is called with --ceph master, the sha1 will be
542
- the tip of master. If called with --ceph v0.94.1, the sha1 will be
552
+ teuthology-suite is called with --ceph main, the sha1 will be
553
+ the tip of main. If called with --ceph v0.94.1, the sha1 will be
543
554
  the v0.94.1 (as returned by git rev-parse v0.94.1 which is not to
544
555
  be confused with git rev-parse v0.94.1^{commit})
545
556
 
@@ -555,11 +566,25 @@ def task(ctx, config):
555
566
  log.debug('project %s' % project)
556
567
  overrides = ctx.config.get('overrides')
557
568
  repos = None
569
+
558
570
  if overrides:
559
- install_overrides = overrides.get('install', {})
560
- teuthology.deep_merge(config, install_overrides.get(project, {}))
561
- repos = install_overrides.get('repos', None)
562
- log.debug('INSTALL overrides: %s' % install_overrides)
571
+ try:
572
+ install_overrides = overrides.get('install', {})
573
+ log.debug('INSTALL overrides: %s' % install_overrides)
574
+ teuthology.deep_merge(config, install_overrides.get(project, {}))
575
+ overrides_extra_system_packages = install_overrides.get('extra_system_packages')
576
+ if overrides_extra_system_packages:
577
+ extra_system_packages = config.get('extra_system_packages')
578
+ config['extra_system_packages'] = teuthology.deep_merge(extra_system_packages, overrides_extra_system_packages)
579
+ repos = install_overrides.get('repos', None)
580
+ except AssertionError:
581
+ raise ConfigError(
582
+ "'install' task config and its overrides contain" \
583
+ "conflicting types for the same config key. Ensure that " \
584
+ "the configuration is of the same type (dict, list, etc.) " \
585
+ "in both the task definition and its overrides."
586
+ )
587
+
563
588
  log.debug('config %s' % config)
564
589
 
565
590
  rhbuild = None
@@ -588,23 +613,27 @@ def task(ctx, config):
588
613
  else:
589
614
  nested_config = dict(
590
615
  branch=config.get('branch'),
591
- tag=config.get('tag'),
592
- sha1=config.get('sha1'),
616
+ cleanup=config.get('cleanup'),
593
617
  debuginfo=config.get('debuginfo'),
594
- flavor=flavor,
595
618
  downgrade_packages=config.get('downgrade_packages', []),
619
+ exclude_packages=config.get('exclude_packages', []),
596
620
  extra_packages=config.get('extra_packages', []),
597
621
  extra_system_packages=config.get('extra_system_packages', []),
598
- exclude_packages=config.get('exclude_packages', []),
599
622
  extras=config.get('extras', None),
600
- wait_for_package=config.get('wait_for_package', False),
601
- project=project,
602
- packages=config.get('packages', dict()),
623
+ enable_coprs=config.get('enable_coprs', []),
624
+ flavor=flavor,
603
625
  install_ceph_packages=config.get('install_ceph_packages', True),
626
+ packages=config.get('packages', dict()),
627
+ project=project,
604
628
  repos_only=config.get('repos_only', False),
629
+ sha1=config.get('sha1'),
630
+ tag=config.get('tag'),
631
+ wait_for_package=config.get('wait_for_package', False),
605
632
  )
606
633
  if repos:
607
634
  nested_config['repos'] = repos
635
+ if 'shaman' in config:
636
+ nested_config['shaman'] = config['shaman']
608
637
  with contextutil.nested(
609
638
  lambda: install(ctx=ctx, config=nested_config),
610
639
  lambda: ship_utilities(ctx=ctx, config=None),
@@ -0,0 +1,16 @@
1
+ #!/bin/sh
2
+ # If we're running as root, allow large amounts of open files.
3
+ USER=$(whoami)
4
+
5
+ # If a ulimit call fails, exit immediately.
6
+ set -e
7
+
8
+ if [ "$USER" = "root" ]
9
+ then
10
+ # Enable large number of open files
11
+ ulimit -n 65536
12
+ fi
13
+
14
+ # Enable core dumps for everything
15
+ ulimit -c unlimited
16
+ exec "$@"
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/python3
2
+
3
+ """
4
+ Helper script for running long-living processes.
5
+
6
+ (Name says daemon, but that is intended to mean "long-living", we
7
+ assume child process does not double-fork.)
8
+
9
+ We start the command passed as arguments, with /dev/null as stdin, and
10
+ then wait for EOF on stdin.
11
+
12
+ When EOF is seen on stdin, the child process is killed.
13
+
14
+ When the child process exits, this helper exits too.
15
+
16
+ Usage:
17
+ daemon-helper <signal> [--kill-group] [nostdin] COMMAND ...
18
+ """
19
+
20
+ from __future__ import print_function
21
+
22
+ import fcntl
23
+ import os
24
+ import select
25
+ import signal
26
+ import struct
27
+ import subprocess
28
+ import sys
29
+ from argparse import ArgumentParser
30
+
31
+ parser = ArgumentParser(epilog=
32
+ 'The remaining parameters are the command to be run. If these\n' +
33
+ 'parameters start wih nostdin, then no stdin input is expected.')
34
+ parser.add_argument('signal')
35
+ parser.add_argument('--kill-group', action='store_true',
36
+ help='kill all processes in the group')
37
+ parser.add_argument('--nostdin', action='store_true',
38
+ help='no stdin input expected')
39
+ parsed, args = parser.parse_known_args()
40
+ end_signal = signal.SIGKILL
41
+ if parsed.signal == 'term':
42
+ end_signal = signal.SIGTERM
43
+ group = parsed.kill_group
44
+ nostdin = parsed.nostdin
45
+ skip_nostdin = 0
46
+ try:
47
+ if args[0] == 'nostdin':
48
+ nostdin = True
49
+ skip_nostdin = 1
50
+ except IndexError:
51
+ print('No command specified')
52
+ sys.exit(1)
53
+
54
+
55
+ proc = None
56
+ if nostdin:
57
+ if len(args) - skip_nostdin == 0:
58
+ print('No command specified')
59
+ sys.exit(1)
60
+ proc = subprocess.Popen(
61
+ args=args[skip_nostdin:],
62
+ )
63
+ else:
64
+ with open('/dev/null', 'rb') as devnull:
65
+ proc = subprocess.Popen(
66
+ args=args,
67
+ stdin=devnull,
68
+ preexec_fn=os.setsid,
69
+ )
70
+
71
+ flags = fcntl.fcntl(0, fcntl.F_GETFL)
72
+ fcntl.fcntl(0, fcntl.F_SETFL, flags | os.O_NDELAY)
73
+
74
+ saw_eof = False
75
+ while True:
76
+ r,w,x = select.select([0], [], [0], 0.2)
77
+ if r:
78
+ data = os.read(0, 1)
79
+ if not data:
80
+ saw_eof = True
81
+ if not group:
82
+ proc.send_signal(end_signal)
83
+ else:
84
+ os.killpg(proc.pid, end_signal)
85
+ break
86
+ else:
87
+ sig, = struct.unpack('!b', data)
88
+ if not group:
89
+ proc.send_signal(sig)
90
+ else:
91
+ os.killpg(proc.pid, end_signal)
92
+
93
+
94
+ if proc.poll() is not None:
95
+ # child exited
96
+ break
97
+
98
+ exitstatus = proc.wait()
99
+ if exitstatus > 0:
100
+ print('{me}: command failed with exit status {exitstatus:d}'.format(
101
+ me=os.path.basename(sys.argv[0]),
102
+ exitstatus=exitstatus,
103
+ ), file=sys.stderr)
104
+ sys.exit(exitstatus)
105
+ elif exitstatus < 0:
106
+ if saw_eof and exitstatus == -end_signal:
107
+ # suppress error from the exit we intentionally caused
108
+ pass
109
+ else:
110
+ print('{me}: command crashed with signal {signal:d}'.format(
111
+ me=os.path.basename(sys.argv[0]),
112
+ signal=-exitstatus,
113
+ ), file=sys.stderr)
114
+ sys.exit(1)