From: Daan De Meyer Date: Sun, 31 Mar 2024 20:18:19 +0000 (+0200) Subject: debug-generator: Add unit and drop-in credentials X-Git-Tag: v256-rc1~310^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8595f578fedb0fa7ee7ae06476aefa87aa094100;p=thirdparty%2Fsystemd.git debug-generator: Add unit and drop-in credentials These allow adding extra units and drop-ins via credentials. --- diff --git a/man/systemd-debug-generator.xml b/man/systemd-debug-generator.xml index 5d1d5b7e605..af3615175e5 100644 --- a/man/systemd-debug-generator.xml +++ b/man/systemd-debug-generator.xml @@ -6,7 +6,7 @@ %entities; ]> - + systemd-debug-generator @@ -70,6 +70,36 @@ systemd.generator7. + + System Credentials + + + + systemd.extra-unit.* + + Credentials prefixed with systemd.extra-unit. specify additional + units to add to the final system. Note that these additional units are added to both the initrd and + the final system. ConditionPathExists=!/etc/initrd-release can be used to make + sure the unit is conditioned out in the initrd. + + + + + + systemd.unit-dropin.* + + Credentials prefixed with systemd.unit-dropin. add drop-ins for + the corresponding units in the final system. Each credential must be suffixed with the full unit name + including the unit extension. Its contents must be a valid unit drop-in file. Only one drop-in per + unit can be specified. The name of the generated drop-in will be + 50-credential.conf. Note that these additional drop-ins are added to both the + initrd and the final system. + + + + + + See Also diff --git a/man/systemd.system-credentials.xml b/man/systemd.system-credentials.xml index 2a345c47b4c..b0fb70c6c5f 100644 --- a/man/systemd.system-credentials.xml +++ b/man/systemd.system-credentials.xml @@ -367,6 +367,16 @@ + + + systemd.extra-unit.* + systemd.unit-dropin.* + + These credentials specify extra units and drop-ins to add to the system. For details + see systemd-debug-generator8. + + + diff --git a/src/debug-generator/debug-generator.c b/src/debug-generator/debug-generator.c index ed3dc20f721..3526b84dee8 100644 --- a/src/debug-generator/debug-generator.c +++ b/src/debug-generator/debug-generator.c @@ -3,12 +3,17 @@ #include #include "alloc-util.h" +#include "creds-util.h" #include "dropin.h" +#include "errno-util.h" +#include "fd-util.h" +#include "fileio-label.h" #include "generator.h" #include "initrd-util.h" #include "parse-util.h" #include "path-util.h" #include "proc-cmdline.h" +#include "recurse-dir.h" #include "special.h" #include "string-util.h" #include "strv.h" @@ -158,8 +163,74 @@ static void install_debug_shell_dropin(void) { log_warning_errno(r, "Failed to write drop-in for debug-shell.service, ignoring: %m"); } +static int process_unit_credentials(const char *credentials_dir) { + int r; + + assert(credentials_dir); + + _cleanup_free_ DirectoryEntries *des = NULL; + r = readdir_all_at(AT_FDCWD, credentials_dir, RECURSE_DIR_SORT|RECURSE_DIR_IGNORE_DOT|RECURSE_DIR_ENSURE_TYPE, &des); + if (r < 0) + return log_error_errno(r, "Failed to enumerate credentials from credentials directory '%s': %m", credentials_dir); + + FOREACH_ARRAY(i, des->entries, des->n_entries) { + _cleanup_free_ void *d = NULL; + struct dirent *de = *i; + const char *unit, *dropin; + + if (de->d_type != DT_REG) + continue; + + unit = startswith(de->d_name, "systemd.extra-unit."); + dropin = startswith(de->d_name, "systemd.unit-dropin."); + + if (!unit && !dropin) + continue; + + if (!unit_name_is_valid(unit ?: dropin, UNIT_NAME_ANY)) { + log_warning("Invalid unit name '%s' in credential '%s', ignoring.", + unit ?: dropin, de->d_name); + continue; + } + + r = read_credential_with_decryption(de->d_name, &d, NULL); + if (r < 0) + continue; + + if (unit) { + _cleanup_free_ char *p = NULL; + + p = path_join(arg_dest, unit); + if (!p) + return log_oom(); + + r = write_string_file_atomic_label(p, d); + if (r < 0) { + log_warning_errno(r, "Failed to write unit file '%s' from credential '%s', ignoring: %m", + unit, de->d_name); + continue; + } + + log_debug("Wrote unit file '%s' from credential '%s'", unit, de->d_name); + + } else { + r = write_drop_in(arg_dest, dropin, 50, "credential", d); + if (r < 0) { + log_warning_errno(r, "Failed to write drop-in for unit '%s' from credential '%s', ignoring: %m", + dropin, de->d_name); + continue; + } + + log_debug("Wrote drop-in for unit '%s' from credential '%s'", dropin, de->d_name); + } + } + + return 0; +} + static int run(const char *dest, const char *dest_early, const char *dest_late) { - int r, q; + const char *credentials_dir; + int r = 0; assert_se(arg_dest = dest_early); @@ -175,10 +246,16 @@ static int run(const char *dest, const char *dest_early, const char *dest_late) install_debug_shell_dropin(); } - r = generate_mask_symlinks(); - q = generate_wants_symlinks(); + if (get_credentials_dir(&credentials_dir) >= 0) + RET_GATHER(r, process_unit_credentials(credentials_dir)); + + if (get_encrypted_credentials_dir(&credentials_dir) >= 0) + RET_GATHER(r, process_unit_credentials(credentials_dir)); - return r < 0 ? r : q; + RET_GATHER(r, generate_mask_symlinks()); + RET_GATHER(r, generate_wants_symlinks()); + + return r; } DEFINE_MAIN_GENERATOR_FUNCTION(run); diff --git a/test/TEST-54-CREDS/test.sh b/test/TEST-54-CREDS/test.sh index c0a9d7a53d5..afcb3481668 100755 --- a/test/TEST-54-CREDS/test.sh +++ b/test/TEST-54-CREDS/test.sh @@ -9,6 +9,19 @@ NSPAWN_CREDS=( ) NSPAWN_ARGUMENTS="${NSPAWN_ARGUMENTS:-} ${NSPAWN_CREDS[*]}" +UNIT_CRED=$(base64 -w 0 <