From: Albert Brox Date: Wed, 29 Sep 2021 14:09:34 +0000 (-0400) Subject: implement aliasing for systemd-analyze verify X-Git-Tag: v250-rc1~336 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=da845dabf576f73f76af2704254e0ce7d8167356;p=thirdparty%2Fsystemd.git implement aliasing for systemd-analyze verify --- diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml index e072d661312..4c3b6d173b0 100644 --- a/man/systemd-analyze.xml +++ b/man/systemd-analyze.xml @@ -551,7 +551,8 @@ NAutoVTs=8 <command>systemd-analyze verify <replaceable>FILE</replaceable>...</command> This command will load unit files and print warnings if any errors are detected. Files specified - on the command line will be loaded, but also any other units referenced by them. The full unit search + on the command line will be loaded, but also any other units referenced by them. A unit's name on disk + can be overridden by specifying an alias after a colon; see below for an example. The full unit search path is formed by combining the directories for all command line arguments, and the usual unit load paths. The variable $SYSTEMD_UNIT_PATH is supported, and may be used to replace or augment the compiled in set of unit load paths; see @@ -613,6 +614,27 @@ Service a.service not loaded, a.socket cannot be started. Service b@0.service not loaded, b.socket cannot be started. + + + Aliasing a unit + + $ cat /tmp/source +[Unit] +Description=Hostname printer + +[Service] +Type=simple +ExecStart=/usr/bin/echo %H +MysteryKey=true + +$ systemd-analyze verify /tmp/source +Failed to prepare filename /tmp/source: Invalid argument + +$ systemd-analyze verify /tmp/source:alias.service +/tmp/systemd-analyze-XXXXXX/alias.service:7: Unknown key name 'MysteryKey' in section 'Service', ignoring. + + + diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index 82fdd3deeea..2d6d327f8d8 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -26,6 +26,7 @@ #include "copy.h" #include "def.h" #include "exit-status.h" +#include "extract-word.h" #include "fd-util.h" #include "fileio.h" #include "filesystems.h" @@ -42,6 +43,7 @@ #include "parse-util.h" #include "path-util.h" #include "pretty-print.h" +#include "rm-rf.h" #if HAVE_SECCOMP # include "seccomp-util.h" #endif @@ -53,6 +55,7 @@ #include "strxcpyx.h" #include "terminal-util.h" #include "time-util.h" +#include "tmpfile-util.h" #include "unit-name.h" #include "util.h" #include "verb-log-control.h" @@ -230,6 +233,53 @@ static int compare_unit_start(const UnitTimes *a, const UnitTimes *b) { return CMP(a->activating, b->activating); } +static int process_aliases(char *argv[], char *tempdir, char ***ret) { + _cleanup_strv_free_ char **filenames = NULL; + char **filename; + int r; + + assert(argv); + assert(tempdir); + assert(ret); + + STRV_FOREACH(filename, strv_skip(argv, 1)) { + _cleanup_free_ char *src = NULL, *dst = NULL, *arg = NULL; + char *parse_arg; + + arg = strdup(*filename); + if (!arg) + return -ENOMEM; + + parse_arg = arg; + r = extract_first_word((const char **) &parse_arg, &src, ":", 0); + if (r < 0) + return r; + + if (!parse_arg) { + r = strv_extend(&filenames, src); + if (r < 0) + return -ENOMEM; + + continue; + } + + dst = path_join(tempdir, basename(parse_arg)); + if (!dst) + return -ENOMEM; + + r = copy_file(src, dst, 0, 0644, 0, 0, COPY_REFLINK); + if (r < 0) + return r; + + r = strv_consume(&filenames, TAKE_PTR(dst)); + if (r < 0) + return -ENOMEM; + } + + *ret = TAKE_PTR(filenames); + return 0; +} + static UnitTimes* unit_times_free_array(UnitTimes *t) { for (UnitTimes *p = t; p && p->has_data; p++) free(p->name); @@ -2257,7 +2307,19 @@ static int do_condition(int argc, char *argv[], void *userdata) { } static int do_verify(int argc, char *argv[], void *userdata) { - return verify_units(strv_skip(argv, 1), arg_scope, arg_man, arg_generators, arg_recursive_errors, arg_root); + _cleanup_strv_free_ char **filenames = NULL; + _cleanup_(rm_rf_physical_and_freep) char *tempdir = NULL; + int r; + + r = mkdtemp_malloc("/tmp/systemd-analyze-XXXXXX", &tempdir); + if (r < 0) + return log_error_errno(r, "Failed to setup working directory: %m"); + + r = process_aliases(argv, tempdir, &filenames); + if (r < 0) + return log_error_errno(r, "Couldn't process aliases: %m"); + + return verify_units(filenames, arg_scope, arg_man, arg_generators, arg_recursive_errors, arg_root); } static int do_security(int argc, char *argv[], void *userdata) { diff --git a/test/units/testsuite-65.sh b/test/units/testsuite-65.sh index 3218462c769..f98a933cb14 100755 --- a/test/units/testsuite-65.sh +++ b/test/units/testsuite-65.sh @@ -76,6 +76,14 @@ systemd-analyze verify /tmp/.testfile.service rm /tmp/.testfile.service +# Alias a unit file's name on disk (see #20061) +cp /tmp/testfile.service /tmp/testsrvc + +systemd-analyze verify /tmp/testsrvc \ + && { echo 'unexpected success'; exit 1; } + +systemd-analyze verify /tmp/testsrvc:alias.service + # Zero exit status since the value used for comparison determine exposure to security threats is by default 100 systemd-analyze security --offline=true /tmp/testfile.service