DBCDK / morph

NixOS deployment tool
MIT License
839 stars 63 forks source link

structured nix invocation args #199

Closed johanot closed 1 year ago

johanot commented 1 year ago

Motivation:

Make it easier to hook into the eval and build processes of morph without destroying morph completely. Currently, it's difficult, due to unstructured args given to nix-instatiate and nix-build respectively. Even though you can wrap these commands and put them on morph PATH, you'd have to build a nix CLI command line parser in order to reverse engineer what was the original intend of morph.i

As an extra bonus, with this change, it'll become easier to switch Nix CLIs from nix-build to nix build later, since logical "morph-intent" is separated from the "ToCLIArgs()" implementation.

nix-copy-closure (Push) have been scoped out and left unchanged. Let me know if we should chane ge this.

Implementation

Everywhere we run nix-instatiate or nix-build, expose a json map in an environment variable containing all the args we supply to the Nix CLI commands. E.g. echo $MORPH_ARGS | jq would give something like:

{
  "ArgsFile": "/run/user/1000/morph-3675721930/morph-args.json",
  "Attr": "machines",
  "DeploymentPath": "/home/johanot/work/project/deploy.nix",
  "Names": [
    "host-1",
    "host-2",
    "host-3"
  ],
  "NixArgs": null,
  "NixBuildTargets": "",
  "NixConfig": null,
  "NixContext": {
    "EvalMachines": "/nix/store/0q404b6p1anmmanpf8hnasi9wq7wgfaj-morph-unstable-dev-lib/eval-machines.nix",
    "ShowTrace": false,
    "KeepGCRoot": false,
    "AllowBuildShell": false
  },
  "ResultLinkPath": "/run/user/1000/morph-3675721930/result"
}

In the special case of nix-build, this JSON map is also written to a file beside the env var. The file can be read by the buildShell.

Example usecase

Make morph a simple flake deployer:

https://gist.github.com/johanot/f8ac86b16d38234b8b34f1242e1a2183