summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Doran <sdoran@redhat.com>2021-01-11 01:47:00 -0500
committerGitHub <noreply@github.com>2021-01-11 00:47:00 -0600
commit1cd09b1ebcba3f54d31bdb0cf884bb2ab02d26d3 (patch)
treef3948847dcc66cecc06eb26659baad27ff2159b8
parentcf21e699d49b929ea88a5e21f97c4a7f5cc760e9 (diff)
downloadansible-1cd09b1ebcba3f54d31bdb0cf884bb2ab02d26d3.tar.gz
[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>
-rw-r--r--changelogs/fragments/systemd-preserve-full-unit-name.yml4
-rw-r--r--lib/ansible/modules/systemd.py8
-rw-r--r--test/integration/targets/systemd/handlers/main.yml4
-rw-r--r--test/integration/targets/systemd/tasks/main.yml133
-rw-r--r--test/integration/targets/systemd/tasks/test_unit_template.yml50
-rw-r--r--test/integration/targets/systemd/templates/sleeper@.service8
-rw-r--r--test/integration/targets/systemd/vars/Debian.yml2
-rw-r--r--test/integration/targets/systemd/vars/default.yml2
8 files changed, 143 insertions, 68 deletions
diff --git a/changelogs/fragments/systemd-preserve-full-unit-name.yml b/changelogs/fragments/systemd-preserve-full-unit-name.yml
new file mode 100644
index 0000000000..1af70a358d
--- /dev/null
+++ b/changelogs/fragments/systemd-preserve-full-unit-name.yml
@@ -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)
diff --git a/lib/ansible/modules/systemd.py b/lib/ansible/modules/systemd.py
index aed276c25a..26e79a547a 100644
--- a/lib/ansible/modules/systemd.py
+++ b/lib/ansible/modules/systemd.py
@@ -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')
diff --git a/test/integration/targets/systemd/handlers/main.yml b/test/integration/targets/systemd/handlers/main.yml
new file mode 100644
index 0000000000..8643a2a0ee
--- /dev/null
+++ b/test/integration/targets/systemd/handlers/main.yml
@@ -0,0 +1,4 @@
+- name: remove unit file
+ file:
+ path: /etc/systemd/system/sleeper@.service
+ state: absent
diff --git a/test/integration/targets/systemd/tasks/main.yml b/test/integration/targets/systemd/tasks/main.yml
index 867a554dea..96781eb825 100644
--- a/test/integration/targets/systemd/tasks/main.yml
+++ b/test/integration/targets/systemd/tasks/main.yml
@@ -20,70 +20,73 @@
## systemctl
##
-- name: check for systemctl command
- shell: which systemctl
- failed_when: False
- register: systemctl_check
-
-- meta: end_host
- when: systemctl_check.rc != 0
-
-- set_fact:
- ssh_service: '{{ "ssh" if ansible_os_family == "Debian" else "sshd" }}'
-
-- 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: 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 }}")'
-
- - 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 }}")'
-
- - 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: End if this system does not use systemd
+ meta: end_host
+ when: ansible_facts.service_mgr != 'systemd'
+
+- 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
+
+- 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: 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 }}")'
+
+- 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 }}")'
+
+- 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
diff --git a/test/integration/targets/systemd/tasks/test_unit_template.yml b/test/integration/targets/systemd/tasks/test_unit_template.yml
new file mode 100644
index 0000000000..47cb1c7872
--- /dev/null
+++ b/test/integration/targets/systemd/tasks/test_unit_template.yml
@@ -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
diff --git a/test/integration/targets/systemd/templates/sleeper@.service b/test/integration/targets/systemd/templates/sleeper@.service
new file mode 100644
index 0000000000..8b47982a01
--- /dev/null
+++ b/test/integration/targets/systemd/templates/sleeper@.service
@@ -0,0 +1,8 @@
+[Unit]
+Description=Basic service to use as a template
+
+[Service]
+ExecStart={{ sleep_bin_path }} %i
+
+[Install]
+WantedBy=multi-user.target
diff --git a/test/integration/targets/systemd/vars/Debian.yml b/test/integration/targets/systemd/vars/Debian.yml
new file mode 100644
index 0000000000..9760744d07
--- /dev/null
+++ b/test/integration/targets/systemd/vars/Debian.yml
@@ -0,0 +1,2 @@
+ssh_service: ssh
+sleep_bin_path: /bin/sleep
diff --git a/test/integration/targets/systemd/vars/default.yml b/test/integration/targets/systemd/vars/default.yml
new file mode 100644
index 0000000000..57491ff0df
--- /dev/null
+++ b/test/integration/targets/systemd/vars/default.yml
@@ -0,0 +1,2 @@
+ssh_service: sshd
+sleep_bin_path: /usr/bin/sleep