NIXOS-与参数导入的模块



假设我的nixos configuration.nix设置如下:

{config, pkgs, ...}:
{
  services.openssh.enable = true;
}

我现在想拥有一个名为networking.nix的文件,该文件基于参数设置我的主机名。

{config, pkgs, hostname, ...}:
{
  networking.hostName = hostname
}

这可能吗?如何包含文件。我已经尝试使用imports = [ ./networking.nix { hostname = "helloworld"; } ];进行操作,但这不起作用。

谢谢。

我今天遇到了这个问题,并在手册中提出了一个相当简单的解决方案。

foobar.nix

{ lib, withFoo ? "bar", ... }:
# simple error checking to ensure garbage isn't passed in
assert lib.asserts.assertOneOf "withFoo" withFoo [
  "bar"
  "baz"
  # other valid choices ...
];
{
  # ...
}

configuration.nix

args@{ ... }:
{
  imports = [
    # ...
    (
      import ./foobar.nix (
        args
        // { withFoo = "baz"; }
      )
    )
    # ...
  ];
}

这是您配置中"一个关闭"选项的理想选择。

a'nixos配置文件'只是一个未定义选项的模块,因此实际上没有区别。configuration.nix文件只是一个模块,通常没有定义任何选项,因此可以以缩写的形式写入。

定义选项是Nixos模块传递信息的正常方式,因此这是最惯用的方法。

但是,如果您确实必须出于某些非常特殊的原因,因为您使用尼克斯(Nixos)做非常不寻常的事情,则可以在imports中放置任意功能。但是您不应该,因为它不能与模块系统的自定义错误消息以及可能依赖于知道模块定义的其他方面的其他方面合作。如果这样做,请确保它是一个实际功能。在您的情况下,这意味着修改networking.nix的第一行以使其成为咖喱功能:

hostname: {config, pkgs, ...}:

我认为不是很漂亮。尽管它对正在发生的事情非常明确,但它偏离了尼克斯模块的期望。

您应该能够使用_module.args选项[1]来完成此操作。因此,您的configuration.nix就像:

{config, pkgs, ...}:
{
  _module.args.hostname = "ahostname";
  services.openssh.enable = true;
}

但是,如果值非常简单,那么直接设置它们可能会容易得多,例如只需在configuration.nix中定义networking.hostname即可。手册的这一部分。合并和优先事项也可能有用[2]。


进一步讨论:

确实将_module.args的值应用于所有导入的配置(尽管该值仅在直接指代它的模块中使用,例如pkgs值,...代表未引用的所有值)。/p>

为了将论点传递给模块,这对我来说似乎是一种很好的方法,但是从您的评论中,也许另一种方法可能更合适。

另一个解决方案可能是翻转导入中的关系:而不是传递多个不同参数的单个公共配置,而是多个不同的配置导入通用配置。例如

$cat ./common.nix
{ services.openssh.enable = true; }
$cat ./ahostname.nix
{ imports = [ ./common.nix ]; networking.hostname = "ahostname"; }

此reddit评论中的nixos配置看起来像使用此方法。人们在网上公开共享了其他许多Nixos配置,因此您可能会在那里找到一些有用的想法。罗伯特·亨辛(Robert Hensing)的答案中的观点也非常有用。

但是,在您的情况下,很难说出更好的解决方案,而不必更多地了解要使用的上下文。您可以创建一个新的So问题,并提供有关有关该问题的更多信息,这可能会使您更容易看到更合适的解决方案。

最新更新