diff --git a/flake.lock b/flake.lock index ed78e43..2f70da1 100644 --- a/flake.lock +++ b/flake.lock @@ -100,6 +100,27 @@ "type": "github" } }, + "disko": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1736864502, + "narHash": "sha256-ItkIZyebGvNH2dK9jVGzJHGPtb6BSWLN8Gmef16NeY0=", + "owner": "nix-community", + "repo": "disko", + "rev": "0141aabed359f063de7413f80d906e1d98c0c123", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "latest", + "repo": "disko", + "type": "github" + } + }, "firefox-gnome-theme": { "flake": false, "locked": { @@ -880,6 +901,21 @@ "type": "github" } }, + "impermanence": { + "locked": { + "lastModified": 1737831083, + "narHash": "sha256-LJggUHbpyeDvNagTUrdhe/pRVp4pnS6wVKALS782gRI=", + "owner": "nix-community", + "repo": "impermanence", + "rev": "4b3e914cdf97a5b536a889e939fb2fd2b043a170", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "impermanence", + "type": "github" + } + }, "ixx": { "inputs": { "flake-utils": [ @@ -1289,10 +1325,12 @@ }, "root": { "inputs": { + "disko": "disko", "home-manager": "home-manager", "hyprland": "hyprland", "hyprland-plugins": "hyprland-plugins", "hyprlock": "hyprlock", + "impermanence": "impermanence", "nixd": "nixd", "nixos-hardware": "nixos-hardware", "nixpkgs": "nixpkgs_4", diff --git a/flake.nix b/flake.nix index f6f79a8..19e511c 100644 --- a/flake.nix +++ b/flake.nix @@ -1,47 +1,48 @@ { description = "flake forward setup with two hosts on different architectures"; - outputs = { - self, - nixpkgs, - home-manager, - ... - } @ inputs: let - # args will later be used in outputs to inherit the flake and its inputs for use in modules. - args = {inherit self inputs;}; - # mkSystem lets us repeat the same config for multiple systems, called later in outputs. - mkSystem = hostname: - nixpkgs.lib.nixosSystem { + outputs = + { + self, + nixpkgs, + home-manager, + ... + }@inputs: + let + # args will later be used in outputs to inherit the flake and its inputs for use in modules. + args = { inherit self inputs; }; + # mkSystem lets us repeat the same config for multiple systems, called later in outputs. + mkSystem = + hostname: + nixpkgs.lib.nixosSystem { + specialArgs = args; + modules = [ + ./systems/${hostname}.nix + + home-manager.nixosModules.home-manager + { + home-manager = { + useGlobalPkgs = true; # inherit the nixpkgs and its config + useUserPackages = true; + extraSpecialArgs = args; + users.rafiq.imports = [ + ./users/rafiq.nix + ]; + }; + } + ]; + }; + in + { + # System Configurations + nixosConfigurations.nemesis = mkSystem "nemesis"; + nixosConfigurations.mellinoe = nixpkgs.lib.nixosSystem { specialArgs = args; modules = [ - ./systems/${hostname}.nix - - home-manager.nixosModules.home-manager - { - home-manager = { - useGlobalPkgs = true; # inherit the nixpkgs and its config - useUserPackages = true; - extraSpecialArgs = args; - users.rafiq.imports = [ - ./users/rafiq.nix - ]; - }; - } + ./systems/mellinoe.nix ]; }; - in { - # System Configurations - nixosConfigurations = builtins.listToAttrs [ - { - name = "nemesis"; - value = mkSystem "nemesis"; - } - { - name = "orpheus"; - value = mkSystem "orpheus"; - } - ]; - }; + }; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; @@ -62,5 +63,8 @@ inputs.hyprland.follows = "hyprland"; }; hyprlock.url = "github:hyprwm/hyprlock"; + disko.url = "github:nix-community/disko/latest"; + disko.inputs.nixpkgs.follows = "nixpkgs"; + impermanence.url = "github:nix-community/impermanence"; }; } diff --git a/systems/hw-mellinoe.nix b/systems/hw-mellinoe.nix new file mode 100644 index 0000000..5c20b05 --- /dev/null +++ b/systems/hw-mellinoe.nix @@ -0,0 +1,39 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ + config, + lib, + pkgs, + modulesPath, + ... +}: + +{ + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ + "xhci_pci" + "nvme" + "usb_storage" + "usbhid" + "sd_mod" + "rtsx_pci_sdmmc" + ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.eth0.useDHCP = lib.mkDefault true; + # networking.interfaces.wlp1s0.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/systems/mellinoe.nix b/systems/mellinoe.nix new file mode 100644 index 0000000..a36fa71 --- /dev/null +++ b/systems/mellinoe.nix @@ -0,0 +1,11 @@ +{ + imports = [ + ./hw-mellinoe.nix + ./modules/common.nix + ./modules/desktop.nix + ./modules/bootloaders/systemd-boot.nix + ./modules/hardware/bluetooth.nix + ]; + networking.hostName = "mellinoe"; + system.stateVersion = "24.11"; +} diff --git a/systems/modules/ephemeral-root.nix b/systems/modules/ephemeral-root.nix new file mode 100644 index 0000000..3d8c055 --- /dev/null +++ b/systems/modules/ephemeral-root.nix @@ -0,0 +1,104 @@ +{ inputs, lib, ... }: +{ + imports = [ + inputs.disko.nixosModules.disko + inputs.impermanence.nixosModules.impermanence + ]; + # Disk Partitioning + disko.devices.disk.main = { + device = "/dev/disk/by-id/nvme-eui.01000000000000008ce38e04019a68ab"; + type = "disk"; + content.type = "gpt"; + content.partitions = { + boot = { + name = "boot"; + type = "EF02"; + size = "1M"; + priority = 1; + }; + esp = { + name = "ESP"; + type = "EF00"; + size = "500M"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + swap = { + size = "4G"; + content = { + type = "swap"; + resumeDevice = true; + }; + }; + root = { + name = "root"; + size = "100%"; + content = { + type = "lvm_pv"; + vg = "root_vg"; + }; + }; + }; + }; + + # Logical Volume Set up + disko.devices.lvm_vg.root_vg = { + type = "lvm_vg"; + lvs.root = { + size = "100%FREE"; + content = { + type = "btrfs"; + extraArgs = [ "-f" ]; + subvolumes = { + "/root".mountpoint = "/"; + "/persist".mountpoint = "/persist"; + "/persist".mountOptions = [ + "subvol=persist" + "noatime" + ]; + "/nix".mountpoint = "/nix"; + "/nix".mountOptions = [ + "subvol=nix" + "noatime" + ]; + }; + }; + }; + }; + + # Back up old roots and delete older ones + boot.initrd.postDeviceCommands = lib.mkAfter '' + mkdir /btrfs_tmp + mount /dev/root_vg/root /btrfs_tmp + if [[ -e /btrfs_tmp/root ]]; then + mkdir -p /btrfs_tmp/old_roots + timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%M-%D_%H:%M:%S") + mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp" + fi + + delete_subvolume_recursively() { + IFS=$'\n' + for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do + delete_subvolume_recursively "/btrfs_tmp/$i" + done + btrfs subvolume delete "$1" + } + + for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +30); do + delete_subvolume_recursively "$i" + done + + btrfs subvolume create /btrfs_tmp/root + umount /btrfs_tmp + ''; + + # Directories to persist between boots + fileSystems."/persist".neededForBoot = true; + environment.persistence."/persist" = { + hideMounts = true; + }; +}