chiark / gitweb /
machinectl: add new "start" verb to start a container as a service in nspawn
[elogind.git] / src / machine / machinectl.c
index 17fbe51f9f8486aae5375fb5487cae609c0b62c0..b0c1533491bc7db74b7d6af34d3565c3cf9a0cf7 100644 (file)
@@ -1417,6 +1417,76 @@ static int read_only_image(int argc, char *argv[], void *userdata) {
         return 0;
 }
 
+static int start_machine(int argc, char *argv[], void *userdata) {
+        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
+        sd_bus *bus = userdata;
+        int r, i;
+
+        assert(bus);
+
+        r = bus_wait_for_jobs_new(bus, &w);
+        if (r < 0)
+                return log_oom();
+
+        for (i = 1; i < argc; i++) {
+                _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
+                _cleanup_free_ char *e = NULL, *unit = NULL;
+                const char *object;
+
+                if (!machine_name_is_valid(argv[i])) {
+                        log_error("Invalid machine name %s.", argv[i]);
+                        return -EINVAL;
+                }
+
+                e = unit_name_escape(argv[i]);
+                if (!e)
+                        return log_oom();
+
+                unit = unit_name_build("systemd-nspawn", e, ".service");
+                if (!unit)
+                        return log_oom();
+
+                r = sd_bus_message_new_method_call(
+                                bus,
+                                &m,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "StartUnit");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_set_allow_interactive_authorization(m, true);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_append(m, "ss", unit, "fail");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_call(bus, m, 0, &error, &reply);
+                if (r < 0) {
+                        log_error("Failed to start unit: %s", bus_error_message(&error, -r));
+                        return r;
+                }
+
+                r = sd_bus_message_read(reply, "o", &object);
+                if (r < 0)
+                        return bus_log_parse_error(r);
+
+                r = bus_wait_for_jobs_add(w, object);
+                if (r < 0)
+                        return log_oom();
+        }
+
+        r = bus_wait_for_jobs(w, false);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
 static int help(int argc, char *argv[], void *userdata) {
 
         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
@@ -1440,6 +1510,7 @@ static int help(int argc, char *argv[], void *userdata) {
                "  status NAME...              Show VM/container details\n"
                "  show NAME...                Show properties of one or more VMs/containers\n"
                "  login NAME                  Get a login prompt on a container\n"
+               "  start NAME...               Start container as a service\n"
                "  poweroff NAME...            Power off one or more containers\n"
                "  reboot NAME...              Reboot one or more containers\n"
                "  terminate NAME...           Terminate one or more VMs/containers\n"
@@ -1594,6 +1665,7 @@ static int machinectl_main(int argc, char *argv[], sd_bus *bus) {
                 { "rename",      3,        3,        0,            rename_image      },
                 { "clone",       3,        3,        0,            clone_image       },
                 { "read-only",   2,        3,        0,            read_only_image   },
+                { "start",       2,        VERB_ANY, 0,            start_machine     },
                 {}
         };