serokell / deploy-rs

A simple multi-profile Nix-flake deploy tool.
Other
1.42k stars 100 forks source link

Incompatibility with content-addressed derivations #164

Open thufschmitt opened 2 years ago

thufschmitt commented 2 years ago

I've been meaning to try deploy-rs for my systems, but it turns out that it doesn't work if the closure to deploy contains some content-addressed derivations. For example given the following flake (slightly modified copy of the example):

flake.nix

```nix # SPDX-FileCopyrightText: 2020 Serokell # # SPDX-License-Identifier: MPL-2.0 { description = "Deploy GNU hello to localhost"; inputs.deploy-rs.url = "github:serokell/deploy-rs"; outputs = { self, nixpkgs, deploy-rs }: let hello = nixpkgs.legacyPackages.x86_64-linux.runCommandNoCC "hello" { __contentAddressed = true; } '' mkdir -p $out/bin cat < $out/bin/hello #!/bin/sh echo Hello EOF ''; in { deploy.nodes.example = { hostname = "localhost"; profiles.hello = { user = "balsoft"; path = deploy-rs.lib.x86_64-linux.setActivate hello "./bin/hello"; }; }; checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib; }; } ```

I get:

$ nix run github:serokell/deploy-rs .
🚀 ℹī¸ [deploy] [INFO] Running checks for flake in .
warning: Git tree '/tmp/tmp.FQSqTMcjgn/deploy-rs' is dirty
warning: unknown flake output 'deploy'
🚀 ℹī¸ [deploy] [INFO] Evaluating flake in .
warning: Git tree '/tmp/tmp.FQSqTMcjgn/deploy-rs' is dirty
🚀 ℹī¸ [deploy] [INFO] The following profiles are going to be deployed:
[example.hello]
user = "balsoft"
ssh_user = "regnat"
path = "/1m3axr5ii129c20a74wg993p2ph1k0ivpc8siprnp3ak1pfrmavj"
hostname = "localhost"
ssh_opts = []

🚀 ❌ [deploy] [ERROR] Failed to push profile: Nix show-derivation command resulted in a bad exit code: Some(1)

What happens (I assume) is that one property of ca derivations is that it's impossible to know their output path before building them. So the derivation contains a placeholder instead (the /1m3qxâ€Ļ thing above), and the only way (roughly) to get the actual output path is to build the derivation. But deploy-rs seems to query it (with show-derivation I guess given the error message), which doesn't work

balsoft commented 2 years ago

Yep. This is a "hack" to remove the need to evaluate the path twice, and it saves a lot of time for IFD situations. I wonder if there's some better way to ask nix which derivation has that particular placeholder. Maybe nix show-derivation should work when passed such a placeholder?

balsoft commented 2 years ago

The error comes from here: https://github.com/serokell/deploy-rs/blob/master/src/push.rs#L63

gador commented 2 years ago

I am also affected by that and cannot use deploy-rs for my CA setup.. :disappointed:

gador commented 2 years ago

I added experimental support for CA derivations. The build/deploy logic had to be adapted. We cannot evaluate a CA output path before actually building it. If anyone wants to check out out and give feedback: https://github.com/gador/deploy-rs/tree/add-ca-support-flake-update

Limitations and caveats:

SuperSandro2000 commented 10 months ago

For me the following diff is enough, to get the build started:

diff --git a/flake.nix b/flake.nix
index 66b2e76..fb8b63b 100644
--- a/flake.nix
+++ b/flake.nix
@@ -49,7 +49,7 @@
             custom =
               {
                 __functor = customSelf: base: activate:
-                  final.buildEnv {
+                  (final.buildEnv {
                     name = ("activatable-" + base.name);
                     paths =
                       [
@@ -83,7 +83,7 @@
                           destination = "/activate-rs";
                         })
                       ];
-                  };
+                  }).drvPath;
               };

             nixos = base:

alternatively the following works, too:

profiles.system = {
  path = (deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.hydrogen).drvPath;
  remoteBuild = true;
};

but it fails when activating...