Modular, context-aware and aspect-oriented dendritic Nix configurations. Discussions: https://oeiuwq.zulipchat.com/join/nqp26cd4kngon6mo3ncgnuap/ den.oeiuwq.com
configurations den dendritic nix aspect oriented

nix-maid integration (#172)

Related #160 #48

authored by oeiuwq.com and committed by

GitHub ff51baed 399c0b38

+222 -1
+30
modules/aspects/provides/maid/maid-integration.nix
··· 1 + { den, lib, ... }: 2 + let 3 + maidClass = "maid"; 4 + 5 + intoMaidUsers = 6 + { host }: 7 + map (user: { inherit host user; }) ( 8 + lib.filter (u: lib.elem maidClass u.classes) (lib.attrValues host.users) 9 + ); 10 + 11 + forwardedToHost = 12 + { host, user }: 13 + den._.forward { 14 + each = lib.singleton true; 15 + fromClass = _: maidClass; 16 + intoClass = _: host.class; 17 + intoPath = _: [ 18 + "users" 19 + "users" 20 + user.userName 21 + "maid" 22 + ]; 23 + fromAspect = _: den.aspects.${user.aspect}; 24 + }; 25 + 26 + in 27 + { 28 + den.ctx.maid-host.into.maid-user = intoMaidUsers; 29 + den.ctx.maid-user._.maid-user = forwardedToHost; 30 + }
+34
modules/aspects/provides/maid/maid-os.nix
··· 1 + { 2 + den, 3 + lib, 4 + inputs, 5 + ... 6 + }: 7 + let 8 + maidClass = "maid"; 9 + maidOsClasses = [ 10 + "nixos" 11 + ]; 12 + maidModule = host: host.maid-module or inputs.nix-maid.nixosModules.default; 13 + 14 + maidDetect = 15 + { host }: 16 + let 17 + isOsSupported = builtins.elem host.class maidOsClasses; 18 + hasMaidModule = (host ? maid-module) || (inputs ? nix-maid); 19 + maidUsers = builtins.filter (u: lib.elem maidClass u.classes) (lib.attrValues host.users); 20 + hasMaidUsers = builtins.length maidUsers > 0; 21 + isMaidHost = isOsSupported && hasMaidUsers && hasMaidModule; 22 + in 23 + lib.optional isMaidHost { inherit host; }; 24 + 25 + in 26 + { 27 + den.ctx.host.into.maid-host = maidDetect; 28 + 29 + den.ctx.maid-host._.maid-host = 30 + { host }: 31 + { 32 + ${host.class}.imports = [ (maidModule host) ]; 33 + }; 34 + }
+80
templates/ci/modules/features/maid-class.nix
··· 1 + { denTest, ... }: 2 + let 3 + mockMaidModule = 4 + { lib, ... }: 5 + { 6 + options.users.users = lib.mkOption { 7 + type = lib.types.attrsOf ( 8 + lib.types.submodule { 9 + options.maid = lib.mkOption { 10 + type = lib.types.submoduleWith { 11 + modules = [ 12 + { 13 + config._module.freeformType = lib.types.lazyAttrsOf lib.types.unspecified; 14 + } 15 + ]; 16 + }; 17 + default = { }; 18 + }; 19 + } 20 + ); 21 + }; 22 + }; 23 + in 24 + { 25 + flake.tests.maid-class = { 26 + 27 + test-maid-forwards-to-users = denTest ( 28 + { den, igloo, ... }: 29 + { 30 + den.hosts.x86_64-linux.igloo = { 31 + users.tux.classes = [ "maid" ]; 32 + maid-module = mockMaidModule; 33 + }; 34 + 35 + den.aspects.tux.maid.description = "maid-tux"; 36 + 37 + expr = igloo.users.users.tux.maid.description; 38 + expected = "maid-tux"; 39 + } 40 + ); 41 + 42 + test-maid-merges-with-nixos = denTest ( 43 + { 44 + den, 45 + lib, 46 + igloo, 47 + ... 48 + }: 49 + { 50 + den.hosts.x86_64-linux.igloo = { 51 + users.tux.classes = [ "maid" ]; 52 + maid-module = mockMaidModule; 53 + }; 54 + 55 + den.aspects.tux.maid.tags = [ "from-maid" ]; 56 + den.aspects.igloo.nixos.users.users.tux.maid.tags = [ "from-nixos" ]; 57 + 58 + expr = lib.sort (a: b: a < b) igloo.users.users.tux.maid.tags; 59 + expected = [ 60 + "from-maid" 61 + "from-nixos" 62 + ]; 63 + } 64 + ); 65 + 66 + test-no-maid-without-maid-class = denTest ( 67 + { den, igloo, ... }: 68 + { 69 + den.hosts.x86_64-linux.igloo = { 70 + users.tux = { }; 71 + maid-module = mockMaidModule; 72 + }; 73 + 74 + expr = igloo.networking.hostName; 75 + expected = "nixos"; 76 + } 77 + ); 78 + 79 + }; 80 + }
+77
templates/ci/modules/features/user-classes.nix
··· 1 + { denTest, ... }: 2 + { 3 + flake.tests.user-classes = { 4 + 5 + test-default-classes = denTest ( 6 + { den, ... }: 7 + { 8 + den.hosts.x86_64-linux.igloo.users.tux = { }; 9 + 10 + expr = den.hosts.x86_64-linux.igloo.users.tux.classes; 11 + expected = [ "homeManager" ]; 12 + } 13 + ); 14 + 15 + test-multiple-classes = denTest ( 16 + { den, lib, ... }: 17 + { 18 + den.hosts.x86_64-linux.igloo.users.tux.classes = [ 19 + "homeManager" 20 + "maid" 21 + ]; 22 + 23 + expr = lib.sort (a: b: a < b) den.hosts.x86_64-linux.igloo.users.tux.classes; 24 + expected = [ 25 + "homeManager" 26 + "maid" 27 + ]; 28 + } 29 + ); 30 + 31 + test-aspect-has-all-user-classes = denTest ( 32 + { 33 + den, 34 + lib, 35 + ... 36 + }: 37 + let 38 + resolve = 39 + class: 40 + let 41 + mod = den.aspects.tux.resolve { inherit class; }; 42 + m = { 43 + options.tag = lib.mkOption { 44 + type = lib.types.str; 45 + default = ""; 46 + }; 47 + }; 48 + in 49 + (lib.evalModules { 50 + modules = [ 51 + mod 52 + m 53 + ]; 54 + }).config.tag; 55 + in 56 + { 57 + den.hosts.x86_64-linux.igloo.users.tux.classes = [ 58 + "homeManager" 59 + "maid" 60 + ]; 61 + 62 + den.aspects.tux.maid.tag = "maid-tag"; 63 + den.aspects.tux.homeManager.tag = "hm-tag"; 64 + 65 + expr = lib.sort (a: b: a < b) [ 66 + (resolve "maid") 67 + (resolve "homeManager") 68 + ]; 69 + expected = [ 70 + "hm-tag" 71 + "maid-tag" 72 + ]; 73 + } 74 + ); 75 + 76 + }; 77 + }
+1 -1
templates/example/modules/aspects/igloo.nix
··· 14 14 provides.alice = 15 15 { user, ... }: 16 16 { 17 - homeManager.programs.helix.enable = user.name == "alice"; 17 + homeManager.programs.tmux.enable = user.name == "alice"; 18 18 }; 19 19 }; 20 20 }