![Alexander Bantyev](/assets/img/avatar_default.png)
Check that nix copy can copy stuff, refuses to copy unsigned paths by default, and doesn't hide the ssh password prompt.
86 lines
2.8 KiB
Nix
86 lines
2.8 KiB
Nix
# 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}")
|
||
'';
|
||
}
|