summaryrefslogtreecommitdiff
path: root/src/machine
diff options
context:
space:
mode:
Diffstat (limited to 'src/machine')
-rw-r--r--src/machine/machine-dbus.c96
-rw-r--r--src/machine/machine.h1
-rw-r--r--src/machine/machinectl.c44
-rw-r--r--src/machine/machined-dbus.c22
-rw-r--r--src/machine/org.freedesktop.machine1.conf4
5 files changed, 165 insertions, 2 deletions
diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c
index c9c3de0d04..14dae0a033 100644
--- a/src/machine/machine-dbus.c
+++ b/src/machine/machine-dbus.c
@@ -28,9 +28,11 @@
#include "bus-util.h"
#include "bus-label.h"
#include "strv.h"
-#include "machine.h"
#include "rtnl-util.h"
#include "bus-errors.h"
+#include "copy.h"
+#include "fileio.h"
+#include "machine.h"
static int property_get_id(
sd_bus *bus,
@@ -333,6 +335,95 @@ int bus_machine_method_get_addresses(sd_bus *bus, sd_bus_message *message, void
return sd_bus_send(bus, reply, NULL);
}
+int bus_machine_method_get_os_release(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+ _cleanup_close_ int mntns_fd = -1, root_fd = -1;
+ _cleanup_close_pair_ int pair[2] = { -1, -1 };
+ _cleanup_strv_free_ char **l = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ Machine *m = userdata;
+ char **k, **v;
+ siginfo_t si;
+ pid_t child;
+ int r;
+
+ assert(bus);
+ assert(message);
+ assert(m);
+
+ r = namespace_open(m->leader, NULL, &mntns_fd, NULL, &root_fd);
+ if (r < 0)
+ return sd_bus_error_set_errno(error, r);
+
+ if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0)
+ return sd_bus_error_set_errno(error, -errno);
+
+ child = fork();
+ if (child < 0)
+ return sd_bus_error_set_errno(error, -errno);
+
+ if (child == 0) {
+ _cleanup_close_ int fd = -1;
+
+ pair[0] = safe_close(pair[0]);
+
+ r = namespace_enter(-1, mntns_fd, -1, root_fd);
+ if (r < 0)
+ _exit(EXIT_FAILURE);
+
+ fd = open("/etc/os-release", O_RDONLY|O_CLOEXEC);
+ if (fd < 0) {
+ fd = open("/usr/lib/os-release", O_RDONLY|O_CLOEXEC);
+ if (fd < 0)
+ _exit(EXIT_FAILURE);
+ }
+
+ r = copy_bytes(fd, pair[1], (off_t) -1);
+ if (r < 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ pair[1] = safe_close(pair[1]);
+
+ f = fdopen(pair[0], "re");
+ if (!f)
+ return sd_bus_error_set_errno(error, -errno);
+
+ pair[0] = -1;
+
+ r = load_env_file_pairs(f, "/etc/os-release", NULL, &l);
+ if (r < 0)
+ return sd_bus_error_set_errno(error, r);
+
+ r = wait_for_terminate(child, &si);
+ if (r < 0)
+ return sd_bus_error_set_errno(error, r);
+ if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
+ return sd_bus_error_set_errno(error, EIO);
+
+ r = sd_bus_message_new_method_return(message, &reply);
+ if (r < 0)
+ return sd_bus_error_set_errno(error, r);
+
+ r = sd_bus_message_open_container(reply, 'a', "{ss}");
+ if (r < 0)
+ return sd_bus_error_set_errno(error, r);
+
+ STRV_FOREACH_PAIR(k, v, l) {
+ r = sd_bus_message_append(reply, "{ss}", *k, *v);
+ if (r < 0)
+ return sd_bus_error_set_errno(error, r);
+ }
+
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ return sd_bus_error_set_errno(error, r);
+
+ return sd_bus_send(bus, reply, NULL);
+}
+
const sd_bus_vtable machine_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Machine, name), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -348,7 +439,8 @@ const sd_bus_vtable machine_vtable[] = {
SD_BUS_METHOD("Terminate", NULL, NULL, bus_machine_method_terminate, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
SD_BUS_METHOD("Kill", "si", NULL, bus_machine_method_kill, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
SD_BUS_METHOD("GetAddresses", NULL, "a(yay)", bus_machine_method_get_addresses, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_VTABLE_END
+ SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_machine_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_VTABLE_END
};
int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
diff --git a/src/machine/machine.h b/src/machine/machine.h
index ed1c81c4f4..fa9262d52c 100644
--- a/src/machine/machine.h
+++ b/src/machine/machine.h
@@ -100,6 +100,7 @@ int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char
int bus_machine_method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_machine_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_machine_method_get_addresses(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
+int bus_machine_method_get_os_release(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
int machine_send_signal(Machine *m, bool new_machine);
int machine_send_create_reply(Machine *m, sd_bus_error *error);
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index c2bf7e5197..022a4ebe50 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -224,6 +224,48 @@ static int print_addresses(sd_bus *bus, const char *name, const char *prefix, co
return 0;
}
+static int print_os_release(sd_bus *bus, const char *name, const char *prefix) {
+ _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+ const char *k, *v, *pretty = NULL;
+ int r;
+
+ assert(bus);
+ assert(name);
+ assert(prefix);
+
+ r = sd_bus_call_method(bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "GetMachineOSRelease",
+ NULL,
+ &reply,
+ "s", name);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_enter_container(reply, 'a', "{ss}");
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ while ((r = sd_bus_message_read(reply, "{ss}", &k, &v)) > 0) {
+ if (streq(k, "PRETTY_NAME"))
+ pretty = v;
+
+ }
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ if (pretty)
+ printf("%s%s\n", prefix, pretty);
+
+ return 0;
+}
+
typedef struct MachineStatusInfo {
char *name;
sd_id128_t id;
@@ -284,6 +326,8 @@ static void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
"\t Address: ",
"\t ");
+ print_os_release(bus, i->name, "\t OS: ");
+
if (i->unit) {
printf("\t Unit: %s\n", i->unit);
show_unit_cgroup(bus, i->unit, i->leader);
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
index 7c1802ce2a..ffcd7c026a 100644
--- a/src/machine/machined-dbus.c
+++ b/src/machine/machined-dbus.c
@@ -371,6 +371,27 @@ static int method_get_machine_addresses(sd_bus *bus, sd_bus_message *message, vo
return bus_machine_method_get_addresses(bus, message, machine, error);
}
+static int method_get_machine_os_release(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ Manager *m = userdata;
+ Machine *machine;
+ const char *name;
+ int r;
+
+ assert(bus);
+ assert(message);
+ assert(m);
+
+ r = sd_bus_message_read(message, "s", &name);
+ if (r < 0)
+ return sd_bus_error_set_errno(error, r);
+
+ machine = hashmap_get(m->machines, name);
+ if (!machine)
+ return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
+
+ return bus_machine_method_get_os_release(bus, message, machine, error);
+}
+
const sd_bus_vtable manager_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_METHOD("GetMachine", "s", "o", method_get_machine, SD_BUS_VTABLE_UNPRIVILEGED),
@@ -381,6 +402,7 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_METHOD("KillMachine", "ssi", NULL, method_kill_machine, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
SD_BUS_METHOD("TerminateMachine", "s", NULL, method_terminate_machine, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
SD_BUS_METHOD("GetMachineAddresses", "s", "a(yay)", method_get_machine_addresses, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetMachineOSRelease", "s", "a{ss}", method_get_machine_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_SIGNAL("MachineNew", "so", 0),
SD_BUS_SIGNAL("MachineRemoved", "so", 0),
SD_BUS_VTABLE_END
diff --git a/src/machine/org.freedesktop.machine1.conf b/src/machine/org.freedesktop.machine1.conf
index ab349a536d..3a77c70bf1 100644
--- a/src/machine/org.freedesktop.machine1.conf
+++ b/src/machine/org.freedesktop.machine1.conf
@@ -56,6 +56,10 @@
send_interface="org.freedesktop.machine1.Machine"
send_member="GetAddresses"/>
+ <allow send_destination="org.freedesktop.machine1"
+ send_interface="org.freedesktop.machine1.Machine"
+ send_member="GetMachineOSRelease"/>
+
<allow receive_sender="org.freedesktop.machine1"/>
</policy>