lib.mapAttrsToList和无限递归

时间:2017-02-10 01:35:53

标签: nixos

问题

我一直致力于网络服务器抽象,但使用lib.mapAttrsToList始终会返回无限递归错误:

# nixos-rebuild build
building Nix...
error: infinite recursion encountered, at /nix/var/nix/profiles/per-user/root/channels/nixos/nixpkgs/lib/modules.nix:59:71
(use ‘--show-trace’ to show detailed location information)
error: infinite recursion encountered, at /nix/var/nix/profiles/per-user/root/channels/nixos/nixpkgs/lib/modules.nix:59: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:59:71
(use ‘--show-trace’ to show detailed location information)

我已经添加了所有其他版本的代码,没有一个返回infinite recursion错误,这是我不理解的。

所以这是我的代码:

configuration.nix

 imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
       /home/joachim/Desktop/projects/nixcloud/nixcloud-webservices-abstraction/nextcloud.nix
    ];

  services.nextcloud = {
    enable=true;
    networks = {
      net1 = { name = "foo"; };
      net2 = { name = "bar"; };
    };

nixcloud.nix

{ config, options, lib, pkgs, ... }:

with lib; 

let
  mergeListToAttrs = fold (c: el: recursiveUpdate el c) {};
  cfg = config.services.nextcloud;
in

{
 options = {
    services.nextcloud = {
      networks = mkOption {
        default = {};
#         type = types.loaOf types.submodule;
        options = {
          name = mkOption {
            default = "";
            type = types.str;
          };
        };
      };
      enable = mkOption {
        default = true;
        type=types.bool;
        description = ''
          Whether to enable the cntlm, which start a local proxy.
        '';
      };
    };
  };

# example 1 - works
#   config = { 
#     systemd.services = {
#       bar = {
#           wantedBy      = [ "multi-user.target" ];
#           after         = [ "" ];
#       };
#       foo = {
#           wantedBy      = [ "multi-user.target" ];
#           after         = [ "" ];
#       };
#     };
#   };



# example 2 - works   
#   config = {
#     systemd.services = lib.flip lib.mapAttrs cfg.networks (network: data:
#       {
#           wantedBy      = [ "multi-user.target" ];
#           after         = [ "network.target" ];
#           serviceConfig = {
#             ExecStart = "";
#             ExecReload  = "";
#             Restart = "always";
#             RestartSec = "10s";
#             StartLimitInterval = "1min";
#         };
#       }
#     );
#   };


# example 3 - works       
#   config = {
#     systemd.services = flip mapAttrs' cfg.networks (network: data: nameValuePair
#       ("tinc.${network}")
#       ({
#             wantedBy      = [ "multi-user.target" ];
#             after         = [ "network.target" ];
#             serviceConfig = {
#               ExecStart = "";
#               ExecReload  = "";
#               Restart = "always";
#               RestartSec = "10s";
#               StartLimitInterval = "1min";
#             };
#         })
#       );
#   };

# example 4 - works    
#     config = 
#       mergeListToAttrs (
#         [
#           { systemd.services.a = {
#             wantedBy      = [ "multi-user.target" ];
#             after         = [ "network.target" ];
#             serviceConfig = {
#               ExecStart = "";
#               ExecReload  = "";
#               Restart = "always";
#               RestartSec = "10s";
#               StartLimitInterval = "1min";
#             };
#           };
#           }
#           {
#           systemd.services.b = {
#             wantedBy      = [ "multi-user.target" ];
#             after         = [ "network.target" ];
#             serviceConfig = {
#               ExecStart = "";
#               ExecReload  = "";
#               Restart = "always";
#               RestartSec = "10s";
#               StartLimitInterval = "1min";
#             };
#           };
#           }
#         ]); 

# example 5 - fails!
# XXXXXXXX the failing function XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    config = 
      mergeListToAttrs (
        lib.flip lib.mapAttrsToList cfg.networks (wsName: wsConfig: {
          systemd.services.${wsName} = {
            wantedBy      = [ "multi-user.target" ];
            after         = [ "network.target" ];
            serviceConfig = {
              ExecStart = "";
              ExecReload  = "";
              Restart = "always";
              RestartSec = "10s";
              StartLimitInterval = "1min";
            };
          };
        })
      ); 

}

1 个答案:

答案 0 :(得分:0)

根据aszlig,问题是example 5 同时更改并从配置读取。解决方案是不要这样做,但要么使用硬编码的右手价值观'如example 4或使用右手值分配systemd.services =。