Skip to content

Commit 08ed87c

Browse files
authored
nixos/test-driver: allow assigning other vsock number ranges (#405508)
2 parents 53e05a9 + b8b8683 commit 08ed87c

File tree

6 files changed

+73
-31
lines changed

6 files changed

+73
-31
lines changed

nixos/doc/manual/development/running-nixos-tests-interactively.section.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,33 @@ $ ssh vsock/3 -o User=root
8787

8888
The socket numbers correspond to the node number of the test VM, but start
8989
at three instead of one because that's the lowest possible
90-
vsock number.
90+
vsock number. The exact SSH commands are also printed out when starting
91+
`nixos-test-driver`.
9192

9293
On non-NixOS systems you'll probably need to enable
9394
the SSH config from {manpage}`systemd-ssh-proxy(1)` yourself.
9495

96+
If starting VM fails with an error like
97+
98+
```
99+
qemu-system-x86_64: -device vhost-vsock-pci,guest-cid=3: vhost-vsock: unable to set guest cid: Address already in use
100+
```
101+
102+
it means that the vsock numbers for the VMs are already in use. This can happen
103+
if another interactive test with SSH backdoor enabled is running on the machine.
104+
105+
In that case, you need to assign another range of vsock numbers. You can pick another
106+
offset with
107+
108+
```nix
109+
{
110+
sshBackdoor = {
111+
enable = true;
112+
vsockOffset = 23542;
113+
};
114+
}
115+
```
116+
95117
## Port forwarding to NixOS test VMs {#sec-nixos-test-port-forwarding}
96118

97119
If your test has only a single VM, you may use e.g.

nixos/doc/manual/redirects.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1832,6 +1832,9 @@
18321832
"test-opt-sshBackdoor.enable": [
18331833
"index.html#test-opt-sshBackdoor.enable"
18341834
],
1835+
"test-opt-sshBackdoor.vsockOffset": [
1836+
"index.html#test-opt-sshBackdoor.vsockOffset"
1837+
],
18351838
"test-opt-defaults": [
18361839
"index.html#test-opt-defaults"
18371840
],

nixos/lib/test-driver/src/test_driver/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def main() -> None:
112112
arg_parser.add_argument(
113113
"--dump-vsocks",
114114
help="indicates that the interactive SSH backdoor is active and dumps information about it on start",
115-
action="store_true",
115+
type=int,
116116
)
117117

118118
args = arg_parser.parse_args()
@@ -141,8 +141,8 @@ def main() -> None:
141141
if args.interactive:
142142
history_dir = os.getcwd()
143143
history_path = os.path.join(history_dir, ".nixos-test-history")
144-
if args.dump_vsocks:
145-
driver.dump_machine_ssh()
144+
if offset := args.dump_vsocks:
145+
driver.dump_machine_ssh(offset)
146146
ptpython.ipython.embed(
147147
user_ns=driver.test_symbols(),
148148
history_filename=history_path,

nixos/lib/test-driver/src/test_driver/driver.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,14 @@ def subtest(name: str) -> Iterator[None]:
178178
)
179179
return {**general_symbols, **machine_symbols, **vlan_symbols}
180180

181-
def dump_machine_ssh(self) -> None:
181+
def dump_machine_ssh(self, offset: int) -> None:
182182
print("SSH backdoor enabled, the machines can be accessed like this:")
183183
print(
184184
f"{Style.BRIGHT}Note:{Style.RESET_ALL} this requires {Style.BRIGHT}systemd-ssh-proxy(1){Style.RESET_ALL} to be enabled (default on NixOS 25.05 and newer)."
185185
)
186186
names = [machine.name for machine in self.machines]
187187
longest_name = len(max(names, key=len))
188-
for num, name in enumerate(names, start=3):
188+
for num, name in enumerate(names, start=offset + 1):
189189
spaces = " " * (longest_name - len(name) + 2)
190190
print(
191191
f" {name}:{spaces}{Style.BRIGHT}ssh -o User=root vsock/{num}{Style.RESET_ALL}"

nixos/lib/testing/nodes.nix

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,22 @@ in
8484
type = types.bool;
8585
description = "Whether to turn on the VSOCK-based access to all VMs. This provides an unauthenticated access intended for debugging.";
8686
};
87+
vsockOffset = mkOption {
88+
default = 2;
89+
type = types.ints.between 2 4294967296;
90+
description = ''
91+
This field is only relevant when multiple users run the (interactive)
92+
driver outside the sandbox and with the SSH backdoor activated.
93+
The typical symptom for this being a problem are error messages like this:
94+
`vhost-vsock: unable to set guest cid: Address already in use`
95+
96+
This option allows to assign an offset to each vsock number to
97+
resolve this.
98+
99+
This is a 32bit number. The lowest possible vsock number is `3`
100+
(i.e. with the lowest node number being `1`, this is 2+1).
101+
'';
102+
};
87103
};
88104

