summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Cassell <code@james.cassell.me>2020-02-05 15:14:57 -0500
committerGitHub <noreply@github.com>2020-02-05 15:14:57 -0500
commitb868f1c933bf2e2d3efd1d20c1cfa1ed9326ea44 (patch)
tree013c1cac16fe4e9a2ff15dd6caa40cf9f233d127
parent48505af9d263411fb14060e9e55bc82b95d4bfe3 (diff)
downloadansible-b868f1c933bf2e2d3efd1d20c1cfa1ed9326ea44.tar.gz
fix systemd use in container builds (#66062)
* systemd: unify "systemctl show" failure cases * systemd: is-enabled to detect configured state * systemd: is-enabled to detect masked status
-rw-r--r--changelogs/fragments/systemd-offline.yml3
-rw-r--r--lib/ansible/modules/system/systemd.py40
2 files changed, 32 insertions, 11 deletions
diff --git a/changelogs/fragments/systemd-offline.yml b/changelogs/fragments/systemd-offline.yml
new file mode 100644
index 0000000000..2001694c4b
--- /dev/null
+++ b/changelogs/fragments/systemd-offline.yml
@@ -0,0 +1,3 @@
+bugfixes:
+- systemd - don't require systemd to be running to enable/disable or mask/unmask
+ units
diff --git a/lib/ansible/modules/system/systemd.py b/lib/ansible/modules/system/systemd.py
index 4d8c4f52f7..eaae69b7f2 100644
--- a/lib/ansible/modules/system/systemd.py
+++ b/lib/ansible/modules/system/systemd.py
@@ -404,14 +404,7 @@ def main():
# check service data, cannot error out on rc as it changes across versions, assume not found
(rc, out, err) = module.run_command("%s show '%s'" % (systemctl, unit))
- if request_was_ignored(out) or request_was_ignored(err):
- # fallback list-unit-files as show does not work on some systems (chroot)
- # not used as primary as it skips some services (like those using init.d) and requires .service/etc notation
- (rc, out, err) = module.run_command("%s list-unit-files '%s'" % (systemctl, unit))
- if rc == 0:
- is_systemd = True
-
- elif rc == 0:
+ if rc == 0 and not (request_was_ignored(out) or request_was_ignored(err)):
# load return of systemctl show into dictionary for easy access and return
if out:
result['status'] = parse_systemctl_show(to_native(out).split('\n'))
@@ -424,8 +417,32 @@ def main():
if is_systemd and not is_masked and 'LoadError' in result['status']:
module.fail_json(msg="Error loading unit file '%s': %s" % (unit, result['status']['LoadError']))
else:
- # Check for systemctl command
- module.run_command(systemctl, check_rc=True)
+ # list taken from man systemctl(1) for systemd 244
+ valid_enabled_states = [
+ "enabled",
+ "enabled-runtime",
+ "linked",
+ "linked-runtime",
+ "masked",
+ "masked-runtime",
+ "static",
+ "indirect",
+ "disabled",
+ "generated",
+ "transient"]
+
+ (rc, out, err) = module.run_command("%s is-enabled '%s'" % (systemctl, unit))
+ if out.strip() in valid_enabled_states:
+ is_systemd = True
+ else:
+ # fallback list-unit-files as show does not work on some systems (chroot)
+ # not used as primary as it skips some services (like those using init.d) and requires .service/etc notation
+ (rc, out, err) = module.run_command("%s list-unit-files '%s'" % (systemctl, unit))
+ if rc == 0:
+ is_systemd = True
+ else:
+ # Check for systemctl command
+ module.run_command(systemctl, check_rc=True)
# Does service exist?
found = is_systemd or is_initd
@@ -435,7 +452,8 @@ def main():
# mask/unmask the service, if requested, can operate on services before they are installed
if module.params['masked'] is not None:
# state is not masked unless systemd affirms otherwise
- masked = ('LoadState' in result['status'] and result['status']['LoadState'] == 'masked')
+ (rc, out, err) = module.run_command("%s is-enabled '%s'" % (systemctl, unit))
+ masked = out.strip() == "masked"
if masked != module.params['masked']:
result['changed'] = True