summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--accounts/.keep0
-rw-r--r--flake.nix94
-rw-r--r--hosts/.keep0
-rw-r--r--modules/.keep0
-rw-r--r--overlays/.keep0
-rw-r--r--pkgs/default.nix3
-rw-r--r--shell.nix16
-rw-r--r--system-profiles/.keep0
-rw-r--r--system-profiles/core.nix47
-rw-r--r--user-profiles/.keep0
-rw-r--r--users/.keep0
-rw-r--r--utils/default.nix57
13 files changed, 219 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..f295f429
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
1result
2result-* \ No newline at end of file
diff --git a/accounts/.keep b/accounts/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/accounts/.keep
diff --git a/flake.nix b/flake.nix
new file mode 100644
index 00000000..fa1e81d6
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,94 @@
1{
2 description = "gkleen's machines";
3
4 inputs = {
5 nixpkgs = {
6 type = "github";
7 owner = "NixOS";
8 repo = "nixpkgs";
9 ref = "master";
10 };
11 home-manager = {
12 type = "github";
13 owner = "nix-community";
14 repo = "home-manager";
15 ref = "master";
16 inputs.nixpkgs.follows = "nixpkgs";
17 };
18 };
19
20 outputs = { self, nixpkgs, home-manager }@inputs:
21 let
22 inherit (builtins) attrNames attrValues elemAt;
23 inherit (nixpkgs) lib;
24 utils = import ./utils { inherit lib; };
25 inherit (utils) recImport overrideModule;
26 inherit (lib) nixosSystem mkIf splitString filterAttrs listToAttrs mapAttrsToList nameValuePair concatMap composeManyExtensions mapAttrs mapAttrs' recursiveUpdate;
27
28 mkNixosConfiguration = dir: path: hostName: nixosSystem rec {
29 specialArgs = {
30 flake = self;
31 flakeInputs = inputs;
32 path = toString ./.;
33 };
34 modules =
35 let
36 defaultProfiles = with self.nixosModules.systemProfiles; [core];
37 local = "${toString dir}/${path}";
38 global._module.args = {
39 customUtils = utils;
40 inherit hostName;
41 };
42 accountModules = attrValues (filterAttrs accountMatchesHost self.nixosModules.accounts);
43 accountMatchesHost = n: _v:
44 let
45 accountName' = splitString "@" n;
46 hostName' = elemAt accountName' 1;
47 in hostName' == hostName;
48 in [ home-manager.nixosModules.home-manager global ] ++ defaultProfiles ++ [ local ] ++ accountModules;
49 };
50
51 mkSystemProfile = dir: path: profileName: {
52 imports = [ "${toString dir}/${path}" ];
53 config = {
54 system.profiles = [profileName];
55 };
56 };
57
58 mkUserModule = dir: path: userName: overrideModule (import "${toString dir}/${path}") (inputs: inputs // { inherit userName; }) (outputs: { _file = "${toString dir}/${path}"; } // outputs);
59
60 mkAccountModule = dir: path: accountName:
61 let
62 accountName' = splitString "@" accountName;
63 userName = elemAt accountName' 0;
64 in overrideModule (import "${toString dir}/${path}") (inputs: inputs // { inherit userName; }) (outputs: { _file = "${toString dir}/${path}"; } // outputs // { imports = [self.nixosModules.users.${userName}] ++ (outputs.imports or []); });
65
66 forAllSystems = f: mapAttrs f nixpkgs.legacyPackages;
67
68 activateHomeManagerConfigurations = forAllSystems (system: _pkgs: mapAttrs' (configName: hmConfig: nameValuePair "${configName}-activate" { type = "app"; program = "${hmConfig.activationPackage}/bin/activate"; }) self.homeManagerConfigurations);
69 activateNixosConfigurations = forAllSystems (system: _pkgs: mapAttrs' (hostName: nixosConfig: nameValuePair "${hostName}-activate" { type = "app"; program = "${nixosConfig.config.system.build.toplevel}/bin/switch-to-configuration"; }) self.nixosConfigurations);
70 in
71 {
72 nixosModules =
73 let modulesAttrs = recImport { dir = ./modules; };
74 systemProfiles = recImport rec { dir = ./system-profiles; _import = mkSystemProfile dir; };
75 userProfiles = recImport rec { dir = ./user-profiles; };
76 users = recImport rec { dir = ./users; _import = mkUserModule dir; };
77 accounts = recImport rec { dir = ./accounts; _import = mkAccountModule dir; };
78 in modulesAttrs // { inherit systemProfiles userProfiles users accounts; };
79 nixosConfigurations = recImport rec { dir = ./hosts; _import = mkNixosConfiguration dir; };
80
81 homeManagerConfigurations = listToAttrs (concatMap ({hostName, users}: mapAttrsToList (userName: homeConfig: nameValuePair "${userName}@${hostName}" homeConfig) users) (mapAttrsToList (hostName: nixosConfig: { inherit hostName; users = nixosConfig.config.home-manager.users; }) (self.nixosConfigurations)));
82
83 overlay = import ./pkgs;
84 overlays = recImport { dir = ./overlays; } // { pkgs = self.overlay; };
85
86 packages = forAllSystems (system: systemPkgs: composeManyExtensions (attrValues self.overlays) (self.legacyPackages.${system}) systemPkgs);
87
88 legacyPackages = forAllSystems (system: systemPkgs: recursiveUpdate systemPkgs self.packages.${system});
89
90 apps = recursiveUpdate activateNixosConfigurations activateHomeManagerConfigurations;
91
92 devShell = forAllSystems (system: systemPkgs: import ./shell.nix { pkgs = self.legacyPackages.${system}; });
93 };
94}
diff --git a/hosts/.keep b/hosts/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/hosts/.keep
diff --git a/modules/.keep b/modules/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/modules/.keep
diff --git a/overlays/.keep b/overlays/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/overlays/.keep
diff --git a/pkgs/default.nix b/pkgs/default.nix
new file mode 100644
index 00000000..b5d83487
--- /dev/null
+++ b/pkgs/default.nix
@@ -0,0 +1,3 @@
1self: super:
2{
3}
diff --git a/shell.nix b/shell.nix
new file mode 100644
index 00000000..2820eb1a
--- /dev/null
+++ b/shell.nix
@@ -0,0 +1,16 @@
1{ pkgs ? import <nixpkgs> {} }:
2let
3 nixWithFlakes = pkgs.symlinkJoin {
4 name = "nix-with-flakes";
5 paths = [ pkgs.nixFlakes ];
6 buildInputs = [ pkgs.makeWrapper ];
7 postBuild = ''
8 wrapProgram $out/bin/nix --add-flags '--option experimental-features "nix-command flakes ca-references"'
9 '';
10 };
11in pkgs.mkShell {
12 name = "nixos";
13 nativeBuildInputs = with pkgs; [
14 nixWithFlakes
15 ];
16}
diff --git a/system-profiles/.keep b/system-profiles/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/system-profiles/.keep
diff --git a/system-profiles/core.nix b/system-profiles/core.nix
new file mode 100644
index 00000000..2af82703
--- /dev/null
+++ b/system-profiles/core.nix
@@ -0,0 +1,47 @@
1{ flake, flakeInputs, path, hostName, config, lib, pkgs, customUtils, ... }:
2let
3 profileSet = customUtils.types.attrNameSet flake.nixosModules.systemProfiles;
4in {
5 options = {
6 # See mkSystemProfile in ../flake.nix
7 system.profiles = lib.mkOption {
8 type = profileSet;
9 default = [];
10 description = ''
11 Set (list without duplicates) of ‘systemProfiles’ enabled for this host
12 '';
13 };
14 };
15
16 config = {
17 networking.hostName = hostName;
18 system.configurationRevision = lib.mkIf (flake ? rev) flake.rev;
19
20 nixpkgs.pkgs = flakeInputs.nixpkgs.legacyPackages.${config.nixpkgs.system};
21 nixpkgs.overlays = lib.attrValues flake.overlays;
22
23 nix = {
24 package = pkgs.nixUnstable;
25 useSandbox = true;
26 allowedUsers = [ "@wheel" ];
27 trustedUsers = [ "root" "@wheel" ];
28 extraOptions = ''
29 experimental-features = nix-command flakes ca-references
30 '';
31 nixPath = [
32 "nixpkgs=${path}"
33 ];
34 registry = {
35 nixpkgs.flake = flakeInputs.nixpkgs;
36 home-manager.flake = flakeInputs.home-manager;
37 machines.flake = flake;
38 };
39 };
40
41 users.mutableUsers = false;
42
43 # documentation.nixos.includeAllModules = true; # incompatible with home-manager (build fails)
44
45 home-manager.useGlobalPkgs = true; # Otherwise home-manager would only work impurely
46 };
47}
diff --git a/user-profiles/.keep b/user-profiles/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/user-profiles/.keep
diff --git a/users/.keep b/users/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/users/.keep
diff --git a/utils/default.nix b/utils/default.nix
new file mode 100644
index 00000000..d00357af
--- /dev/null
+++ b/utils/default.nix
@@ -0,0 +1,57 @@
1{ lib }:
2rec {
3 inherit (builtins) readDir;
4 inherit (lib) filterAttrs hasSuffix removeSuffix mapAttrs' nameValuePair isFunction functionArgs setFunctionArgs id;
5 mapFilterAttrs = seive: f: attrs: filterAttrs seive (mapAttrs' f attrs);
6 recImport = { dir, _import ? name: _base: import "${toString dir}/${name}" }:
7 mapFilterAttrs
8 (_: v: v != null)
9 (n: v:
10 if n != "default.nix" && hasSuffix ".nix" n && v == "regular"
11 then
12 let name = removeSuffix ".nix" n; in nameValuePair (name) (_import n name)
13 else
14 if v == "directory"
15 then
16 nameValuePair n (_import n n)
17 else
18 nameValuePair ("") (null))
19 (readDir dir);
20
21 types.attrNameSet = attr:
22 let
23 elemType = lib.types.enum (builtins.attrNames attr);
24 in lib.types.mkOptionType rec {
25 name = "attrNameSet";
26 description = "set of names taken from an attribute set";
27 check = lib.isList;
28 emptyValue = { value = {}; };
29 getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["*"]);
30 getSubModules = elemType.getSubModules;
31 substSubModules = m: lib.types.listOf (elemType.substSubModules m);
32 functor = (lib.types.defaultFunctor name) // { wrapped = elemType; };
33 merge = loc: defs: map (x: x.value) (lib.lists.filter (x: x ? value) (lib.lists.unique (lib.lists.concatLists (lib.lists.imap1 (n: def:
34 lib.lists.imap1 (m: def':
35 (lib.modules.mergeDefinitions
36 (loc ++ ["[definition ${toString n}-entry ${toString m}]"])
37 elemType
38 [{ inherit (def) file; value = def'; }]
39 ).optionalValue
40 ) def.value
41 ) defs))));
42 };
43
44 overrideModuleArgs =
45 let
46 overrideModuleArgs = module: appOverride: if isFunction module then overrideModuleArgs' module appOverride else module;
47 overrideModuleArgs' = module: appOverride: setFunctionArgs (inputs: overrideModuleArgs (module (appOverride inputs)) id) (functionArgs module);
48 in overrideModuleArgs;
49
50 overrideModuleOutput =
51 let
52 overrideModuleOutput = module: appOverride: if isFunction module then overrideModuleOutput' module appOverride else appOverride module;
53 overrideModuleOutput' = module: appOverride: setFunctionArgs (inputs: overrideModuleOutput (module inputs) appOverride) (functionArgs module);
54 in overrideModuleOutput;
55
56 overrideModule = module: appInput: appOutput: overrideModuleOutput (overrideModuleArgs module appInput) appOutput;
57}