diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e370078 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +result/ +result diff --git a/artifacts.nix b/artifacts.nix new file mode 100644 index 0000000..cf1bcea --- /dev/null +++ b/artifacts.nix @@ -0,0 +1,73 @@ +{ inputs, hosts, self, system }: +let + nixpkgs = inputs.nixpkgs; + lib = nixpkgs.lib; + nixos-generators = inputs.nixos-generators; + + mkInstaller = hostName: + let + targetConfig = self.nixosConfigurations.${hostName}.config; + targetSystem = targetConfig.system.build.toplevel; + diskoScript = targetConfig.system.build.diskoScript; + in + nixpkgs.lib.nixosSystem { + inherit system; + specialArgs = { + inherit inputs hostName targetSystem diskoScript; + hostPlatform = system; + }; + modules = [ + "${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix" + inputs.disko.nixosModules.disko + ./installer/auto-install.nix + ]; + }; + + mkGenerator = hostName: format: + nixos-generators.nixosGenerate { + inherit system; + specialArgs = { inherit inputs; }; + modules = hosts.modules.${hostName} ++ [ + { + disko.enableConfig = lib.mkForce false; + services.upower.enable = lib.mkForce false; + } + ]; + inherit format; + }; + + hostNames = builtins.attrNames hosts.nixosConfigurations; + + installerPackages = lib.listToAttrs (lib.concatMap (name: + let cfg = hosts.nixosConfigurations.${name}; in + if lib.elem "iso" cfg.config.host.buildMethods then [{ + name = "installer-iso-${name}"; + value = (mkInstaller name).config.system.build.isoImage; + }] else [] + ) hostNames); + + lxcPackages = lib.listToAttrs (lib.concatMap (name: + let cfg = hosts.nixosConfigurations.${name}; in + if lib.elem "lxc" cfg.config.host.buildMethods then [{ + name = "lxc-${name}"; + value = + if cfg.config.boot.isContainer then + cfg.config.system.build.tarball + else + mkGenerator name "lxc"; + }] else [] + ) hostNames); + + proxmoxPackages = lib.listToAttrs (lib.concatMap (name: + let cfg = hosts.nixosConfigurations.${name}; in + if lib.elem "proxmox" cfg.config.host.buildMethods then [{ + name = "proxmox-${name}"; + value = + if cfg.config.boot.isContainer then + cfg.config.system.build.tarball + else + mkGenerator name "proxmox"; + }] else [] + ) hostNames); +in +installerPackages // lxcPackages // proxmoxPackages diff --git a/flake.lock b/flake.lock index 9bdfa28..5fecac2 100644 --- a/flake.lock +++ b/flake.lock @@ -284,6 +284,42 @@ "type": "github" } }, + "nixlib": { + "locked": { + "lastModified": 1736643958, + "narHash": "sha256-tmpqTSWVRJVhpvfSN9KXBvKEXplrwKnSZNAoNPf/S/s=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "1418bc28a52126761c02dd3d89b2d8ca0f521181", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixos-generators": { + "inputs": { + "nixlib": "nixlib", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1764234087, + "narHash": "sha256-NHF7QWa0ZPT8hsJrvijREW3+nifmF2rTXgS2v0tpcEA=", + "owner": "nix-community", + "repo": "nixos-generators", + "rev": "032a1878682fafe829edfcf5fdfad635a2efe748", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixos-generators", + "type": "github" + } + }, "nixos-hardware": { "locked": { "lastModified": 1764440730, @@ -409,6 +445,7 @@ "disko": "disko", "home-manager": "home-manager", "lazyvim-nixvim": "lazyvim-nixvim", + "nixos-generators": "nixos-generators", "nixos-hardware": "nixos-hardware", "nixpkgs": "nixpkgs_2", "nixpkgs-old-kernel": "nixpkgs-old-kernel", diff --git a/flake.nix b/flake.nix index 40e4e0d..7239249 100644 --- a/flake.nix +++ b/flake.nix @@ -36,6 +36,12 @@ url = "github:nix-community/nixos-vscode-server"; inputs.nixpkgs.follows = "nixpkgs"; }; + + # NixOS Generators for creating ISOs, LXC, etc. + nixos-generators = { + url = "github:nix-community/nixos-generators"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; outputs = inputs@{ @@ -47,13 +53,22 @@ lazyvim-nixvim, nixos-hardware, vscode-server, + nixos-generators, ... }: + let + hosts = import ./hosts { inherit inputs; }; + system = "x86_64-linux"; + in { # Formatter for 'nix fmt' formatter.x86_64-linux = nixpkgs.legacyPackages.x86_64-linux.nixfmt-rfc-style; # Generate NixOS configurations from hosts/default.nix - nixosConfigurations = import ./hosts { inherit inputs; }; + nixosConfigurations = hosts.nixosConfigurations; + + packages.${system} = import ./artifacts.nix { + inherit inputs hosts self system; + }; }; } diff --git a/hosts/boot.nix b/hosts/boot.nix index 77cb2cd..8001fc8 100644 --- a/hosts/boot.nix +++ b/hosts/boot.nix @@ -23,6 +23,11 @@ description = "The size of the swap partition."; }; }; + buildMethods = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ "iso" ]; + description = "List of allowed build methods (iso, lxc, proxmox)."; + }; }; config = { diff --git a/hosts/default.nix b/hosts/default.nix index 0bfe0ae..1fcd511 100644 --- a/hosts/default.nix +++ b/hosts/default.nix @@ -69,11 +69,20 @@ let { } ) accounts; in - lib.nixosSystem { - inherit system; + { + system = lib.nixosSystem { + inherit system; - specialArgs = { inherit inputs; }; + specialArgs = { inherit inputs; }; + modules = + commonModules + ++ userFlakeModules + ++ extraModules + ++ [ + { networking.hostName = hostName; } + ]; + }; modules = commonModules ++ userFlakeModules @@ -122,17 +131,19 @@ let "flakeUrl" "hostname" "modules" + "buildMethods" ]; extraConfig = lib.removeAttrs devConf [ "extraUsers" "flakeUrl" "hostname" + "buildMethods" ]; in - lib.mkIf hasOverride (lib.recursiveUpdate { + lib.mkIf hasOverride (lib.recursiveUpdate (lib.recursiveUpdate { host.filesystem = fsConf; modules.users.enabledUsers = devConf.extraUsers or [ ]; - } extraConfig); + } (lib.optionalAttrs (devConf ? buildMethods) { host.buildMethods = devConf.buildMethods; })) extraConfig); config = mkHost { hostName = hostName; @@ -170,5 +181,9 @@ let } ) hosts; + allHosts = lib.foldl' lib.recursiveUpdate { } hostGroups; in -lib.foldl' lib.recursiveUpdate { } hostGroups +{ + nixosConfigurations = lib.mapAttrs (n: v: v.system) allHosts; + modules = lib.mapAttrs (n: v: v.modules) allHosts; +} diff --git a/hosts/types/nix-laptop.nix b/hosts/types/nix-laptop.nix index 84f697d..2478a27 100644 --- a/hosts/types/nix-laptop.nix +++ b/hosts/types/nix-laptop.nix @@ -39,7 +39,7 @@ host.filesystem.swapSize = lib.mkDefault "34G"; # Suspend / logind behavior - services.upower.enable = true; + services.upower.enable = lib.mkDefault true; services.logind.settings = { Login = { HandleLidSwitch = "suspend"; diff --git a/hosts/types/nix-lxc.nix b/hosts/types/nix-lxc.nix index 0f43597..f651060 100644 --- a/hosts/types/nix-lxc.nix +++ b/hosts/types/nix-lxc.nix @@ -35,6 +35,7 @@ ]; services.vscode-server.enable = true; system.stateVersion = "25.11"; + host.buildMethods = lib.mkDefault [ "lxc" "proxmox" ]; } ) { diff --git a/installer/auto-install.nix b/installer/auto-install.nix new file mode 100644 index 0000000..bb152a6 --- /dev/null +++ b/installer/auto-install.nix @@ -0,0 +1,47 @@ +{ config, lib, pkgs, inputs, hostName, hostPlatform, targetSystem, diskoScript, ... }: +{ + environment.systemPackages = [ + pkgs.git + pkgs.bashInteractive + pkgs.curl + targetSystem + ]; + + # Enable networking + networking.hostName = "autoinstaller-${hostName}"; + networking.networkmanager.enable = lib.mkForce false; + networking.wireless = { + enable = true; + networks = { + "IOT_sensors".psk = "aaaaaaaa"; + }; + }; + nixpkgs.hostPlatform = hostPlatform; + + systemd.services.auto-install = { + description = "Automatic NixOS install for ${hostName}"; + after = [ "network-online.target" "systemd-udev-settle.service" ]; + wants = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + Type = "oneshot"; + StandardOutput = "journal+console"; + StandardError = "journal+console"; + Environment = "PATH=/run/current-system/sw/bin"; + }; + + script = '' + echo "=== AUTO INSTALL START for ${hostName} ===" + + echo ">>> Running disko script..." + ${diskoScript} + + echo ">>> Running nixos-install..." + nixos-install --no-root-passwd --system ${targetSystem} + + echo ">>> Done. Rebooting." + systemctl reboot + ''; + }; +}