[stable-2.10] systemd - do not overwrite unit name when searching (#72985) (#73013)

PR #72702 introduced a bug that changed the unit name when splitting it up for the purpose
of searching for the unit. This only happens on unit file templates on systems that have a 5.8
or newer kernel and a version of systemd that does not contain a bugfix that causes systmed
to fail to parse dbus.

* Use facts rather than a manual probe to determine if systmed is present
* Remove unnecessary block
* Use vars files instead of set_fact
* Add tests for using a templated unit file
* Update changelog fragment
* Use template to get correct path to sleep binary
(cherry picked from commit 48803604cd)

Co-authored-by: Sam Doooran <sdoran@redhat.com>
This commit is contained in:
Sam Doran 2021-01-11 01:47:00 -05:00 committed by GitHub
parent cf21e699d4
commit 1cd09b1ebc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 135 additions and 60 deletions

View file

@ -0,0 +1,4 @@
bugfixes:
- >
systemd - preserve the full unit name when using a templated service and
``systemd`` failed to parse dbus due to a known bug in ``systemd`` (https://github.com/ansible/ansible/pull/72985)

View file

@ -420,10 +420,10 @@ def main():
elif err and rc == 1 and 'Failed to parse bus message' in err:
result['status'] = parse_systemctl_show(to_native(out).split('\n'))
unit, sep, suffix = unit.partition('@')
unit_search = '{unit}{sep}*'.format(unit=unit, sep=sep)
(rc, out, err) = module.run_command("{systemctl} list-unit-files '{unit_search}'".format(systemctl=systemctl, unit_search=unit_search))
is_systemd = unit in out
unit_base, sep, suffix = unit.partition('@')
unit_search = '{unit_base}{sep}'.format(unit_base=unit_base, sep=sep)
(rc, out, err) = module.run_command("{systemctl} list-unit-files '{unit_search}*'".format(systemctl=systemctl, unit_search=unit_search))
is_systemd = unit_search in out
(rc, out, err) = module.run_command("{systemctl} is-active '{unit}'".format(systemctl=systemctl, unit=unit))
result['status']['ActiveState'] = out.rstrip('\n')

View file

@ -0,0 +1,4 @@
- name: remove unit file
file:
path: /etc/systemd/system/sleeper@.service
state: absent

View file

@ -20,70 +20,73 @@
## systemctl
##
- name: check for systemctl command
shell: which systemctl
failed_when: False
register: systemctl_check
- name: End if this system does not use systemd
meta: end_host
when: ansible_facts.service_mgr != 'systemd'
- meta: end_host
when: systemctl_check.rc != 0
- name: Include distribution specific variables
include_vars: "{{ lookup('first_found', params) }}"
vars:
params:
files:
- "{{ ansible_facts.distribution }}.yml"
- "{{ ansible_facts.os_family }}.yml"
- default.yml
paths:
- vars
- set_fact:
ssh_service: '{{ "ssh" if ansible_os_family == "Debian" else "sshd" }}'
- name: get a list of running services
shell: systemctl | fgrep 'running' | awk '{print $1}' | sed 's/\.service//g' | fgrep -v '.' | egrep ^[a-z]
register: running_names
- debug: var=running_names
- block:
- name: get a list of running services
shell: systemctl | fgrep 'running' | awk '{print $1}' | sed 's/\.service//g' | fgrep -v '.' | egrep ^[a-z]
register: running_names
- debug: var=running_names
- name: check running state
systemd:
name: "{{ running_names.stdout_lines|random }}"
state: started
register: systemd_test0
- debug: var=systemd_test0
- name: validate results for test0
assert:
that:
- 'systemd_test0.changed is defined'
- 'systemd_test0.name is defined'
- 'systemd_test0.state is defined'
- 'systemd_test0.status is defined'
- 'not systemd_test0.changed'
- 'systemd_test0.state == "started"'
- name: check running state
systemd:
name: "{{ running_names.stdout_lines|random }}"
state: started
register: systemd_test0
- debug: var=systemd_test0
- name: validate results for test0
assert:
that:
- 'systemd_test0.changed is defined'
- 'systemd_test0.name is defined'
- 'systemd_test0.state is defined'
- 'systemd_test0.status is defined'
- 'not systemd_test0.changed'
- 'systemd_test0.state == "started"'
- name: the module must fail when a service is not found
systemd:
name: '{{ fake_service }}'
state: stopped
register: result
ignore_errors: yes
- name: the module must fail when a service is not found
systemd:
name: '{{ fake_service }}'
state: stopped
register: result
ignore_errors: yes
- assert:
that:
- result is failed
- 'result is search("Could not find the requested service {{ fake_service }}")'
- assert:
that:
- result is failed
- 'result is search("Could not find the requested service {{ fake_service }}")'
- name: the module must fail in check_mode as well when a service is not found
systemd:
name: '{{ fake_service }}'
state: stopped
register: result
check_mode: yes
ignore_errors: yes
- name: the module must fail in check_mode as well when a service is not found
systemd:
name: '{{ fake_service }}'
state: stopped
register: result
check_mode: yes
ignore_errors: yes
- assert:
that:
- result is failed
- 'result is search("Could not find the requested service {{ fake_service }}")'
- assert:
that:
- result is failed
- 'result is search("Could not find the requested service {{ fake_service }}")'
- name: check that the module works even when systemd is offline (eg in chroot)
systemd:
name: "{{ running_names.stdout_lines|random }}"
state: started
environment:
SYSTEMD_OFFLINE: 1
- name: check that the module works even when systemd is offline (eg in chroot)
systemd:
name: "{{ running_names.stdout_lines|random }}"
state: started
environment:
SYSTEMD_OFFLINE: 1
- name: Disable ssh 1
systemd:
@ -114,3 +117,5 @@
- systemd_disable_ssh_2 is not changed
- systemd_enable_ssh_1 is changed
- systemd_enable_ssh_2 is not changed
- import_tasks: test_unit_template.yml

View file

@ -0,0 +1,50 @@
- name: Copy service file
template:
src: sleeper@.service
dest: /etc/systemd/system/sleeper@.service
owner: root
group: root
mode: '0644'
notify: remove unit file
- name: Reload systemd
systemd:
daemon_reload: yes
- name: Start and enable service using unit template
systemd:
name: sleeper@100.service
state: started
enabled: yes
register: template_test_1
- name: Start and enable service using unit template again
systemd:
name: sleeper@100.service
state: started
enabled: yes
register: template_test_2
- name: Stop and disable service using unit template
systemd:
name: sleeper@100.service
state: stopped
enabled: no
register: template_test_3
- name: Stop and disable service using unit template again
systemd:
name: sleeper@100.service
state: stopped
enabled: no
register: template_test_4
- name:
assert:
that:
- template_test_1 is changed
- template_test_1 is success
- template_test_2 is not changed
- template_test_2 is success
- template_test_3 is changed
- template_test_4 is not changed

View file

@ -0,0 +1,8 @@
[Unit]
Description=Basic service to use as a template
[Service]
ExecStart={{ sleep_bin_path }} %i
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,2 @@
ssh_service: ssh
sleep_bin_path: /bin/sleep

View file

@ -0,0 +1,2 @@
ssh_service: sshd
sleep_bin_path: /usr/bin/sleep