89105
node.type = mkOption {
@@ -182,17 +198,39 @@ in
182198
passthru.nodes = config.nodesCompat;
183199

184200
extraDriverArgs = mkIf config.sshBackdoor.enable [
185-
"--dump-vsocks"
201+
"--dump-vsocks=${toString config.sshBackdoor.vsockOffset}"
186202
];
187203

188204
defaults = mkMerge [
189205
(mkIf config.node.pkgsReadOnly {
190206
nixpkgs.pkgs = config.node.pkgs;
191207
imports = [ ../../modules/misc/nixpkgs/read-only.nix ];
192208
})
193-
(mkIf config.sshBackdoor.enable {
194-
testing.sshBackdoor.enable = true;
195-
})
209+
(mkIf config.sshBackdoor.enable (
210+
let
211+
inherit (config.sshBackdoor) vsockOffset;
212+
in
213+
{ config, ... }:
214+
{
215+
services.openssh = {
216+
enable = true;
217+
settings = {
218+
PermitRootLogin = "yes";
219+
PermitEmptyPasswords = "yes";
220+
};
221+
};
222+
223+
security.pam.services.sshd = {
224+
allowNullPassword = true;
225+
};
226+
227+
virtualisation.qemu.options = [
228+
"-device vhost-vsock-pci,guest-cid=${
229+
toString (config.virtualisation.test.nodeNumber + vsockOffset)
230+
}"
231+
];
232+
}
233+
))
196234
];
197235

198236
};

nixos/modules/testing/test-instrumentation.nix

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,6 @@ in
8686
enables commands to be sent to test and debug stage 1. Use
8787
machine.switch_root() to leave stage 1 and proceed to stage 2
8888
'';
89-
90-
sshBackdoor = {
91-
enable = mkEnableOption "vsock-based ssh backdoor for the VM";
92-
};
93-
9489
};
9590

9691
config = {
@@ -104,18 +99,6 @@ in
10499
}
105100
];
106101

107-
services.openssh = mkIf config.testing.sshBackdoor.enable {
108-
enable = true;
109-
settings = {
110-
PermitRootLogin = "yes";
111-
PermitEmptyPasswords = "yes";
112-
};
113-
};
114-
115-
security.pam.services.sshd = mkIf config.testing.sshBackdoor.enable {
116-
allowNullPassword = true;
117-
};
118-
119102
systemd.services.backdoor = lib.mkMerge [
120103
backdoorService
121104
{
@@ -191,10 +174,6 @@ in
191174
# we avoid defining attributes if not possible.
192175
# TODO: refactor such that test-instrumentation can import qemu-vm
193176
package = lib.mkDefault pkgs.qemu_test;
194-
195-
options = mkIf config.testing.sshBackdoor.enable [
196-
"-device vhost-vsock-pci,guest-cid=${toString (config.virtualisation.test.nodeNumber + 2)}"
197-
];
198177
};
199178
};
200179

0 commit comments

Comments
 (0)