594167
From db20c5cec8adf865dd47672bc091092b8cea5e0e Mon Sep 17 00:00:00 2001
594167
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
594167
Date: Thu, 10 Mar 2022 15:47:12 +0100
594167
Subject: [PATCH] shared/install: return failure when enablement fails, but
594167
 process as much as possible
594167
594167
So far we'd issue a warning (before this series, just in the logs on the server
594167
side, and before this commit, on stderr on the caller's side), but return
594167
success. It seems that successfull return was introduced by mistake in
594167
aa0f357fd833feecbea6c3e9be80b643e433bced (my fault :( ), which was supposed to
594167
be a refactoring without a functional change. I think it's better to fail,
594167
because if enablement fails, the user will most likely want to diagnose the
594167
issue.
594167
594167
Note that we still do partial enablement, as far as that is possible. So if
594167
e.g. we have [Install] Alias=foo.service foobar, we'll create the symlink
594167
'foo.service', but not 'foobar', since that's not a valid unit name. We'll
594167
print info about the action taken, and about 'foobar' being invalid, and return
594167
failure.
594167
594167
(cherry picked from commit 0d11db59825a9deee0b56fdede0602ef1c37c5c5)
594167
594167
Related: #2082131
594167
---
594167
 src/shared/install.c          | 10 +++++----
594167
 test/test-systemctl-enable.sh | 39 ++++++++++++++++++-----------------
594167
 2 files changed, 26 insertions(+), 23 deletions(-)
594167
594167
diff --git a/src/shared/install.c b/src/shared/install.c
594167
index 6da9ba6b0c..a541d32fb7 100644
594167
--- a/src/shared/install.c
594167
+++ b/src/shared/install.c
594167
@@ -1802,20 +1802,22 @@ static int install_info_symlink_alias(
594167
                 q = install_name_printf(scope, info, *s, info->root, &dst);
594167
                 if (q < 0) {
594167
                         unit_file_changes_add(changes, n_changes, q, *s, NULL);
594167
-                        return q;
594167
+                        r = r < 0 ? r : q;
594167
+                        continue;
594167
                 }
594167
 
594167
                 q = unit_file_verify_alias(info, dst, &dst_updated, changes, n_changes);
594167
-                if (q < 0)
594167
+                if (q < 0) {
594167
+                        r = r < 0 ? r : q;
594167
                         continue;
594167
+                }
594167
 
594167
                 alias_path = path_make_absolute(dst_updated ?: dst, config_path);
594167
                 if (!alias_path)
594167
                         return -ENOMEM;
594167
 
594167
                 q = create_symlink(lp, info->path, alias_path, force, changes, n_changes);
594167
-                if (r == 0)
594167
-                        r = q;
594167
+                r = r < 0 ? r : q;
594167
         }
594167
 
594167
         return r;
594167
diff --git a/test/test-systemctl-enable.sh b/test/test-systemctl-enable.sh
594167
index 8ac1342b91..32bc6e5ef7 100644
594167
--- a/test/test-systemctl-enable.sh
594167
+++ b/test/test-systemctl-enable.sh
594167
@@ -56,19 +56,27 @@ test ! -e "$root/etc/systemd/system/default.target.wants/test1.service"
594167
 test ! -e "$root/etc/systemd/system/special.target.requires/test1.service"
594167
 
594167
 : -------aliases----------------------------------------------
594167
-"$systemctl" --root="$root" enable test1
594167
-test -h "$root/etc/systemd/system/default.target.wants/test1.service"
594167
-test -h "$root/etc/systemd/system/special.target.requires/test1.service"
594167
-
594167
 cat >>"$root/etc/systemd/system/test1.service" <
594167
 Alias=test1-goodalias.service
594167
 Alias=test1@badalias.service
594167
 Alias=test1-badalias.target
594167
 Alias=test1-badalias.socket
594167
+# we have a series of good, bad, and then good again
594167
+Alias=test1-goodalias2.service
594167
 EOF
594167
 
594167
+"$systemctl" --root="$root" enable test1 && { echo "Expected failure" >&2; exit 1; }
594167
+test -h "$root/etc/systemd/system/default.target.wants/test1.service"
594167
+test -h "$root/etc/systemd/system/special.target.requires/test1.service"
594167
+test ! -e "$root/etc/systemd/system/test1-goodalias.service"
594167
+test -h "$root/etc/systemd/system/test1-goodalias.service"
594167
+test ! -e "$root/etc/systemd/system/test1@badalias.service"
594167
+test ! -e "$root/etc/systemd/system/test1-badalias.target"
594167
+test ! -e "$root/etc/systemd/system/test1-badalias.socket"
594167
+test -h "$root/etc/systemd/system/test1-goodalias2.service"
594167
+
594167
 : -------aliases in reeanble----------------------------------
594167
-"$systemctl" --root="$root" reenable test1
594167
+"$systemctl" --root="$root" reenable test1 && { echo "Expected failure" >&2; exit 1; }
594167
 test -h "$root/etc/systemd/system/default.target.wants/test1.service"
594167
 test ! -e "$root/etc/systemd/system/test1-goodalias.service"
594167
 test -h "$root/etc/systemd/system/test1-goodalias.service"
594167
@@ -328,7 +336,7 @@ Alias=link4alias.service
594167
 Alias=link4alias2.service
594167
 EOF
594167
 
594167
-"$systemctl" --root="$root" enable 'link4.service'
594167
+"$systemctl" --root="$root" enable 'link4.service' && { echo "Expected failure" >&2; exit 1; }
594167
 test ! -h "$root/etc/systemd/system/link4.service"  # this is our file
594167
 test ! -h "$root/etc/systemd/system/link4@.service"
594167
 test ! -h "$root/etc/systemd/system/link4@inst.service"
594167
@@ -343,18 +351,20 @@ test ! -h "$root/etc/systemd/system/link4alias.service"
594167
 test ! -h "$root/etc/systemd/system/link4alias2.service"
594167
 
594167
 : -------systemctl enable on path to unit file----------------
594167
+cat >"$root/etc/systemd/system/link4.service" <
594167
+[Install]
594167
+Alias=link4alias.service
594167
+Alias=link4alias2.service
594167
+EOF
594167
+
594167
 # Apparently this works. I'm not sure what to think.
594167
 "$systemctl" --root="$root" enable '/etc/systemd/system/link4.service'
594167
 test ! -h "$root/etc/systemd/system/link4.service"  # this is our file
594167
-test ! -h "$root/etc/systemd/system/link4@.service"
594167
-test ! -h "$root/etc/systemd/system/link4@inst.service"
594167
 islink "$root/etc/systemd/system/link4alias.service" "/etc/systemd/system/link4.service"
594167
 islink "$root/etc/systemd/system/link4alias2.service" "/etc/systemd/system/link4.service"
594167
 
594167
 "$systemctl" --root="$root" disable '/etc/systemd/system/link4.service'
594167
 test ! -h "$root/etc/systemd/system/link4.service"
594167
-test ! -h "$root/etc/systemd/system/link4@.service"
594167
-test ! -h "$root/etc/systemd/system/link4@inst.service"
594167
 test ! -h "$root/etc/systemd/system/link4alias.service"
594167
 test ! -h "$root/etc/systemd/system/link4alias2.service"
594167
 
594167
@@ -364,25 +374,18 @@ cat >"$root/etc/systemd/system/link5.service" <
594167
 [Install]
594167
 # FIXME: self-alias should be ignored
594167
 # Alias=link5.service
594167
-Alias=link5@.service
594167
-Alias=link5@inst.service
594167
 Alias=link5alias.service
594167
 Alias=link5alias2.service
594167
 EOF
594167
 
594167
 "$systemctl" --root="$root" enable 'link5.service'
594167
 test ! -h "$root/etc/systemd/system/link5.service"  # this is our file
594167
-test ! -h "$root/etc/systemd/system/link5@.service"
594167
-test ! -h "$root/etc/systemd/system/link5@inst.service"
594167
 # FIXME/CLARIFYME: will systemd think that link5alias2, link5alias, link5 are all aliases?
594167
 # https://github.com/systemd/systemd/issues/661#issuecomment-1057931149
594167
 islink "$root/etc/systemd/system/link5alias.service" "/etc/systemd/system/link5.service"
594167
 islink "$root/etc/systemd/system/link5alias2.service" "/etc/systemd/system/link5.service"
594167
 
594167
 "$systemctl" --root="$root" disable 'link5.service'
594167
-test ! -h "$root/etc/systemd/system/link5.service"
594167
-test ! -h "$root/etc/systemd/system/link5@.service"
594167
-test ! -h "$root/etc/systemd/system/link5@inst.service"
594167
 test ! -h "$root/etc/systemd/system/link5alias.service"
594167
 test ! -h "$root/etc/systemd/system/link5alias2.service"
594167
 
594167
@@ -528,8 +531,6 @@ check_alias % '%' && { echo "Expected failure because % is not legal in unit nam
594167
 
594167
 check_alias z 'z' && { echo "Expected failure because %z is not known" >&2; exit 1; }
594167
 
594167
-# FIXME: if there's an invalid Alias=, we shouldn't preach about empty [Install]
594167
-
594167
 # TODO: repeat the tests above for presets
594167
 
594167
 : -------SYSTEMD_OS_RELEASE relative to root------------------