From: Ivan Kruglov Date: Mon, 6 Jan 2025 15:31:02 +0000 (+0100) Subject: machine: introduce io.systemd.Machine.OpenRootDirectory X-Git-Tag: v258-rc1~1653^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8633bf583692175ccef0a47450d4a1b0491dde6e;p=thirdparty%2Fsystemd.git machine: introduce io.systemd.Machine.OpenRootDirectory --- diff --git a/src/machine/machine-varlink.c b/src/machine/machine-varlink.c index a889b94d804..89d047f954f 100644 --- a/src/machine/machine-varlink.c +++ b/src/machine/machine-varlink.c @@ -919,3 +919,40 @@ int vl_method_copy_internal(sd_varlink *link, sd_json_variant *parameters, sd_va op->done = copy_done; return 1; } + +int vl_method_open_root_directory_internal(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { + _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL; + _cleanup_close_ int fd = -EBADF; + Machine *machine = ASSERT_PTR(userdata); + Manager *manager = ASSERT_PTR(machine->manager); + int r; + + r = varlink_verify_polkit_async( + link, + manager->bus, + "org.freedesktop.machine1.manage-machines", + (const char**) STRV_MAKE("name", machine->name, + "verb", "open_root_directory"), + &manager->polkit_registry); + if (r <= 0) + return r; + + fd = machine_open_root_directory(machine); + if (ERRNO_IS_NEG_NOT_SUPPORTED(fd)) + return sd_varlink_error(link, "io.systemd.Machine.NotSupported", NULL); + if (fd < 0) + return log_debug_errno(fd, "Failed to open root directory of machine '%s': %m", machine->name); + + int fd_idx = sd_varlink_push_fd(link, fd); + /* no need to handle -EPERM because server has SD_VARLINK_SERVER_ALLOW_FD_PASSING_OUTPUT */ + if (fd_idx < 0) + return log_debug_errno(fd_idx, "Failed to push file descriptor over varlink: %m"); + + TAKE_FD(fd); + + r = sd_json_buildo(&v, SD_JSON_BUILD_PAIR_INTEGER("fileDescriptor", fd_idx)); + if (r < 0) + return r; + + return sd_varlink_reply(link, v); +} diff --git a/src/machine/machine-varlink.h b/src/machine/machine-varlink.h index bd80cb2653c..3d56e2150e9 100644 --- a/src/machine/machine-varlink.h +++ b/src/machine/machine-varlink.h @@ -29,3 +29,4 @@ int vl_method_map_from(sd_varlink *link, sd_json_variant *parameters, sd_varlink int vl_method_map_to(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); int vl_method_bind_mount(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); int vl_method_copy_internal(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata, bool copy_from); +int vl_method_open_root_directory_internal(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); diff --git a/src/machine/machined-varlink.c b/src/machine/machined-varlink.c index e0de3aca012..b94cce296d8 100644 --- a/src/machine/machined-varlink.c +++ b/src/machine/machined-varlink.c @@ -599,6 +599,10 @@ static int vl_method_copy_to(sd_varlink *link, sd_json_variant *parameters, sd_v return vl_method_copy_internal(link, parameters, flags, userdata, /* copy_from = */ false); } +static int vl_method_open_root_directory(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { + return lookup_machine_and_call_method(link, parameters, flags, userdata, vl_method_open_root_directory_internal); +} + static int list_image_one_and_maybe_read_metadata(sd_varlink *link, Image *image, bool more, AcquireMetadata am) { int r; @@ -774,21 +778,22 @@ static int manager_varlink_init_machine(Manager *m) { r = sd_varlink_server_bind_method_many( s, - "io.systemd.Machine.Register", vl_method_register, - "io.systemd.Machine.List", vl_method_list, - "io.systemd.Machine.Unregister", vl_method_unregister, - "io.systemd.Machine.Terminate", vl_method_terminate, - "io.systemd.Machine.Kill", vl_method_kill, - "io.systemd.Machine.Open", vl_method_open, - "io.systemd.Machine.MapFrom", vl_method_map_from, - "io.systemd.Machine.MapTo", vl_method_map_to, - "io.systemd.Machine.BindMount", vl_method_bind_mount, - "io.systemd.Machine.CopyFrom", vl_method_copy_from, - "io.systemd.Machine.CopyTo", vl_method_copy_to, - "io.systemd.MachineImage.List", vl_method_list_images, - "io.systemd.MachineImage.Update", vl_method_update_image, - "io.systemd.MachineImage.Clone", vl_method_clone_image, - "io.systemd.MachineImage.Remove", vl_method_remove_image); + "io.systemd.Machine.Register", vl_method_register, + "io.systemd.Machine.List", vl_method_list, + "io.systemd.Machine.Unregister", vl_method_unregister, + "io.systemd.Machine.Terminate", vl_method_terminate, + "io.systemd.Machine.Kill", vl_method_kill, + "io.systemd.Machine.Open", vl_method_open, + "io.systemd.Machine.OpenRootDirectory", vl_method_open_root_directory, + "io.systemd.Machine.MapFrom", vl_method_map_from, + "io.systemd.Machine.MapTo", vl_method_map_to, + "io.systemd.Machine.BindMount", vl_method_bind_mount, + "io.systemd.Machine.CopyFrom", vl_method_copy_from, + "io.systemd.Machine.CopyTo", vl_method_copy_to, + "io.systemd.MachineImage.List", vl_method_list_images, + "io.systemd.MachineImage.Update", vl_method_update_image, + "io.systemd.MachineImage.Clone", vl_method_clone_image, + "io.systemd.MachineImage.Remove", vl_method_remove_image); if (r < 0) return log_error_errno(r, "Failed to register varlink methods: %m"); diff --git a/src/shared/varlink-io.systemd.Machine.c b/src/shared/varlink-io.systemd.Machine.c index 1953f2fc612..1d6cab8da77 100644 --- a/src/shared/varlink-io.systemd.Machine.c +++ b/src/shared/varlink-io.systemd.Machine.c @@ -179,6 +179,12 @@ static SD_VARLINK_DEFINE_METHOD( SD_VARLINK_FIELD_COMMENT("If true the destination will be replaced"), SD_VARLINK_DEFINE_INPUT(replace, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE)); +static SD_VARLINK_DEFINE_METHOD( + OpenRootDirectory, + VARLINK_DEFINE_MACHINE_LOOKUP_AND_POLKIT_INPUT_FIELDS, + SD_VARLINK_FIELD_COMMENT("File descriptor of opened root directory"), + SD_VARLINK_DEFINE_OUTPUT(fileDescriptor, SD_VARLINK_INT, 0)); + static SD_VARLINK_DEFINE_ERROR(NoSuchMachine); static SD_VARLINK_DEFINE_ERROR(MachineExists); static SD_VARLINK_DEFINE_ERROR(NoPrivateNetworking); @@ -225,6 +231,8 @@ SD_VARLINK_DEFINE_INTERFACE( &vl_method_CopyFrom, SD_VARLINK_SYMBOL_COMMENT("Copy files or directories from the host into a container"), &vl_method_CopyTo, + SD_VARLINK_SYMBOL_COMMENT("Opens machine's root directory"), + &vl_method_OpenRootDirectory, SD_VARLINK_SYMBOL_COMMENT("No matching machine currently running"), &vl_error_NoSuchMachine, &vl_error_MachineExists,