Add a test for nix copy over ssh

Check that nix copy can copy stuff, refuses to copy unsigned paths by
default, and doesn't hide the ssh password prompt.
This commit is contained in:
Alexander Bantyev 2023-03-16 13:34:48 +04:00
parent 5291a82cd9
commit 85a2d1d94f
No known key found for this signature in database
GPG key ID: 48ABA304F3A30FE9
3 changed files with 89 additions and 2 deletions

View file

@ -577,6 +577,8 @@
tests.nix-copy-closure = runNixOSTestFor "x86_64-linux" ./tests/nixos/nix-copy-closure.nix;
tests.nix-copy = runNixOSTestFor "x86_64-linux" ./tests/nixos/nix-copy.nix;
tests.nssPreload = runNixOSTestFor "x86_64-linux" ./tests/nixos/nss-preload.nix;
tests.githubFlakes = runNixOSTestFor "x86_64-linux" ./tests/nixos/github-flakes.nix;

View file

@ -129,6 +129,7 @@ public:
void resume() override {
state_.lock()->paused = false;
writeToStderr("\r\e[K");
state_.lock()->haveUpdate = true;
updateCV.notify_one();
}
@ -350,9 +351,8 @@ public:
{
auto nextWakeup = std::chrono::milliseconds::max();
if (state.paused) return nextWakeup;
state.haveUpdate = false;
if (!state.active) return nextWakeup;
if (state.paused || !state.active) return nextWakeup;
std::string line;

85
tests/nixos/nix-copy.nix Normal file
View file

@ -0,0 +1,85 @@
# Test that nix copy works over ssh.
{ lib, config, nixpkgs, hostPkgs, ... }:
let
pkgs = config.nodes.client.nixpkgs.pkgs;
pkgA = pkgs.cowsay;
pkgB = pkgs.wget;
pkgC = pkgs.hello;
pkgD = pkgs.tmux;
in {
name = "nix-copy";
enableOCR = true;
nodes =
{ client =
{ config, lib, pkgs, ... }:
{ virtualisation.writableStore = true;
virtualisation.additionalPaths = [ pkgA pkgD.drvPath ];
nix.settings.substituters = lib.mkForce [ ];
nix.settings.experimental-features = [ "nix-command" ];
services.getty.autologinUser = "root";
};
server =
{ config, pkgs, ... }:
{ services.openssh.enable = true;
services.openssh.permitRootLogin = "yes";
users.users.root.password = "foobar";
virtualisation.writableStore = true;
virtualisation.additionalPaths = [ pkgB pkgC ];
};
};
testScript = { nodes }: ''
# fmt: off
import subprocess
# Create an SSH key on the client.
subprocess.run([
"${pkgs.openssh}/bin/ssh-keygen", "-t", "ed25519", "-f", "key", "-N", ""
], capture_output=True, check=True)
start_all()
server.wait_for_unit("sshd")
client.wait_for_unit("network.target")
client.wait_for_unit("getty@tty1.service")
client.wait_for_text("]#")
# Copy the closure of package A from the client to the server using password authentication,
# and check that all prompts are visible
server.fail("nix-store --check-validity ${pkgA}")
client.send_chars("nix copy --to ssh://server ${pkgA} >&2; echo done\n")
client.wait_for_text("continue connecting")
client.send_chars("yes\n")
client.wait_for_text("Password:")
client.send_chars("foobar\n")
client.wait_for_text("done")
server.succeed("nix-store --check-validity ${pkgA}")
client.copy_from_host("key", "/root/.ssh/id_ed25519")
client.succeed("chmod 600 /root/.ssh/id_ed25519")
# Install the SSH key on the server.
server.copy_from_host("key.pub", "/root/.ssh/authorized_keys")
server.succeed("systemctl restart sshd")
client.succeed(f"ssh -o StrictHostKeyChecking=no {server.name} 'echo hello world'")
# Copy the closure of package B from the server to the client, using ssh-ng.
client.fail("nix-store --check-validity ${pkgB}")
# Shouldn't download untrusted paths by default
client.fail("nix copy --from ssh-ng://server ${pkgB} >&2")
client.succeed("nix copy --no-check-sigs --from ssh-ng://server ${pkgB} >&2")
client.succeed("nix-store --check-validity ${pkgB}")
# Copy the derivation of package D's derivation from the client to the server.
server.fail("nix-store --check-validity ${pkgD.drvPath}")
client.succeed("nix copy --derivation --to ssh://server ${pkgD.drvPath} >&2")
server.succeed("nix-store --check-validity ${pkgD.drvPath}")
'';
}