]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
import-generator: optionally import images into /run/ hierarchy rather than /var/
authorLennart Poettering <lennart@poettering.net>
Mon, 10 Feb 2025 10:57:19 +0000 (11:57 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 21 Feb 2025 09:03:32 +0000 (10:03 +0100)
This is useful in particular in the initrd, as this ensures any
downloaded images are not deleted during the initrd→host transition
(where /var/ does not survive, but /run/ does). Might be useful in other
cases too, for example for transiently deployed confexts and such.

man/systemd-import-generator.xml
src/import/import-generator.c
src/import/importd.c
src/shared/discover-image.c
src/shared/discover-image.h

index d60c9c96fedc2850a600b307fccf167bc1c20a3b..cea015e6f8aad5c2ec9884c071a4586de1164a7a 100644 (file)
 
             <xi:include href="version-info.xml" xpointer="v258"/></listitem>
           </varlistentry>
+
+          <varlistentry>
+            <term>runtime=</term>
+
+            <listitem><para>Takes a boolean argument. If set to true, the image is downloaded below the
+            <filename>/run/</filename> hierarchy, if set to false below the <filename>/var/lib/</filename>
+            hierarchy. If not specified defaults to true in the initial RAM disk (initrd) and to false on the
+            host system.</para>
+
+            <xi:include href="version-info.xml" xpointer="v258"/></listitem>
+          </varlistentry>
         </variablelist>
 
         <xi:include href="version-info.xml" xpointer="v257"/></listitem>
index 5d2f37107e8a14ad95cd2d6abb9c51c0ef12551a..d63ed23a7b94aa0cab8141b2057e06e801628172 100644 (file)
@@ -11,6 +11,7 @@
 #include "import-util.h"
 #include "initrd-util.h"
 #include "json-util.h"
+#include "parse-util.h"
 #include "proc-cmdline.h"
 #include "special.h"
 #include "specifier.h"
@@ -22,6 +23,7 @@ typedef struct Transfer {
         ImportType type;
         char *local;
         char *remote;
+        const char *image_root;
         bool blockdev;
         sd_json_variant *json;
 } Transfer;
@@ -78,7 +80,7 @@ static int parse_pull_expression(const char *v) {
         ImportType type = _IMPORT_TYPE_INVALID;
         ImageClass class = _IMAGE_CLASS_INVALID;
         ImportVerify verify = IMPORT_VERIFY_SIGNATURE;
-        bool ro = false, blockdev = false, bootorigin = false;
+        bool ro = false, blockdev = false, bootorigin = false, runtime = in_initrd();
 
         const char *o = options;
         for (;;) {
@@ -100,7 +102,13 @@ static int parse_pull_expression(const char *v) {
                         blockdev = true;
                 else if (streq(opt, "bootorigin"))
                         bootorigin = true;
-                else if ((suffix = startswith(opt, "verify="))) {
+                else if ((suffix = startswith(opt, "runtime="))) {
+                        r = parse_boolean(suffix);
+                        if (r < 0)
+                                log_warning_errno(r, "Unknown runtime= parameter, ignoring: %s", suffix);
+                        else
+                                runtime = r;
+                } else if ((suffix = startswith(opt, "verify="))) {
                         ImportVerify w = import_verify_from_string(suffix);
 
                         if (w < 0)
@@ -187,8 +195,9 @@ static int parse_pull_expression(const char *v) {
         if (!GREEDY_REALLOC(arg_transfers, arg_n_transfers + 1))
                 return log_oom();
 
-        _cleanup_(sd_json_variant_unrefp) sd_json_variant *j = NULL;
+        const char *image_root = runtime ? image_root_runtime_to_string(class) : image_root_to_string(class);
 
+        _cleanup_(sd_json_variant_unrefp) sd_json_variant *j = NULL;
         r = sd_json_buildo(
                         &j,
                         SD_JSON_BUILD_PAIR("remote", SD_JSON_BUILD_STRING(remote)),
@@ -196,7 +205,8 @@ static int parse_pull_expression(const char *v) {
                         SD_JSON_BUILD_PAIR("class", JSON_BUILD_STRING_UNDERSCORIFY(image_class_to_string(class))),
                         SD_JSON_BUILD_PAIR("type", JSON_BUILD_STRING_UNDERSCORIFY(import_type_to_string(type))),
                         SD_JSON_BUILD_PAIR("readOnly", SD_JSON_BUILD_BOOLEAN(ro)),
-                        SD_JSON_BUILD_PAIR("verify", JSON_BUILD_STRING_UNDERSCORIFY(import_verify_to_string(verify))));
+                        SD_JSON_BUILD_PAIR("verify", JSON_BUILD_STRING_UNDERSCORIFY(import_verify_to_string(verify))),
+                        SD_JSON_BUILD_PAIR("imageRoot", SD_JSON_BUILD_STRING(image_root)));
         if (r < 0)
                 return log_error_errno(r, "Failed to build import JSON object: %m");
 
@@ -205,6 +215,7 @@ static int parse_pull_expression(const char *v) {
                 .type = type,
                 .local = TAKE_PTR(local),
                 .remote = TAKE_PTR(remote),
+                .image_root = image_root,
                 .json = TAKE_PTR(j),
                 .blockdev = blockdev,
         };
@@ -322,11 +333,11 @@ static int transfer_generate(const Transfer *t, size_t c) {
                 fputs("Wants=network-online.target\n"
                       "After=network-online.target\n", f);
 
-        _cleanup_free_ char *local_path = NULL, *loop_service = NULL;
+        _cleanup_free_ char *loop_service = NULL;
         if (t->blockdev) {
                 assert(t->type == IMPORT_RAW);
 
-                local_path = strjoin(image_root_to_string(t->class), "/", t->local, ".raw");
+                _cleanup_free_ char *local_path = strjoin(t->image_root, "/", t->local, ".raw");
                 if (!local_path)
                         return log_oom();
 
index 324bb618a450723ec17b63a3e167e265cae7fadb..5a1dcb92a5dd444580bbfdb344563e9eb96a20ed 100644 (file)
@@ -1862,7 +1862,7 @@ static int vl_method_pull(sd_varlink *link, sd_json_variant *parameters, sd_varl
                 { "force",        SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool,      offsetof(struct p, force),         0                 },
                 { "readOnly",     SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool,      offsetof(struct p, read_only),     0                 },
                 { "keepDownload", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool,      offsetof(struct p, keep_download), 0                 },
-                { "imageRoot",    SD_JSON_VARIANT_BOOLEAN, json_dispatch_const_path,      offsetof(struct p, image_root),    SD_JSON_STRICT    },
+                { "imageRoot",    SD_JSON_VARIANT_STRING,  json_dispatch_const_path,      offsetof(struct p, image_root),    SD_JSON_STRICT    },
                 VARLINK_DISPATCH_POLKIT_FIELD,
                 {},
         };
index e2f05dca93dbc994aa8742c7a3e42b21f280ee1c..d6afa53a6bfc65f014945c33bc1ed78b2923320f 100644 (file)
@@ -110,6 +110,15 @@ static const char *const image_root_table[_IMAGE_CLASS_MAX] = {
 
 DEFINE_STRING_TABLE_LOOKUP_TO_STRING(image_root, ImageClass);
 
+static const char *const image_root_runtime_table[_IMAGE_CLASS_MAX] = {
+        [IMAGE_MACHINE]  = "/run/machines",
+        [IMAGE_PORTABLE] = "/run/portables",
+        [IMAGE_SYSEXT]   = "/run/extensions",
+        [IMAGE_CONFEXT]  = "/run/confexts",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_TO_STRING(image_root_runtime, ImageClass);
+
 static Image *image_free(Image *i) {
         assert(i);
 
index c64d0baefb50d8a253b5a82d8ffd4ac14f3ac019..66dc7ef3d283dd2155d9548e807e1242cca6f71f 100644 (file)
@@ -122,6 +122,7 @@ static inline bool IMAGE_IS_HOST(const struct Image *i) {
 int image_to_json(const struct Image *i, sd_json_variant **ret);
 
 const char* image_root_to_string(ImageClass c) _const_;
+const char* image_root_runtime_to_string(ImageClass c) _const_;
 
 extern const struct hash_ops image_hash_ops;