vmspawn: register with io.systemd.Machine.Register
When available, use varlink to register the VM, so that we can talk over SSH to the guest. Enables 'machinectl shell' for vmspawn guests.
This commit is contained in:
committed by
Luca Boccassi
parent
506aa3713b
commit
1e83cfff8d
@@ -5,36 +5,72 @@
|
||||
|
||||
#include "bus-error.h"
|
||||
#include "bus-locator.h"
|
||||
#include "json.h"
|
||||
#include "macro.h"
|
||||
#include "process-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "string-util.h"
|
||||
#include "varlink.h"
|
||||
#include "vmspawn-register.h"
|
||||
|
||||
int register_machine(sd_bus *bus, const char *machine_name, sd_id128_t uuid, const char *service, const char *directory) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
int register_machine(
|
||||
sd_bus *bus,
|
||||
const char *machine_name,
|
||||
sd_id128_t uuid,
|
||||
const char *service,
|
||||
const char *directory,
|
||||
unsigned cid,
|
||||
const char *address,
|
||||
const char *key_path) {
|
||||
|
||||
_cleanup_(varlink_unrefp) Varlink *vl = NULL;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(machine_name);
|
||||
assert(service);
|
||||
|
||||
r = bus_call_method(
|
||||
bus,
|
||||
bus_machine_mgr,
|
||||
"RegisterMachine",
|
||||
&error,
|
||||
NULL,
|
||||
"sayssus",
|
||||
machine_name,
|
||||
SD_BUS_MESSAGE_APPEND_ID128(uuid),
|
||||
service,
|
||||
"vm",
|
||||
(uint32_t) getpid_cached(),
|
||||
strempty(directory));
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register machine: %s", bus_error_message(&error, r));
|
||||
/* First try to use varlink, as it provides more features (such as SSH support). */
|
||||
r = varlink_connect_address(&vl, "/run/systemd/machine/io.systemd.Machine");
|
||||
if (r == -ENOENT || ERRNO_IS_DISCONNECT(r)) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
|
||||
return 0;
|
||||
assert(bus);
|
||||
|
||||
/* In case we are running with an older machined, fallback to the existing D-Bus method. */
|
||||
r = bus_call_method(
|
||||
bus,
|
||||
bus_machine_mgr,
|
||||
"RegisterMachine",
|
||||
&error,
|
||||
NULL,
|
||||
"sayssus",
|
||||
machine_name,
|
||||
SD_BUS_MESSAGE_APPEND_ID128(uuid),
|
||||
service,
|
||||
"vm",
|
||||
(uint32_t) getpid_cached(),
|
||||
strempty(directory));
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register machine: %s", bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to machined on /run/systemd/machine/io.systemd.Machine: %m");
|
||||
|
||||
|
||||
return varlink_callb_and_log(vl,
|
||||
"io.systemd.Machine.Register",
|
||||
NULL,
|
||||
JSON_BUILD_OBJECT(
|
||||
JSON_BUILD_PAIR_STRING("name", machine_name),
|
||||
JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(uuid), "id", JSON_BUILD_ID128(uuid)),
|
||||
JSON_BUILD_PAIR_STRING("service", service),
|
||||
JSON_BUILD_PAIR_STRING("class", "vm"),
|
||||
JSON_BUILD_PAIR_CONDITION(VSOCK_CID_IS_REGULAR(cid), "vsockCid", JSON_BUILD_UNSIGNED(cid)),
|
||||
JSON_BUILD_PAIR_CONDITION(directory, "rootDirectory", JSON_BUILD_STRING(directory)),
|
||||
JSON_BUILD_PAIR_CONDITION(address, "sshAddress", JSON_BUILD_STRING(address)),
|
||||
JSON_BUILD_PAIR_CONDITION(key_path, "sshPrivateKeyPath", JSON_BUILD_STRING(key_path))));
|
||||
}
|
||||
|
||||
int unregister_machine(sd_bus *bus, const char *machine_name) {
|
||||
|
||||
@@ -3,5 +3,13 @@
|
||||
#include "sd-bus.h"
|
||||
#include "sd-id128.h"
|
||||
|
||||
int register_machine(sd_bus *bus, const char *machine_name, sd_id128_t uuid, const char *service, const char *directory);
|
||||
int register_machine(
|
||||
sd_bus *bus,
|
||||
const char *machine_name,
|
||||
sd_id128_t uuid,
|
||||
const char *service,
|
||||
const char *directory,
|
||||
unsigned cid,
|
||||
const char *address,
|
||||
const char *key_path);
|
||||
int unregister_machine(sd_bus *bus, const char *machine_name);
|
||||
|
||||
+17
-6
@@ -1222,12 +1222,6 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (arg_register) {
|
||||
r = register_machine(bus, arg_machine, arg_uuid, trans_scope, arg_directory);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
bool use_kvm = arg_kvm > 0;
|
||||
if (arg_kvm < 0) {
|
||||
r = qemu_check_kvm_support();
|
||||
@@ -1931,6 +1925,23 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
|
||||
log_debug("Executing: %s", joined);
|
||||
}
|
||||
|
||||
if (arg_register) {
|
||||
char vm_address[STRLEN("vsock/") + DECIMAL_STR_MAX(unsigned)];
|
||||
|
||||
xsprintf(vm_address, "vsock/%u", child_cid);
|
||||
r = register_machine(
|
||||
bus,
|
||||
arg_machine,
|
||||
arg_uuid,
|
||||
trans_scope,
|
||||
arg_directory,
|
||||
child_cid,
|
||||
child_cid != VMADDR_CID_ANY ? vm_address : NULL,
|
||||
ssh_private_key_path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
assert_se(sigprocmask_many(SIG_BLOCK, /* old_sigset=*/ NULL, SIGCHLD, SIGWINCH) >= 0);
|
||||
|
||||
_cleanup_(sd_event_source_unrefp) sd_event_source *notify_event_source = NULL;
|
||||
|
||||
Reference in New Issue
Block a user