Introduce oneshot docker_restart_policy

docker_restart_policy: no causes systemd units to not get created
and we use it in CI to disable restarts on services.

Introducing oneshot policy to not create systemd unit for oneshot
containers (those that are running bootstrap tasks, like db
bootstrap and don't need a systemd unit), but still create systemd
units for long lived containers but with Restart=No.

Change-Id: I9e0d656f19143ec2fcad7d6d345b2c9387551604
This commit is contained in:
Michal Nasiadka 2023-04-27 11:41:55 +02:00
parent e545515e50
commit cea076f379
59 changed files with 83 additions and 71 deletions
ansible
library
module_utils
roles
releasenotes/notes
tests

@ -180,6 +180,7 @@ options:
choices:
- no
- on-failure
- oneshot
- always
- unless-stopped
restart_retries:
@ -314,6 +315,7 @@ def generate_module():
restart_policy=dict(required=False, type='str', choices=[
'no',
'on-failure',
'oneshot',
'always',
'unless-stopped']),
restart_retries=dict(required=False, type='int'),

@ -354,7 +354,7 @@ class DockerWorker(ContainerWorker):
self.changed = True
options = self.build_container_options()
self.dc.create_container(**options)
if self.params.get('restart_policy') != 'no':
if self.params.get('restart_policy') != 'oneshot':
self.changed |= self.systemd.create_unit_file()
def recreate_or_restart_container(self):
@ -397,7 +397,7 @@ class DockerWorker(ContainerWorker):
if not container['Status'].startswith('Up '):
self.changed = True
if self.params.get('restart_policy') == 'no':
if self.params.get('restart_policy') == 'oneshot':
self.dc.start(container=self.params.get('name'))
else:
self.systemd.create_unit_file()
@ -466,7 +466,7 @@ class DockerWorker(ContainerWorker):
msg="No such container: {}".format(name))
else:
self.changed = True
if self.params.get('restart_policy') != 'no':
if self.params.get('restart_policy') != 'oneshot':
self.systemd.create_unit_file()
if not self.systemd.restart():
self.module.fail_json(

@ -535,7 +535,7 @@ class PodmanWorker(ContainerWorker):
if container.status != 'running':
self.changed = True
if self.params.get('restart_policy') == 'no':
if self.params.get('restart_policy') == 'oneshot':
container = self.check_container()
container.start()
else:
@ -583,7 +583,7 @@ class PodmanWorker(ContainerWorker):
elif not (container.status == 'exited' or
container.status == 'stopped'):
self.changed = True
if self.params.get('restart_policy') != 'no':
if self.params.get('restart_policy') != 'oneshot':
self.systemd.create_unit_file()
self.systemd.stop()
else:

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_aodh"
restart_policy: no
restart_policy: oneshot
volumes: "{{ aodh_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[aodh_api.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_barbican"
restart_policy: no
restart_policy: oneshot
volumes: "{{ barbican_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[barbican_api.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_blazar"
restart_policy: no
restart_policy: oneshot
volumes: "{{ blazar_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[blazar_api.group][0] }}"

@ -16,7 +16,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_ceilometer"
restart_policy: no
restart_policy: oneshot
volumes: "{{ ceilometer_notification.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[ceilometer_notification.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_cinder"
restart_policy: no
restart_policy: oneshot
volumes: "{{ cinder_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[cinder_api.group][0] }}"

@ -30,7 +30,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_cinder"
restart_policy: no
restart_policy: oneshot
volumes: "{{ cinder_api.volumes }}"
run_once: True
delegate_to: "{{ groups[cinder_api.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_cloudkitty"
restart_policy: no
restart_policy: oneshot
volumes: "{{ cloudkitty_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[cloudkitty_api.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_cyborg"
restart_policy: no
restart_policy: oneshot
volumes: "{{ cyborg_api.volumes }}"
run_once: True
delegate_to: "{{ groups[cyborg_api.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_designate"
restart_policy: no
restart_policy: oneshot
volumes: "{{ designate_central.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[designate_central.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_freezer"
restart_policy: no
restart_policy: oneshot
volumes: "{{ freezer_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[freezer_api.group][0] }}"

@ -31,7 +31,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_glance"
restart_policy: no
restart_policy: oneshot
volumes: "{{ glance_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ glance_api_hosts[0] }}"

@ -43,7 +43,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_glance"
restart_policy: no
restart_policy: oneshot
volumes: "{{ glance_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ glance_api_hosts[0] }}"
@ -64,7 +64,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_glance"
restart_policy: no
restart_policy: oneshot
volumes: "{{ glance_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ glance_api_hosts[0] }}"
@ -96,7 +96,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_glance"
restart_policy: no
restart_policy: oneshot
volumes: "{{ glance_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ glance_api_hosts[0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_gnocchi"
restart_policy: no
restart_policy: oneshot
volumes: "{{ gnocchi_api.volumes }}"
run_once: True
delegate_to: "{{ groups[gnocchi_api.group][0] }}"

@ -24,7 +24,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_heat"
restart_policy: no
restart_policy: oneshot
volumes: "{{ heat_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[heat_api.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_horizon"
restart_policy: no
restart_policy: oneshot
volumes: "{{ horizon.volumes }}"
run_once: True
delegate_to: "{{ groups[horizon.group][0] }}"

@ -18,7 +18,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_ironic"
restart_policy: no
restart_policy: oneshot
volumes: "{{ ironic_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[ironic_api.group][0] }}"
@ -39,7 +39,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_ironic_inspector"
restart_policy: no
restart_policy: oneshot
volumes: "{{ ironic_inspector.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[ironic_inspector.group][0] }}"
@ -62,6 +62,6 @@
labels:
BOOTSTRAP:
name: "bootstrap_ironic_tftp"
restart_policy: no
restart_policy: oneshot
volumes: "{{ ironic_tftp.volumes }}"
when: inventory_hostname in groups[ironic_tftp.group]

@ -42,7 +42,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_ironic"
restart_policy: no
restart_policy: oneshot
volumes: "{{ ironic_api.volumes }}"
run_once: True
delegate_to: "{{ groups[ironic_api.group][0] }}"

@ -18,7 +18,7 @@
labels:
KOLLA_UPGRADE:
name: "init_upgrade_database"
restart_policy: no
restart_policy: oneshot
volumes: "{{ service.volumes | reject('equalto', '') | list }}"
dimensions: "{{ service.dimensions }}"
run_once: True
@ -90,7 +90,7 @@
labels:
KOLLA_UPGRADE:
name: "finish_upgrade_database"
restart_policy: no
restart_policy: oneshot
volumes: "{{ service.volumes | reject('equalto', '') | list }}"
dimensions: "{{ service.dimensions }}"
run_once: True

@ -45,7 +45,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_keystone"
restart_policy: no
restart_policy: oneshot
volumes: "{{ keystone.volumes | reject('equalto', '') | list }}"
run_once: True
@ -67,7 +67,7 @@
keystone-manage --config-file /etc/keystone/keystone.conf
fernet_setup --keystone-user {{ keystone_username }} --keystone-group {{ keystone_groupname }}'
name: "bootstrap_keystone_fernet"
restart_policy: no
restart_policy: oneshot
volumes: "{{ keystone_fernet.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups['keystone'][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_magnum"
restart_policy: no
restart_policy: oneshot
volumes: "{{ magnum_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[magnum_api.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_manila"
restart_policy: no
restart_policy: oneshot
volumes: "{{ manila_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[manila_api.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "{{ service.container_name }}"
restart_policy: no
restart_policy: oneshot
volumes: "{{ service.volumes }}"
dimensions: "{{ service.dimensions }}"
listen: Bootstrap MariaDB cluster

@ -8,7 +8,7 @@
detach: False
image: "{{ mariabackup_image_full }}"
name: "mariabackup"
restart_policy: no
restart_policy: oneshot
remove_on_exit: True
environment:
BACKUP_TYPE: "{{ mariadb_backup_type }}"

@ -17,7 +17,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_mariadb"
restart_policy: no
restart_policy: oneshot
volumes: "{{ service.volumes }}"
notify:
- Bootstrap MariaDB cluster

@ -19,6 +19,6 @@
labels:
UPGRADE:
name: "upgrade_mariadb"
restart_policy: no
restart_policy: oneshot
volumes: "{{ service.volumes }}"
no_log: true

@ -38,7 +38,7 @@
labels:
BOOTSTRAP:
name: mariadb_wsrep_recovery
restart_policy: no
restart_policy: oneshot
volumes: "{{ mariadb_service.volumes }}"
- name: Copying MariaDB log file to /tmp
@ -120,7 +120,7 @@
labels:
BOOTSTRAP:
name: "{{ mariadb_service.container_name }}"
restart_policy: no
restart_policy: oneshot
volumes: "{{ mariadb_service.volumes }}"
when:
- bootstrap_host is defined

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_masakari"
restart_policy: "no"
restart_policy: "oneshot"
volumes: "{{ masakari_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[masakari_api.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_mistral"
restart_policy: no
restart_policy: oneshot
volumes: "{{ mistral_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[mistral_api.group][0] }}"

@ -12,7 +12,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_murano"
restart_policy: no
restart_policy: oneshot
volumes:
- "{{ node_config_directory }}/murano-api/:{{ container_config_directory }}/:ro"
- "/etc/localtime:/etc/localtime:ro"

@ -15,7 +15,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_neutron"
restart_policy: no
restart_policy: oneshot
volumes: "{{ neutron_server.volumes }}"
run_once: True
delegate_to: "{{ groups[neutron_server.group][0] }}"

@ -27,7 +27,7 @@
labels:
UPGRADE:
name: "bootstrap_neutron"
restart_policy: no
restart_policy: oneshot
volumes: "{{ neutron_server.volumes }}"
run_once: True
delegate_to: "{{ groups['neutron-server'][0] }}"
@ -79,7 +79,7 @@
labels:
UPGRADE:
name: "bootstrap_neutron"
restart_policy: no
restart_policy: oneshot
volumes: "{{ neutron_server.volumes }}"
run_once: True
delegate_to: "{{ groups['neutron-server'][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "nova_cell_bootstrap"
restart_policy: no
restart_policy: oneshot
volumes: "{{ nova_cell_bootstrap_default_volumes + nova_cell_bootstrap_extra_volumes }}"
register: bootstrap_result
changed_when: bootstrap_result.stdout | default("") | length > 0

@ -16,7 +16,7 @@
labels:
BOOTSTRAP:
name: "create_cell_nova"
restart_policy: no
restart_policy: oneshot
volumes: "{{ nova_cell_bootstrap_default_volumes + nova_cell_bootstrap_extra_volumes }}"
register: nova_cell_create
changed_when:
@ -42,7 +42,7 @@
labels:
BOOTSTRAP:
name: "create_cell_nova"
restart_policy: no
restart_policy: oneshot
volumes: "{{ nova_cell_bootstrap_default_volumes + nova_cell_bootstrap_extra_volumes }}"
register: nova_cell_updated
changed_when:

@ -12,7 +12,7 @@
labels:
BOOTSTRAP:
name: "nova_list_cells"
restart_policy: no
restart_policy: oneshot
volumes: "{{ nova_cell_bootstrap_default_volumes + nova_cell_bootstrap_extra_volumes }}"
register: existing_cells_list
changed_when: false

@ -14,6 +14,6 @@
labels:
BOOTSTRAP:
name: "nova_cell_online_data_migrations"
restart_policy: "no"
restart_policy: "oneshot"
volumes: "{{ nova_cell_bootstrap_default_volumes + nova_cell_bootstrap_extra_volumes }}"
when: inventory_hostname == groups[nova_cell_conductor_group][0]

@ -16,7 +16,7 @@
labels:
BOOTSTRAP:
name: "nova_api_bootstrap"
restart_policy: no
restart_policy: oneshot
volumes: "{{ nova_api_bootstrap_default_volumes + nova_api_bootstrap_extra_volumes }}"
register: bootstrap_result
changed_when: bootstrap_result.stdout | default("") | length > 0

@ -13,7 +13,7 @@
labels:
BOOTSTRAP:
name: "nova_api_map_cell0"
restart_policy: no
restart_policy: oneshot
volumes: "{{ nova_api_bootstrap_default_volumes + nova_api_bootstrap_extra_volumes }}"
register: map_cell0
changed_when:

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "nova_api_online_data_migrations"
restart_policy: "no"
restart_policy: "oneshot"
volumes: "{{ nova_api_bootstrap_default_volumes + nova_api_bootstrap_extra_volumes }}"
run_once: true
delegate_to: "{{ groups[nova_api.group][0] }}"

@ -14,7 +14,7 @@
labels:
UPGRADE:
name: "nova_upgrade_checks"
restart_policy: no
restart_policy: oneshot
volumes: "{{ nova_api_default_volumes + nova_api_extra_volumes }}"
run_once: True
register: nova_upgrade_check_stdout

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_octavia"
restart_policy: no
restart_policy: oneshot
volumes: "{{ octavia_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[octavia_api.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_placement"
restart_policy: no
restart_policy: oneshot
volumes: "{{ placement_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[placement_api.group][0] }}"

@ -28,7 +28,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_placement"
restart_policy: no
restart_policy: oneshot
volumes: "{{ placement_api.volumes }}"
run_once: True
delegate_to: "{{ groups[placement_api.group][0] }}"

@ -21,6 +21,6 @@
labels:
BOOTSTRAP:
name: "{{ project_name }}_bootstrap"
restart_policy: no
restart_policy: oneshot
volumes: "{{ service.volumes }}"
when: rabbitmq_volume is changed

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_sahara"
restart_policy: no
restart_policy: oneshot
volumes: "{{ sahara_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[sahara_api.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_senlin"
restart_policy: no
restart_policy: oneshot
volumes: "{{ senlin_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[senlin_api.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_skyline"
restart_policy: no
restart_policy: oneshot
volumes: "{{ skyline_apiserver.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[skyline_apiserver.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_solum"
restart_policy: no
restart_policy: oneshot
volumes: "{{ solum_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[solum_api.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_tacker"
restart_policy: no
restart_policy: oneshot
volumes: "{{ tacker_server.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[tacker_server.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_trove"
restart_policy: no
restart_policy: oneshot
volumes: "{{ trove_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[trove_api.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_vitrage"
restart_policy: no
restart_policy: oneshot
volumes: "{{ vitrage_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[vitrage_api.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_watcher"
restart_policy: no
restart_policy: oneshot
volumes: "{{ watcher_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[watcher_api.group][0] }}"

@ -14,7 +14,7 @@
labels:
BOOTSTRAP:
name: "bootstrap_zun"
restart_policy: no
restart_policy: oneshot
volumes: "{{ zun_api.volumes | reject('equalto', '') | list }}"
run_once: True
delegate_to: "{{ groups[zun_api.group][0] }}"

@ -0,0 +1,9 @@
---
features:
- |
Adds new ``restart_policy`` called ``oneshot`` that does not create
systemd units and is used for bootstrap tasks.
upgrade:
- |
``restart_policy: no`` will now create systemd units, but with
``Restart`` property set to ``no``.

@ -478,7 +478,7 @@ class TestContainer(base.BaseTestCase):
def test_start_container_no_systemd(self):
self.fake_data['params'].update({'name': 'my_container',
'restart_policy': 'no',
'restart_policy': 'oneshot',
'auth_username': 'fake_user',
'auth_password': 'fake_psw',
'auth_registry': 'myrepo/myapp',
@ -537,7 +537,7 @@ class TestContainer(base.BaseTestCase):
def test_stop_container_no_systemd(self):
self.dw = get_DockerWorker({'name': 'my_container',
'action': 'stop_container',
'restart_policy': 'no'})
'restart_policy': 'oneshot'})
self.dw.dc.containers.return_value = self.fake_data['containers']
self.dw.systemd.check_unit_file.return_value = False
self.dw.stop_container()
@ -624,7 +624,7 @@ class TestContainer(base.BaseTestCase):
def test_restart_container_no_systemd(self):
self.dw = get_DockerWorker({'name': 'my_container',
'action': 'stop_container',
'restart_policy': 'no'})
'restart_policy': 'oneshot'})
self.dw.dc.containers.return_value = self.fake_data['containers']
self.fake_data['container_inspect'].update(
self.fake_data['containers'][0])

@ -373,7 +373,7 @@ class TestContainer(base.BaseTestCase):
def test_start_container_no_systemd(self):
self.fake_data['params'].update({'name': 'my_container',
'restart_policy': 'no',
'restart_policy': 'oneshot',
'auth_username': 'fake_user',
'auth_password': 'fake_psw',
'auth_registry': 'myrepo/myapp',
@ -437,7 +437,7 @@ class TestContainer(base.BaseTestCase):
def test_stop_container_no_systemd(self):
self.pw = get_PodmanWorker({'name': 'my_container',
'action': 'stop_container',
'restart_policy': 'no'})
'restart_policy': 'oneshot'})
full_cont_list = get_containers(self.fake_data['containers'])
container = full_cont_list[0]
self.pw.pc.containers.list.return_value = full_cont_list

@ -83,6 +83,7 @@ class ModuleArgsTest(base.BaseTestCase):
restart_policy=dict(
required=False, type='str', choices=['no',
'on-failure',
'oneshot',
'always',
'unless-stopped']),
restart_retries=dict(required=False, type='int'),