]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
debug-generator: Allow specifying name of unit-dropin credential
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Sat, 11 May 2024 14:42:24 +0000 (16:42 +0200)
committerLuca Boccassi <luca.boccassi@gmail.com>
Sat, 11 May 2024 17:46:15 +0000 (19:46 +0200)
A fixed name is too rigid, let's give users the ability to define
custom drop-in names which at the same time also allows defining
multiple dropins per unit.

We use ~ as the separator because:
- ':' is not allowed in credential names
- '=' is used to separate credential from value in mkosi's --credential
  argument.
- '-' is commonly used in filenames
- '@' already has meaning as the unit template specifier which might be
  confusing when adding dropins for template units

man/systemd-debug-generator.xml
src/debug-generator/debug-generator.c
src/shared/dropin.c
test/TEST-54-CREDS/test.sh
test/units/testsuite-54.sh

index 126d1efc0026d99d44d2aee511db2b1c3ab212ac..744fcb9c7a3e223ce1d4c2e7686094be12a4619c 100644 (file)
@@ -91,8 +91,9 @@
 
         <listitem><para>Credentials prefixed with <literal>systemd.unit-dropin.</literal> 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
+        including the unit extension. Its contents must be a valid unit drop-in file. Optionally, the unit
+        name may be followed with <literal>~</literal>, followed by the drop-in name without the
+        <literal>.conf</literal> suffix. If not specified, the name of the generated drop-in will be
         <literal>50-credential.conf</literal>. Note that these additional drop-ins are added to both the
         initrd and the final system.</para>
 
index 1b14f1222abd1d9b80c9455918067850c0c18b2c..76379806896a576c4e261566ebe17e8565450bc5 100644 (file)
@@ -185,12 +185,6 @@ static int process_unit_credentials(const char *credentials_dir) {
                 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;
-                }
-
                 _cleanup_free_ char *d = NULL;
 
                 r = read_credential_with_decryption(de->d_name, (void**) &d, NULL);
@@ -202,6 +196,12 @@ static int process_unit_credentials(const char *credentials_dir) {
                 if (unit) {
                         _cleanup_free_ char *p = NULL;
 
+                        if (!unit_name_is_valid(unit, UNIT_NAME_ANY)) {
+                                log_warning("Invalid unit name '%s' in credential '%s', ignoring.",
+                                            unit, de->d_name);
+                                continue;
+                        }
+
                         p = path_join(arg_dest, unit);
                         if (!p)
                                 return log_oom();
@@ -216,14 +216,35 @@ static int process_unit_credentials(const char *credentials_dir) {
                         log_debug("Wrote unit file '%s' from credential '%s'", unit, de->d_name);
 
                 } else if (dropin) {
-                        r = write_drop_in(arg_dest, dropin, 50, "credential", d);
+                        _cleanup_free_ char *dropin_unit = NULL;
+                        const char *tilde, *dropin_name;
+
+                        tilde = strchrnul(dropin, '~');
+                        dropin_unit = strndup(dropin, tilde - dropin);
+                        if (!dropin_unit)
+                                return log_oom();
+
+                        if (!unit_name_is_valid(dropin_unit, UNIT_NAME_ANY)) {
+                                log_warning("Invalid unit name '%s' in credential '%s', ignoring.",
+                                            dropin_unit, de->d_name);
+                                continue;
+                        }
+
+                        dropin_name = isempty(tilde) ? "50-credential" : tilde + 1;
+                        if (isempty(dropin_name)) {
+                                log_warning("Empty drop-in name for unit '%s' in credential '%s', ignoring.",
+                                            dropin_unit, de->d_name);
+                                continue;
+                        }
+
+                        r = write_drop_in(arg_dest, dropin_unit, /* level = */ UINT_MAX, dropin_name, 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);
+                                log_warning_errno(r, "Failed to write drop-in '%s' for unit '%s' from credential '%s', ignoring: %m",
+                                                  dropin_name, dropin_unit, de->d_name);
                                 continue;
                         }
 
-                        log_debug("Wrote drop-in for unit '%s' from credential '%s'", dropin, de->d_name);
+                        log_debug("Wrote drop-in '%s' for unit '%s' from credential '%s'", dropin_name, dropin_unit, de->d_name);
                 } else
                         assert_not_reached();
         }
index d46e8380440921994eac61837f7c519a8529633a..9a786d0603905b137245c3a17d9a22a7942b0c7f 100644 (file)
@@ -26,7 +26,7 @@
 int drop_in_file(const char *dir, const char *unit, unsigned level,
                  const char *name, char **ret_p, char **ret_q) {
 
-        char prefix[DECIMAL_STR_MAX(unsigned)];
+        char prefix[DECIMAL_STR_MAX(unsigned) + 1] = {};
         _cleanup_free_ char *b = NULL, *p = NULL, *q = NULL;
 
         assert(unit);
@@ -34,7 +34,8 @@ int drop_in_file(const char *dir, const char *unit, unsigned level,
         assert(ret_p);
         assert(ret_q);
 
-        sprintf(prefix, "%u", level);
+        if (level != UINT_MAX)
+                xsprintf(prefix, "%u-", level);
 
         b = xescape(name, "/.");
         if (!b)
@@ -44,7 +45,7 @@ int drop_in_file(const char *dir, const char *unit, unsigned level,
                 return -EINVAL;
 
         p = strjoin(dir, "/", unit, ".d");
-        q = strjoin(p, "/", prefix, "-", b, ".conf");
+        q = strjoin(p, "/", prefix, b, ".conf");
         if (!p || !q)
                 return -ENOMEM;
 
index afcb348166865a1ff2ad74bb1c4539057e64a397..99c44e30122d6cd310114e618cc456a3c1dfb009 100755 (executable)
@@ -17,10 +17,14 @@ EOF
 )
 DROPIN_CRED=$(base64 -w 0 <<EOF
 [Service]
-ExecStart=
 ExecStart=touch /tmp/unit-dropin
 EOF
 )
+NAMED_DROPIN_CRED=$(base64 -w 0 <<EOF
+[Service]
+ExecStart=touch /tmp/unit-named-dropin
+EOF
+)
 
 QEMU_CREDS=(
     "-fw_cfg name=opt/io.systemd.credentials/myqemucredential,string=othervalue"
@@ -32,6 +36,7 @@ QEMU_CREDS=(
     "-smbios type=11,value=io.systemd.credential:getty.ttys.container=idontexist"
     "-smbios type=11,value=io.systemd.credential.binary:systemd.extra-unit.my-service.service=$UNIT_CRED"
     "-smbios type=11,value=io.systemd.credential.binary:systemd.unit-dropin.my-service.service=$DROPIN_CRED"
+    "-smbios type=11,value=io.systemd.credential.binary:systemd.unit-dropin.my-service.service~30-named=$NAMED_DROPIN_CRED"
 )
 QEMU_OPTIONS="${QEMU_OPTIONS:-} ${QEMU_CREDS[*]}"
 
index a8d5a0c3fa52cdf3720d7f668709d1119402a8ba..fe410d567e9c9f9765695227217f99ec3339922f 100755 (executable)
@@ -210,7 +210,9 @@ elif [ -d /sys/firmware/qemu_fw_cfg/by_name ]; then
 
     # Verify that adding a unit and drop-in via credentials worked
     systemctl start my-service
+    test -f /tmp/unit-cred
     test -f /tmp/unit-dropin
+    test -f /tmp/unit-named-dropin
 else
     echo "qemu_fw_cfg support missing in kernel. Sniff!"
     expected_credential=""