machinectl: Add plumbing for a --force flag for file copy

machine: Add APIs CopyTo[Machine]WithFlags + CopyFrom[Machine]WithFlags
- Same API to those without `WithFlags` (except this can take flags)
- Initially, only a flag to allow replacing a file if it already exists
This commit is contained in:
Alexander Wilson 2022-07-22 04:08:11 -07:00
parent 922409558e
commit ae03e1a972
6 changed files with 88 additions and 5 deletions

View file

@ -305,7 +305,7 @@
</varlistentry>
<varlistentry>
<term><command>copy-to</command> <replaceable>NAME</replaceable> <replaceable>PATH</replaceable> [<replaceable>PATH</replaceable>]</term>
<term><command>copy-to</command> <replaceable>NAME</replaceable> <replaceable>PATH</replaceable> [<replaceable>PATH</replaceable>] <option>--force</option></term>
<listitem><para>Copies files or directories from the host
system into a running container. Takes a container name,
@ -319,7 +319,7 @@
</varlistentry>
<varlistentry>
<term><command>copy-from</command> <replaceable>NAME</replaceable> <replaceable>PATH</replaceable> [<replaceable>PATH</replaceable>]</term>
<term><command>copy-from</command> <replaceable>NAME</replaceable> <replaceable>PATH</replaceable> [<replaceable>PATH</replaceable>] <option>--force</option></term>
<listitem><para>Copies files or directories from a container
into the host system. Takes a container name, followed by the

View file

