commit 5679c003d8e97394ba775aa3124186a00d5a7282 Author: Jonas Rabenstein Date: Sun Jan 5 16:35:55 2025 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9b46d6b --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +* +!*/ +!*.nix diff --git a/export/hmModule.nix b/export/hmModule.nix new file mode 100644 index 0000000..165dbac --- /dev/null +++ b/export/hmModule.nix @@ -0,0 +1,3 @@ +{ ... }@flake: { ... }@inputs: { ... }@imports: { + imports = builtins.attrValues (flake.hmModules or {}); +} diff --git a/export/hmModules.nix b/export/hmModules.nix new file mode 100644 index 0000000..ff37dd1 --- /dev/null +++ b/export/hmModules.nix @@ -0,0 +1,4 @@ +flake: { ... }@inputs: { ... }@imports: let + module' = name: imports: builtins.trace "user module: ${name}" { inherit imports; }; + modules = builtins.mapAttrs module' imports."user/module"; +in { default = module' "default" (builtins.attrValues modules); } // modules diff --git a/export/hmProfiles.nix b/export/hmProfiles.nix new file mode 100644 index 0000000..192bda7 --- /dev/null +++ b/export/hmProfiles.nix @@ -0,0 +1,4 @@ +{ ... }@flake: { ... }@inputs: { profile, ... }@imports: let + profile' = name: snippets: builtins.trace "home-manager: profile: ${name}" { imports = snippets; }; +in builtins.mapAttrs profile' profile + diff --git a/export/iso.nix b/export/iso.nix new file mode 100644 index 0000000..153bd59 --- /dev/null +++ b/export/iso.nix @@ -0,0 +1,32 @@ +{ nixosUsers ? {}, nixosGroups ? {}, nixosModules, hmModules ? { default = {}; }, ...}@flake: { ... }@inputs: { host, ... }@imports: let + host' = name: snippets: let + + overlay = self: super: { + makeModulesClosure = x: super.makeModulesClosure (x // { allowMissing = true; }); + }; + + common = { modulesPath, lib, ... }: { + config.nixpkgs.overlays = [ overlay ]; + config.networking.hostName = lib.mkForce name; + config.home-manager = { + sharedModules = [ hmModules.default ] ; + }; + + imports = [ + (modulesPath + "/installer/cd-dvd/installation-cd-minimal-new-kernel-no-zfs.nix") + nixosModules.default + inputs.home-manager.nixosModules.default + ]; + }; + + system = inputs.nixpkgs.lib.nixosSystem { + specialArgs = { inherit inputs flake; }; + modules = [ common ] + ++ snippets + ++ builtins.attrValues nixosUsers + ++ builtins.attrValues nixosGroups + ; + }; + in system.config.system.build.isoImage; + +in builtins.mapAttrs host' host diff --git a/export/nixosConfigurations.nix b/export/nixosConfigurations.nix new file mode 100644 index 0000000..00665fe --- /dev/null +++ b/export/nixosConfigurations.nix @@ -0,0 +1,18 @@ +{ nixosUsers ? {}, nixosGroups ? {}, nixosModules, hmModules ? { default = {}; }, ...}@flake: { ... }@inputs: { host, ... }@imports: let + host' = name: snippets: let + system = { namespace?"fbs42", nixpkgs?"nixpkgs" }: inputs.${nixpkgs}.lib.nixosSystem { + specialArgs = { inherit inputs flake; namespace = if builtins.isList namespace then namespace else [ namespace ]; }; + modules = builtins.concatLists (map (base: builtins.attrValues (flake.lib.scan { base = "${base}/host/${name}"; })) flake.lib.schema.base) + ++ [ { config.networking.hostName = name; } ] + ++ [ nixosModules.default ] + ++ [ inputs.home-manager.nixosModules.default ] + ++ [ { config.home-manager.sharedModules = [ hmModules.default ]; } ] + ++ builtins.attrValues nixosUsers + ++ builtins.attrValues nixosGroups + ; + }; + + cfg = assert builtins.length snippets == 1; builtins.head snippets; + in system cfg; + +in builtins.mapAttrs host' host diff --git a/export/nixosGroup.nix b/export/nixosGroup.nix new file mode 100644 index 0000000..159b8c1 --- /dev/null +++ b/export/nixosGroup.nix @@ -0,0 +1,10 @@ +flake: { ... }@inputs: { group, ... }@imports: let + group' = name: snippets: { pkgs, lib, options, config, ... }@args: let + invoke = x: if builtins.isFunction x then x args else x; + in { + options.fbs42.group.${name} = lib.mkEnableOption name; + config.users.groups.${name} = lib.mkIf + (config.fbs42.group.${name} || builtins.any (usr: usr.group == name) (builtins.attrValues config.users.users)) + (lib.mkMerge (map invoke snippets)); + }; +in builtins.mapAttrs group' group diff --git a/export/nixosModules.nix b/export/nixosModules.nix new file mode 100644 index 0000000..c5dae22 --- /dev/null +++ b/export/nixosModules.nix @@ -0,0 +1,3 @@ +flake: { ... }@inputs: { module, ... }@imports: let + modules = builtins.mapAttrs (name: imports: builtins.trace "module: ${name}" { inherit imports; }) module; +in { default = { imports = builtins.attrValues modules; }; } // modules diff --git a/export/nixosProfiles.nix b/export/nixosProfiles.nix new file mode 100644 index 0000000..1655190 --- /dev/null +++ b/export/nixosProfiles.nix @@ -0,0 +1,2 @@ +{ ... }@flake: { ... }@inputs: { profile, ... }@imports: + builtins.mapAttrs (name: imports: builtins.trace "profile: ${name}" { inherit imports; }) profile diff --git a/export/nixosUsers.nix b/export/nixosUsers.nix new file mode 100644 index 0000000..f0ff763 --- /dev/null +++ b/export/nixosUsers.nix @@ -0,0 +1,17 @@ +self: { ... }@inputs: { user, ... }@imports: let + user' = name: snippets: { pkgs, lib, config, ... }@args: + builtins.trace "user: ${name}" { + options.fbs42.user.${name} = lib.mkEnableOption name; + ## no longer with nixos-24.11 + #config.users.users.${name} = lib.mkIf config.fbs42.user.${name} { + # group = lib.mkDefault name; + #}; + + imports = map ({ user, home-manager}: { + config = lib.mkIf config.fbs42.user.${name} { + users.users.${name} = (user args); + home-manager.users.${name} = home-manager; + }; + }) snippets; + }; +in builtins.mapAttrs user' user diff --git a/export/sdcard-rpi4.nix b/export/sdcard-rpi4.nix new file mode 100644 index 0000000..24a1a9d --- /dev/null +++ b/export/sdcard-rpi4.nix @@ -0,0 +1,34 @@ +{ nixosUsers ? {}, nixosGroups ? {}, nixosModules, hmModules ? { default = {}; }, ...}@flake: { ... }@inputs: { host, ... }@imports: let + host' = name: snippets: let + + overlay = self: super: { + makeModulesClosure = x: super.makeModulesClosure (x // { allowMissing = true; }); + }; + + common = { modulesPath, lib, ... }: { + config.nixpkgs.overlays = [ overlay ]; + config.networking.hostName = lib.mkForce name; + config.home-manager = { + sharedModules = [ hmModules.default ] ; + }; + + imports = [ + #(modulesPath + "/installer/cd-dvd/installation-cd-minimal-new-kernel-no-zfs.nix") + #(modulesPath + "/installer/sd-card/sd-image-aarch64.nix") + (modulesPath + "/installer/sd-card/sd-image-raspberrypi.nix") + nixosModules.default + inputs.home-manager.nixosModules.default + ]; + }; + + system = inputs.nixpkgs.lib.nixosSystem { + specialArgs = { inherit inputs flake; }; + modules = [ common ] + ++ snippets + ++ builtins.attrValues nixosUsers + ++ builtins.attrValues nixosGroups + ; + }; + in system.config.system.build.sdImage; + +in builtins.mapAttrs host' host diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..d302c2b --- /dev/null +++ b/flake.lock @@ -0,0 +1,65 @@ +{ + "nodes": { + "hardware": { + "locked": { + "lastModified": 1735388221, + "narHash": "sha256-e5IOgjQf0SZcFCEV/gMGrsI0gCJyqOKShBQU0iiM3Kg=", + "owner": "nixos", + "repo": "nixos-hardware", + "rev": "7c674c6734f61157e321db595dbfcd8523e04e19", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixos-hardware", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1735344290, + "narHash": "sha256-oJDtWPH1oJT34RJK1FSWjwX4qcGOBRkcNQPD0EbSfNM=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "613691f285dad87694c2ba1c9e6298d04736292d", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "release-24.11", + "repo": "home-manager", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1735922141, + "narHash": "sha256-vk0xwGZSlvZ/596yxOtsk4gxsIx2VemzdjiU8zhjgWw=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "d29ab98cd4a70a387b8ceea3e930b3340d41ac5a", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "hardware": "hardware", + "home-manager": "home-manager", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..5f5c238 --- /dev/null +++ b/flake.nix @@ -0,0 +1,12 @@ +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11"; + hardware.url = "github:nixos/nixos-hardware"; + home-manager = { + url = "github:nix-community/home-manager/release-24.11"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { self, ... }@inputs: import ./lib/flake.nix inputs ./.; +} diff --git a/group/nix.nix b/group/nix.nix new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/group/nix.nix @@ -0,0 +1 @@ +{} diff --git a/import/group.nix b/import/group.nix new file mode 100644 index 0000000..e261696 --- /dev/null +++ b/import/group.nix @@ -0,0 +1 @@ +name: group: group diff --git a/import/group/module.nix b/import/group/module.nix new file mode 100644 index 0000000..7225727 --- /dev/null +++ b/import/group/module.nix @@ -0,0 +1 @@ +name: group'module: group'module diff --git a/import/host.nix b/import/host.nix new file mode 100644 index 0000000..7752346 --- /dev/null +++ b/import/host.nix @@ -0,0 +1 @@ +name: host: host diff --git a/import/module.nix b/import/module.nix new file mode 100644 index 0000000..e2c62dc --- /dev/null +++ b/import/module.nix @@ -0,0 +1 @@ +name: module: module diff --git a/import/profile.nix b/import/profile.nix new file mode 100644 index 0000000..bdf2229 --- /dev/null +++ b/import/profile.nix @@ -0,0 +1 @@ +name: profile: profile diff --git a/import/user.nix b/import/user.nix new file mode 100644 index 0000000..0e5562d --- /dev/null +++ b/import/user.nix @@ -0,0 +1,21 @@ +let + function = name: value: let + result = if builtins.isAttrs value then {...}: value else value; + result' = builtins.trace "result ${name}=${builtins.typeOf result}" result; + in + assert builtins.isFunction result'; + result; + + config = { user?{}, home-manager?{} }@set: + builtins.mapAttrs function { inherit user home-manager; }; + +in name: value: let + result = if builtins.isFunction value + then + config { user = value; } + else if builtins.any (attr: builtins.hasAttr attr value) [ "user" "home-manager" ] + then + config value + else + config { user = value; }; +in result diff --git a/import/user/module.nix b/import/user/module.nix new file mode 100644 index 0000000..dd69792 --- /dev/null +++ b/import/user/module.nix @@ -0,0 +1 @@ +iname: user'module: user'module diff --git a/import/user/profile.nix b/import/user/profile.nix new file mode 100644 index 0000000..db2953a --- /dev/null +++ b/import/user/profile.nix @@ -0,0 +1,2 @@ +name: profile: profile + diff --git a/lib/flake.nix b/lib/flake.nix new file mode 100644 index 0000000..4655a5d --- /dev/null +++ b/lib/flake.nix @@ -0,0 +1,34 @@ +let + scan = import ./scan.nix; + + flake' = self: { imports, exports , base }@schema: { ... }@inputs: { ... }@imports: let + lib = { + inherit scan schema inputs imports; + extend = flake schema inputs imports; + new = flake {} {} {}; + # TODO: override + }; + convert = attr: value: value self inputs imports; + + result = (builtins.mapAttrs convert schema.exports); + in result // { lib = lib // (result.lib or {}); }; + + flake = { imports?{}, exports?{}, base?[] }@schema'old: { ... }@inputs'old: { ... }@imports'old: { ... }@inputs'new: base: let + schema = { + imports = (schema'old.imports or {}) // scan { base = base + "/import"; recursive = true; }; + exports = (schema'old.exports or {}) // scan { base = base + "/export"; }; + base = [ base ] ++ (schema'old.base or []); + }; + + merge = attr: let + old = imports'old.${attr} or {}; + new = imports'new.${attr} or {}; + in builtins.mapAttrs (attr: _: (old.${attr} or []) ++ (new.${attr} or [])) (old//new); + + imports'new = builtins.mapAttrs (name: value: scan { base = base + "/${name}"; convert = name: content: [ (value name content) ]; }) schema.imports; + result = flake' result schema + (inputs'old // (builtins.removeAttrs inputs'new ["self"])) + (builtins.mapAttrs (attr: _: merge attr) schema.imports); + in result; + +in flake {} {} {} diff --git a/lib/host.nix b/lib/host.nix new file mode 100644 index 0000000..b387ebc --- /dev/null +++ b/lib/host.nix @@ -0,0 +1 @@ +self: diff --git a/lib/scan.nix b/lib/scan.nix new file mode 100644 index 0000000..d664df9 --- /dev/null +++ b/lib/scan.nix @@ -0,0 +1,23 @@ +{ base, convert ? name: value: value, recursive ? false }: +let + scan = sub: let + all = builtins.readDir (base + "/${builtins.concatStringsSep "/" sub}"); + names = filter: builtins.filter filter (builtins.attrNames all); + nix = name: all.${name} == "regular" && builtins.stringLength name > 4 && builtins.substring (builtins.stringLength name - 4) 4 name == ".nix"; + dir = name: all.${name} == "directory"; + files = map (name: sub ++ [ (builtins.substring 0 (builtins.stringLength name - 4) name) ]) (names nix); + dirs = builtins.concatLists (map (name: scan (sub ++ [name])) (names dir)); + in if recursive then files ++ dirs else files; + + root = scan []; + + item = relative: let + name = builtins.concatStringsSep "/" relative; + absolute = base + "/${name}.nix"; + content = import absolute; + value = convert name content; + in { inherit name value; }; + + items = map item root; + +in if builtins.pathExists base then builtins.listToAttrs (map item root) else {} diff --git a/user/root.nix b/user/root.nix new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/user/root.nix @@ -0,0 +1 @@ +{}