Skip to content

Commit

Permalink
Add a test for nix copy over ssh
Browse files Browse the repository at this point in the history
Check that nix copy can copy stuff, refuses to copy unsigned paths by
default, and doesn't hide the ssh password prompt.
  • Loading branch information
balsoft committed Mar 22, 2023
1 parent 5291a82 commit 85a2d1d
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 2 deletions.
2 changes: 2 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/libmain/progress-bar.cc
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class ProgressBar : public Logger
void resume() override {
state_.lock()->paused = false;
writeToStderr("\r\e[K");
state_.lock()->haveUpdate = true;
updateCV.notify_one();
}

Expand Down Expand Up @@ -350,9 +351,8 @@ class ProgressBar : public Logger
{
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;

Expand Down
85 changes: 85 additions & 0 deletions tests/nixos/nix-copy.nix
Original file line number Diff line number Diff line change
@@ -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("[email protected]")
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:https://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:https://server ${pkgB} >&2")
client.succeed("nix copy --no-check-sigs --from ssh-ng:https://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:https://server ${pkgD.drvPath} >&2")
server.succeed("nix-store --check-validity ${pkgD.drvPath}")
'';
}

0 comments on commit 85a2d1d

Please sign in to comment.