diff --git a/changelogs/fragments/10400-sysrc.yml b/changelogs/fragments/10400-sysrc.yml new file mode 100644 index 0000000000..ac5d5a5f3f --- /dev/null +++ b/changelogs/fragments/10400-sysrc.yml @@ -0,0 +1,2 @@ +bugfixes: + - "sysrc - use ``shlex`` to improve parsing of ``sysrc -e -a`` output (https://github.com/ansible-collections/community.general/issues/10394, https://github.com/ansible-collections/community.general/pull/10400)." diff --git a/plugins/modules/sysrc.py b/plugins/modules/sysrc.py index dad379d1c0..1202883c23 100644 --- a/plugins/modules/sysrc.py +++ b/plugins/modules/sysrc.py @@ -103,6 +103,7 @@ changed: """ from ansible.module_utils.basic import AnsibleModule +from shlex import split import re @@ -130,11 +131,12 @@ class Sysrc(object): Use this dictionary to preform the tests. """ (rc, out, err) = self.run_sysrc('-e', '-a') - conf = dict([i.split('=', 1) for i in out.splitlines()]) + conf = dict((part.split('=', 1) for part in split(out, comments=True))) + if self.value is None: return self.name in conf else: - return self.name in conf and conf[self.name] == '"%s"' % self.value + return conf.get(self.name) == self.value def contains(self): (rc, out, err) = self.run_sysrc('-n', self.name) diff --git a/tests/integration/targets/sysrc/files/10394.conf b/tests/integration/targets/sysrc/files/10394.conf new file mode 100644 index 0000000000..5e5c3f5c5d --- /dev/null +++ b/tests/integration/targets/sysrc/files/10394.conf @@ -0,0 +1,7 @@ +# Copyright (c) Ansible Project +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later +k1="v1" +jail_list=" + foo + bar" diff --git a/tests/integration/targets/sysrc/tasks/main.yml b/tests/integration/targets/sysrc/tasks/main.yml index 549a1b8387..c5c249e7cd 100644 --- a/tests/integration/targets/sysrc/tasks/main.yml +++ b/tests/integration/targets/sysrc/tasks/main.yml @@ -369,14 +369,67 @@ - "value_2 == sysrc_equals_sign_2.value" - "value_2 == conf.spamd_flags" + ## + ## sysrc - #10004 state=absent when using default settings will report `changed=true` + ## + - name: Test that a key from /etc/defaults/rc.conf is not used to mark changed + sysrc: + name: dumpdev + state: absent + path: /tmp/10004.conf + register: sysrc_10004_absent + + - name: Ensure that the defaults are not consulted + assert: + that: + - not sysrc_10004_absent.changed + + - name: Test that a delimited key from /etc/defaults/rc.conf is not used to mark changed + sysrc: + name: rc_conf_files + state: value_absent + path: /tmp/10004.conf + register: sysrc_10004_value_absent + + - name: Ensure that the default is not consulted + assert: + that: + - not sysrc_10004_value_absent.changed + + ## + ## sysrc - #10394 Ensure that files with multi-line values work + ## + - name: Copy 10394.conf + copy: + src: 10394.conf + dest: /tmp/10394.conf + + - name: Change value for k1 + sysrc: + name: k1 + value: v2 + path: /tmp/10394.conf + register: sysrc_10394_changed + + - name: Get file content + shell: "cat /tmp/10394.conf" + register: sysrc_10394_content + + - name: Ensure sysrc changed k1 from v1 to v2 + assert: + that: + - sysrc_10394_changed.changed + - > + 'k1="v2"' in sysrc_10394_content.stdout_lines + always: - name: Restore /etc/rc.conf copy: - content: "{{ cached_etc_rcconf_content }}" + content: "{{ cached_etc_rcconf_content.stdout }}" dest: /etc/rc.conf - name: Restore /boot/loader.conf copy: - content: "{{ cached_boot_loaderconf_content }}" + content: "{{ cached_boot_loaderconf_content.stdout }}" dest: /boot/loader.conf