@ -116,6 +116,14 @@ node /org/freedesktop/machine1 {
CopyToMachine(in s name,
in s source,
in s destination);
CopyFromMachineWithFlags(in s name,
in s source,
in s destination,
in t flags);
CopyToMachineWithFlags(in s name,
in s source,
in s destination,
in t flags);
OpenMachineRootDirectory(in s name,
out h fd);
GetMachineUIDShift(in s name,
@ -176,6 +184,8 @@ node /org/freedesktop/machine1 {
<!--method UnregisterMachine is not documented!-->
<!--method CopyToMachineWithFlags is not documented!-->
<!--method OpenMachineRootDirectory is not documented!-->
<!--method GetMachineUIDShift is not documented!-->
@ -236,6 +246,10 @@ node /org/freedesktop/machine1 {
<variablelist class="dbus-method" generated="True" extra-ref="CopyToMachine()"/>
<variablelist class="dbus-method" generated="True" extra-ref="CopyFromMachineWithFlags()"/>
<variablelist class="dbus-method" generated="True" extra-ref="CopyToMachineWithFlags()"/>
<variablelist class="dbus-method" generated="True" extra-ref="OpenMachineRootDirectory()"/>
<variablelist class="dbus-method" generated="True" extra-ref="GetMachineUIDShift()"/>
@ -394,8 +408,10 @@ node /org/freedesktop/machine1 {
<para><function>CopyFromMachine()</function> copies files or directories from a container into the
host. It takes a container name, a source directory in the container and a destination directory on the
host as arguments. <function>CopyToMachine()</function> does the opposite and copies files from a source
directory on the host into a destination directory in the container.</para>
host as arguments.
<function>CopyToMachine()</function> does the opposite and copies files from a source
directory on the host into a destination directory in the container.
<function>CopyFromMachineWithFlags()</function> and <function>CopyToMachineWithFlags</function> do the same but take an additional flags argument.</para>
<para><function>RemoveImage()</function> removes the image with the specified name.</para>
@ -465,6 +481,12 @@ node /org/freedesktop/machine1/machine/rawhide {
in s destination);
CopyTo(in s source,
in s destination);
CopyFromWithFlags(in s source,
in s destination,
in t flags);
CopyToWithFlags(in s source,
in s destination,
in t flags);
OpenRootDirectory(out h fd);
properties:
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
@ -510,6 +532,10 @@ node /org/freedesktop/machine1/machine/rawhide {
<!--method CopyTo is not documented!-->
<!--method CopyFromWithFlags is not documented!-->
<!--method CopyToWithFlags is not documented!-->
<!--method OpenRootDirectory is not documented!-->
<!--Autogenerated cross-references for systemd.directives, do not edit-->
@ -540,6 +566,10 @@ node /org/freedesktop/machine1/machine/rawhide {
<variablelist class="dbus-method" generated="True" extra-ref="CopyTo()"/>
<variablelist class="dbus-method" generated="True" extra-ref="CopyFromWithFlags()"/>
<variablelist class="dbus-method" generated="True" extra-ref="CopyToWithFlags()"/>
<variablelist class="dbus-method" generated="True" extra-ref="OpenRootDirectory()"/>
<variablelist class="dbus-property" generated="True" extra-ref="Name"/>

View file

@ -928,6 +928,20 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro
if (r < 0)
return r;
if (endswith(sd_bus_message_get_member(message), "WithFlags")) {
uint64_t raw_flags;
r = sd_bus_message_read(message, "t", &raw_flags);
if (r < 0)
return r;
if ((raw_flags & ~_MACHINE_COPY_FLAGS_MASK_PUBLIC) != 0)
return -EINVAL;
if (raw_flags & MACHINE_COPY_REPLACE)
copy_flags |= COPY_REPLACE;
}
if (!path_is_absolute(src))
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Source path must be absolute.");
@ -1328,6 +1342,16 @@ static const sd_bus_vtable machine_vtable[] = {
SD_BUS_NO_RESULT,
bus_machine_method_copy,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("CopyFromWithFlags",
SD_BUS_ARGS("s", source, "s", destination, "t", flags),
SD_BUS_NO_RESULT,
bus_machine_method_copy,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("CopyToWithFlags",
SD_BUS_ARGS("s", source, "s", destination, "t", flags),
SD_BUS_NO_RESULT,
bus_machine_method_copy,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("OpenRootDirectory",
SD_BUS_NO_ARGS,
SD_BUS_RESULT("h", fd),

View file

@ -6,6 +6,11 @@
#include "bus-util.h"
#include "machine.h"
typedef enum {
MACHINE_COPY_REPLACE = 1 << 0, /* Public API via DBUS, do not change */
_MACHINE_COPY_FLAGS_MASK_PUBLIC = MACHINE_COPY_REPLACE,
} MachineCopyFlags;
extern const BusObjectImplementation machine_object;
char *machine_bus_path(Machine *s);

View file

@ -34,6 +34,7 @@
#include "locale-util.h"
#include "log.h"
#include "logs-show.h"
#include "machine-dbus.h"
#include "macro.h"
#include "main-func.h"
#include "mkdir.h"
@ -1093,6 +1094,13 @@ static int terminate_machine(int argc, char *argv[], void *userdata) {
return 0;
}
static const char *select_copy_method(bool copy_from, bool force) {
if (force)
return copy_from ? "CopyFromMachineWithFlags" : "CopyToMachineWithFlags";
else
return copy_from ? "CopyFromMachine" : "CopyToMachine";
}
static int copy_files(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
@ -1123,7 +1131,7 @@ static int copy_files(int argc, char *argv[], void *userdata) {
bus,
&m,
bus_machine_mgr,
copy_from ? "CopyFromMachine" : "CopyToMachine");
select_copy_method(copy_from, arg_force));
if (r < 0)
return bus_log_create_error(r);
@ -1136,6 +1144,12 @@ static int copy_files(int argc, char *argv[], void *userdata) {
if (r < 0)
return bus_log_create_error(r);
if (arg_force) {
r = sd_bus_message_append(m, "t", MACHINE_COPY_REPLACE);
if (r < 0)
return bus_log_create_error(r);
}
/* This is a slow operation, hence turn off any method call timeouts */
r = sd_bus_call(bus, m, USEC_INFINITY, &error, NULL);
if (r < 0)

View file

@ -1110,6 +1110,16 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_NO_RESULT,
method_copy_machine,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("CopyFromMachineWithFlags",
SD_BUS_ARGS("s", name, "s", source, "s", destination, "t", flags),
SD_BUS_NO_RESULT,
method_copy_machine,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("CopyToMachineWithFlags",
SD_BUS_ARGS("s", name, "s", source, "s", destination, "t", flags),
SD_BUS_NO_RESULT,
method_copy_machine,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("OpenMachineRootDirectory",
SD_BUS_ARGS("s", name),
SD_BUS_RESULT("h", fd),