2

我在 上维护我的个人更改nixpkgs,我将其用于系统重建(通过 NixOps)和在我的工作站上进行开发(主要通过nix-shell)。更改是基于通道顶部的提交,nixos-17.09并存储在私有 git 服务器上。部署中的所有机器都对该 git 服务器具有读取权限。

在远程机器上使用nix-shell时,我会得到来自机器安装时间的旧包(在我的情况下nixos-17.03)。

nixpkgs有没有办法在远程机器上使用完全相同的版本进行部署?

4

2 回答 2

4

您遇到的问题是由于 NixOps 在本地构建,然后将闭包复制到远程机器,因此不在nix-channel --update远程机器上运行,Nix Packages Collection (nixpkgs) 不会在远程机器上更新。

诸如nix-envand之类的命令nix-shell依赖于nixpkgs指向的$NIX_PATH(或您通过-I参数提供的任何路径)。

解决方案

解决方案是将您的版本nixpkgs放入远程机器并确保$NIX_PATH指向它。默认情况下,$NIX_PATH如下所示:

nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos/nixpkgs:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels

所以这个想法是让它看起来像这样:

nixpkgs=/nix/store/blah-blah-blah:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels

其中blah-blah-blah是您nixpkgs插入到 Nix 商店的 Git 存储库。这是一个如何做到这一点的例子:

let
    # This will point to whatever NIX_PATH states on the local machine,
    # unless overwritten with -I.
    hostNixpkgs = import <nixpkgs> {};

    # Some other nixpkgs from a GitHub repo
    romildo = hostNixpkgs.pkgs.fetchFromGitHub {
         owner = "romildo";
         repo = "nixpkgs";
         rev = "b167ba35987c2e69dc1bb91d5c245a04421ee7ed";
         sha256 = "02d8dfvginz45h2zhq745kynzygnsy760qh7yy152wpfhczag180";
    };
in
{
    network.description = "My NixOS VMs";

    vm0 = { config, lib, pkgs, ... }:
    {
      ...

      # This is really hacky, but it works.
      # I'd prefer to set environment.etc.NIX_PATH, but that's not allowed,
      # because that value is "read-only".
      environment.extraInit = "export NIX_PATH=nixpkgs=${romildo}:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels";
    };
}

这个怎么运作

Nix 创建/nix/store/BLAH-set-environment导出一堆环境变量等。该文件在所有 shell 会话中都可用。environment.extraInit可以将您想要的任何外壳中性 (sh) 代码附加到此环境。因为这个任意代码被插入到脚本的末尾,它可以用来覆盖环境变量,例如NIX_PATH.

需要注意的是,您必须在部署后重新登录才能使更改生效。但结果NIX_PATH将如下所示:nixpkgs=/nix/store/mzxkszfv05np2f6rgdi2kwxd937f0sxa-source:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels. 所以在这个例子中,nix-shell将寻找nixpkgsat /nix/store/mzxkszfv05np2f6rgdi2kwxd937f0sxa-source

于 2018-01-01T20:19:37.280 回答
0

将其设置为configuration.nix(或者无论您如何构建配置):

{
  nix.nixPath = [ "nixpkgs=${pkgs.path}:/other/custom/paths/you/need" ];
}
于 2021-11-19T03:27:29.113 回答