nixos: Check for duplicate assignments

This commit is contained in:
Jack O'Sullivan 2022-06-11 16:33:32 +01:00
parent 58b2c6d8c5
commit 1f51a3ec08
3 changed files with 66 additions and 17 deletions

View File

@ -2,7 +2,7 @@
let
inherit (builtins) head tail mapAttrs attrValues;
inherit (lib) flatten optional mkOption mkDefault mkOptionType;
inherit (lib.my) homeStateVersion mkOpt' commonOpts inlineModule';
inherit (lib.my) homeStateVersion mkOpt' commonOpts inlineModule' applyAssertions;
cfg = config.home-manager;
@ -40,7 +40,11 @@ let
] ++ (tail defs);
};
homeOpts = with lib.types; { config, ... }: {
homeOpts = with lib.types; { ... }@args:
let
config' = args.config;
in
{
options = {
inherit (commonOpts) system nixpkgs home-manager;
# TODO: docCustom for home-manager?
@ -53,16 +57,16 @@ let
description = "home-manager configuration module.";
type = mkOptionType {
name = "home-manager configuration";
merge = _: defs: mkHome {
config' = config;
merge = _: defs: applyAssertions config (mkHome {
inherit config';
defs = map (d: inlineModule' d.file d.value) defs;
};
});
};
};
};
config = {
nixpkgs = mkDefault config.home-manager;
nixpkgs = mkDefault config'.home-manager;
};
};
in

23
lib.nix
View File

@ -1,9 +1,10 @@
{ lib }:
let
inherit (builtins) length match replaceStrings elemAt mapAttrs head split;
inherit (builtins) length match replaceStrings elemAt mapAttrs head split filter;
inherit (lib)
genAttrs mapAttrs' mapAttrsToList filterAttrsRecursive nameValuePair types
mkOption mkOverride mkForce mkIf mergeEqualOption optional hasPrefix;
mkOption mkOverride mkForce mkIf mergeEqualOption optional hasPrefix
showWarnings concatStringsSep flatten unique;
inherit (lib.flake) defaultSystems;
in
rec {
@ -69,6 +70,24 @@ rec {
mkDefault' = mkOverride 900;
mkVMOverride' = mkOverride 9;
# This is shocking...
duplicates = l:
flatten
(map
(e:
optional
((length (filter (e2: e2 == e) l)) > 1)
e)
(unique l));
applyAssertions = config: res:
let
failedAssertions = map (x: x.message) (filter (x: !x.assertion) config.assertions);
in
if failedAssertions != []
then throw "\nFailed assertions:\n${concatStringsSep "\n" (map (x: "- ${x}") failedAssertions)}"
else showWarnings config.warnings res;
homeStateVersion = hmBranch: {
# The flake passes a default setting, but we don't care about that
# Currently don't need any logic here, but we might need to use a newer version later

View File

@ -1,8 +1,10 @@
{ lib, pkgsFlakes, hmFlakes, inputs, pkgs', config, ... }:
let
inherit (builtins) attrValues mapAttrs;
inherit (lib) substring flatten optional optionals mkIf mkDefault mkForce mkOption mkOptionType;
inherit (lib.my) naiveIPv4Gateway homeStateVersion mkOpt' mkBoolOpt' mkDefault' commonOpts inlineModule';
inherit (lib)
substring flatten optional optionals mkIf mkDefault mkForce mkOption mkOptionType;
inherit (lib.my)
naiveIPv4Gateway homeStateVersion mkOpt' mkBoolOpt' mkDefault' commonOpts inlineModule' applyAssertions duplicates;
cfg = config.nixos;
@ -114,7 +116,11 @@ let
};
};
systemOpts = with lib.types; { name, config, ... }: {
systemOpts = with lib.types; { name, ... }@args:
let
config' = args.config;
in
{
options = {
inherit (commonOpts) system nixpkgs home-manager;
hmNixpkgs = commonOpts.nixpkgs;
@ -131,18 +137,17 @@ let
# Based on the definition of containers.<name>.config
type = mkOptionType {
name = "Toplevel NixOS config";
merge = _: defs: mkSystem {
inherit name;
config' = config;
merge = _: defs: applyAssertions config (mkSystem {
inherit name config';
defs = map (d: inlineModule' d.file d.value) defs;
};
});
};
};
};
config = {
home-manager = mkDefault config.nixpkgs;
hmNixpkgs = mkDefault config.nixpkgs;
home-manager = mkDefault config'.nixpkgs;
hmNixpkgs = mkDefault config'.nixpkgs;
};
};
in
@ -156,4 +161,25 @@ in
systems = mkOpt' (attrsOf (submodule systemOpts)) { } "NixOS systems to be exported by nixfiles.";
};
};
config = {
assertions =
let
assignedIPs =
flatten
(map
(as:
map
(a: [ a.ipv4.address a.ipv6.address ])
(attrValues as))
(attrValues allAssignments));
dupIPs = duplicates assignedIPs;
in
[
{
assertion = dupIPs == [ ];
message = "Duplicate assignments: ${toString dupIPs}";
}
];
};
}