]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
mkosi: Add zsh to Arch packages 20521/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 23 Aug 2021 15:44:58 +0000 (16:44 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 1 Sep 2021 08:01:18 +0000 (10:01 +0200)
Useful for testing zsh completion changes.

.mkosi/mkosi.arch
man/systemd-analyze.xml
shell-completion/bash/systemd-analyze
src/analyze/analyze-condition.c
src/analyze/analyze-condition.h
src/analyze/analyze.c

index cb8fb01ef2751f61c829344b1dec3ec41319ba53..f584d2d126700ecf03dbb1632b2d74a76a2d0071 100644 (file)
@@ -56,3 +56,6 @@ Packages=
         man-db
         # For testing systemd's bash completion scripts.
         bash-completion
+        # For testing systemd's zsh completion scripts
+        # Run `autoload -Uz compinit; compinit` from a zsh shell in the booted image to enable completions.
+        zsh
index 932218d80e04d38522d7e9fc9f8bf91552d878ac..fb2a1caa9e5378cf392ada1895766fdcb3061cb5 100644 (file)
@@ -1123,6 +1123,20 @@ Service b@0.service not loaded, b.socket cannot be started.
         to the specified point in time. If not specified defaults to the current time.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--unit=<replaceable>UNIT</replaceable></option></term>
+
+        <listitem><para>When used with the <command>condition</command> command, evaluate all the
+        <varname index="false">Condition*=...</varname> and <varname index="false">Assert*=...</varname>
+        assignments in the specified unit file. The full unit search path is formed by combining the
+        directories for the specified unit with the usual unit load paths. The variable
+        <varname>$SYSTEMD_UNIT_PATH</varname> is supported, and may be used to replace or augment the
+        compiled in set of unit load paths; see
+        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>. All
+        units files present in the directory containing the specified unit will be used in preference to the
+        other paths.</para></listitem>
+      </varlistentry>
+
       <xi:include href="user-system-options.xml" xpointer="host" />
       <xi:include href="user-system-options.xml" xpointer="machine" />
 
index 07d069a6d71caa297cd95741a6d81ab99260baa3..6bed5e73e8bbb1062d4625ac6faca4e4b3621d17 100644 (file)
@@ -55,13 +55,14 @@ _systemd_analyze() {
     )
 
     local -A VERBS=(
-        [STANDALONE]='time blame plot dump unit-paths exit-status condition calendar timestamp timespan'
+        [STANDALONE]='time blame plot dump unit-paths exit-status calendar timestamp timespan'
         [CRITICAL_CHAIN]='critical-chain'
         [DOT]='dot'
         [VERIFY]='verify'
         [SECCOMP_FILTER]='syscall-filter'
         [CAT_CONFIG]='cat-config'
         [SECURITY]='security'
+        [CONDITION]='condition'
     )
 
     local CONFIGS='systemd/bootchart.conf systemd/coredump.conf systemd/journald.conf
@@ -153,6 +154,18 @@ _systemd_analyze() {
             fi
             comps=$( __get_services $mode )
         fi
+
+    elif __contains_word "$verb" ${VERBS[CONDITION]}; then
+        if [[ $cur = -* ]]; then
+            comps='--help --version --system --user --global --no-pager --root --image'
+        elif [[ $prev = "-u" ]] || [[ $prev = "--unit" ]]; then
+            if __contains_word "--user" ${COMP_WORDS[*]}; then
+                mode=--user
+            else
+                mode=--system
+            fi
+            comps=$( __get_services $mode )
+        fi
     fi
 
     COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
index 09870b95ec497b1e28e34feb6dcad05eb7a45467..f57bb27b9a8192679a392ec73f92a378e5f47766 100644 (file)
@@ -3,6 +3,7 @@
 #include <stdlib.h>
 
 #include "analyze-condition.h"
+#include "analyze-verify.h"
 #include "condition.h"
 #include "conf-parser.h"
 #include "load-fragment.h"
@@ -72,29 +73,57 @@ static int log_helper(void *userdata, int level, int error, const char *file, in
         return r;
 }
 
-int verify_conditions(char **lines, UnitFileScope scope) {
+int verify_conditions(char **lines, UnitFileScope scope, const char *unit, const char *root) {
         _cleanup_(manager_freep) Manager *m = NULL;
         Unit *u;
-        char **line;
         int r, q = 1;
 
+        if (unit) {
+                _cleanup_strv_free_ char **filenames = NULL;
+                _cleanup_free_ char *var = NULL;
+
+                filenames = strv_new(unit);
+                if (!filenames)
+                        return log_oom();
+
+                r = verify_generate_path(&var, filenames);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to generate unit load path: %m");
+
+                assert_se(set_unit_path(var) >= 0);
+        }
+
         r = manager_new(scope, MANAGER_TEST_RUN_MINIMAL, &m);
         if (r < 0)
                 return log_error_errno(r, "Failed to initialize manager: %m");
 
         log_debug("Starting manager...");
-        r = manager_startup(m, /* serialization= */ NULL, /* fds= */ NULL, /* root= */ NULL);
+        r = manager_startup(m, /* serialization= */ NULL, /* fds= */ NULL, root);
         if (r < 0)
                 return r;
 
-        r = unit_new_for_name(m, sizeof(Service), "test.service", &u);
-        if (r < 0)
-                return log_error_errno(r, "Failed to create test.service: %m");
+        if (unit) {
+                _cleanup_free_ char *prepared = NULL;
 
-        STRV_FOREACH(line, lines) {
-                r = parse_condition(u, *line);
+                r = verify_prepare_filename(unit, &prepared);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to prepare filename %s: %m", unit);
+
+                r = manager_load_startable_unit_or_warn(m, NULL, prepared, &u);
                 if (r < 0)
                         return r;
+        } else {
+                char **line;
+
+                r = unit_new_for_name(m, sizeof(Service), "test.service", &u);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to create test.service: %m");
+
+                STRV_FOREACH(line, lines) {
+                        r = parse_condition(u, *line);
+                        if (r < 0)
+                                return r;
+                }
         }
 
         r = condition_test_list(u->asserts, environ, assert_type_to_string, log_helper, u);
index 7b52669d05ea267f0d6cf52e8572d022c3f38837..9ebd205b6d64d178d506a51db972c1789a43a2a0 100644 (file)
@@ -3,4 +3,4 @@
 
 #include "install.h"
 
-int verify_conditions(char **lines, UnitFileScope scope);
+int verify_conditions(char **lines, UnitFileScope scope, const char *unit, const char *root);
index 816532f69e09c1eedaf3d87fbb449faac61efda3..68b9941afe5a9ad197fe1aedf2b638ef7e992089 100644 (file)
@@ -96,12 +96,14 @@ static bool arg_offline = false;
 static unsigned arg_threshold = 100;
 static unsigned arg_iterations = 1;
 static usec_t arg_base_time = USEC_INFINITY;
+static char *arg_unit = NULL;
 
 STATIC_DESTRUCTOR_REGISTER(arg_dot_from_patterns, strv_freep);
 STATIC_DESTRUCTOR_REGISTER(arg_dot_to_patterns, strv_freep);
 STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_security_policy, freep);
+STATIC_DESTRUCTOR_REGISTER(arg_unit, freep);
 
 typedef struct BootTimes {
         usec_t firmware_time;
@@ -2147,7 +2149,7 @@ static int service_watchdogs(int argc, char *argv[], void *userdata) {
 }
 
 static int do_condition(int argc, char *argv[], void *userdata) {
-        return verify_conditions(strv_skip(argv, 1), arg_scope);
+        return verify_conditions(strv_skip(argv, 1), arg_scope, arg_unit, arg_root);
 }
 
 static int do_verify(int argc, char *argv[], void *userdata) {
@@ -2327,6 +2329,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "machine",          required_argument, NULL, 'M'                  },
                 { "iterations",       required_argument, NULL, ARG_ITERATIONS       },
                 { "base-time",        required_argument, NULL, ARG_BASE_TIME        },
+                { "unit",             required_argument, NULL, 'U'                  },
                 {}
         };
 
@@ -2335,7 +2338,7 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hH:M:", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "hH:M:U:", options, NULL)) >= 0)
                 switch (c) {
 
                 case 'h':
@@ -2465,6 +2468,16 @@ static int parse_argv(int argc, char *argv[]) {
 
                         break;
 
+                case 'U': {
+                        _cleanup_free_ char *mangled = NULL;
+
+                        r = unit_name_mangle(optarg, UNIT_NAME_MANGLE_WARN, &mangled);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to mangle unit name %s: %m", optarg);
+
+                        free_and_replace(arg_unit, mangled);
+                        break;
+                }
                 case '?':
                         return -EINVAL;
 
@@ -2493,15 +2506,24 @@ static int parse_argv(int argc, char *argv[]) {
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "Option --security-policy= is only supported for security.");
 
-        if ((arg_root || arg_image) && (!STRPTR_IN_SET(argv[optind], "cat-config", "verify")) &&
+        if ((arg_root || arg_image) && (!STRPTR_IN_SET(argv[optind], "cat-config", "verify", "condition")) &&
            (!(streq_ptr(argv[optind], "security") && arg_offline)))
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "Options --root= and --image= are only supported for cat-config, verify and security when used with --offline= right now.");
+                                       "Options --root= and --image= are only supported for cat-config, verify, condition and security when used with --offline= right now.");
 
         /* Having both an image and a root is not supported by the code */
         if (arg_root && arg_image)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Please specify either --root= or --image=, the combination of both is not supported.");
 
+        if (arg_unit && !streq_ptr(argv[optind], "condition"))
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Option --unit= is only supported for condition");
+
+        if (streq_ptr(argv[optind], "condition") && !arg_unit && optind >= argc - 1)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Too few arguments for condition");
+
+        if (streq_ptr(argv[optind], "condition") && arg_unit && optind < argc - 1)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No conditions can be passed if --unit= is used.");
+
         return 1; /* work to do */
 }
 
@@ -2532,7 +2554,7 @@ static int run(int argc, char *argv[]) {
                 { "exit-status",       VERB_ANY, VERB_ANY, 0,            dump_exit_status       },
                 { "syscall-filter",    VERB_ANY, VERB_ANY, 0,            dump_syscall_filters   },
                 { "capability",        VERB_ANY, VERB_ANY, 0,            dump_capabilities      },
-                { "condition",         2,        VERB_ANY, 0,            do_condition           },
+                { "condition",         VERB_ANY, VERB_ANY, 0,            do_condition           },
                 { "verify",            2,        VERB_ANY, 0,            do_verify              },
                 { "calendar",          2,        VERB_ANY, 0,            test_calendar          },
                 { "timestamp",         2,        VERB_ANY, 0,            test_timestamp         },