#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"
char *remote;
char *local;
- bool force_local;
- bool read_only;
-
+ ImageClass class;
+ ImportFlags flags;
char *format;
PidRef pidref;
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 */
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) {
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);
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;
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);
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)
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);
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)
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)
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);
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,
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);
return r;
t->type = type;
+ t->class = class;
+ t->flags = flags;
if (!isempty(format)) {
t->format = strdup(format);
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);
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,
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))
t->type = type;
t->verify = v;
- t->force_local = force;
+ t->flags = flags;
+ t->class = class;
t->remote = strdup(remote);
if (!t->remote)
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;
}
r = bus_verify_polkit_async(
msg,
- "org.freedesktop.import1.pull",
+ "org.freedesktop.import1.cancel",
/* details= */ NULL,
&m->polkit_registry,
error);
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)
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)
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)
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)
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)
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)
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),