diff --git a/README.md b/README.md index 6caf191..a6e4cee 100644 --- a/README.md +++ b/README.md @@ -6,30 +6,22 @@
## 🚧 State of development -All the basic functionality of v2 should be working correctly, including: - -- The custom lib implementation at self.lib, recursively built from the contents of the `lib` directory. -- Loading of systems from the `systems` directory, using easy-hosts. - - A basic workstation archetype for desktop systems. -- Creating users in your systems through ${self.namespace}.users, -automatically maps home-manager configurations from the `homes` directory to their corresponding users. - -Nonetheless, one should still consider this implementation experimental, -once I start using this on my laptop, -I'll aim for production grade stability. +Version 2.0 is still very much an experiment and not ready to be used in a production +environment. If you must, try running it within a VM using the provided deployment +instructions. ## 🚀 Deployment To deploy a system run the following command in your terminal of choice. ```sh -sudo nixos-rebuild switch --flake .#hostname --accept-flake-config +sudo nixos-rebuild switch --flake .#hostname ``` If you're interested in a quick way to experiment with this configuration, you may use the following command to build a VM. ```sh -sudo nixos-rebuild build-vm --flake .#hostname --accept-flake-config +sudo nixos-rebuild build-vm --flake .#hostname ``` ## 📝 Goals and improvements diff --git a/homes/x86_64-linux/cyn/default.nix b/homes/x86_64-linux/cyn/default.nix deleted file mode 100644 index bdf7c40..0000000 --- a/homes/x86_64-linux/cyn/default.nix +++ /dev/null @@ -1,6 +0,0 @@ -{pkgs, ...}: { - home.packages = with pkgs; [ - cowsay - cmatrix - ]; -} diff --git a/homes/x86_64-linux/jo/default.nix b/homes/x86_64-linux/jo/default.nix index bd62c1a..21cf78b 100644 --- a/homes/x86_64-linux/jo/default.nix +++ b/homes/x86_64-linux/jo/default.nix @@ -1,7 +1,10 @@ -{pkgs, ...}: { +{ + pkgs, + ... +}: { home.packages = with pkgs; [ - zed-editor - firefox + vscodium + cmatrix ]; home.stateVersion = "25.05"; diff --git a/lib/module/default.nix b/lib/module/default.nix index 61c73ae..3d52e9d 100644 --- a/lib/module/default.nix +++ b/lib/module/default.nix @@ -1,13 +1,8 @@ -{ - lib, - self, - ... -}: { +{ lib, self, ... }: { # Create a NixOS module option on a single line. mkOpt = type: default: description: lib.mkOption {inherit type default description;}; - # Create a simple bool options mkBool = default: description: lib.mkOption { inherit default description; @@ -15,17 +10,20 @@ }; # Create a module compliant with the NixOS module system. - mkModule = { - name ? "puzzlevision", - class, - modules, - }: { - _class = class; - # Template: "[path-to-flake]/flake.nix#[class-name]Modules.[module-name]" - # Example: "[path-to-flake]/flake.nix#nixosModules.system.audio" - _file = "${self.outPath}/flake.nix#${class}Modules.${name}"; - imports = modules; - }; + mkModule = + { + name ? "puzzlevision", + class, + modules, + }: { + _class = class; + + # Template: "[path-to-flake]/flake.nix#[class-name]Modules.[module-name]" + # Example: "[path-to-flake]/flake.nix#nixosModules.system.audio" + _file = "${self.outPath}/flake.nix#${class}Modules.${name}"; + + imports = modules; + }; # TODO: add mkIfElse function } diff --git a/modules/flake/default.nix b/modules/flake/default.nix index 33820cf..fb9d01d 100644 --- a/modules/flake/default.nix +++ b/modules/flake/default.nix @@ -6,7 +6,13 @@ # Automagically imports libs from "/lib/lib-name" and exposes them to the `flake.lib` output. ./lib.nix + # Recursively imports overlays from "/overlays/overlay-name" and exposes them to the `flake.overlays` output. + #./overlays.nix + # Automagically imports systems from "/systems/arch-classname/system-name". ./systems.nix + + # Automagically imports homes from "/homes/user-name". + #./homes.nix ]; } diff --git a/modules/flake/modules.nix b/modules/flake/modules.nix index 1952945..9fa3d3e 100644 --- a/modules/flake/modules.nix +++ b/modules/flake/modules.nix @@ -1,10 +1,10 @@ -{self, ...}: { +{ self, ... }: +{ flake = { - # TODO: figure out why this isn't working correctly - nixosModules.puzzlevision = self.lib.mkModule { - class = "nixos"; - modules = self.lib.dirToModuleList ../nixos; - }; + #nixosModules.puzzlevision = self.lib.mkModule { + # class = "nixos"; + # modules = self.lib.dirToModuleList ../nixos; + #}; homeModules.puzzlevision = self.lib.mkModule { class = "home"; diff --git a/modules/flake/systems.nix b/modules/flake/systems.nix index ea6523e..b0198bb 100644 --- a/modules/flake/systems.nix +++ b/modules/flake/systems.nix @@ -1,12 +1,10 @@ { lib, - self, inputs, + self, ... }: { - imports = [ - inputs.easy-hosts.flakeModule - ]; + imports = [ inputs.easy-hosts.flakeModule ]; easyHosts = { autoConstruct = true; diff --git a/modules/home/default.nix b/modules/home/default.nix deleted file mode 100644 index ea8f50d..0000000 --- a/modules/home/default.nix +++ /dev/null @@ -1,2 +0,0 @@ -{...}: { -} diff --git a/modules/home/desktop/gnome/default.nix b/modules/home/desktop/gnome/default.nix new file mode 100644 index 0000000..daa75f5 --- /dev/null +++ b/modules/home/desktop/gnome/default.nix @@ -0,0 +1,33 @@ +{ + lib, + pkgs, + self, + config, + osConfig, + ... +}: let + inherit (lib) mkIf mkOption; + inherit (self) namespace; + + cfg = config.${namespace}.desktop.gnome; +in { + options.${namespace}.desktop.gnome = with lib.types; { + enabled-extensions = mkOption { + type = listOf package; + default = with pkgs.gnomeExtensions; [dash-to-dock user-themes blur-my-shell appindicator unite color-picker clipboard-history]; + example = [dash-to-dock blur-my-shell]; + description = "Specify gnome extensions to install."; + }; + }; + + config = mkIf osConfig.${namespace}.desktop.gnome.enable { + home.packages = cfg.enabled-extensions; + + dconf.settings = { + "org/gnome/shell" = { + enabled-extensions = lib.forEach cfg.enabled-extensions (x: x.extensionUuid); + disabled-extensions = []; # Make sure none of our extensions are disabled on system rebuild + }; + }; + }; +} diff --git a/modules/nixos/archetypes/workstation/default.nix b/modules/nixos/archetypes/workstation/default.nix deleted file mode 100644 index 32b3c1a..0000000 --- a/modules/nixos/archetypes/workstation/default.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ - lib, - self, - config, - ... -}: let - inherit (lib) mkEnableOption mkIf mkDefault; - inherit (self) namespace; - - cfg = config.${namespace}.archetypes.workstation; -in { - options.${namespace}.archetypes.workstation = { - enable = mkEnableOption "the workstation archetype."; - }; - - config = mkIf cfg.enable { - ${namespace} = { - # Basic system functionality - system.grub.enable = true; - system.networking.enable = true; - system.kernel.enable = true; - - # Services - services.docker.enable = true; - - # Desktop environment - desktop.gnome.enable = true; - }; - - time.timeZone = mkDefault "Europe/Berlin"; - }; -} diff --git a/modules/nixos/system/grub/default.nix b/modules/nixos/common/grub/default.nix similarity index 72% rename from modules/nixos/system/grub/default.nix rename to modules/nixos/common/grub/default.nix index ef2ab0e..5ec7745 100644 --- a/modules/nixos/system/grub/default.nix +++ b/modules/nixos/common/grub/default.nix @@ -3,22 +3,21 @@ self, config, ... -}: let +}: +let inherit (lib) mkEnableOption mkIf; inherit (self) namespace; - cfg = config.${namespace}.system.grub; + cfg = config.${namespace}.common.grub; in { - options.${namespace}.system.grub = { - enable = mkEnableOption "the grub bootloader."; - }; + options.${namespace}.common.grub = { enable = mkEnableOption "grub"; }; config = mkIf cfg.enable { boot.loader.systemd-boot.enable = false; boot.loader.grub = { enable = true; - devices = ["nodev"]; + devices = [ "nodev" ]; efiInstallAsRemovable = true; efiSupport = true; diff --git a/modules/nixos/desktop/gnome/default.nix b/modules/nixos/desktop/gnome/default.nix index 01e40ba..d2432b5 100644 --- a/modules/nixos/desktop/gnome/default.nix +++ b/modules/nixos/desktop/gnome/default.nix @@ -9,9 +9,7 @@ cfg = config.${namespace}.desktop.gnome; in { - options.${namespace}.desktop.gnome = { - enable = mkEnableOption "the gnome desktop environment"; - }; + options.${namespace}.desktop.gnome = {enable = mkEnableOption "Enable the gnome desktop environment ${namespace}";}; config = mkIf cfg.enable { services.xserver.enable = true; diff --git a/modules/nixos/services/docker/default.nix b/modules/nixos/services/docker/default.nix deleted file mode 100644 index bb3f805..0000000 --- a/modules/nixos/services/docker/default.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ - lib, - self, - config, - ... -}: let - inherit (lib) mkIf mkEnableOption; - inherit (self) namespace; - - cfg = config.${namespace}.services.docker; -in { - options.${namespace}.services.docker = { - enable = mkEnableOption "the docker service."; - }; - - config = mkIf cfg.enable { - # Enable docker - virtualisation.docker.enable = true; - }; -} diff --git a/modules/nixos/system/kernel/default.nix b/modules/nixos/system/kernel/default.nix deleted file mode 100644 index 521846d..0000000 --- a/modules/nixos/system/kernel/default.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ - lib, - pkgs, - self, - config, - ... -}: let - inherit (lib) mkEnableOption mkIf; - inherit (self) namespace; - inherit (self.lib) mkOpt; - - cfg = config.${namespace}.system.kernel; -in { - options.${namespace}.system.kernel = { - enable = mkEnableOption "Modify the standard kernel settings"; - version = mkOpt lib.types.str "linuxPackages_latest" "Set the kernel version to be used by your system"; - }; - - config = mkIf cfg.enable { - boot.kernelPackages = pkgs.${cfg.version}; - }; -} diff --git a/modules/nixos/system/networking/default.nix b/modules/nixos/system/networking/default.nix deleted file mode 100644 index 2130053..0000000 --- a/modules/nixos/system/networking/default.nix +++ /dev/null @@ -1,19 +0,0 @@ -{ - lib, - self, - config, - ... -}: let - inherit (lib) mkEnableOption mkIf; - inherit (self) namespace; - - cfg = config.${namespace}.system.networking; -in { - options.${namespace}.system.networking = { - enable = mkEnableOption "networking."; - }; - - config = mkIf cfg.enable { - networking.networkmanager.enable = true; - }; -} diff --git a/modules/nixos/users/default.nix b/modules/nixos/users/default.nix index 4d91d25..ef2d6dc 100644 --- a/modules/nixos/users/default.nix +++ b/modules/nixos/users/default.nix @@ -1,78 +1,81 @@ { lib, + config, self, pkgs, - config, ... }: let - inherit (lib) types mkEnableOption mkOption mkIf; + inherit (lib) mkEnableOption mkIf mkOption types; inherit (self) namespace; - inherit (self.lib) dirToModuleList; + inherit (self.lib) mkOpt dirToModuleList; + + cfg = config.${namespace}.users; # The identifier of the current system type, e.g. "x86_64-linux" or "aarch64-darwin" system = pkgs.system; - cfg = config.${namespace}.users; - userSubmodule = types.submodule { + # Type for a user configuration + userType = types.submodule { options = { - enable = mkEnableOption "this user."; - isNormalUser = self.lib.mkBool true "Whether this user is considered a normal user."; - isSystemUser = self.lib.mkBool false "Whether this user is considered a system user."; - initialPassword = self.lib.mkOpt (types.nullOr types.str) null "Plaintext insecure initial user password, only recommended for testing."; - password = self.lib.mkOpt (types.nullOr types.str) null "Plaintext insecure user password, only recommended for testing."; - extraGroups = self.lib.mkOpt (types.listOf types.str) [] "List of additional groups this user belongs to."; + enable = mkEnableOption "this user"; + initialPassword = mkOpt (types.nullOr types.str) null "Initial password for the user"; + password = mkOpt (types.nullOr types.str) null "Plaintext password for the user"; + hashedPassword = mkOpt (types.nullOr types.str) null "Hashed password for the user"; + isNormalUser = mkOpt types.bool true "Whether this user is a normal user"; + extraGroups = mkOpt (types.listOf types.str) [] "Extra groups for the user"; }; }; + # Function to get home configuration path for a username getHomeConfigPath = username: "${self.outPath}/homes/${system}/${username}"; - homeConfigExists = username: let - path = getHomeConfigPath username; - in - builtins.pathExists "${path}/default.nix"; + # Function to check if a home configuration exists for a username + homeConfigExists = username: + let path = getHomeConfigPath username; + in builtins.pathExists "${path}/default.nix"; + + # Import all home-manager modules homeModules = dirToModuleList "${self.outPath}/modules/home"; in { options.${namespace}.users = mkOption { - type = types.attrsOf userSubmodule; + type = types.attrsOf userType; default = {}; - description = "List of users to create. Also handles home configurations, placed in self.outPath/homes/[x86_64-linux, aarch64-linux, etc...], through home-manager."; + description = "User configurations with auto-imported home-manager setup"; }; config = { - # TODO: fix this - #nix.settings.trusted-users = ["root" (lib.forEach cfg (username: toString username))]; - - # Manage users declaratively and map userConfig to users.users by name; + # Ensure users are fully managed by NixOS users.mutableUsers = false; + + # Create the actual system users users.users = lib.mapAttrs (username: userConfig: mkIf userConfig.enable { name = username; - inherit (userConfig) isNormalUser isSystemUser initialPassword password extraGroups; - }) - cfg; + inherit (userConfig) extraGroups initialPassword hashedPassword isNormalUser password; + } + ) cfg; + # Configure home-manager with auto-imported user configuration home-manager = { useGlobalPkgs = true; useUserPackages = true; extraSpecialArgs = { - inherit self system; + inherit self; namespace = self.namespace; }; - users = - lib.mapAttrs ( - username: userConfig: - mkIf (userConfig.enable && homeConfigExists username) ( - {osConfig, ...}: { - # Import user home configuration and general home modules - imports = [(getHomeConfigPath username)] ++ homeModules; + users = lib.mapAttrs (username: userConfig: + mkIf (userConfig.enable && homeConfigExists username) ( + { ... }: { + imports = [ + (getHomeConfigPath username) # Import the user's specific home configuration + ]; #++ homeModules; # Include all generalized home modules - home.stateVersion = lib.mkDefault osConfig.system.stateVersion; - } - ) + home.stateVersion = lib.mkDefault config.system.stateVersion; + } ) - cfg; + ) cfg; }; }; } diff --git a/modules/nixos/utils/vm/default.nix b/modules/nixos/utils/vm/default.nix new file mode 100644 index 0000000..5a72bbb --- /dev/null +++ b/modules/nixos/utils/vm/default.nix @@ -0,0 +1,26 @@ +{ + lib, + config, + self, + ... +}: let + inherit (lib) mkIf; + inherit (self) namespace; + + cfg = config.${namespace}.utils.vm; +in { + options.${namespace}.utils.vm = { + enable = self.lib.mkBool true "Whether to enable custom vm presets"; + preset = self.lib.mkOpt lib.types.str "performance" "Specify the prefered vm settings preset: performance, balance or powersave"; + }; + + config = mkIf cfg.enable { + virtualisation.vmVariant = { + virtualisation = { + cores = 6; + memorySize = 4096; + graphics = true; + }; + }; + }; +} diff --git a/systems/x86_64-nixos/puzzlevision/default.nix b/systems/x86_64-nixos/puzzlevision/default.nix index dcde7a3..af76b22 100644 --- a/systems/x86_64-nixos/puzzlevision/default.nix +++ b/systems/x86_64-nixos/puzzlevision/default.nix @@ -1,43 +1,30 @@ -{pkgs, ...}: { +{ + pkgs, + ... +}: { imports = [ ./hardware.nix ]; puzzlevision = { - users.cyn = { - enable = true; - password = "cynical"; # For testing only, replace with sops secret before production use - extraGroups = ["wheel"]; + # TODO: improve home-manager configuration loading as development continues and make sure everything works correctly. + users = { + jo = { + enable = true; + initialPassword = "balls"; + extraGroups = [ "wheel" ]; + }; }; - users.jo = { - enable = true; - password = "jo"; # For testing only, replace with sops secret before production use - extraGroups = ["wheel"]; - }; - - archetypes.workstation.enable = true; + desktop.gnome.enable = true; + utils.vm.enable = true; + common.grub.enable = true; }; - # Configure 8GB SWAP partition - swapDevices = [ - { - device = "/swapfile"; - size = 8 * 1024; - } + environment.systemPackages = with pkgs; [ + ghostty + firefox ]; - boot = { - # Configure additional kernel modules. - extraModulePackages = [ - pkgs.linuxPackages_latest.rtl8821ce # Use custom network-card driver. - ]; - - blacklistedKernelModules = [ - "rtw88_8821ce" # Block the default network-card driver. - ]; - }; - - networking.hostName = "puzzlevision"; system.stateVersion = "25.05"; }