diff --git a/flake.nix b/flake.nix index 009d257..84fcd34 100755 --- a/flake.nix +++ b/flake.nix @@ -22,117 +22,34 @@ (nixpkgs.lib.filterAttrs (k: _v: nixpkgs.lib.hasSuffix ".nix" k) (builtins.readDir dir)); + # Given a path to a directory, return a module that imports «path»/*.nix + collectModules = path: + let modules = list-nix-directory path; + in { pkgs, lib, ... }: { + imports = + lib.debug.traceVal + (builtins.map (m: ./${path}/${m}) modules); + }; in { # REVIEW: Why don't we put each module under nixosModules.? + # TODO: Deduplicate. nixosModules.default = let modules = list-nix-directory ./modules/nixos; - in { ... }: { + in { pkgs, lib, ... }: { imports = builtins.map (m: ./modules/nixos/${m}) modules; }; + # TODO: Deduplicate. homeManagerModules.default = let modules = list-nix-directory ./modules/home; - in { ... }: { + in { pkgs, lib, ... }: { imports = builtins.map (m: ./modules/home/${m}) modules; }; - nixosConfigurations = ( - let mkHost = k: v: nixpkgs.lib.nixosSystem { - specialArgs = inputs; - system = import ./hosts/${k}/system.nix; - # TODO: This is very ad-hoc, and I don't like it. Organise this better. - modules = [ - ./hosts/${k}/configuration.nix - - inputs.self.nixosModules.default - - inputs.disko.nixosModules.disko - inputs.sops-nix.nixosModules.sops - inputs.impermanence.nixosModules.impermanence + nixosConfigurations = import ./outputs/nixosConfigurations.nix inputs; - # Directory name should always match host name. - ({ ... }: { networking.hostName = k; }) - - # Get system users - ({ config, lib, ... }: { - users.users = - (lib.mapAttrs - (k: v: (import ./users/${k}).systemConfiguration) - (lib.filterAttrs - (k: _v: builtins.elem k config.sydnix.users.users) - (builtins.readDir ./users))); - }) - - # Nixpkgs configuration - ({ pkgs, ... }: { - nixpkgs.config.allowUnfree = true; - - documentation = { - man.enable = true; - info.enable = true; - }; - - environment.systemPackages = with pkgs; [ - man-pages - stdman - man-pages-posix - stdmanpages - ]; - }) - - # home-manager configuration. - inputs.home-manager.nixosModules.home-manager - ({ config, lib, self, ... }: { - home-manager.useGlobalPkgs = true; - # home-manager.useUserPackages = true; - - home-manager.users = - lib.filterAttrs - (k: _v: builtins.elem k config.sydnix.users.users) - self.homeConfigurations; - - home-manager.extraSpecialArgs = { - utils = import ./lib/utils.nix { - inherit config lib; - pkgs = nixpkgs; - }; - }; - }) - ]; - }; - in - builtins.mapAttrs mkHost (builtins.readDir ./hosts) - ); - - homeConfigurations = - let users = builtins.readDir ./users; - mkUser = username: _v: { - # TODO: This is very ad-hoc, and I don't like it. Organise this - # better. - imports = [ - (import ./users/${username}/default.nix).homeConfiguration - - inputs.self.homeManagerModules.default - - ({ lib, ... }: { - home.username = username; - }) - - ({ pkgs, lib, ... }: { - nix = { - settings.experimental-features = - lib.mkDefault - [ "nix-command" "flakes" ]; - }; - }) - - inputs.sops-nix.homeManagerModules.sops - inputs.impermanence.homeManagerModules.impermanence - ]; - }; - in - builtins.mapAttrs mkUser users; + homeConfigurations = import ./outputs/homeConfigurations.nix inputs; }; } diff --git a/modules/nixos/defaults.nix b/modules/nixos/defaults.nix new file mode 100644 index 0000000..cb1b358 --- /dev/null +++ b/modules/nixos/defaults.nix @@ -0,0 +1,15 @@ +{ config, lib, pkgs, ... }: + +let + # TODO: Move to a fucking utility library already! + listNixFilesInDirectory = dir: + builtins.attrNames + (lib.filterAttrs + (k: _v: lib.hasSuffix ".nix" k) + (builtins.readDir dir)); +in { + imports = + builtins.map + (k: ./defaults/${k}) + (listNixFilesInDirectory ./defaults); +} diff --git a/modules/nixos/defaults/documentation.nix b/modules/nixos/defaults/documentation.nix new file mode 100644 index 0000000..200373e --- /dev/null +++ b/modules/nixos/defaults/documentation.nix @@ -0,0 +1,30 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.sydnix.defaults.documentation; +in { + options = { + sydnix.defaults.documentation = { + enable = mkOption { + description = "Madeleine's default documentation settings"; + default = true; + type = types.bool; + }; + }; + }; + + config = mkIf cfg.enable { + documentation = { + man.enable = true; + info.enable = true; + }; + + environment.systemPackages = with pkgs; [ + man-pages + stdman + man-pages-posix + stdmanpages + ]; + }; +} diff --git a/modules/nixos/defaults/nixpkgs.nix b/modules/nixos/defaults/nixpkgs.nix new file mode 100644 index 0000000..60d5f73 --- /dev/null +++ b/modules/nixos/defaults/nixpkgs.nix @@ -0,0 +1,20 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.sydnix.defaults.nixpkgs; +in { + options = { + sydnix.defaults.nixpkgs = { + enable = mkOption { + description = "Madeleine's default Nixpkgs settings"; + default = true; + type = types.bool; + }; + }; + }; + + config = mkIf cfg.enable { + nixpkgs.config.allowUnfree = true; + }; +} diff --git a/outputs/homeConfigurations.nix b/outputs/homeConfigurations.nix new file mode 100644 index 0000000..45c3b77 --- /dev/null +++ b/outputs/homeConfigurations.nix @@ -0,0 +1,26 @@ +{ ... }@inputs: + +let users = builtins.readDir ../users; + mkUser = username: _: { + imports = [ + (import ../users/${username}/default.nix).homeConfiguration + + inputs.self.homeManagerModules.default + + inputs.sops-nix.homeManagerModules.sops + inputs.impermanence.homeManagerModules.impermanence + + # Directory name should always match username. + ({ ... }: { home.username = username; }) + + ({ lib, ... }: { + nix = { + settings.experimental-features = + lib.mkDefault + [ "nix-command" "flakes" ]; + }; + }) + ]; + }; +in +builtins.mapAttrs mkUser users diff --git a/outputs/nixosConfigurations.nix b/outputs/nixosConfigurations.nix new file mode 100644 index 0000000..5c40ddd --- /dev/null +++ b/outputs/nixosConfigurations.nix @@ -0,0 +1,59 @@ +{ nixpkgs, ... }@inputs: + +let + # Given a hostName, return a NixOS module defining each user specified by + # `sydnix.users.users`. + mkHostUsers = hostName: { config, lib, ... }: { + users.users = + (lib.mapAttrs + # Only import the user's system configuration. The code responsible for + # importing the user's home configuration lives in + # outputs/homeConfigurations. + (username: _: (import ../users/${username}).systemConfiguration) + # The directory users/ hosts a 'universe' of user profiles, which + # specific hosts may select any subset of, by setting the option + # `sydnix.users.users` to a list of choice usernames. + (lib.filterAttrs + (username: _: builtins.elem username config.sydnix.users.users) + (builtins.readDir ../users))); + }; + + mkHost = hostName: nixpkgs.lib.nixosSystem { + specialArgs = inputs; + system = import ../hosts/${hostName}/system.nix; + # TODO: This is very ad-hoc, and I don't like it. Organise this better. + modules = [ + ../hosts/${hostName}/configuration.nix + + inputs.self.nixosModules.default + + inputs.disko.nixosModules.disko + inputs.sops-nix.nixosModules.sops + inputs.impermanence.nixosModules.impermanence + + # Directory name should always match host name. + ({ ... }: { networking.hostName = hostName; }) + + (mkHostUsers hostName) + + # home-manager configuration. + inputs.home-manager.nixosModules.home-manager + ({ config, lib, self, ... }: { + home-manager.useGlobalPkgs = true; + + home-manager.users = + lib.filterAttrs + (username: _: builtins.elem username config.sydnix.users.users) + self.homeConfigurations; + + home-manager.extraSpecialArgs = { + utils = import ../lib/utils.nix { + inherit config lib; + pkgs = nixpkgs; + }; + }; + }) + ]; + }; +in +builtins.mapAttrs (dirName: _: mkHost dirName) (builtins.readDir ../hosts)