nix 复制一个带有覆盖定义的 nixpkgs

问题描述

有没有办法以与 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 copypkgs。我可以复制 pkgs.path 定义,但不能复制叠加层,因为它是 lambda 的列表,而不是路径。我希望有一个非常简单的解决方案,比如有一个pkgs.pathpkgs.drv 这样的属性而不是 pkgs.out 可以导入,例如import pkgs.out 并提供覆盖的包集。

解决方法

叠加层仅存在于 Nix 语言级别。它们只是函数属性集的一种模式。 Nix 语言的实现不提供序列化任意表达式并复制它们的操作。因此,如果您想复制 Nix 表达式,则必须在文件级别自己进行。

退后一步,也许最好发布构建的闭包或共享 git 存储库。 交付内置闭包是 NixOps 所做的,它的优点是一切都可以在一个 Nix 评估过程中定义,但不允许机器用户使用定义机器的表达式。对于推送部署的服务器来说,这是一个很好的权衡。同样,您可以使用 nixos-rebuild --target-host 或基于 nix-copy-closure 的自定义内容在没有 NixOps 的情况下执行远程部署。

另一方面,如果您想从远程机器启动安装,则需要在那里使用表达式,而 git repo 可能是实现该目标的最实用方法。