systemd - do not overwrite unit name when searching (#72985)

* systemd - do not overwrite unit name when searching

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

* Remov 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
This commit is contained in:
Sam Doooran 2020-12-17 15:29:22 -05:00 committed by GitHub
parent 13bf04e95a
commit 48803604cd
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

@ -415,10 +415,10 @@ def main():
elif err and rc == 1 and 'Failed to parse bus message' in err: elif err and rc == 1 and 'Failed to parse bus message' in err:
result['status'] = parse_systemctl_show(to_native(out).split('\n')) result['status'] = parse_systemctl_show(to_native(out).split('\n'))
unit, sep, suffix = unit.partition('@') unit_base, sep, suffix = unit.partition('@')
unit_search = '{unit}{sep}*'.format(unit=unit, sep=sep) 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)) (rc, out, err) = module.run_command("{systemctl} list-unit-files '{unit_search}*'".format(systemctl=systemctl, unit_search=unit_search))
is_systemd = unit in out is_systemd = unit_search in out
(rc, out, err) = module.run_command("{systemctl} is-active '{unit}'".format(systemctl=systemctl, unit=unit)) (rc, out, err) = module.run_command("{systemctl} is-active '{unit}'".format(systemctl=systemctl, unit=unit))
result['status']['ActiveState'] = out.rstrip('\n') 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 ## systemctl
## ##
- name: check for systemctl command - name: End if this system does not use systemd
shell: which systemctl meta: end_host
failed_when: False when: ansible_facts.service_mgr != 'systemd'
register: systemctl_check
- meta: end_host - name: Include distribution specific variables
when: systemctl_check.rc != 0 include_vars: "{{ lookup('first_found', params) }}"
vars:
params:
files:
- "{{ ansible_facts.distribution }}.yml"
- "{{ ansible_facts.os_family }}.yml"
- default.yml
paths:
- vars
- set_fact: - name: get a list of running services
ssh_service: '{{ "ssh" if ansible_os_family == "Debian" else "sshd" }}' 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: check running state
- name: get a list of running services systemd:
shell: systemctl | fgrep 'running' | awk '{print $1}' | sed 's/\.service//g' | fgrep -v '.' | egrep ^[a-z] name: "{{ running_names.stdout_lines|random }}"
register: running_names state: started
- debug: var=running_names 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 - name: the module must fail when a service is not found
systemd: systemd:
name: "{{ running_names.stdout_lines|random }}" name: '{{ fake_service }}'
state: started state: stopped
register: systemd_test0 register: result
- debug: var=systemd_test0 ignore_errors: yes
- 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 - assert:
systemd: that:
name: '{{ fake_service }}' - result is failed
state: stopped - 'result is search("Could not find the requested service {{ fake_service }}")'
register: result
ignore_errors: yes
- assert: - name: the module must fail in check_mode as well when a service is not found
that: systemd:
- result is failed name: '{{ fake_service }}'
- 'result is search("Could not find the requested service {{ 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 - assert:
systemd: that:
name: '{{ fake_service }}' - result is failed
state: stopped - 'result is search("Could not find the requested service {{ fake_service }}")'
register: result
check_mode: yes
ignore_errors: yes
- assert: - name: check that the module works even when systemd is offline (eg in chroot)
that: systemd:
- result is failed name: "{{ running_names.stdout_lines|random }}"
- 'result is search("Could not find the requested service {{ fake_service }}")' state: started
environment:
- name: check that the module works even when systemd is offline (eg in chroot) SYSTEMD_OFFLINE: 1
systemd:
name: "{{ running_names.stdout_lines|random }}"
state: started
environment:
SYSTEMD_OFFLINE: 1
- name: Disable ssh 1 - name: Disable ssh 1
systemd: systemd:
@ -114,3 +117,5 @@
- systemd_disable_ssh_2 is not changed - systemd_disable_ssh_2 is not changed
- systemd_enable_ssh_1 is changed - systemd_enable_ssh_1 is changed
- systemd_enable_ssh_2 is not 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