mirror of
https://github.com/systemd/systemd
synced 2024-10-04 15:21:01 +00:00
importd: add support for downloading sysext/confext/portable images too
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.
This commit is contained in:
parent
83d7411209
commit
7af5785d77
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -25,9 +25,10 @@
|
|||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,16 +14,19 @@
|
|||
#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),
|
||||
|
|
|
@ -42,6 +42,10 @@
|
|||
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"/>
|
||||
|
@ -50,30 +54,58 @@
|
|||
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"/>
|
||||
|
|
|
@ -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>
|
||||
|
@ -39,8 +39,18 @@
|
|||
</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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -26,11 +26,12 @@
|
|||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue