aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bantyev <balsoft@balsoft.ru>2023-03-16 13:34:48 +0400
committerAlexander Bantyev <balsoft@balsoft.ru>2023-03-22 09:45:08 +0400
commit85a2d1d94fbb682d4ff1e85ee083fac55b6bc9cb (patch)
treebc88e677d90c644652765834792afdcbe4f63878
parent5291a82cd9b9d8d7cd6b8338a5224c94c6f23eb7 (diff)
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.
-rw-r--r--flake.nix2
-rw-r--r--src/libmain/progress-bar.cc4
-rw-r--r--tests/nixos/nix-copy.nix85
3 files changed, 89 insertions, 2 deletions
diff --git a/flake.nix b/flake.nix
index af0ce5022..3c02a7935 100644
--- a/flake.nix
+++ b/flake.nix
@@ -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;
diff --git a/src/libmain/progress-bar.cc b/src/libmain/progress-bar.cc
index 882deb169..6600ec177 100644
--- a/src/libmain/progress-bar.cc
+++ b/src/libmain/progress-bar.cc
@@ -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;
diff --git a/tests/nixos/nix-copy.nix b/tests/nixos/nix-copy.nix
new file mode 100644
index 000000000..ee8b77100
--- /dev/null
+++ b/tests/nixos/nix-copy.nix
@@ -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}")
+ '';
+}