1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-14 04:58:28 +03:00

import-generator: optionally import images into /run/ hierarchy rather than /var/

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.
This commit is contained in:
Lennart Poettering 2025-02-10 11:57:19 +01:00
parent 576c97e165
commit 8b918a3a38
5 changed files with 39 additions and 7 deletions

View File

@ -144,6 +144,17 @@
<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>

View 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();

View 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,
{},
};

View 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);

View 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;