使用值作为标识符在 NixOS 中循环列表?

问题描述 投票:0回答:1

在 vhost.nix 中,我想在循环中添加用户,就像 httpd.virtualHosts 中的工作示例一样。

这是我在虚拟机中使用的

configuration.nix

# vm.nix
{ lib, config, ... }:
{
  imports = [
    ./vhosts.nix
  ];

  services.httpd.enable = true;

  vhosts = {
    "test.example.de" = {
      customer = "web2";
      phpuser = "web2www1";
    };
    "test2.example.de" = {
      customer = "web3";
      phpuser = "web3www1";
    };
  };

}

这是我的模块

vhost.nix

{ config, pkgs, lib, ... }: 
with lib;
let
  cfg = config.vhosts;
in
  {
    options.vhosts = lib.mkOption {
      type = with lib.types; attrsOf (submodule ({domain, ... }: {
        options = {
          customer = mkOption {
            type = str;
          };
          phpuser = mkOption {
            type = str;
          };
        };
      }));
    };
    config = {
      services.httpd.virtualHosts = lib.mapAttrs (domain: cfg: {
        documentRoot = "/srv/www/${cfg.customer}/${domain}";
      }) cfg;

      # how do I solve this in a loop like above ?
      users.users.web2www1.isNormalUser = true;  
      users.users.web3www1.isNormalUser = true;
    };
  }

如何在像上面这样的循环中解决这个问题?

nix nixos
1个回答
0
投票

正如 Chris 指出的那样,在 Nix 中,不使用传统的命令式编程结构,如 for 循环。相反,采用函数式编程范例,特别是对列表或属性集进行操作的 map

fold
filter
 等函数。

您可以使用

mapAttrs f attrset


{ config, pkgs, lib, ... }: with lib; let cfg = config.vhosts; in { options.vhosts = lib.mkOption { type = with lib.types; attrsOf (submodule ({domain, ... }: { options = { customer = mkOption { type = str; }; phpuser = mkOption { type = str; }; }; })); }; config = { services.httpd.virtualHosts = lib.mapAttrs (domain: cfg: { documentRoot = "/srv/www/${cfg.customer}/${domain}"; }) cfg; users.users = lib.foldl' (acc: domain: let user = cfg.${domain}.phpuser; in acc // { "${user}".isNormalUser = true; } ) {} (lib.attrNames cfg); }; }

lib.foldl'

 用于迭代 
vhosts
 属性集。
对于
vhosts
 中的每个域,它会提取 
phpuser
 并将 
isNormalUser
 设置为用户配置中的 
true

© www.soinside.com 2019 - 2024. All rights reserved.