Right now it wrongly seems as if you can set
`sshBackdoor.enable = true;` for each test and not only for debugging
purposes.
This is wrong however since you'd need to pass /dev/vhost-vsock into the
sandbox for this (which is also a prerequisite for #392117).
To make that clear, two things were changed:
* add a warning to the manual to communicate this.
* exit both interactive and non-interactive driver early if
/dev/vhost-vsock is missing and the ssh backdoor is enabled.
If that's the case, we pass a CLI flag to the driver already in the
interactive case. This change also sets the flag for the
non-interactive case.
That way we also get a better error if somebody tries to enable this
on a system that doesn't support that.
I'm a little annoyed at myself that I only realized this _after_ #392030
got merged. But I realized that if something else is using AF_VSOCK or
you simply have another interactive test running (e.g. by another user
on a larger builder), starting up VMs in the driver fails with
qemu-system-x86_64: -device vhost-vsock-pci,guest-cid=3: vhost-vsock: unable to set guest cid: Address already in use
Multi-user setups are broken anyways because you usually don't have
permissions to remove the VM state from another user and thus starting
the driver fails with
PermissionError: [Errno 13] Permission denied: PosixPath('/tmp/vm-state-machine')
but this is something you can work around at least.
I was considering to generate random offsets, but that's not feasible
given we need to know the numbers at eval time to inject them into the
QEMU args. Also, while we could do this via the test-driver, we should
also probe if the vsock numbers are unused making the code even more
complex for a use-case I consider rather uncommon.
Hence the solution is to do
sshBackdoor.vsockOffset = 23542;
when encountering conflicts.
With this it's possible to trivially SSH into running machines from the
test-driver. This is especially useful when running VM tests
interactively on a remote system.
This is based on `systemd-ssh-proxy(1)`, so there's no need to configure
any additional networking on the host-side.
Suggested-by: Ryan Lahfa <masterancpp@gmail.com>
verified with following minimal test, embedded in a flake for ease of
execution:
```nix
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/master";
outputs = { nixpkgs, ... }:
let
pkgs = import nixpkgs { system = "x86_64-linux"; };
in
{
nixosTests.x86_64-linux.internet = pkgs.nixosTest {
name = "internet";
nodes.machine = { };
# only succeeds in interactive mode
testScript = ''
machine.wait_for_unit("default.target")
print(machine.succeed("curl -4 https://nixos.org"))
'';
};
};
}
```
Launch this test interactively as described in the manual & run
`test_script()` to verify that the VM has Internet access.
In my earlier commit
manual: Don't suggest exposing VM port to local network.
I made a side change titled
Use `127.0.0.1` also on the VM side, otherwise connections to
services that, in the VM, bind to `127.0.0.1` only
(doing the safe approach) do not work.
Unfortunately, that was wrong:
QEMU inside the VM always communicates via the virtualised
Ethernet interface, not via the VM's loopback interface.
So trying to connect to `127.0.0.1` on the VM's side cannot work.
`shell_interact()` is currently not nice to use. If you try to cancel
the socat process, it will also break the nixos test. Furthermore
ptpython creates it's own terminal that subprocesses are running in,
which breaks some of the terminal features of socat.
Hence this commit extends `shell_interact` to allow also to connect to
arbitrary servers i.e. tcp servers started by socat.
Previously the driver was configured exclusively through convoluted
environment variables.
Now the driver's defaults are configured through env variables.
Some additional concerns are in the github comments of this PR.