diff --git a/.sops.yaml b/.sops.yaml index 1f12d95..25b1f02 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -1,7 +1,9 @@ keys: - &sv1 age1zr5m64rzl8r5pk5cnwcfycc8ze09lx4xqa6s0cpkf24gwwxxpy2sltfsug + - &dk1 age14x7k4stulqyp849x3uksprk2w3vjyn6pjlvgrp6up3tem6g6xucqvms68t creation_rules: - path_regex: library/secrets/.*.yaml key_groups: - age: - *sv1 + - *dk1 diff --git a/applications/default.nix b/applications/default.nix index 7051552..0e3bb3e 100644 --- a/applications/default.nix +++ b/applications/default.nix @@ -1,2 +1,4 @@ {pkgs}: { + write-iso = pkgs.callPackage ./write-iso.nix {}; + install-remote = pkgs.callPackage ./install-remote.nix {}; } diff --git a/applications/install-remote.nix b/applications/install-remote.nix new file mode 100644 index 0000000..1f3bd82 --- /dev/null +++ b/applications/install-remote.nix @@ -0,0 +1,4 @@ +{remote-installer}: { + type = "app"; + program = "${remote-installer}/bin/remote-installer"; +} diff --git a/applications/write-iso.nix b/applications/write-iso.nix new file mode 100644 index 0000000..586ea22 --- /dev/null +++ b/applications/write-iso.nix @@ -0,0 +1,4 @@ +{iso-writer}: { + type = "app"; + program = "${iso-writer}/bin/iso-writer"; +} diff --git a/configurations/default.nix b/configurations/default.nix index 6a710f0..e6d7ff9 100644 --- a/configurations/default.nix +++ b/configurations/default.nix @@ -1,4 +1,5 @@ {lib}: { sv1 = lib.callFragment ./sv1.nix {}; dk1 = lib.callFragment ./dk1.nix {}; + dk1-iso = lib.callFragment ./dk1-iso.nix {}; } diff --git a/configurations/dk1-iso.nix b/configurations/dk1-iso.nix new file mode 100644 index 0000000..77c02d4 --- /dev/null +++ b/configurations/dk1-iso.nix @@ -0,0 +1,9 @@ +{ + nixosSystem, + nixosSystems, + nixosModules, +}: +nixosSystem { + system = nixosSystems.x86_64-linux; + modules = [nixosModules.dk1-iso]; +} diff --git a/flake.lock b/flake.lock index 58663ab..82a86ab 100644 --- a/flake.lock +++ b/flake.lock @@ -20,6 +20,27 @@ "type": "github" } }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nixos-anywhere", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1743550720, + "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "c621e8422220273271f52058f618c94e405bb0f5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, "impermanence": { "locked": { "lastModified": 1731242966, @@ -35,7 +56,75 @@ "type": "github" } }, + "nixos-anywhere": { + "inputs": { + "disko": [ + "disko" + ], + "flake-parts": "flake-parts", + "nixos-images": "nixos-images", + "nixos-stable": [ + "nixpkgs" + ], + "nixpkgs": "nixpkgs", + "treefmt-nix": "treefmt-nix" + }, + "locked": { + "lastModified": 1745505025, + "narHash": "sha256-F9IekLaLYVG/UNUiaN194qu0n1pOgeqjGkD1l5OVEgM=", + "owner": "nix-community", + "repo": "nixos-anywhere", + "rev": "edf1adb89307f921575b5fcd0c6bb4e684fbd38b", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixos-anywhere", + "type": "github" + } + }, + "nixos-images": { + "inputs": { + "nixos-stable": [ + "nixos-anywhere", + "nixos-stable" + ], + "nixos-unstable": [ + "nixos-anywhere", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1744853194, + "narHash": "sha256-NBOdBdQdxb3FdM4Ywb4cATMLfFtkPqDYh0LIQMZ7eRY=", + "owner": "nix-community", + "repo": "nixos-images", + "rev": "8f6f8060a13096934c2a502eb0508bdc3f1284a1", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixos-images", + "type": "github" + } + }, "nixpkgs": { + "locked": { + "lastModified": 1745991046, + "narHash": "sha256-+WiKX2uUkuWrkUdfy8XP0Lic2qN7h3pH+tWn1DfTfFg=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "920a79ee9b49febd7a8b7251e210aeee9c06b644", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable-small", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { "locked": { "lastModified": 1733261153, "narHash": "sha256-eq51hyiaIwtWo19fPEeE0Zr2s83DYMKJoukNLgGGpek=", @@ -55,7 +144,8 @@ "inputs": { "disko": "disko", "impermanence": "impermanence", - "nixpkgs": "nixpkgs", + "nixos-anywhere": "nixos-anywhere", + "nixpkgs": "nixpkgs_2", "sops-nix": "sops-nix" } }, @@ -78,6 +168,27 @@ "repo": "sops-nix", "type": "github" } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "nixos-anywhere", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1744961264, + "narHash": "sha256-aRmUh0AMwcbdjJHnytg1e5h5ECcaWtIFQa6d9gI85AI=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "8d404a69efe76146368885110f29a2ca3700bee6", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 0cd2c21..d5883fc 100644 --- a/flake.nix +++ b/flake.nix @@ -12,6 +12,13 @@ url = "github:Mic92/sops-nix"; inputs.nixpkgs.follows = "nixpkgs"; }; + nixos-anywhere = { + url = "github:nix-community/nixos-anywhere"; + inputs = { + nixos-stable.follows = "nixpkgs"; + disko.follows = "disko"; + }; + }; }; outputs = { @@ -20,6 +27,7 @@ disko, impermanence, sops-nix, + nixos-anywhere, }: let lib = nixpkgs.lib.extend self.overlays.lib; pkgs = nixpkgs.legacyPackages.x86_64-linux.extend self.overlays.pkgs; @@ -28,7 +36,7 @@ in { overlays = import ./overlays { nixos-config = self // {inherit library;}; - inherit disko impermanence sops-nix; + inherit disko impermanence sops-nix nixos-anywhere; }; nixosConfigurations = import ./configurations {inherit lib;}; nixosModules = import ./modules; diff --git a/library/secrets/default.nix b/library/secrets/default.nix index fc449b3..af7129d 100644 --- a/library/secrets/default.nix +++ b/library/secrets/default.nix @@ -1,3 +1,5 @@ { sb1 = ./sb1.yaml; + network-manager = ./network-manager.yaml; + users = ./users.yaml; } diff --git a/library/secrets/network-manager.yaml b/library/secrets/network-manager.yaml new file mode 100644 index 0000000..2a4a581 --- /dev/null +++ b/library/secrets/network-manager.yaml @@ -0,0 +1,31 @@ +home-ssid: ENC[AES256_GCM,data:zi9AkDx7lInM8Qpn,iv:/ivnuq0L2fc8UQZtjlw073EbzslN+GBl4dYOZm+MYQQ=,tag:X9MztKFvdG1aKuYMa94h8w==,type:str] +home-psk: ENC[AES256_GCM,data:GEY/+0imm1o=,iv:FsUyy479GQ+PfXwdEvXqX1qPcRcYKGIiMCyTf7wYVTs=,tag:2d7LtoiRrF0NhwKhfYQnkA==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1zr5m64rzl8r5pk5cnwcfycc8ze09lx4xqa6s0cpkf24gwwxxpy2sltfsug + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByRDNtR1huOVJ6clNycERp + M0R0SnM2RUVCVXFFWWUrdnZzVHVIS1luZkEwCkUrVHpjTWlPdmZJRXQ2M2xGdzBn + OTVlcDRFdzZsUlRFVE1Vd1VFKy81R00KLS0tIFRSNHowK3E0UGZlYzk1RW5HR2tV + bWNYUG16QTZ1b3RHWThPcm5vdUpGenMKs7xWFe70u3ochn51t7uGITG/oHRDC4v5 + LJIl5LBauwkJO3ddZqPnc57ci2lXukM8Z4EKi3QwYiJ6dxxtizTAng== + -----END AGE ENCRYPTED FILE----- + - recipient: age14x7k4stulqyp849x3uksprk2w3vjyn6pjlvgrp6up3tem6g6xucqvms68t + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHbG9VZDBvM3k2Z0pFMTNO + ZHQ2UUtMWnJhVGY2M256L2lEbVpLUFM4R0V3ClhCNUV1b0ZEQkhaRklMenpyRzJq + Ym95Y21BUHpacXhFcnhwY2FwMUMzQ2MKLS0tIDRuY2FnbVEzQ295R3JqUnk0NjVC + enEyWkRVT014Vk1FTktmVU5kbjVaUTAKJKIIMjBDLJxXv6y9nIzirH5vaqkQyZ6a + pF45ayqxXOAdonrnn0hbyxW8NcKp0Jjy0ehTd6AfAnNCrxPomPbflw== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-04-27T13:55:15Z" + mac: ENC[AES256_GCM,data:sV9QVvQTeHAqPVluN+RHyUXI9zmMw3P6ok1VQ+XHnOcJb4GSWkUdOmWT4XcAMWUSPKEIbexei97rfj46BMT+2VbJS414buoOxvKSx17UVEdFwlXGVIv3jvmyrfp3jd66gSYzznJe8wBakbdKWCHb5kLnF4tqGpdgKprAxwaYnlU=,iv:wEk4qVEF20OZzdjRCRjMzZgipI76hIew39GF/dknKr4=,tag:jJU5JBHsElMxgIgANDcuJg==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.8.1 diff --git a/library/secrets/sb1.yaml b/library/secrets/sb1.yaml index 52ba84f..5b39d52 100644 --- a/library/secrets/sb1.yaml +++ b/library/secrets/sb1.yaml @@ -9,11 +9,20 @@ sops: - recipient: age1zr5m64rzl8r5pk5cnwcfycc8ze09lx4xqa6s0cpkf24gwwxxpy2sltfsug enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFdlpSYXhOdndtS0Y0QTRz - N2pxczhIQVBWSnV1dnY3WDVVRlErYnh4OWdnClRUSjVXeWMrTmxWVEVGT0V6YUMr - V2ovSVhpcmRIN3ljWUx0cmJnSnBzMzAKLS0tIHBNalN3emcrbjZZcytoVFgyQTh2 - elREcXRxeGdVTW1TZGtKelVURkdlWW8KSWpXIAL0Vb1a3un8WIcjMNbIbR41VcK2 - 604AZYjooB6OzX2sOkGOOAIvB17S2nesL/nQUobWkM8bQSuH/TgR5g== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwZWllVjN5TE1YUENueFFo + NVZDbXc5cEFBZ25PaVVRYWtGN3ZuMDI3cVhnCmRSM0g3SzU3dWZueGF2dGZYa01z + OFFuMVFIbFdRUkFGaDcyWThnME56cW8KLS0tIFkxanBHUEdOOEJ1cXppSmhDUUdC + czExSmg1YWo4YlZQM0plSG5vNnpsR28KQ8v96L/EcZmyBFnKjhJPsgN6miKdWHGt + 61KwpMn8g89+f+QdFfji4NkJfteeLsnHMG+JKzoetVB05Xp+cDwfmg== + -----END AGE ENCRYPTED FILE----- + - recipient: age14x7k4stulqyp849x3uksprk2w3vjyn6pjlvgrp6up3tem6g6xucqvms68t + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkQ2d2ZVlpTG5NTnZ0RHYx + WDVyMlkvVHdhNCtPSFluSHVQSW4yM1dhdmc0CktUazdwK1J1ME1CZERnZlRDM25p + bFczQ2hUYWY5YVZ0TTU3R2FLSHk4RkEKLS0tIGJBVkEwcDk4MjdJL3FMVnVXd0ZO + YS9pM3VKcTlTSVArK1B3ZHZnRzhvQW8KfdvpHYMWHkTaprrB1WgRIBHzQnaWeKmp + Rx6xKwOeTaIS4g62Lv9M9uHJzaVD2v22Q53MNeHOPS+47D7XBrstrA== -----END AGE ENCRYPTED FILE----- lastmodified: "2025-01-01T22:35:24Z" mac: ENC[AES256_GCM,data:PH0lfE79d1ZuE0YyMZuWhpZNu1OHh+9JMNbr66RJoRRPpLa134Y6mQE+PzZXOZ0PR2mT+VOrkNhNRhzEhr79oScM0d3ahBfKVY8VcNpvP34Llb9PQWPAZpQ5moa9o6g850bLrXl3XolLPEMpZg4BVa5EzFjo9BXNbuSY/zoW2x0=,iv:my+mb+qbjDs3iHdmaEptylgHbNu7a6zwHx2NEhlwi1Q=,tag:YfEYhl4QOulNbKALLB8ylg==,type:str] diff --git a/library/secrets/users.yaml b/library/secrets/users.yaml new file mode 100644 index 0000000..11d0db8 --- /dev/null +++ b/library/secrets/users.yaml @@ -0,0 +1,31 @@ +root-password: ENC[AES256_GCM,data:SaK/GlzszoYqf1l+fxqXe24ipAhU6xicqwXjTeeABIag4ZOqc6fYp6h1faPDOzNqfKX0D2wrWVahTcZ5eJM8Jc3mi8AJi9VrLg==,iv:no4IU8AolKrvuTediCOQgrJkuRX4BInmVnRLER3QVjI=,tag:l2zWu7ieqiT9dsjVe80T4g==,type:str] +user-password: ENC[AES256_GCM,data:0kN3tnoZ2OD1YO/xz9WnvJixShopigtDGVnvaTRvib2vkO7pMl2Jlg5WIFo37Bb3zwWw0OkIiA2exXcBiSRJiIxmoWR8mmBI4Q==,iv:qHbE6GqJPUHTUgMd/ty+clg5roJLswoCw2xO5M1KKqo=,tag:85KUx5wrd9SnRITsUAMUPg==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1zr5m64rzl8r5pk5cnwcfycc8ze09lx4xqa6s0cpkf24gwwxxpy2sltfsug + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBveHVjN2EwYjgrc2FLRVpL + cVBUNStRRkI2RnpBb3YzZUx6dnpJUHhiamwwCkJ1L3lubWZ3Y0YyWXNQWmJkMjhL + TkxTejRWUWIzajBNcFBqSnJBQ1BFL2cKLS0tIEl0TllEcStwTWF0NngxWVM1cUdI + M2E5TG56S3FMaFVhUG5JQmw2SWpKQjAKNmddLTfypjo3wU84jOsCQULX5cmUunWt + WM712sCFeJShWTA47zBg9um4+dWhY+QungDiuJO2+zoj6UMuE31vew== + -----END AGE ENCRYPTED FILE----- + - recipient: age14x7k4stulqyp849x3uksprk2w3vjyn6pjlvgrp6up3tem6g6xucqvms68t + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5cUFWeDJ2L1lWazE1eFZC + MEZSQmRiNDhuY0VvWStMUkUrQ0Z0V1BrYVdZCitFTDB4d2ZWVE5lLzhMbWFVSFZ3 + RkdxTzlYQkRyclFFclhnRXdqa1o3Z0kKLS0tIEFmNUFTWkl4K3dtTWhJK2ptWXpJ + NUdwczNJNDVEQkk5cnl4Mmh3UGMra1EKFEIbff+6kGo67KCd1Dj+dRaqlfM5Rmi5 + MiYibYIb5Ff47HG/uEA/u5nt/DHE8yUGeBldbJoqE92arA18st8dgg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-04-27T13:58:51Z" + mac: ENC[AES256_GCM,data:uMCeMLYJrfAHQ037NZKmXTuPuZnSU1GOCFMsVE/xjGBkZnXJ4yYh3Fec3ncyuD0HWHgEeFGh4lRi3YNu6nkiK2R/mCrIrm4A3Ry0k0yGjam6Q8dfigaV9RkmMf50bV+JA6j03G5pxfyrBq5OTSWohYSmsvOTJXRKvIJalxfn+f0=,iv:AUcoar5Ls3qLtcg6WkHjElYefwsHN2GNKIMinvF0bps=,tag:qDCpTXRMsjS8880csWRTpw==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.8.1 diff --git a/modules/default.nix b/modules/default.nix index 329cc50..bbc334a 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -1,4 +1,5 @@ { sv1 = import ./sv1.nix; dk1 = import ./dk1.nix; + dk1-iso = import ./dk1-iso.nix; } diff --git a/modules/dk1-iso.nix b/modules/dk1-iso.nix new file mode 100644 index 0000000..fbd8b73 --- /dev/null +++ b/modules/dk1-iso.nix @@ -0,0 +1,133 @@ +{ + lib, + config, + pkgs, + modulesPath, + ... +}: { + imports = with lib.nixosModules; [ + (modulesPath + "/installer/cd-dvd/installation-cd-minimal.nix") + sops + ]; + + sops = { + gnupg.sshKeyPaths = []; + age = { + sshKeyPaths = []; + keyFile = "/iso/key"; + }; + secrets = { + root-password = { + sopsFile = lib.secrets.users; + neededForUsers = true; + }; + user-password = { + sopsFile = lib.secrets.users; + neededForUsers = true; + }; + home-ssid.sopsFile = lib.secrets.network-manager; + home-psk.sopsFile = lib.secrets.network-manager; + }; + templates.network-manager.content = '' + home_ssid="${config.sops.placeholder.home-ssid}" + home_psk="${config.sops.placeholder.home-psk}" + ''; + }; + + boot.extraModulePackages = with config.boot.kernelPackages; [ + rtl88xxau-aircrack + ]; + + networking = { + hostName = "dk1-iso"; + wireless.enable = false; + networkmanager = { + enable = true; + ensureProfiles = { + profiles.home = { + connection = { + id = "home"; + type = "wifi"; + }; + ipv4 = { + method = "manual"; + address1 = "192.168.0.200/24"; + gateway = "192.168.0.1"; + dns = "192.168.0.1"; + }; + wifi = { + ssid = "$home_ssid"; + mode = "infrastructure"; + }; + wifi-security = { + auth-alg = "open"; + key-mgmt = "wpa-psk"; + psk = "$home_psk"; + }; + }; + environmentFiles = [config.sops.templates.network-manager.path]; + }; + }; + }; + + time.timeZone = "Europe/London"; + i18n.defaultLocale = "en_GB.UTF-8"; + console.keyMap = "uk"; + + users = { + mutableUsers = false; + users = { + root = { + isSystemUser = true; + hashedPassword = null; + hashedPasswordFile = config.sops.secrets.root-password.path; + openssh.authorizedKeys.keys = with lib.sshKeys; [ + lp1.user + lp2.user + ]; + }; + user = { + isNormalUser = true; + extraGroups = ["wheel"]; + hashedPassword = null; + hashedPasswordFile = config.sops.secrets.user-password.path; + openssh.authorizedKeys.keys = with lib.sshKeys; [ + lp1.user + lp2.user + ]; + }; + nixos = { + hashedPassword = null; + hashedPasswordFile = config.sops.secrets.user-password.path; + }; + }; + }; + + services = { + openssh = { + enable = true; + settings.PermitRootLogin = lib.mkForce "without-password"; + }; + getty = { + helpLine = lib.mkForce ""; + autologinUser = lib.mkForce null; + }; + }; + + nixpkgs.overlays = [lib.overlays.pkgs]; + environment.systemPackages = with pkgs; [ + git + my-vim + nixos-anywhere + ]; + + nix.settings = { + trusted-users = ["root"]; + experimental-features = [ + "nix-command" + "flakes" + ]; + }; + + system.stateVersion = "24.11"; +} diff --git a/modules/dk1.nix b/modules/dk1.nix index f716a1e..aef97d3 100644 --- a/modules/dk1.nix +++ b/modules/dk1.nix @@ -7,7 +7,7 @@ imports = with lib.nixosModules; [disko]; disko.devices.disk.NixOS = { - device = "/dev/"; + device = "/dev/nvme0n1"; type = "disk"; content = { type = "gpt"; @@ -44,7 +44,10 @@ efiSupport = true; device = "nodev"; }; - efi.efiSysMountPoint = "/efi"; + efi = { + canTouchEfiVariables = true; + efiSysMountPoint = "/efi"; + }; }; extraModulePackages = with config.boot.kernelPackages; [rtl88xxau-aircrack]; }; @@ -73,7 +76,7 @@ }; }; - nixpkgs.overlays = with lib.overlays; [pkgs]; + nixpkgs.overlays = [lib.overlays.pkgs]; environment.systemPackages = with pkgs; [ git my-vim diff --git a/overlays/default.nix b/overlays/default.nix index 3abf2f3..a571873 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -3,7 +3,8 @@ disko, impermanence, sops-nix, + nixos-anywhere, }: { lib = import ./lib.nix {inherit nixos-config disko impermanence sops-nix;}; - pkgs = import ./pkgs.nix {inherit nixos-config;}; + pkgs = import ./pkgs.nix {inherit nixos-config nixos-anywhere;}; } diff --git a/overlays/lib.nix b/overlays/lib.nix index 744af5d..d23eb29 100644 --- a/overlays/lib.nix +++ b/overlays/lib.nix @@ -4,13 +4,13 @@ impermanence, sops-nix, }: final: prev: let - inherit (nixos-config) overlays library; + inherit (nixos-config) library overlays nixosConfigurations nixosModules; in library - // {inherit overlays;} + // {inherit overlays nixosConfigurations;} // { nixosModules = - nixos-config.nixosModules + nixosModules // disko.nixosModules // sops-nix.nixosModules // impermanence.nixosModules; diff --git a/overlays/pkgs.nix b/overlays/pkgs.nix index 43cc01d..ff80026 100644 --- a/overlays/pkgs.nix +++ b/overlays/pkgs.nix @@ -1,4 +1,11 @@ -{nixos-config}: final: prev: let +{ + nixos-config, + nixos-anywhere, +}: final: prev: let inherit (nixos-config) overlays packages; in - packages.x86_64-linux // {lib = prev.lib.extend overlays.lib;} + packages.x86_64-linux + // { + lib = prev.lib.extend overlays.lib; + inherit (nixos-anywhere.packages.x86_64-linux) nixos-anywhere; + } diff --git a/packages/default.nix b/packages/default.nix index aad8295..d1ddc20 100644 --- a/packages/default.nix +++ b/packages/default.nix @@ -1,4 +1,7 @@ {pkgs}: { my-vim = pkgs.callPackage ./my-vim {}; my-site = pkgs.callPackage ./my-site {}; + iso-writer = pkgs.callPackage ./iso-writer {}; + dk1-iso = pkgs.callPackage ./dk1-iso {}; + remote-installer = pkgs.callPackage ./remote-installer {}; } diff --git a/packages/dk1-iso/default.nix b/packages/dk1-iso/default.nix new file mode 100644 index 0000000..56bb5f0 --- /dev/null +++ b/packages/dk1-iso/default.nix @@ -0,0 +1,4 @@ +{lib}: let + inherit (lib.nixosConfigurations) dk1-iso; +in + dk1-iso.config.system.build.isoImage diff --git a/packages/iso-writer/default.nix b/packages/iso-writer/default.nix new file mode 100644 index 0000000..ce166e1 --- /dev/null +++ b/packages/iso-writer/default.nix @@ -0,0 +1,30 @@ +{ + lib, + stdenvNoCC, + makeWrapper, + coreutils, + xorriso, + dk1-iso, +}: let + inherit (lib) makeBinPath; + runtimeInputs = [ + coreutils + xorriso + ]; +in + stdenvNoCC.mkDerivation { + name = "iso-writer"; + src = ./src; + nativeBuildInputs = [makeWrapper]; + buildInputs = runtimeInputs; + installPhase = '' + mkdir -p $out/bin + cp $src/iso-writer.sh $out/bin/iso-writer + chmod +x $out/bin/iso-writer + ''; + postFixup = '' + wrapProgram $out/bin/iso-writer \ + --set PATH ${makeBinPath runtimeInputs} \ + --set source ${dk1-iso}/iso/${dk1-iso.isoName} + ''; + } diff --git a/packages/iso-writer/src/iso-writer.sh b/packages/iso-writer/src/iso-writer.sh new file mode 100644 index 0000000..0d6f545 --- /dev/null +++ b/packages/iso-writer/src/iso-writer.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +read -a arguments <<< "$@" +number_of_arguments="${#arguments[@]}" +arguments_last_index="$(expr $number_of_arguments - 1)" +for argument_index in $(seq 0 "$arguments_last_index") +do + argument="${arguments[argument_index]}" + next_argument_index="$(expr $argument_index + 1)" + next_argument="${arguments[next_argument_index]}" + case "$argument" in + --*) + name="${argument/--/}" + [ "$argument_index" -eq "$arguments_last_index" \ + -o "${next_argument:0:2}" = "--" ] \ + && declare "$name=$name" + ;; + *) + value="$argument" + [ -n "$name" ] \ + && declare "$name=$value" + name="" + ;; + esac +done + +[ -n "$help" ] \ + && printf "Usage: iso-writer" \ + && printf " [--help]" \ + && printf " --source source" \ + && printf " [--key key]" \ + && printf " [--target target]" \ + && printf " --device device" \ + && printf "\n" \ + && printf "Write a keyed nixos-config iso to a device." \ + && printf "\n" \ + && exit + +root_id="0" +[ "$(id -u)" -ne "$root_id" ] \ + && printf "Not running as root, exiting.\n" >&2 \ + && exit +[ -z "$source" ] \ + && printf "Source missing, exiting.\n" >&2 \ + && exit +[ -z "$device" ] \ + && printf "Device missing, exiting.\n" >&2 \ + && exit +[ -z "$key" ] \ + && target="$source" +[ -n "$key" -a -z "$target" ] \ + && temporary_directory="$(mktemp -d)" \ + && target="$temporary_directory/target.iso" \ + && trap "rm -rf \"$target\"" SIGTERM + +[ -n "$key" ] \ + && xorriso \ + -indev "$source" \ + -outdev "$target" \ + -map "$key" /key \ + -boot_image any replay +dd bs=4M status=progress if="$target" of="$device" diff --git a/packages/remote-installer/default.nix b/packages/remote-installer/default.nix new file mode 100644 index 0000000..45bccd8 --- /dev/null +++ b/packages/remote-installer/default.nix @@ -0,0 +1,28 @@ +{ + lib, + stdenvNoCC, + makeWrapper, + coreutils, + nixos-anywhere, +}: let + inherit (lib) makeBinPath; + runtimeInputs = [ + coreutils + nixos-anywhere + ]; +in + stdenvNoCC.mkDerivation { + name = "remote-installer"; + src = ./src; + nativeBuildInputs = [makeWrapper]; + buildInputs = runtimeInputs; + installPhase = '' + mkdir -p $out/bin + cp $src/remote-installer.sh $out/bin/remote-installer + chmod +x $out/bin/remote-installer + ''; + postFixup = '' + wrapProgram $out/bin/remote-installer \ + --set PATH ${makeBinPath runtimeInputs} + ''; + } diff --git a/packages/remote-installer/src/remote-installer.sh b/packages/remote-installer/src/remote-installer.sh new file mode 100644 index 0000000..294bc2e --- /dev/null +++ b/packages/remote-installer/src/remote-installer.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +read -a arguments <<< "$@" +number_of_arguments="${#arguments[@]}" +arguments_last_index="$(expr $number_of_arguments - 1)" +for argument_index in $(seq 0 "$arguments_last_index") +do + argument="${arguments[argument_index]}" + next_argument_index="$(expr $argument_index + 1)" + next_argument="${arguments[next_argument_index]}" + case "$argument" in + --*) + name="${argument/--/}" + [ "$argument_index" -eq "$arguments_last_index" \ + -o "${next_argument:0:2}" = "--" ] \ + && declare "$name=$name" + ;; + *) + value="$argument" + [ -n "$name" ] \ + && declare "$name=$value" + name="" + ;; + esac +done + +[ -n "$help" ] \ + && printf "Usage: remote-installer" \ + && printf " [--help]" \ + && printf "\n" \ + && printf "Install a NixOS configuration remotely." \ + && printf "\n" \ + && exit + +[ -z "$flake_address" ] \ + && protocol="git+https" \ + && gitea="gitea.dylanblades.com" \ + && repository="Bladesy/nixos-config" \ + && flake_address="$protocol://$gitea/$repository" +[ -z "$host_name" ] \ + && printf "host_name not provided.\n" \ + && exit +[ -z "$host_address" ] \ + && printf "host_address not provided.\n" \ + && exit + +nixos-anywhere \ + --disko-mode disko \ + --flake "$flake_address#$host_name" \ + --target-host "root@$host_address"