在nixos模块中使用带有硬编码路径的mmm效果很好,这里有一个例子:
{ config, pkgs, lib, ... } @ args:
{
config = { ... };
options = {
services.nixcloud-reverse-proxy = {
configDir = mkOption {
type = types.path;
default = ./. + "/reverse-proxy-config-tests/";
description = ''An absolute path to reverse proxy configurations. This is used for nixcloud.io deployment mainly, where we rebuild the reverse proxy configuration based on many individual configurations.'';
};
};
imports =
let
# walk through all configs in the mmm and merge them
mmm = ./. + "/reverse-proxy-config-tests/";
filesToLoad = attrNames (filterAttrs (k: v: v == "regular") (builtins.readDir mmm));
configsFromPath = map (el: (mmm + ("/" + el) )) filesToLoad;
in configsFromPath;
}
我希望将mmm
替换为config.services.nixcloud-reverse-proxy.configDir
,但这会导致:
nixos-rebuild build
building Nix...
error: infinite recursion encountered, at /nix/var/nix/profiles/per-user/root/channels/nixos/nixpkgs/lib/modules.nix:60:71
(use ‘--show-trace’ to show detailed location information)
building the system configuration...
error: infinite recursion encountered, at /nix/var/nix/profiles/per-user/root/channels/nixos/nixpkgs/lib/modules.nix:60:71
(use ‘--show-trace’ to show detailed location information)
答案 0 :(得分:1)
简而言之,没办法。
事实上,您无法在imports
内定义config
条款:
{ config, ... }: {
options = { ... };
config = {
imports = [ ... ]; # <--- error !!!
...
};
}
是关于NixOS模块系统如何工作的说明。其中一个问题是 - 您无法根据其他配置选项动态分支或以其他方式控制所包含模块的数量。这就是为什么许多模块定义module.enable
选项的原因,允许这样做。
因此,回到您的问题,imports
子句不能依赖config.services.nixcloud-reverse-proxy.configDir
,因为config
变量要求所有imports
已合并。使用当前模块系统几乎无法修复。或许可以通过使用另一个变量(不是config
)来克服这个问题,但这是你想要的吗?
答案 1 :(得分:0)
我终于找到了可能的解决方法:
builtins.getEnv
可用于传递'变量'。这不如lib.mkOption
好,但与lib.mkOption
或{ myPath ? "/reverse-proxy-config-tests/ } : { ... }
不同,它不会创建每次无限递归错误。
这意味着,在我做之前:nix-build -A reverse-proxy
我需要导出环境变量以传入我的自定义nix文件所在的路径,该路径类似于--args但不限于{{1}并且还应该与nix-build
答案 2 :(得分:0)
如此处所示:https://github.com/NixOS/nixpkgs/issues/30190
我现在已经考虑了很长一段时间了,paul&amp;我刚刚发现了这个解决方案:
我们在default.nix
内创建reverse-proxy/reverse-proxy-config-tests2
,其中包含:
{ config, pkgs, lib, ... }:
with lib;
{
# import config files (nixcloud.io specific for reverse proxy configuration)
# use the nix module system to have type validation and inherit meaningful default values for options which are not set explicitly
config = {
};
imports =
let
cDir = builtins.toPath (./config);
filesToLoad = attrNames (filterAttrs (k: v: v == "regular") (builtins.readDir cDir));
configsFromPath = map (el: (cDir + ("/" + el) )) filesToLoad;
toModule = x: ({ config, pkgs, lib, ... }: {
options = {};
config.nixcloud.reverse-proxy.extraMappings = x;
});
in
fold (el: c: c ++ [(toModule (import el))]) [ ] configsFromPath;
}
并称之为:
machine = { pkgs, lib, ... }: {
nix.nixPath = [ "nixpkgs=${<nixpkgs>}" "nixos-config=/etc/nixos/configuration.nix" ];
nix.binaryCaches = lib.mkForce [];
nixcloud.reverse-proxy.enable = true;
imports = [ ../reverse-proxy/reverse-proxy-config-tests2 ];
# Needed so that we have all dependencies available for building the
# container config within the VM.
virtualisation.pathsInNixDB = let
emptyClosure = (import <nixpkgs/nixos/lib/eval-config.nix> {
modules = lib.singleton { boot.isContainer = true; };
}).config.system.build.toplevel;
in [ pkgs.stdenv emptyClosure ];
};
更新default.nix
现在是有状态的,因为需要将default.nix
的代码更新复制到我们即将加载的配置的目录中。
说,我们选择此解决方案,因为它不需要环境变量,让我们动态更改包含路径,只需要主imports [ ]
中的另一个configuration.nix
。