将 `imports` 与 lib.mkOption 给出的参数一起使用
using `imports` with argument given by lib.mkOption
我有什么
在 nixos 模块中使用带有硬编码路径的 mmm 效果很好,这里有一个例子:
nixcloud-反向-proxy.nix
{ 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;
}
问题
我很想用 config.services.nixcloud-reverse-proxy.configDir
替换 mmm
但这会导致:
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)
总之,没办法。
事实上,您不能在 config
中定义 imports
子句:
{ config, ... }: {
options = { ... };
config = {
imports = [ ... ]; # <--- error !!!
...
};
}
是关于 NixOS 模块系统如何工作的说明。其中一个假设是 - 您不能根据其他配置选项动态分支或以其他方式控制包含的模块数量。这就是为什么许多模块定义 module.enable
选项,它允许这样做。
所以,回到你的问题,imports
子句不能依赖于 config.services.nixcloud-reverse-proxy.configDir
,因为 config
变量要求所有 imports
已经合并。目前的模块系统很难解决这个问题。也许可以通过使用另一个变量(不是 config
)来克服这个问题,但这是你想要的吗?
我终于找到了一个可能的解决方法:
builtins.getEnv
可用于传递 'varible'。这不如 lib.mkOption
但不像 lib.mkOption
或 { myPath ? "/reverse-proxy-config-tests/ } : { ... }
它赢了不要每次都创建 无限递归 错误。
这意味着,在我这样做之前:nix-build -A reverse-proxy
我需要导出环境变量以传入我的自定义 nix 文件所在的路径,该路径类似于 --args 但不限于 nix-build
并且还应该与 nixos-rebuild
一起使用
如此处所述:https://github.com/NixOS/nixpkgs/issues/30190
我已经考虑这个问题很长一段时间了,保罗和我刚刚发现了这个解决方案:
可能的解决方案 4
我们在 reverse-proxy/reverse-proxy-config-tests2
中创建一个 default.nix
,其中包含:
{ 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
的代码更新需要复制到我们即将加载的配置目录中。
就是说,我们选择这个解决方案是因为它不需要环境变量,让我们动态更改包含路径,只需要在主 configuration.nix
.[=19= 中添加另一个 imports [ ]
]
我有什么
在 nixos 模块中使用带有硬编码路径的 mmm 效果很好,这里有一个例子:
nixcloud-反向-proxy.nix
{ 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;
}
问题
我很想用 config.services.nixcloud-reverse-proxy.configDir
替换 mmm
但这会导致:
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)
总之,没办法。
事实上,您不能在 config
中定义 imports
子句:
{ config, ... }: {
options = { ... };
config = {
imports = [ ... ]; # <--- error !!!
...
};
}
是关于 NixOS 模块系统如何工作的说明。其中一个假设是 - 您不能根据其他配置选项动态分支或以其他方式控制包含的模块数量。这就是为什么许多模块定义 module.enable
选项,它允许这样做。
所以,回到你的问题,imports
子句不能依赖于 config.services.nixcloud-reverse-proxy.configDir
,因为 config
变量要求所有 imports
已经合并。目前的模块系统很难解决这个问题。也许可以通过使用另一个变量(不是 config
)来克服这个问题,但这是你想要的吗?
我终于找到了一个可能的解决方法:
builtins.getEnv
可用于传递 'varible'。这不如 lib.mkOption
但不像 lib.mkOption
或 { myPath ? "/reverse-proxy-config-tests/ } : { ... }
它赢了不要每次都创建 无限递归 错误。
这意味着,在我这样做之前:nix-build -A reverse-proxy
我需要导出环境变量以传入我的自定义 nix 文件所在的路径,该路径类似于 --args 但不限于 nix-build
并且还应该与 nixos-rebuild
如此处所述:https://github.com/NixOS/nixpkgs/issues/30190
我已经考虑这个问题很长一段时间了,保罗和我刚刚发现了这个解决方案:
可能的解决方案 4
我们在 reverse-proxy/reverse-proxy-config-tests2
中创建一个 default.nix
,其中包含:
{ 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
的代码更新需要复制到我们即将加载的配置目录中。
就是说,我们选择这个解决方案是因为它不需要环境变量,让我们动态更改包含路径,只需要在主 configuration.nix
.[=19= 中添加另一个 imports [ ]
]