问题描述
有没有办法以与 nix copy
兼容的方式恢复由 nixpkgs 创建的带有覆盖的包集?
以nix repl
overlays = [(self: super: {aardvark = "does aardvark";})]
pkgs = import <nixpkgs> { inherit overlays; }
pkgs2 = import pkgs.path {}
pkgs3 = import pkgs.path { inherit (pkgs) overlays; }
pkgs.aardvark
存在并被覆盖放置在那里,但如果我尝试重新导入生成的 pkgs
路径,我只会导入 <nixpkgs>
的商店版本。
pkgs3.aardvark
也存在,但这不是我正在寻找的解决方案。
我的预期用途是使用叠加层执行 nix copy
的 pkgs
。我可以复制 pkgs.path
定义,但不能复制叠加层,因为它是 lambda 的列表,而不是路径。我希望有一个非常简单的解决方案,比如有一个像 pkgs.path
或 pkgs.drv
这样的属性而不是 pkgs.out
可以导入,例如import pkgs.out
并提供覆盖的包集。
解决方法
叠加层仅存在于 Nix 语言级别。它们只是函数属性集的一种模式。 Nix 语言的实现不提供序列化任意表达式并复制它们的操作。因此,如果您想复制 Nix 表达式,则必须在文件级别自己进行。
退后一步,也许最好发布构建的闭包或共享 git 存储库。
交付内置闭包是 NixOps 所做的,它的优点是一切都可以在一个 Nix 评估过程中定义,但不允许机器用户使用定义机器的表达式。对于推送部署的服务器来说,这是一个很好的权衡。同样,您可以使用 nixos-rebuild --target-host
或基于 nix-copy-closure
的自定义内容在没有 NixOps 的情况下执行远程部署。
另一方面,如果您想从远程机器启动安装,则需要在那里使用表达式,而 git repo 可能是实现该目标的最实用方法。