]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
importd: add support for downloading sysext/confext/portable images too
authorLennart Poettering <lennart@poettering.net>
Thu, 22 Feb 2024 08:43:01 +0000 (09:43 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 1 Mar 2024 21:25:42 +0000 (22:25 +0100)
This adds "Ex" versions of all bus calls import implements, that make
two changes:

1. A "class" parameter is added that allows choosing between
   machine/sysext/confext/portable images to download. Depending on the
   chose class the target directory is selected differently (i.e. not
   just /var/lib/machines/, but alternatively /var/lib/portables/,
   /var/lib/extensions/, /var/lib/confexts/.

2. The boolean flags are replaced by a 64bit flags parameter.

15 files changed:
src/import/export.c
src/import/import-common.h
src/import/import-fs.c
src/import/import-raw.c
src/import/import-tar.c
src/import/import.c
src/import/importd.c
src/import/org.freedesktop.import1.conf
src/import/org.freedesktop.import1.policy
src/import/pull-common.c
src/import/pull-raw.c
src/import/pull-tar.c
src/import/pull.c
src/shared/discover-image.c
src/shared/discover-image.h

index ee65cc8d36279d8cebf39d79c221641bf382f818..ac81b2fbabcc6a58b649b0145c4fecf0f9cc763d 100644 (file)
@@ -23,6 +23,7 @@
 #include "verbs.h"
 
 static ImportCompressType arg_compress = IMPORT_COMPRESS_UNKNOWN;
+static ImageClass arg_class = IMAGE_MACHINE;
 
 static void determine_compression_from_filename(const char *p) {
 
@@ -63,7 +64,7 @@ static int export_tar(int argc, char *argv[], void *userdata) {
         int r, fd;
 
         if (hostname_is_valid(argv[1], 0)) {
-                r = image_find(IMAGE_MACHINE, argv[1], NULL, &image);
+                r = image_find(arg_class, argv[1], NULL, &image);
                 if (r == -ENOENT)
                         return log_error_errno(r, "Machine image %s not found.", argv[1]);
                 if (r < 0)
@@ -135,7 +136,7 @@ static int export_raw(int argc, char *argv[], void *userdata) {
         int r, fd;
 
         if (hostname_is_valid(argv[1], 0)) {
-                r = image_find(IMAGE_MACHINE, argv[1], NULL, &image);
+                r = image_find(arg_class, argv[1], NULL, &image);
                 if (r == -ENOENT)
                         return log_error_errno(r, "Machine image %s not found.", argv[1]);
                 if (r < 0)
@@ -190,14 +191,16 @@ static int export_raw(int argc, char *argv[], void *userdata) {
 
 static int help(int argc, char *argv[], void *userdata) {
         printf("%1$s [OPTIONS...] {COMMAND} ...\n"
-               "\n%4$sExport container or virtual machine images.%5$s\n"
+               "\n%4$sExport disk images.%5$s\n"
                "\n%2$sCommands:%3$s\n"
                "  tar NAME [FILE]              Export a TAR image\n"
                "  raw NAME [FILE]              Export a RAW image\n"
                "\n%2$sOptions:%3$s\n"
                "  -h --help                    Show this help\n"
                "     --version                 Show package version\n"
-               "     --format=FORMAT           Select format\n",
+               "     --format=FORMAT           Select format\n"
+               "     --class=CLASS             Select image class (machine, sysext, confext,\n"
+               "                               portable)\n",
                program_invocation_short_name,
                ansi_underline(),
                ansi_normal(),
@@ -212,12 +215,14 @@ static int parse_argv(int argc, char *argv[]) {
         enum {
                 ARG_VERSION = 0x100,
                 ARG_FORMAT,
+                ARG_CLASS,
         };
 
         static const struct option options[] = {
                 { "help",    no_argument,       NULL, 'h'         },
                 { "version", no_argument,       NULL, ARG_VERSION },
                 { "format",  required_argument, NULL, ARG_FORMAT  },
+                { "class",   required_argument, NULL, ARG_CLASS   },
                 {}
         };
 
@@ -250,6 +255,13 @@ static int parse_argv(int argc, char *argv[]) {
                                                        "Unknown format: %s", optarg);
                         break;
 
+                case ARG_CLASS:
+                        arg_class = image_class_from_string(optarg);
+                        if (arg_class < 0)
+                                return log_error_errno(arg_class, "Failed to parse --class= argument: %s", optarg);
+
+                        break;
+
                 case '?':
                         return -EINVAL;
 
index edde7fd8bd23cd8db7e01199dbc00a5b8e55d108..2bb20754624e77a4bbdb246ff69ee85f132502cf 100644 (file)
@@ -27,6 +27,8 @@ typedef enum ImportFlags {
         /* The supported flags for the tar and the raw pulling */
         IMPORT_PULL_FLAGS_MASK_TAR     = IMPORT_FLAGS_MASK_TAR|IMPORT_PULL_SETTINGS,
         IMPORT_PULL_FLAGS_MASK_RAW     = IMPORT_FLAGS_MASK_RAW|IMPORT_PULL_SETTINGS|IMPORT_PULL_ROOTHASH|IMPORT_PULL_ROOTHASH_SIGNATURE|IMPORT_PULL_VERITY,
+
+        _IMPORT_FLAGS_INVALID = -EINVAL,
 } ImportFlags;
 
 int import_fork_tar_c(const char *path, pid_t *ret);
index a89c835f573d89395640c82d7e7a31751a9115b3..e37fd7b41d2d2a6a949328089abd8dce5ab00b6f 100644 (file)
@@ -31,7 +31,8 @@ static bool arg_btrfs_subvol = true;
 static bool arg_btrfs_quota = true;
 static bool arg_sync = true;
 static bool arg_direct = false;
-static const char *arg_image_root = "/var/lib/machines";
+static const char *arg_image_root = NULL;
+static ImageClass arg_class = IMAGE_MACHINE;
 
 typedef struct ProgressInfo {
         RateLimit limit;
@@ -143,7 +144,7 @@ static int import_fs(int argc, char *argv[], void *userdata) {
                         return log_oom();
 
                 if (!arg_force) {
-                        r = image_find(IMAGE_MACHINE, local, NULL, NULL);
+                        r = image_find(arg_class, local, NULL, NULL);
                         if (r < 0) {
                                 if (r != -ENOENT)
                                         return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local);
@@ -266,7 +267,9 @@ static int help(int argc, char *argv[], void *userdata) {
                "                              instead of a directory\n"
                "     --btrfs-quota=BOOL       Controls whether to set up quota for btrfs\n"
                "                              subvolume\n"
-               "     --sync=BOOL              Controls whether to sync() before completing\n",
+               "     --sync=BOOL              Controls whether to sync() before completing\n"
+               "     --class=CLASS            Select image class (machine, sysext, confext,\n"
+               "                              portable)\n",
                program_invocation_short_name,
                ansi_underline(),
                ansi_normal(),
@@ -287,6 +290,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_BTRFS_SUBVOL,
                 ARG_BTRFS_QUOTA,
                 ARG_SYNC,
+                ARG_CLASS,
         };
 
         static const struct option options[] = {
@@ -299,6 +303,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "btrfs-subvol",    required_argument, NULL, ARG_BTRFS_SUBVOL    },
                 { "btrfs-quota",     required_argument, NULL, ARG_BTRFS_QUOTA     },
                 { "sync",            required_argument, NULL, ARG_SYNC            },
+                { "class",           required_argument, NULL, ARG_CLASS           },
                 {}
         };
 
@@ -354,6 +359,13 @@ static int parse_argv(int argc, char *argv[]) {
 
                         break;
 
+                case ARG_CLASS:
+                        arg_class = image_class_from_string(optarg);
+                        if (arg_class < 0)
+                                return log_error_errno(arg_class, "Failed to parse --class= argument: %s", optarg);
+
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -361,6 +373,9 @@ static int parse_argv(int argc, char *argv[]) {
                         assert_not_reached();
                 }
 
+        if (!arg_image_root)
+                arg_image_root = image_root_to_string(arg_class);
+
         return 1;
 }
 
index f7ed163d86461270b3ad8f6059274b77d2e3abbb..ee9b297bfeb70d5e585cb9275321f2d9a6fd900f 100644 (file)
@@ -95,8 +95,9 @@ int raw_import_new(
         int r;
 
         assert(ret);
+        assert(image_root);
 
-        root = strdup(image_root ?: "/var/lib/machines");
+        root = strdup(image_root);
         if (!root)
                 return -ENOMEM;
 
index 90202709ecc80bca3732ccdd57d5f48cfed92d8c..39df11b5ff6e94088ac40d761f1c07da93a23711 100644 (file)
@@ -97,8 +97,9 @@ int tar_import_new(
         int r;
 
         assert(ret);
+        assert(image_root);
 
-        root = strdup(image_root ?: "/var/lib/machines");
+        root = strdup(image_root);
         if (!root)
                 return -ENOMEM;
 
index 50059870a072e936e0fa6a4f32572c891143f812..22ce6f5aaa7f793f88f4953cedc8d0ef46f3e752 100644 (file)
 #include "terminal-util.h"
 #include "verbs.h"
 
-static const char *arg_image_root = "/var/lib/machines";
+static const char *arg_image_root = NULL;
 static ImportFlags arg_import_flags = IMPORT_BTRFS_SUBVOL | IMPORT_BTRFS_QUOTA | IMPORT_CONVERT_QCOW2 | IMPORT_SYNC;
 static uint64_t arg_offset = UINT64_MAX, arg_size_max = UINT64_MAX;
+static ImageClass arg_class = IMAGE_MACHINE;
 
 static int normalize_local(const char *local, char **ret) {
         _cleanup_free_ char *ll = NULL;
@@ -61,7 +62,7 @@ static int normalize_local(const char *local, char **ret) {
                         local = "imported";
 
                 if (!FLAGS_SET(arg_import_flags, IMPORT_FORCE)) {
-                        r = image_find(IMAGE_MACHINE, local, NULL, NULL);
+                        r = image_find(arg_class, local, NULL, NULL);
                         if (r < 0) {
                                 if (r != -ENOENT)
                                         return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local);
@@ -266,7 +267,7 @@ static int import_raw(int argc, char *argv[], void *userdata) {
 static int help(int argc, char *argv[], void *userdata) {
 
         printf("%1$s [OPTIONS...] {COMMAND} ...\n"
-               "\n%4$sImport container or virtual machine images.%5$s\n"
+               "\n%4$sImport disk images.%5$s\n"
                "\n%2$sCommands:%3$s\n"
                "  tar FILE [NAME]             Import a TAR image\n"
                "  raw FILE [NAME]             Import a RAW image\n"
@@ -285,7 +286,9 @@ static int help(int argc, char *argv[], void *userdata) {
                "                              regular disk images\n"
                "     --sync=BOOL              Controls whether to sync() before completing\n"
                "     --offset=BYTES           Offset to seek to in destination\n"
-               "     --size-max=BYTES         Maximum number of bytes to write to destination\n",
+               "     --size-max=BYTES         Maximum number of bytes to write to destination\n"
+               "     --class=CLASS            Select image class (machine, sysext, confext,\n"
+               "                              portable)\n",
                program_invocation_short_name,
                ansi_underline(),
                ansi_normal(),
@@ -309,6 +312,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_SYNC,
                 ARG_OFFSET,
                 ARG_SIZE_MAX,
+                ARG_CLASS,
         };
 
         static const struct option options[] = {
@@ -324,6 +328,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "sync",            required_argument, NULL, ARG_SYNC            },
                 { "offset",          required_argument, NULL, ARG_OFFSET          },
                 { "size-max",        required_argument, NULL, ARG_SIZE_MAX        },
+                { "class",           required_argument, NULL, ARG_CLASS           },
                 {}
         };
 
@@ -416,6 +421,13 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
                 }
 
+                case ARG_CLASS:
+                        arg_class = image_class_from_string(optarg);
+                        if (arg_class < 0)
+                                return log_error_errno(arg_class, "Failed to parse --class= argument: %s", optarg);
+
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -432,6 +444,9 @@ static int parse_argv(int argc, char *argv[]) {
         if (arg_offset != UINT64_MAX && !FLAGS_SET(arg_import_flags, IMPORT_DIRECT))
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "File offset only supported in --direct mode.");
 
+        if (!arg_image_root)
+                arg_image_root = image_root_to_string(arg_class);
+
         return 1;
 }
 
index dbf2fba4ab62cc9cc336c0e0ddc303dee0ec7605..47dfb2dfafce59114516ac8c175b46e5eda49e0e 100644 (file)
 #include "common-signal.h"
 #include "constants.h"
 #include "daemon-util.h"
+#include "discover-image.h"
 #include "env-util.h"
 #include "event-util.h"
 #include "fd-util.h"
 #include "float.h"
 #include "hostname-util.h"
+#include "import-common.h"
 #include "import-util.h"
 #include "machine-pool.h"
 #include "main-func.h"
 #include "missing_capability.h"
 #include "mkdir-label.h"
+#include "os-util.h"
 #include "parse-util.h"
 #include "path-util.h"
 #include "percent-util.h"
@@ -64,9 +67,8 @@ struct Transfer {
 
         char *remote;
         char *local;
-        bool force_local;
-        bool read_only;
-
+        ImageClass class;
+        ImportFlags flags;
         char *format;
 
         PidRef pidref;
@@ -382,6 +384,8 @@ static int transfer_start(Transfer *t) {
                         NULL, /* tar, raw  */
                         NULL, /* --verify= */
                         NULL, /* verify argument */
+                        NULL, /* --class= */
+                        NULL, /* class argument */
                         NULL, /* maybe --force */
                         NULL, /* maybe --read-only */
                         NULL, /* if so: the actual URL */
@@ -457,9 +461,14 @@ static int transfer_start(Transfer *t) {
                         cmd[k++] = import_verify_to_string(t->verify);
                 }
 
-                if (t->force_local)
+                if (t->class != IMAGE_MACHINE) {
+                        cmd[k++] = "--class";
+                        cmd[k++] = image_class_to_string(t->class);
+                }
+
+                if (FLAGS_SET(t->flags, IMPORT_FORCE))
                         cmd[k++] = "--force";
-                if (t->read_only)
+                if (FLAGS_SET(t->flags, IMPORT_READ_ONLY))
                         cmd[k++] = "--read-only";
 
                 if (t->format) {
@@ -702,12 +711,13 @@ static Transfer *manager_find(Manager *m, TransferType type, const char *remote)
 
 static int method_import_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_error *error) {
         _cleanup_(transfer_unrefp) Transfer *t = NULL;
-        int fd, force, read_only, r;
-        const char *local, *object;
+        ImageClass class = _IMAGE_CLASS_INVALID;
         Manager *m = ASSERT_PTR(userdata);
+        const char *local;
         TransferType type;
         struct stat st;
-        uint32_t id;
+        uint64_t flags;
+        int fd, r;
 
         assert(msg);
 
@@ -722,9 +732,34 @@ static int method_import_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_
         if (r == 0)
                 return 1; /* Will call us back */
 
-        r = sd_bus_message_read(msg, "hsbb", &fd, &local, &force, &read_only);
-        if (r < 0)
-                return r;
+        if (endswith(sd_bus_message_get_member(msg), "Ex")) {
+                const char *sclass;
+
+                r = sd_bus_message_read(msg, "hsst", &fd, &local, &sclass, &flags);
+                if (r < 0)
+                        return r;
+
+                class = image_class_from_string(sclass);
+                if (class < 0)
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
+                                                 "Image class '%s' not known", sclass);
+
+                if (flags & ~(IMPORT_READ_ONLY|IMPORT_FORCE))
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
+                                                 "Flags 0x%" PRIx64 " invalid", flags);
+        } else {
+                int force, read_only;
+
+                r = sd_bus_message_read(msg, "hsbb", &fd, &local, &force, &read_only);
+                if (r < 0)
+                        return r;
+
+                class = IMAGE_MACHINE;
+
+                flags = 0;
+                SET_FLAG(flags, IMPORT_FORCE, force);
+                SET_FLAG(flags, IMPORT_READ_ONLY, read_only);
+        }
 
         if (fstat(fd, &st) < 0)
                 return -errno;
@@ -736,11 +771,13 @@ static int method_import_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
                                          "Local name %s is invalid", local);
 
-        r = setup_machine_directory(error, m->use_btrfs_subvol, m->use_btrfs_quota);
-        if (r < 0)
-                return r;
+        if (class == IMAGE_MACHINE) {
+                r = setup_machine_directory(error, m->use_btrfs_subvol, m->use_btrfs_quota);
+                if (r < 0)
+                        return r;
+        }
 
-        type = streq_ptr(sd_bus_message_get_member(msg), "ImportTar") ?
+        type = startswith(sd_bus_message_get_member(msg), "ImportTar") ?
                 TRANSFER_IMPORT_TAR : TRANSFER_IMPORT_RAW;
 
         r = transfer_new(m, &t);
@@ -748,8 +785,8 @@ static int method_import_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_
                 return r;
 
         t->type = type;
-        t->force_local = force;
-        t->read_only = read_only;
+        t->class = class;
+        t->flags = flags;
 
         t->local = strdup(local);
         if (!t->local)
@@ -763,19 +800,21 @@ static int method_import_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_
         if (r < 0)
                 return r;
 
-        object = t->object_path;
-        id = t->id;
-        t = NULL;
+        r = sd_bus_reply_method_return(msg, "uo", t->id, t->object_path);
+        if (r < 0)
+                return r;
 
-        return sd_bus_reply_method_return(msg, "uo", id, object);
+        TAKE_PTR(t);
+        return 1;
 }
 
 static int method_import_fs(sd_bus_message *msg, void *userdata, sd_bus_error *error) {
         _cleanup_(transfer_unrefp) Transfer *t = NULL;
-        int fd, force, read_only, r;
-        const char *local, *object;
+        ImageClass class = _IMAGE_CLASS_INVALID;
         Manager *m = ASSERT_PTR(userdata);
-        uint32_t id;
+        const char *local;
+        uint64_t flags;
+        int fd, r;
 
         assert(msg);
 
@@ -790,9 +829,34 @@ static int method_import_fs(sd_bus_message *msg, void *userdata, sd_bus_error *e
         if (r == 0)
                 return 1; /* Will call us back */
 
-        r = sd_bus_message_read(msg, "hsbb", &fd, &local, &force, &read_only);
-        if (r < 0)
-                return r;
+        if (endswith(sd_bus_message_get_member(msg), "Ex")) {
+                const char *sclass;
+
+                r = sd_bus_message_read(msg, "hsst", &fd, &local, &sclass, &flags);
+                if (r < 0)
+                        return r;
+
+                class = image_class_from_string(sclass);
+                if (class < 0)
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
+                                                 "Image class '%s' not known", sclass);
+
+                if (flags & ~(IMPORT_READ_ONLY|IMPORT_FORCE))
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
+                                                 "Flags 0x%" PRIx64 " invalid", flags);
+        } else {
+                int force, read_only;
+
+                r = sd_bus_message_read(msg, "hsbb", &fd, &local, &force, &read_only);
+                if (r < 0)
+                        return r;
+
+                class = IMAGE_MACHINE;
+
+                flags = 0;
+                SET_FLAG(flags, IMPORT_FORCE, force);
+                SET_FLAG(flags, IMPORT_READ_ONLY, read_only);
+        }
 
         r = fd_verify_directory(fd);
         if (r < 0)
@@ -802,17 +866,19 @@ static int method_import_fs(sd_bus_message *msg, void *userdata, sd_bus_error *e
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
                                          "Local name %s is invalid", local);
 
-        r = setup_machine_directory(error, m->use_btrfs_subvol, m->use_btrfs_quota);
-        if (r < 0)
-                return r;
+        if (class == IMAGE_MACHINE) {
+                r = setup_machine_directory(error, m->use_btrfs_subvol, m->use_btrfs_quota);
+                if (r < 0)
+                        return r;
+        }
 
         r = transfer_new(m, &t);
         if (r < 0)
                 return r;
 
         t->type = TRANSFER_IMPORT_FS;
-        t->force_local = force;
-        t->read_only = read_only;
+        t->class = class;
+        t->flags = flags;
 
         t->local = strdup(local);
         if (!t->local)
@@ -826,21 +892,23 @@ static int method_import_fs(sd_bus_message *msg, void *userdata, sd_bus_error *e
         if (r < 0)
                 return r;
 
-        object = t->object_path;
-        id = t->id;
-        t = NULL;
+        r = sd_bus_reply_method_return(msg, "uo", t->id, t->object_path);
+        if (r < 0)
+                return r;
 
-        return sd_bus_reply_method_return(msg, "uo", id, object);
+        TAKE_PTR(t);
+        return 1;
 }
 
 static int method_export_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_error *error) {
         _cleanup_(transfer_unrefp) Transfer *t = NULL;
-        int fd, r;
-        const char *local, *object, *format;
+        ImageClass class = _IMAGE_CLASS_INVALID;
         Manager *m = ASSERT_PTR(userdata);
+        const char *local, *format;
         TransferType type;
+        uint64_t flags;
         struct stat st;
-        uint32_t id;
+        int fd, r;
 
         assert(msg);
 
@@ -855,9 +923,29 @@ static int method_export_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_
         if (r == 0)
                 return 1; /* Will call us back */
 
-        r = sd_bus_message_read(msg, "shs", &local, &fd, &format);
-        if (r < 0)
-                return r;
+        if (endswith(sd_bus_message_get_member(msg), "Ex")) {
+                const char *sclass;
+
+                r = sd_bus_message_read(msg, "sshst", &local, &sclass, &fd, &format, &flags);
+                if (r < 0)
+                        return r;
+
+                class = image_class_from_string(sclass);
+                if (class < 0)
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
+                                                 "Image class '%s' not known", sclass);
+
+                if (flags != 0)
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
+                                                 "Flags 0x%" PRIx64 " invalid", flags);
+        } else {
+                r = sd_bus_message_read(msg, "shs", &local, &fd, &format);
+                if (r < 0)
+                        return r;
+
+                class = IMAGE_MACHINE;
+                flags = 0;
+        }
 
         if (!hostname_is_valid(local, 0))
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
@@ -869,7 +957,7 @@ static int method_export_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_
         if (!S_ISREG(st.st_mode) && !S_ISFIFO(st.st_mode))
                 return -EINVAL;
 
-        type = streq_ptr(sd_bus_message_get_member(msg), "ExportTar") ?
+        type = startswith(sd_bus_message_get_member(msg), "ExportTar") ?
                 TRANSFER_EXPORT_TAR : TRANSFER_EXPORT_RAW;
 
         r = transfer_new(m, &t);
@@ -877,6 +965,8 @@ static int method_export_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_
                 return r;
 
         t->type = type;
+        t->class = class;
+        t->flags = flags;
 
         if (!isempty(format)) {
                 t->format = strdup(format);
@@ -896,21 +986,23 @@ static int method_export_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_
         if (r < 0)
                 return r;
 
-        object = t->object_path;
-        id = t->id;
-        t = NULL;
+        r = sd_bus_reply_method_return(msg, "uo", t->id, t->object_path);
+        if (r < 0)
+                return r;
 
-        return sd_bus_reply_method_return(msg, "uo", id, object);
+        TAKE_PTR(t);
+        return 1;
 }
 
 static int method_pull_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_error *error) {
         _cleanup_(transfer_unrefp) Transfer *t = NULL;
-        const char *remote, *local, *verify, *object;
+        ImageClass class = _IMAGE_CLASS_INVALID;
+        const char *remote, *local, *verify;
         Manager *m = ASSERT_PTR(userdata);
-        ImportVerify v;
         TransferType type;
-        int force, r;
-        uint32_t id;
+        uint64_t flags;
+        ImportVerify v;
+        int r;
 
         assert(msg);
 
@@ -925,9 +1017,33 @@ static int method_pull_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_er
         if (r == 0)
                 return 1; /* Will call us back */
 
-        r = sd_bus_message_read(msg, "sssb", &remote, &local, &verify, &force);
-        if (r < 0)
-                return r;
+        if (endswith(sd_bus_message_get_member(msg), "Ex")) {
+                const char *sclass;
+
+                r = sd_bus_message_read(msg, "sssst", &remote, &local, &sclass, &verify, &flags);
+                if (r < 0)
+                        return r;
+
+                class = image_class_from_string(sclass);
+                if (class < 0)
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
+                                                 "Image class '%s' not known", sclass);
+
+                if (flags & ~(IMPORT_FORCE|IMPORT_READ_ONLY))
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
+                                                 "Flags 0x%" PRIx64 " invalid", flags);
+        } else {
+                int force;
+
+                r = sd_bus_message_read(msg, "sssb", &remote, &local, &verify, &force);
+                if (r < 0)
+                        return r;
+
+                class = IMAGE_MACHINE;
+
+                flags = 0;
+                SET_FLAG(flags, IMPORT_FORCE, force);
+        }
 
         if (!http_url_is_valid(remote) && !file_url_is_valid(remote))
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
@@ -947,11 +1063,13 @@ static int method_pull_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_er
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
                                          "Unknown verification mode %s", verify);
 
-        r = setup_machine_directory(error, m->use_btrfs_subvol, m->use_btrfs_quota);
-        if (r < 0)
-                return r;
+        if (class == IMAGE_MACHINE) {
+                r = setup_machine_directory(error, m->use_btrfs_subvol, m->use_btrfs_quota);
+                if (r < 0)
+                        return r;
+        }
 
-        type = streq_ptr(sd_bus_message_get_member(msg), "PullTar") ?
+        type = startswith(sd_bus_message_get_member(msg), "PullTar") ?
                 TRANSFER_PULL_TAR : TRANSFER_PULL_RAW;
 
         if (manager_find(m, type, remote))
@@ -964,7 +1082,8 @@ static int method_pull_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_er
 
         t->type = type;
         t->verify = v;
-        t->force_local = force;
+        t->flags = flags;
+        t->class = class;
 
         t->remote = strdup(remote);
         if (!t->remote)
@@ -980,40 +1099,81 @@ static int method_pull_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_er
         if (r < 0)
                 return r;
 
-        object = t->object_path;
-        id = t->id;
-        t = NULL;
+        r = sd_bus_reply_method_return(msg, "uo", t->id, t->object_path);
+        if (r < 0)
+                return r;
 
-        return sd_bus_reply_method_return(msg, "uo", id, object);
+        TAKE_PTR(t);
+        return 1;
 }
 
 static int method_list_transfers(sd_bus_message *msg, void *userdata, sd_bus_error *error) {
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
         Manager *m = ASSERT_PTR(userdata);
+        ImageClass class = _IMAGE_CLASS_INVALID;
         Transfer *t;
         int r;
 
         assert(msg);
 
+        bool ex = endswith(sd_bus_message_get_member(msg), "Ex");
+        if (ex) {
+                const char *sclass;
+                uint64_t flags;
+
+                r = sd_bus_message_read(msg, "st", &sclass, &flags);
+                if (r < 0)
+                        return bus_log_parse_error(r);
+
+                if (!isempty(sclass)) {
+                        class = image_class_from_string(sclass);
+                        if (class < 0)
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
+                                                         "Image class '%s' not known", sclass);
+                }
+
+                if (flags != 0)
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
+                                                 "Flags 0x%" PRIx64 " invalid", flags);
+        }
+
         r = sd_bus_message_new_method_return(msg, &reply);
         if (r < 0)
                 return r;
 
-        r = sd_bus_message_open_container(reply, 'a', "(usssdo)");
+        if (ex)
+                r = sd_bus_message_open_container(reply, 'a', "(ussssdo)");
+        else
+                r = sd_bus_message_open_container(reply, 'a', "(usssdo)");
         if (r < 0)
                 return r;
 
         HASHMAP_FOREACH(t, m->transfers) {
 
-                r = sd_bus_message_append(
-                                reply,
-                                "(usssdo)",
-                                t->id,
-                                transfer_type_to_string(t->type),
-                                t->remote,
-                                t->local,
-                                transfer_percent_as_double(t),
-                                t->object_path);
+                if (class >= 0 && class != t->class)
+                        continue;
+
+                if (ex)
+                        r = sd_bus_message_append(
+                                        reply,
+                                        "(ussssdo)",
+                                        t->id,
+                                        transfer_type_to_string(t->type),
+                                        t->remote,
+                                        t->local,
+                                        image_class_to_string(t->class),
+                                        transfer_percent_as_double(t),
+                                        t->object_path);
+                else
+                        r = sd_bus_message_append(
+                                        reply,
+                                        "(usssdo)",
+                                        t->id,
+                                        transfer_type_to_string(t->type),
+                                        t->remote,
+                                        t->local,
+                                        transfer_percent_as_double(t),
+                                        t->object_path);
                 if (r < 0)
                         return r;
         }
@@ -1059,7 +1219,7 @@ static int method_cancel_transfer(sd_bus_message *msg, void *userdata, sd_bus_er
 
         r = bus_verify_polkit_async(
                         msg,
-                        "org.freedesktop.import1.pull",
+                        "org.freedesktop.import1.cancel",
                         /* details= */ NULL,
                         &m->polkit_registry,
                         error);
@@ -1212,6 +1372,17 @@ static const sd_bus_vtable manager_vtable[] = {
                                  SD_BUS_PARAM(transfer_path),
                                  method_import_tar_or_raw,
                                  SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_NAMES("ImportTarEx",
+                                 "hsst",
+                                 SD_BUS_PARAM(fd)
+                                 SD_BUS_PARAM(local_name)
+                                 SD_BUS_PARAM(class)
+                                 SD_BUS_PARAM(flags),
+                                 "uo",
+                                 SD_BUS_PARAM(transfer_id)
+                                 SD_BUS_PARAM(transfer_path),
+                                 method_import_tar_or_raw,
+                                 SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD_WITH_NAMES("ImportRaw",
                                  "hsbb",
                                  SD_BUS_PARAM(fd)
@@ -1223,6 +1394,17 @@ static const sd_bus_vtable manager_vtable[] = {
                                  SD_BUS_PARAM(transfer_path),
                                  method_import_tar_or_raw,
                                  SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_NAMES("ImportRawEx",
+                                 "hsst",
+                                 SD_BUS_PARAM(fd)
+                                 SD_BUS_PARAM(local_name)
+                                 SD_BUS_PARAM(class)
+                                 SD_BUS_PARAM(flags),
+                                 "uo",
+                                 SD_BUS_PARAM(transfer_id)
+                                 SD_BUS_PARAM(transfer_path),
+                                 method_import_tar_or_raw,
+                                 SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD_WITH_NAMES("ImportFileSystem",
                                  "hsbb",
                                  SD_BUS_PARAM(fd)
@@ -1234,6 +1416,17 @@ static const sd_bus_vtable manager_vtable[] = {
                                  SD_BUS_PARAM(transfer_path),
                                  method_import_fs,
                                  SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_NAMES("ImportFileSystemEx",
+                                 "hsst",
+                                 SD_BUS_PARAM(fd)
+                                 SD_BUS_PARAM(local_name)
+                                 SD_BUS_PARAM(class)
+                                 SD_BUS_PARAM(flags),
+                                 "uo",
+                                 SD_BUS_PARAM(transfer_id)
+                                 SD_BUS_PARAM(transfer_path),
+                                 method_import_fs,
+                                 SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD_WITH_NAMES("ExportTar",
                                  "shs",
                                  SD_BUS_PARAM(local_name)
@@ -1244,6 +1437,18 @@ static const sd_bus_vtable manager_vtable[] = {
                                  SD_BUS_PARAM(transfer_path),
                                  method_export_tar_or_raw,
                                  SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_NAMES("ExportTarEx",
+                                 "sshst",
+                                 SD_BUS_PARAM(local_name)
+                                 SD_BUS_PARAM(class)
+                                 SD_BUS_PARAM(fd)
+                                 SD_BUS_PARAM(format)
+                                 SD_BUS_PARAM(flags),
+                                 "uo",
+                                 SD_BUS_PARAM(transfer_id)
+                                 SD_BUS_PARAM(transfer_path),
+                                 method_export_tar_or_raw,
+                                 SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD_WITH_NAMES("ExportRaw",
                                  "shs",
                                  SD_BUS_PARAM(local_name)
@@ -1254,6 +1459,18 @@ static const sd_bus_vtable manager_vtable[] = {
                                  SD_BUS_PARAM(transfer_path),
                                  method_export_tar_or_raw,
                                  SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_NAMES("ExportRawEx",
+                                 "sshst",
+                                 SD_BUS_PARAM(local_name)
+                                 SD_BUS_PARAM(class)
+                                 SD_BUS_PARAM(fd)
+                                 SD_BUS_PARAM(format)
+                                 SD_BUS_PARAM(flags),
+                                 "uo",
+                                 SD_BUS_PARAM(transfer_id)
+                                 SD_BUS_PARAM(transfer_path),
+                                 method_export_tar_or_raw,
+                                 SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD_WITH_NAMES("PullTar",
                                  "sssb",
                                  SD_BUS_PARAM(url)
@@ -1265,6 +1482,18 @@ static const sd_bus_vtable manager_vtable[] = {
                                  SD_BUS_PARAM(transfer_path),
                                  method_pull_tar_or_raw,
                                  SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_NAMES("PullTarEx",
+                                 "sssst",
+                                 SD_BUS_PARAM(url)
+                                 SD_BUS_PARAM(local_name)
+                                 SD_BUS_PARAM(class)
+                                 SD_BUS_PARAM(verify_mode)
+                                 SD_BUS_PARAM(flags),
+                                 "uo",
+                                 SD_BUS_PARAM(transfer_id)
+                                 SD_BUS_PARAM(transfer_path),
+                                 method_pull_tar_or_raw,
+                                 SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD_WITH_NAMES("PullRaw",
                                  "sssb",
                                  SD_BUS_PARAM(url)
@@ -1276,12 +1505,32 @@ static const sd_bus_vtable manager_vtable[] = {
                                  SD_BUS_PARAM(transfer_path),
                                  method_pull_tar_or_raw,
                                  SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_NAMES("PullRawEx",
+                                 "sssst",
+                                 SD_BUS_PARAM(url)
+                                 SD_BUS_PARAM(local_name)
+                                 SD_BUS_PARAM(class)
+                                 SD_BUS_PARAM(verify_mode)
+                                 SD_BUS_PARAM(flags),
+                                 "uo",
+                                 SD_BUS_PARAM(transfer_id)
+                                 SD_BUS_PARAM(transfer_path),
+                                 method_pull_tar_or_raw,
+                                 SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD_WITH_NAMES("ListTransfers",
                                  NULL,,
                                  "a(usssdo)",
                                  SD_BUS_PARAM(transfers),
                                  method_list_transfers,
                                  SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_NAMES("ListTransfersEx",
+                                 "st",
+                                 SD_BUS_PARAM(class)
+                                 SD_BUS_PARAM(flags),
+                                 "a(ussssdo)",
+                                 SD_BUS_PARAM(transfers),
+                                 method_list_transfers,
+                                 SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD_WITH_NAMES("CancelTransfer",
                                  "u",
                                  SD_BUS_PARAM(transfer_id),
index d252ff64606b4ef8d7feb62e17ac247e4755ad0f..f775aa061c1d548757e8af1883eba85b3b9f77bc 100644 (file)
                        send_interface="org.freedesktop.import1.Manager"
                        send_member="ListTransfers"/>
 
+                <allow send_destination="org.freedesktop.import1"
+                       send_interface="org.freedesktop.import1.Manager"
+                       send_member="ListTransfersEx"/>
+
                 <allow send_destination="org.freedesktop.import1"
                        send_interface="org.freedesktop.import1.Manager"
                        send_member="CancelTransfer"/>
                        send_interface="org.freedesktop.import1.Manager"
                        send_member="ImportTar"/>
 
+                <allow send_destination="org.freedesktop.import1"
+                       send_interface="org.freedesktop.import1.Manager"
+                       send_member="ImportTarEx"/>
+
                 <allow send_destination="org.freedesktop.import1"
                        send_interface="org.freedesktop.import1.Manager"
                        send_member="ImportRaw"/>
 
+                <allow send_destination="org.freedesktop.import1"
+                       send_interface="org.freedesktop.import1.Manager"
+                       send_member="ImportRawEx"/>
+
                 <allow send_destination="org.freedesktop.import1"
                        send_interface="org.freedesktop.import1.Manager"
                        send_member="ImportFileSystem"/>
 
+                <allow send_destination="org.freedesktop.import1"
+                       send_interface="org.freedesktop.import1.Manager"
+                       send_member="ImportFileSystemEx"/>
+
                 <allow send_destination="org.freedesktop.import1"
                        send_interface="org.freedesktop.import1.Manager"
                        send_member="ExportTar"/>
 
+                <allow send_destination="org.freedesktop.import1"
+                       send_interface="org.freedesktop.import1.Manager"
+                       send_member="ExportTarEx"/>
+
                 <allow send_destination="org.freedesktop.import1"
                        send_interface="org.freedesktop.import1.Manager"
                        send_member="ExportRaw"/>
 
+                <allow send_destination="org.freedesktop.import1"
+                       send_interface="org.freedesktop.import1.Manager"
+                       send_member="ExportRawEx"/>
+
                 <allow send_destination="org.freedesktop.import1"
                        send_interface="org.freedesktop.import1.Manager"
                        send_member="PullTar"/>
 
+                <allow send_destination="org.freedesktop.import1"
+                       send_interface="org.freedesktop.import1.Manager"
+                       send_member="PullTarEx"/>
+
                 <allow send_destination="org.freedesktop.import1"
                        send_interface="org.freedesktop.import1.Manager"
                        send_member="PullRaw"/>
 
+                <allow send_destination="org.freedesktop.import1"
+                       send_interface="org.freedesktop.import1.Manager"
+                       send_member="PullRawEx"/>
+
                 <allow send_destination="org.freedesktop.import1"
                        send_interface="org.freedesktop.import1.Transfer"
                        send_member="Cancel"/>
index 88e436dc3af557261c71c038e2d1b239bd5cded9..45c11def674e7de5a29c619883c6f97a6b2a8489 100644 (file)
@@ -19,8 +19,8 @@
         <vendor_url>https://systemd.io</vendor_url>
 
         <action id="org.freedesktop.import1.import">
-                <description gettext-domain="systemd">Import a VM or container image</description>
-                <message gettext-domain="systemd">Authentication is required to import a VM or container image</message>
+                <description gettext-domain="systemd">Import a disk image</description>
+                <message gettext-domain="systemd">Authentication is required to import an image</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
@@ -29,8 +29,8 @@
         </action>
 
         <action id="org.freedesktop.import1.export">
-                <description gettext-domain="systemd">Export a VM or container image</description>
-                <message gettext-domain="systemd">Authentication is required to export a VM or container image</message>
+                <description gettext-domain="systemd">Export a disk image</description>
+                <message gettext-domain="systemd">Authentication is required to export disk image</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
         </action>
 
         <action id="org.freedesktop.import1.pull">
-                <description gettext-domain="systemd">Download a VM or container image</description>
-                <message gettext-domain="systemd">Authentication is required to download a VM or container image</message>
+                <description gettext-domain="systemd">Download a disk image</description>
+                <message gettext-domain="systemd">Authentication is required to download a disk image</message>
+                <defaults>
+                        <allow_any>auth_admin</allow_any>
+                        <allow_inactive>auth_admin</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.import1.cancel">
+                <description gettext-domain="systemd">Cancel transfer of a disk image</description>
+                <message gettext-domain="systemd">Authentication is required to cancel the ongoing transfer of a disk image</message>
                 <defaults>
                         <allow_any>auth_admin</allow_any>
                         <allow_inactive>auth_admin</allow_inactive>
index 783905776956f977c6f4b6d34686a543bd0a6065..4fca08437c21f1616b92c00ea40ef9b9a0781a35 100644 (file)
@@ -37,11 +37,9 @@ int pull_find_old_etags(
         int r;
 
         assert(url);
+        assert(image_root);
         assert(etags);
 
-        if (!image_root)
-                image_root = "/var/lib/machines";
-
         _cleanup_free_ char *escaped_url = xescape(url, FILENAME_ESCAPE);
         if (!escaped_url)
                 return -ENOMEM;
@@ -128,11 +126,9 @@ int pull_make_path(const char *url, const char *etag, const char *image_root, co
         char *path;
 
         assert(url);
+        assert(image_root);
         assert(ret);
 
-        if (!image_root)
-                image_root = "/var/lib/machines";
-
         escaped_url = xescape(url, FILENAME_ESCAPE);
         if (!escaped_url)
                 return -ENOMEM;
index ebe479fb802874d007a02a3f90631e18fea1fd46..50785fe431ccf1c2dca969d3bcc7ee97f9c59f22 100644 (file)
@@ -60,7 +60,7 @@ struct RawPull {
         void *userdata;
 
         char *local; /* In PULL_DIRECT mode the path we are supposed to place things in, otherwise the
-                      * machine name of the final copy we make */
+                      * image name of the final copy we make */
 
         char *final_path;
         char *temp_path;
@@ -127,8 +127,9 @@ int raw_pull_new(
         int r;
 
         assert(ret);
+        assert(image_root);
 
-        root = strdup(image_root ?: "/var/lib/machines");
+        root = strdup(image_root);
         if (!root)
                 return -ENOMEM;
 
index 99d8ff0553ccd766a3e7590a96d63e8860d41364..ae573f1b5403e8e340523a77458d86dce012797d 100644 (file)
@@ -106,9 +106,10 @@ int tar_pull_new(
         _cleanup_free_ char *root = NULL;
         int r;
 
+        assert(image_root);
         assert(ret);
 
-        root = strdup(image_root ?: "/var/lib/machines");
+        root = strdup(image_root);
         if (!root)
                 return -ENOMEM;
 
index 518755b61df19626d254ec36b0e05c8913ff93ef..f281ab04fddd0e9084e2b9dfdbb5de32025a75af 100644 (file)
 #include "verbs.h"
 #include "web-util.h"
 
-static const char *arg_image_root = "/var/lib/machines";
+static const char *arg_image_root = NULL;
 static ImportVerify arg_verify = IMPORT_VERIFY_SIGNATURE;
 static ImportFlags arg_import_flags = IMPORT_PULL_SETTINGS | IMPORT_PULL_ROOTHASH | IMPORT_PULL_ROOTHASH_SIGNATURE | IMPORT_PULL_VERITY | IMPORT_BTRFS_SUBVOL | IMPORT_BTRFS_QUOTA | IMPORT_CONVERT_QCOW2 | IMPORT_SYNC;
 static uint64_t arg_offset = UINT64_MAX, arg_size_max = UINT64_MAX;
 static char *arg_checksum = NULL;
+static ImageClass arg_class = IMAGE_MACHINE;
 
 STATIC_DESTRUCTOR_REGISTER(arg_checksum, freep);
 
@@ -64,7 +65,7 @@ static int normalize_local(const char *local, const char *url, char **ret) {
                                                local);
 
                 if (!FLAGS_SET(arg_import_flags, IMPORT_FORCE)) {
-                        r = image_find(IMAGE_MACHINE, local, NULL, NULL);
+                        r = image_find(arg_class, local, NULL, NULL);
                         if (r < 0) {
                                 if (r != -ENOENT)
                                         return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local);
@@ -241,7 +242,7 @@ static int pull_raw(int argc, char *argv[], void *userdata) {
 static int help(int argc, char *argv[], void *userdata) {
 
         printf("%1$s [OPTIONS...] {COMMAND} ...\n"
-               "\n%4$sDownload container or virtual machine images.%5$s\n"
+               "\n%4$sDownload disk images.%5$s\n"
                "\n%2$sCommands:%3$s\n"
                "  tar URL [NAME]              Download a TAR image\n"
                "  raw URL [NAME]              Download a RAW image\n"
@@ -267,7 +268,9 @@ static int help(int argc, char *argv[], void *userdata) {
                "                              regular disk images\n"
                "     --sync=BOOL              Controls whether to sync() before completing\n"
                "     --offset=BYTES           Offset to seek to in destination\n"
-               "     --size-max=BYTES         Maximum number of bytes to write to destination\n",
+               "     --size-max=BYTES         Maximum number of bytes to write to destination\n"
+               "     --class=CLASS            Select image class (machine, sysext, confext,\n"
+               "                              portable)\n",
                program_invocation_short_name,
                ansi_underline(),
                ansi_normal(),
@@ -296,6 +299,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_SYNC,
                 ARG_OFFSET,
                 ARG_SIZE_MAX,
+                ARG_CLASS,
         };
 
         static const struct option options[] = {
@@ -316,10 +320,12 @@ static int parse_argv(int argc, char *argv[]) {
                 { "sync",               required_argument, NULL, ARG_SYNC               },
                 { "offset",             required_argument, NULL, ARG_OFFSET             },
                 { "size-max",           required_argument, NULL, ARG_SIZE_MAX           },
+                { "class",              required_argument, NULL, ARG_CLASS              },
                 {}
         };
 
         int c, r;
+        bool auto_settings = true;
 
         assert(argc >= 0);
         assert(argv);
@@ -381,6 +387,7 @@ static int parse_argv(int argc, char *argv[]) {
                                 return r;
 
                         SET_FLAG(arg_import_flags, IMPORT_PULL_SETTINGS, r);
+                        auto_settings = false;
                         break;
 
                 case ARG_ROOTHASH:
@@ -478,6 +485,13 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
                 }
 
+                case ARG_CLASS:
+                        arg_class = image_class_from_string(optarg);
+                        if (arg_class < 0)
+                                return log_error_errno(arg_class, "Failed to parse --class= argument: %s", optarg);
+
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -497,6 +511,13 @@ static int parse_argv(int argc, char *argv[]) {
         if (arg_checksum && (arg_import_flags & (IMPORT_PULL_SETTINGS|IMPORT_PULL_ROOTHASH|IMPORT_PULL_ROOTHASH_SIGNATURE|IMPORT_PULL_VERITY)) != 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Literal checksum verification only supported if no associated files are downloaded.");
 
+        if (!arg_image_root)
+                arg_image_root = image_root_to_string(arg_class);
+
+        /* .nspawn settings files only really make sense for machine images, not for sysext/confext/portable */
+        if (auto_settings && arg_class != IMAGE_MACHINE)
+                arg_import_flags &= ~IMPORT_PULL_SETTINGS;
+
         return 1;
 }
 
index 72f20c8eb7e24aa52eeb74888a70437c9c54f6bb..00d32a9c87673ad74ee25e350839157d9c54ebd2 100644 (file)
@@ -99,6 +99,15 @@ static const char* image_class_suffix_table[_IMAGE_CLASS_MAX] = {
 
 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(image_class_suffix, ImageClass);
 
+static const char *const image_root_table[_IMAGE_CLASS_MAX] = {
+        [IMAGE_MACHINE]  = "/var/lib/machines",
+        [IMAGE_PORTABLE] = "/var/lib/portables",
+        [IMAGE_SYSEXT]   = "/var/lib/extensions",
+        [IMAGE_CONFEXT]  = "/var/lib/confexts",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_TO_STRING(image_root, ImageClass);
+
 static Image *image_free(Image *i) {
         assert(i);
 
index a30a3d92ba00b56a7a1cb8aa34d7915238bfbf77..350c3a22cc0af6b22e77ab02080a5bacbfd6139f 100644 (file)
@@ -119,4 +119,6 @@ static inline bool IMAGE_IS_HOST(const struct Image *i) {
 
 int image_to_json(const struct Image *i, JsonVariant **ret);
 
+const char *image_root_to_string(ImageClass c) _const_;
+
 extern const struct hash_ops image_hash_ops;