From bdf660cc569b8aa8845e51033b5f1e50c8ea327c Mon Sep 17 00:00:00 2001 From: Ray Andrew Date: Sat, 26 Oct 2024 21:07:14 -0500 Subject: [PATCH] use zfs as snapshot (#1) Reviewed-on: https://git.rs.ht/rayandrew/nix-priv/pulls/1 Co-authored-by: Ray Andrew Co-committed-by: Ray Andrew --- README.md | 4 + disko.nix | 96 ----- flake.lock | 21 ++ flake.nix | 72 +++- hardware-configuration.nix | 26 -- home.nix | 347 ------------------ src/home/bash.nix | 16 + src/home/default.nix | 82 +++++ src/home/emacs.nix | 8 + src/home/git.nix | 10 + src/home/gui/1password.nix | 9 + src/home/gui/default.nix | 35 ++ src/home/gui/firefox.nix | 35 ++ src/home/gui/gnome.nix | 78 ++++ src/home/gui/keyd.nix | 20 + src/home/gui/skype.nix | 13 + src/home/gui/slack.nix | 13 + src/home/gui/vscode.nix | 13 + src/home/gui/xdg.nix | 40 ++ src/home/gui/zathura.nix | 8 + src/home/gui/zoom.nix | 16 + src/home/impermanence.nix | 53 +++ src/home/ssh.nix | 13 + src/hosts/default.nix | 65 ++++ .../hosts/pickwick/default.nix | 123 +++---- src/hosts/pickwick/disko.nix | 119 ++++++ src/hosts/pickwick/hardware.nix | 63 ++++ src/hosts/pickwick/home.nix | 59 +++ src/lib.nix | 4 + src/nixos/default.nix | 13 + src/nixos/impermanence.nix | 136 +++++++ src/nixos/users.nix | 36 ++ 32 files changed, 1090 insertions(+), 556 deletions(-) delete mode 100644 disko.nix delete mode 100644 hardware-configuration.nix delete mode 100644 home.nix create mode 100644 src/home/bash.nix create mode 100644 src/home/default.nix create mode 100644 src/home/emacs.nix create mode 100644 src/home/git.nix create mode 100644 src/home/gui/1password.nix create mode 100644 src/home/gui/default.nix create mode 100644 src/home/gui/firefox.nix create mode 100644 src/home/gui/gnome.nix create mode 100644 src/home/gui/keyd.nix create mode 100644 src/home/gui/skype.nix create mode 100644 src/home/gui/slack.nix create mode 100644 src/home/gui/vscode.nix create mode 100644 src/home/gui/xdg.nix create mode 100644 src/home/gui/zathura.nix create mode 100644 src/home/gui/zoom.nix create mode 100644 src/home/impermanence.nix create mode 100644 src/home/ssh.nix create mode 100644 src/hosts/default.nix rename configuration.nix => src/hosts/pickwick/default.nix (57%) create mode 100644 src/hosts/pickwick/disko.nix create mode 100644 src/hosts/pickwick/hardware.nix create mode 100644 src/hosts/pickwick/home.nix create mode 100644 src/lib.nix create mode 100644 src/nixos/default.nix create mode 100644 src/nixos/impermanence.nix create mode 100644 src/nixos/users.nix diff --git a/README.md b/README.md index e8ae5ca..5073578 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,8 @@ +``` +sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode disko /tmp/nix-priv/src/hosts/pickwick/disko.nix +``` + - https://github.com/iynaix/dotfiles/blob/13c2fcec880d292726f52be1075277d521caf3a7/nixos/zfs.nix - https://github.com/iynaix/dotfiles/blob/13c2fcec880d292726f52be1075277d521caf3a7/nixos/impermanence.nix#L69 - https://github.com/maydayv7/dotfiles diff --git a/disko.nix b/disko.nix deleted file mode 100644 index 4c2301c..0000000 --- a/disko.nix +++ /dev/null @@ -1,96 +0,0 @@ -{ - device ? throw "Set this to your disk device, e.g. /dev/sda", - ... -}: -{ - disko.devices = { - nodev = { - "/" = { - fsType = "tmpfs"; - mountOptions = [ - "defaults" - "size=8G" - "mode=755" - ]; - }; - }; - - disk.main = { - type = "disk"; - inherit device; - - content = { - type = "gpt"; - partitions = { - boot = { - name = "boot"; - size = "1M"; - type = "EF02"; - }; - esp = { - priority = 1; - size = "512M"; - type = "EF00"; - content = { - type = "filesystem"; - format = "vfat"; - mountpoint = "/boot"; - mountOptions = [ - "defaults" - "umask=0077" - ]; - }; - }; - - luks = { - size = "100%"; - content = { - type = "luks"; - name = "crypted"; - settings = { - allowDiscards = true; - }; - content = { - type = "lvm_pv"; - vg = "pool"; - }; - }; - }; - }; - }; - }; - - lvm_vg = { - pool = { - type = "lvm_vg"; - lvs = { - root = { - size = "100%FREE"; - content = { - type = "btrfs"; - extraArgs = ["-f"]; - - subvolumes = { - "/persist" = { - mountOptions = ["subvol=persist" "compress=zstd" "noatime"]; - mountpoint = "/persist"; - }; - - "/nix" = { - mountOptions = ["subvol=nix" "compress=zstd" "noatime"]; - mountpoint = "/nix"; - }; - - "/swap" = { - mountpoint = "/swap"; - mountOptions = ["noatime"]; - swap.swapfile.size = "108G"; - }; - }; - }; - }; - }; - }; - }; - }; -} diff --git a/flake.lock b/flake.lock index ef81198..a4c1454 100644 --- a/flake.lock +++ b/flake.lock @@ -55,6 +55,26 @@ "type": "github" } }, + "nix-index-database": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1729394935, + "narHash": "sha256-2ntUG+NJKdfhlrh/tF+jOU0fOesO7lm5ZZVSYitsvH8=", + "owner": "nix-community", + "repo": "nix-index-database", + "rev": "04f8a11f247ba00263b060fbcdc95484fd046104", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-index-database", + "type": "github" + } + }, "nixos-hardware": { "locked": { "lastModified": 1729742320, @@ -92,6 +112,7 @@ "disko": "disko", "home-manager": "home-manager", "impermanence": "impermanence", + "nix-index-database": "nix-index-database", "nixos-hardware": "nixos-hardware", "nixpkgs": "nixpkgs" } diff --git a/flake.nix b/flake.nix index 82d1f01..60e2591 100644 --- a/flake.nix +++ b/flake.nix @@ -9,21 +9,65 @@ home-manager.url = "github:nix-community/home-manager"; home-manager.inputs.nixpkgs.follows = "nixpkgs"; nixos-hardware.url = "github:NixOS/nixos-hardware/master"; + nix-index-database.url = "github:nix-community/nix-index-database"; + nix-index-database.inputs.nixpkgs.follows = "nixpkgs"; }; - outputs = {nixpkgs, ...} @ inputs: - { - nixosConfigurations.pickwick = nixpkgs.lib.nixosSystem { - specialArgs = { inherit inputs; }; - modules = [ - inputs.disko.nixosModules.default - (import ./disko.nix { device = "/dev/nvme0n1"; }) - - ./configuration.nix - - inputs.home-manager.nixosModules.default - inputs.impermanence.nixosModules.impermanence - ]; + outputs = + inputs@{ nixpkgs, self, ... }: + let + system = "x86_64-linux"; + pkgs = import inputs.nixpkgs { + inherit system; + config.allowUnfree = true; + }; + lib = import ./src/lib.nix { + inherit (nixpkgs) lib; + inherit pkgs; + inherit (inputs) home-manager; + }; + createCommonArgs = system: { + inherit + self + inputs + nixpkgs + lib + pkgs + system + ; + specialArgs = { + inherit self inputs; + }; + }; + commonArgs = createCommonArgs system; + # call with forAllSystems (commonArgs: function body) + forAllSystems = + fn: + lib.genAttrs [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ] (system: fn (createCommonArgs system)); + in + { + inherit lib self; + nixosConfigurations = (import ./src/hosts/default.nix commonArgs); }; - }; + + # outputs = {nixpkgs, ...} @ inputs: + # { + # nixosConfigurations.pickwick = nixpkgs.lib.nixosSystem { + # specialArgs = { inherit inputs; }; + # modules = [ + # inputs.disko.nixosModules.default + # (import ./disko.nix { device = "/dev/nvme0n1"; }) + + # ./configuration.nix + # + # inputs.home-manager.nixosModules.default + # inputs.impermanence.nixosModules.impermanence + # ]; + # }; + # }; } diff --git a/hardware-configuration.nix b/hardware-configuration.nix deleted file mode 100644 index 9ded9b2..0000000 --- a/hardware-configuration.nix +++ /dev/null @@ -1,26 +0,0 @@ -# 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 = [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "usbhid" "sd_mod" ]; - boot.initrd.kernelModules = [ "dm-snapshot" ]; - boot.kernelModules = [ "kvm-amd" ]; - 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.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; -} diff --git a/home.nix b/home.nix deleted file mode 100644 index e954d3a..0000000 --- a/home.nix +++ /dev/null @@ -1,347 +0,0 @@ -{ config, pkgs, inputs, lib, ... }: - -{ - imports = [ - inputs.impermanence.nixosModules.home-manager.impermanence - ]; - - home.persistence."/persist/home/rayandrew/common" = { - directories = [ - "Downloads" - "Music" - "Pictures" - "Documents" - "Videos" - "Code" - ".gnupg" - # ".ssh" - ".local/share/keyrings" - ".local/share/direnv" - ".config/1Password" - ".zoom" - ".config/Slack" - ".config/skypeforlinux" - ]; - files = [ - ".bash_history" - ".config/zoomus.conf" - ]; - allowOther = false; - }; - - home.persistence."/persist/home/rayandrew/desktop" = { - removePrefixDirectory = false; - allowOther = false; - directories = [ - ".config/gtk-3.0" - ".config/gtk-4.0" - ".config/KDE" - ".config/kde.org" - ".config/plasma-workspace" - ".config/xsettingsd" - ".kde" - - ".local/share/baloo" - ".local/share/dolphin" - ".local/share/kactivitymanagerd" - ".local/share/kate" - ".local/share/klipper" - ".local/share/konsole" - ".local/share/kscreen" - ".local/share/kwalletd" - ".local/share/kxmlgui5" - ".local/share/RecentDocuments" - ".local/share/sddm" - ]; - files = [ - ".config/monitors.xml" - ".config/akregatorrc" - ".config/baloofileinformationrc" - ".config/baloofilerc" - ".config/bluedevilglobalrc" - ".config/device_automounter_kcmrc" - ".config/dolphinrc" - ".config/filetypesrc" - # ".config/gtkrc" - # ".config/gtkrc-2.0" - # ".config/gtkrc-3.0" - ".config/gwenviewrc" - ".config/kactivitymanagerd-pluginsrc" - ".config/kactivitymanagerd-statsrc" - ".config/kactivitymanagerd-switcher" - ".config/kactivitymanagerdrc" - ".config/katemetainfos" - ".config/katerc" - ".config/kateschemarc" - ".config/katevirc" - ".config/kcmfonts" - ".config/kcminputrc" - ".config/kconf_updaterc" - ".config/kded5rc" - ".config/kdeglobals" - ".config/kgammarc" - ".config/kglobalshortcutsrc" - ".config/khotkeysrc" - ".config/kmixrc" - ".config/konsolerc" - ".config/kscreenlockerrc" - ".config/ksmserverrc" - ".config/ksplashrc" - ".config/ktimezonedrc" - ".config/kwinrc" - ".config/kwinrulesrc" - ".config/kxkbrc" - # ".config/mimeapps.list" - ".config/partitionmanagerrc" - ".config/plasma-localerc" - ".config/plasma-nm" - ".config/plasma-org.kde.plasma.desktop-appletsrc" - ".config/plasmanotifyrc" - ".config/plasmarc" - ".config/plasmashellrc" - ".config/PlasmaUserFeedback" - ".config/plasmawindowed-appletsrc" - ".config/plasmawindowedrc" - ".config/powermanagementprofilesrc" - ".config/spectaclerc" - ".config/startkderc" - ".config/systemsettingsrc" - ".config/Trolltech.conf" - # ".config/user-dirs.dirs" - ".config/user-dirs.locale" - - ".local/share/krunnerstaterc" - ".local/share/user-places.xbel" - # ".local/share/user-places.xbel.bak" - ".local/share/user-places.xbel.tbcache" - ]; - }; - - home.persistence."/persist/home/rayandrew/firefox" = { - directories = [ - ".mozilla" - ]; - allowOther = true; - }; - - home.persistence."/persist/home/rayandrew/dotfiles" = { - removePrefixDirectory = true; - allowOther = true; - directories = [ - "scripts/bin" - "ssh/.ssh" - ]; - files = [ - ]; - }; - - programs.home-manager = { - enable = true; - }; - - dconf.settings = { - "org/gnome/shell" = { - disable-user-extensions = false; - enabled-extensions = [ - "pop-shell@system76.com" - "keyd" - ]; - favorite-apps = [ - "org.gnome.Console.desktop" - "firefox.desktop" - ]; - }; - "org/gnome/desktop/wm/keybindings" = { - minimize = []; - lock = []; - switch-to-workspace-left = []; - switch-to-workspace-right = []; - maximize = [ "f" ]; - unmaximize = [ "f" ]; - move-to-monitor-up = [ ]; - move-to-monitor-down = []; - move-to-monitor-left = []; - move-to-monitor-right = []; - move-to-workspace-down = []; - move-to-workspace-up = []; - close = [ "q" "F4" ]; - }; - "org/gnome/settings-daemon/plugins/media-keys" = { - video-out = [ ]; - custom-keybindings = [ - "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/terminal/" - ]; - }; - "org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/terminal" = { - binding = "Return"; - command = "kgx"; - name = "GNOME Console"; - }; - "org/gnome/mutter/keybindings" = { - toggle-tiled-left = []; - toggle-tiled-right = []; - switch-monitor = [ "XF86Display" ]; - }; - "org/gnome/shell/extensions/pop-shell" = { - activate-launcher = [ "Space" ]; - toggle-float = [ "p" ]; - tile-enter = ["r"]; - tile-by-default = true; - }; - "org/gnome/desktop/background" = { - picture-uri-dark = "file://${pkgs.nixos-artwork.wallpapers.nineish-dark-gray.src}"; - }; - "org/gnome/desktop/interface" = { - color-scheme = "prefer-dark"; - }; - }; - - gtk = { - enable = true; - theme = { - name = "Adwaita-dark"; - package = pkgs.gnome-themes-extra; - }; - gtk2 = { - configLocation = "${config.home.homeDirectory}/.config/gtkrc-2.0"; - }; - }; - - qt = { - enable = true; - platformTheme.name = "adwaita"; - style.name = "adwaita-dark"; - }; - - xdg = { - mimeApps = { - enable = true; - defaultApplications = { - "application/pdf" = "firefox.desktop"; - "application/x-extension-htm" = "firefox.desktop"; - "application/x-extension-html" = "firefox.desktop"; - "application/x-extension-shtml" = "firefox.desktop"; - "application/x-extension-xht" = "firefox.desktop"; - "application/x-extension-xhtml" = "firefox.desktop"; - "application/xhtml+xml" = "firefox.desktop"; - "image/jpeg" = "firefox.desktop"; - "image/png" = "firefox.desktop"; - "text/html" = "firefox.desktop"; - "text/uri-list" = "firefox.desktop"; - "x-scheme-handler/chrome" = "firefox.desktop"; - "x-scheme-handler/http" = "firefox.desktop"; - "x-scheme-handler/https" = "firefox.desktop"; - }; - }; - configFile."mimeapps.list".force = true; - }; - - xdg.portal = { - enable = true; - xdgOpenUsePortal = true; - extraPortals = with pkgs; [ - xdg-desktop-portal-kde - xdg-desktop-portal-gnome - xdg-desktop-portal-gtk - ]; - config = { - common = { default = [ "gtk" ]; }; - gnome = { default = [ "gnome" "gtk" ]; }; - }; - }; - - home.packages = with pkgs; [ - zoom-us - slack - skypeforlinux - desktop-file-utils - gnomeExtensions.pop-shell - gnomeExtensions.tray-icons-reloaded - gnomeExtensions.hibernate-status-button - pop-launcher - ]; - - programs.git = { - enable = true; - }; - - programs.bash.profileExtra = lib.mkAfter '' - rm -rf ${config.home.homeDirectory}/.local/share/applications/home-manager - rm -rf ${config.home.homeDirectory}/.icons/nix-icons - ls ${config.home.homeDirectory}/.nix-profile/share/applications/*.desktop > ${config.home.homeDirectory}/.cache/current_desktop_files.txt - ''; - - home.activation = { - linkDesktopApplications = { - after = ["writeBoundary" "createXdgUserDirectories"]; - before = []; - data = '' - rm -rf ${config.home.homeDirectory}/.local/share/applications/home-manager - rm -rf ${config.home.homeDirectory}/.icons/nix-icons - mkdir -p ${config.home.homeDirectory}/.local/share/applications/home-manager - mkdir -p ${config.home.homeDirectory}/.icons - ln -sf ${config.home.homeDirectory}/.nix-profile/share/icons ${config.home.homeDirectory}/.icons/nix-icons - - # Check if the cached desktop files list exists - if [ -f ${config.home.homeDirectory}/.cache/current_desktop_files.txt ]; then - current_files=$(cat ${config.home.homeDirectory}/.cache/current_desktop_files.txt) - else - current_files="" - fi - - # Symlink new desktop entries - for desktop_file in ${config.home.homeDirectory}/.nix-profile/share/applications/*.desktop; do - if ! echo "$current_files" | grep -q "$(basename $desktop_file)"; then - ln -sf "$desktop_file" ${config.home.homeDirectory}/.local/share/applications/home-manager/$(basename $desktop_file) - fi - done - - # Update desktop database - ${pkgs.desktop-file-utils}/bin/update-desktop-database ${config.home.homeDirectory}/.local/share/applications - ''; - }; - }; - - programs.emacs = { - enable = true; - package = pkgs.emacs; - }; - - programs.vscode = { - enable = true; - }; - - programs.zathura = { - enable = true; - }; - - xdg.configFile."keyd/app.conf" = { - text = '' -[firefox] - -control.p = up -control.n = down -control.e = end -control.a = home -control.shift.p = macro(C-S-p) -''; - }; - - home.file.".local/share/gnome-shell/extensions/keyd" = { - source = "${pkgs.keyd}/share/keyd/gnome-extension-45"; - recursive = true; - }; - - # systemd.user.services.keyd-application-mapper = { - # Install.WantedBy = [ "default.target" ]; - # Unit = { Description = "keyd-application-mapper"; }; - # Service = { - # ExecStart = "${pkgs.keyd}/bin/keyd-application-mapper"; - # }; - # }; - - # Wayland, X, etc. support for session vars - systemd.user.sessionVariables = config.home.sessionVariables; - - home.stateVersion = "24.11"; -} diff --git a/src/home/bash.nix b/src/home/bash.nix new file mode 100644 index 0000000..239a2e3 --- /dev/null +++ b/src/home/bash.nix @@ -0,0 +1,16 @@ +{ lib, pkgs, config, ... }: + +{ + programs.bash.enable = true; + programs.bash.profileExtra = lib.mkAfter '' + rm -rf ${config.home.homeDirectory}/.local/share/applications/home-manager + rm -rf ${config.home.homeDirectory}/.icons/nix-icons + ls ${config.home.homeDirectory}/.nix-profile/share/applications/*.desktop > ${config.home.homeDirectory}/.cache/current_desktop_files.txt + ''; + + custom.persist = { + home.files = [ + ".bash_history" + ]; + }; +} diff --git a/src/home/default.nix b/src/home/default.nix new file mode 100644 index 0000000..5e21144 --- /dev/null +++ b/src/home/default.nix @@ -0,0 +1,82 @@ +{ + config, + lib, + pkgs, + user, + ... +}: + +{ + imports = [ + ./bash.nix + ./emacs.nix + ./impermanence.nix + ./git.nix + ./gui + ./ssh.nix + ]; + + config = { + + # setup fonts for other distros, run "fc-cache -f" to refresh fonts + fonts.fontconfig.enable = true; + + home = { + stateVersion = "24.11"; + username = user; + homeDirectory = "/home/${user}"; + activation = { + # linkDesktopApplications = { + # after = ["writeBoundary" "createXdgUserDirectories"]; + # before = []; + # data = '' + # rm -rf ${config.home.homeDirectory}/.local/share/applications/home-manager + # rm -rf ${config.home.homeDirectory}/.icons/nix-icons + # mkdir -p ${config.home.homeDirectory}/.local/share/applications/home-manager + # mkdir -p ${config.home.homeDirectory}/.icons + # ln -sf ${config.home.homeDirectory}/.nix-profile/share/icons ${config.home.homeDirectory}/.icons/nix-icons + + # # Check if the cached desktop files list exists + # if [ -f ${config.home.homeDirectory}/.cache/current_desktop_files.txt ]; then + # current_files=$(cat ${config.home.homeDirectory}/.cache/current_desktop_files.txt) + # else + # current_files="" + # fi + + # # Symlink new desktop entries + # ${pkgs.bash}/bin/bash -c < + # for desktop_file in "${config.home.homeDirectory}/.nix-profile/share/applications/*.desktop"; do + # if ! echo "$current_files" | grep -q "$(basename $desktop_file)"; then + # echo $desktop_file + # ln -sf "$desktop_file" ${config.home.homeDirectory}/.local/share/applications/home-manager/$(basename $desktop_file) + # fi + # done + + # # Update desktop database + # ${pkgs.desktop-file-utils}/bin/update-desktop-database ${config.home.homeDirectory}/.local/share/applications + # ''; + # }; + }; + + }; + + programs.home-manager.enable = true; + + xdg = { + enable = true; + userDirs.enable = true; + mimeApps.enable = true; + }; + + custom = { + persist = { + home.directories = [ + "Documents" + "Downloads" + "Pictures" + "Code" + ]; + }; + }; + }; +} diff --git a/src/home/emacs.nix b/src/home/emacs.nix new file mode 100644 index 0000000..eb50a68 --- /dev/null +++ b/src/home/emacs.nix @@ -0,0 +1,8 @@ +{ pkgs, ... }: + +{ + programs.emacs = { + enable = true; + package = pkgs.emacs; + }; +} diff --git a/src/home/git.nix b/src/home/git.nix new file mode 100644 index 0000000..aaa26a9 --- /dev/null +++ b/src/home/git.nix @@ -0,0 +1,10 @@ +{ lib, pkgs, config, ... }: + +{ + home.packages = with pkgs; [ + git + ]; + # programs.git = { + # enable = true; + # }; +} diff --git a/src/home/gui/1password.nix b/src/home/gui/1password.nix new file mode 100644 index 0000000..e590571 --- /dev/null +++ b/src/home/gui/1password.nix @@ -0,0 +1,9 @@ +{ config, pkgs, ... }: + +{ + custom.persist = { + home.directories = [ + ".config/1Password" + ]; + }; +} diff --git a/src/home/gui/default.nix b/src/home/gui/default.nix new file mode 100644 index 0000000..807039c --- /dev/null +++ b/src/home/gui/default.nix @@ -0,0 +1,35 @@ +{ pkgs, config, ... }: + +{ + imports = [ + ./1password.nix + ./firefox.nix + ./keyd.nix + ./gnome.nix + ./slack.nix + ./skype.nix + ./vscode.nix + ./xdg.nix + ./zathura.nix + ./zoom.nix + ]; + + config = { + gtk = { + enable = true; + theme = { + name = "Adwaita-dark"; + package = pkgs.gnome-themes-extra; + }; + gtk2 = { + configLocation = "${config.home.homeDirectory}/.config/gtkrc-2.0"; + }; + }; + + qt = { + enable = true; + platformTheme.name = "adwaita"; + style.name = "adwaita-dark"; + }; + }; +} diff --git a/src/home/gui/firefox.nix b/src/home/gui/firefox.nix new file mode 100644 index 0000000..f013d51 --- /dev/null +++ b/src/home/gui/firefox.nix @@ -0,0 +1,35 @@ +{ config, pkgs, lib, user, ... }: + +let + vendorPath = ".config/.mozilla"; + configPath = "${vendorPath}/firefox"; +in +{ + programs.firefox = { + enable = true; + package = pkgs.firefox-bin.overrideAttrs (o: { + buildCommand = + o.buildCommand + + '' + wrapProgram "$executablePath" \ + --set 'HOME' '${config.xdg.configHome}' \ + --append-flags "${ + lib.concatStringsSep " " ( + [ + "--name firefox" + "-P ${user}" + # "--profile ${config.xdg.configHome}/.mozilla/${user}" + ] + ) + }" + ''; + }); + }; + + custom.persist = { + home.directories = [ + ".cache/mozilla" + ".config/.mozilla" + ]; + }; +} diff --git a/src/home/gui/gnome.nix b/src/home/gui/gnome.nix new file mode 100644 index 0000000..92ec3b5 --- /dev/null +++ b/src/home/gui/gnome.nix @@ -0,0 +1,78 @@ +{ lib, pkgs, config, ... }: + +{ + home.packages = with pkgs; [ + pop-launcher + gnomeExtensions.pop-shell + gnomeExtensions.tray-icons-reloaded + gnomeExtensions.hibernate-status-button + ]; + + dconf.settings = { + "org/gnome/shell" = { + disable-user-extensions = false; + enabled-extensions = [ + "pop-shell@system76.com" + "keyd" + ]; + favorite-apps = [ + "org.gnome.Console.desktop" + "firefox.desktop" + ]; + }; + "org/gnome/desktop/wm/keybindings" = { + minimize = []; + lock = []; + switch-to-workspace-left = []; + switch-to-workspace-right = []; + maximize = [ "f" ]; + unmaximize = [ "f" ]; + move-to-monitor-up = [ ]; + move-to-monitor-down = []; + move-to-monitor-left = []; + move-to-monitor-right = []; + move-to-workspace-down = []; + move-to-workspace-up = []; + close = [ "q" "F4" ]; + }; + "org/gnome/settings-daemon/plugins/media-keys" = { + video-out = [ ]; + custom-keybindings = [ + "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/terminal/" + ]; + }; + "org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/terminal" = { + binding = "Return"; + command = "kgx"; + name = "GNOME Console"; + }; + "org/gnome/mutter/keybindings" = { + toggle-tiled-left = []; + toggle-tiled-right = []; + switch-monitor = [ "XF86Display" ]; + }; + "org/gnome/shell/extensions/pop-shell" = { + activate-launcher = [ "Space" ]; + toggle-float = [ "p" ]; + tile-enter = ["r"]; + tile-by-default = true; + }; + "org/gnome/desktop/background" = { + picture-uri-dark = "file://${pkgs.nixos-artwork.wallpapers.nineish-dark-gray.src}"; + }; + "org/gnome/desktop/interface" = { + color-scheme = "prefer-dark"; + }; + }; + + custom.persist = { + home = { + directories = [ + ".local/share/keyrings" + ]; + files = [ + ".config/monitors.xml" + ]; + }; + }; +} diff --git a/src/home/gui/keyd.nix b/src/home/gui/keyd.nix new file mode 100644 index 0000000..7211380 --- /dev/null +++ b/src/home/gui/keyd.nix @@ -0,0 +1,20 @@ +{ pkgs, ... }: + +{ + xdg.configFile."keyd/app.conf" = { + text = '' +[firefox] + +control.p = up +control.n = down +control.e = end +control.a = home +control.shift.p = macro(C-S-p) +''; + }; + + home.file.".local/share/gnome-shell/extensions/keyd" = { + source = "${pkgs.keyd}/share/keyd/gnome-extension-45"; + recursive = true; + }; +} diff --git a/src/home/gui/skype.nix b/src/home/gui/skype.nix new file mode 100644 index 0000000..4ecbe6d --- /dev/null +++ b/src/home/gui/skype.nix @@ -0,0 +1,13 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + skypeforlinux + ]; + + custom.persist = { + home.directories = [ + ".config/skypeforlinux" + ]; + }; +} diff --git a/src/home/gui/slack.nix b/src/home/gui/slack.nix new file mode 100644 index 0000000..2d2e5c0 --- /dev/null +++ b/src/home/gui/slack.nix @@ -0,0 +1,13 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + slack + ]; + + custom.persist = { + home.directories = [ + ".config/Slack" + ]; + }; +} diff --git a/src/home/gui/vscode.nix b/src/home/gui/vscode.nix new file mode 100644 index 0000000..8d0846d --- /dev/null +++ b/src/home/gui/vscode.nix @@ -0,0 +1,13 @@ +{ config, pkgs, ... }: + +{ + programs.vscode = { + enable = true; + }; + + custom.persist = { + home.directories = [ + ".config/Code" + ]; + }; +} diff --git a/src/home/gui/xdg.nix b/src/home/gui/xdg.nix new file mode 100644 index 0000000..b667aed --- /dev/null +++ b/src/home/gui/xdg.nix @@ -0,0 +1,40 @@ +{ pkgs, ... }: + +{ + xdg = { + mimeApps = { + enable = true; + defaultApplications = { + "application/pdf" = "firefox.desktop"; + "application/x-extension-htm" = "firefox.desktop"; + "application/x-extension-html" = "firefox.desktop"; + "application/x-extension-shtml" = "firefox.desktop"; + "application/x-extension-xht" = "firefox.desktop"; + "application/x-extension-xhtml" = "firefox.desktop"; + "application/xhtml+xml" = "firefox.desktop"; + "image/jpeg" = "firefox.desktop"; + "image/png" = "firefox.desktop"; + "text/html" = "firefox.desktop"; + "text/uri-list" = "firefox.desktop"; + "x-scheme-handler/chrome" = "firefox.desktop"; + "x-scheme-handler/http" = "firefox.desktop"; + "x-scheme-handler/https" = "firefox.desktop"; + }; + }; + configFile."mimeapps.list".force = true; + }; + + xdg.portal = { + enable = true; + xdgOpenUsePortal = true; + extraPortals = with pkgs; [ + xdg-desktop-portal-kde + xdg-desktop-portal-gnome + xdg-desktop-portal-gtk + ]; + config = { + common = { default = [ "gtk" ]; }; + gnome = { default = [ "gnome" "gtk" ]; }; + }; + }; +} diff --git a/src/home/gui/zathura.nix b/src/home/gui/zathura.nix new file mode 100644 index 0000000..50023b7 --- /dev/null +++ b/src/home/gui/zathura.nix @@ -0,0 +1,8 @@ +_: + +{ + programs.zathura = { + enable = true; + }; +} + diff --git a/src/home/gui/zoom.nix b/src/home/gui/zoom.nix new file mode 100644 index 0000000..2c0927e --- /dev/null +++ b/src/home/gui/zoom.nix @@ -0,0 +1,16 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + zoom-us + ]; + + custom.persist = { + home.directories = [ + ".zoom" + ]; + home.files = [ + ".config/zoomus.conf" + ]; + }; +} diff --git a/src/home/impermanence.nix b/src/home/impermanence.nix new file mode 100644 index 0000000..018bf6e --- /dev/null +++ b/src/home/impermanence.nix @@ -0,0 +1,53 @@ +# note: this file exists just to define options for home-manager, +# impermanence is not actually used in standalone home-manager as +# it doesn't serve much utility on legacy distros +{ lib, user, config, ... }: + +let + cfg = config.custom.persist; +in +{ + options.custom = with lib; { + persist = { + home = { + directories = mkOption { + type = types.listOf types.str; + default = [ ]; + description = "Directories to persist in home directory"; + }; + files = mkOption { + type = types.listOf types.str; + default = [ ]; + description = "Files to persist in home directory"; + }; + cache = { + directories = mkOption { + type = types.listOf types.str; + default = [ ]; + description = "Directories to persist, but not to snapshot"; + }; + files = mkOption { + type = types.listOf types.str; + default = [ ]; + description = "Files to persist, but not to snapshot"; + }; + }; + }; + }; + }; + + config = { + # home.persistence = { + # "/persist/home/${user}" = { + # files = cfg.home.files; + # directories = cfg.home.directories; + # allowOther = false; + # }; + # "/cache/home/${user}" = { + # files = cfg.home.cache.files; + # directories = cfg.home.cache.directories; + # allowOther = true; + # }; + # }; + }; +} diff --git a/src/home/ssh.nix b/src/home/ssh.nix new file mode 100644 index 0000000..b86a2e0 --- /dev/null +++ b/src/home/ssh.nix @@ -0,0 +1,13 @@ +{ config, pkgs, ... }: + +{ + programs.ssh = { + enable = true; + }; + + custom.persist = { + home.directories = [ + ".ssh" + ]; + }; +} diff --git a/src/hosts/default.nix b/src/hosts/default.nix new file mode 100644 index 0000000..674f4ed --- /dev/null +++ b/src/hosts/default.nix @@ -0,0 +1,65 @@ +{ + inputs, + lib, + system, + specialArgs, + user ? "rayandrew", + ... +}: +let + # provide an optional { pkgs } 2nd argument to override the pkgs + mkNixosConfiguration = + host: + { + pkgs ? ( + import inputs.nixpkgs { + inherit system; + config.allowUnfree = true; + } + ), + }: + lib.nixosSystem { + inherit pkgs; + + specialArgs = specialArgs // { + inherit host user; + }; + + modules = [ + inputs.disko.nixosModules.default + ./${host} + ./${host}/hardware.nix + ../nixos + { + home-manager = { + useGlobalPkgs = true; + useUserPackages = true; + + extraSpecialArgs = specialArgs // { + inherit host user; + }; + + users.${user} = { + imports = [ + inputs.nix-index-database.hmModules.nix-index + inputs.impermanence.nixosModules.home-manager.impermanence + # ./${host}/home.nix + ../home + ]; + }; + }; + } + # alias for home-manager + (lib.mkAliasOptionModule [ "hm" ] [ + "home-manager" + "users" + user + ]) + inputs.home-manager.nixosModules.home-manager + inputs.impermanence.nixosModules.impermanence + ]; + }; +in +{ + pickwick = mkNixosConfiguration "pickwick" { }; +} diff --git a/configuration.nix b/src/hosts/pickwick/default.nix similarity index 57% rename from configuration.nix rename to src/hosts/pickwick/default.nix index 0e6969e..a1e8fa6 100644 --- a/configuration.nix +++ b/src/hosts/pickwick/default.nix @@ -1,19 +1,11 @@ { config, lib, pkgs, inputs, ... }: { - imports = [ - ./hardware-configuration.nix - inputs.nixos-hardware.nixosModules.framework-13-7040-amd - ]; + imports = []; - nixpkgs.config.allowUnfree = true; - - boot.kernelParams = [ "resume_offset=533760" ]; - boot.resumeDevice = "/dev/pool/root"; - boot.loader.systemd-boot.enable = true; - boot.loader.efi.canTouchEfiVariables = true; networking.hostName = "pickwick"; + networking.hostId = builtins.substring 0 8 (builtins.hashString "md5" config.networking.hostName); networking.networkmanager.enable = true; time.timeZone = "America/Chicago"; @@ -21,15 +13,11 @@ i18n.defaultLocale = "en_US.UTF-8"; services.xserver.enable = true; - # services.displayManager.sddm.enable = true; - # services.desktopManager.plasma6.enable = true; services.xserver.displayManager.gdm.enable = true; services.xserver.desktopManager.gnome.enable = true; services.xserver.xkb.layout = "us"; - # services.xserver.xkb.options = "caps:ctrl_modifier"; - security.sudo.extraConfig = "Defaults lecture=never"; security.pam.services.login.fprintAuth = false; security.pam.services.sudo.fprintAuth = false; @@ -52,33 +40,24 @@ services.libinput.enable = true; - users.users.root.hashedPasswordFile = "/persist/passwords/root"; - users.users.rayandrew = { - isNormalUser = true; - # initialPassword = "12345"; - hashedPasswordFile = "/persist/passwords/rayandrew"; - extraGroups = [ "wheel" "audio" "keyd" ]; - packages = with pkgs; [ - firefox - tree - ]; - }; + # users.users.root.hashedPasswordFile = "/persist/passwords/root"; + # users.users.rayandrew = { + # isNormalUser = true; + # # initialPassword = "12345"; + # hashedPasswordFile = "/persist/passwords/rayandrew"; + # extraGroups = [ "wheel" "audio" "keyd" ]; + # packages = with pkgs; [ + # firefox + # tree + # ]; + # }; users.groups.keyd = {}; environment.systemPackages = with pkgs; [ vim wget htop-vim - - # gnome keyd - # gnomeExtensions.pop-launcher-super-key - ]; - - environment.plasma6.excludePackages = with pkgs.kdePackages; [ - # plasma-browser-integration - # konsole - oxygen ]; environment.gnome.excludePackages = with pkgs; [ @@ -113,43 +92,30 @@ programs.dconf.enable = true; - fileSystems."/persist".neededForBoot = true; - environment.persistence."/persist/system" = { - hideMounts = true; - directories = [ - "/etc/nixos" - # "/etc/gdm" - "/var/log" - "/var/lib/fprint" - "/var/lib/nixos" - "/var/lib/bluetooth" - "/var/lib/systemd/coredump" - "/etc/NetworkManager/system-connections" - { directory = "/var/lib/colord"; user = "colord"; group = "colord"; mode = "u=rwx,g=rx,o="; } - ]; - files = [ - "/etc/machine-id" - ]; - }; + # environment.persistence."/persist/system" = { + # hideMounts = true; + # directories = [ + # "/var/log" + # "/var/lib/fprint" + # "/var/lib/nixos" + # "/var/lib/bluetooth" + # "/var/lib/systemd/coredump" + # "/etc/NetworkManager/system-connections" + # { directory = "/var/lib/colord"; user = "colord"; group = "colord"; mode = "u=rwx,g=rx,o="; } + # ]; + # files = [ + # "/etc/machine-id" + # ]; + # }; programs.fuse.userAllowOther = true; - home-manager = { - extraSpecialArgs = {inherit inputs pkgs;}; - users = { - "rayandrew" = import ./home.nix; - }; - useGlobalPkgs = true; - useUserPackages = true; - }; - - - # xdg.portal = { - # enable = true; - # xdgOpenUsePortal = true; - # extraPortals = [ - # pkgs.xdg-desktop-portal-gnome - # pkgs.xdg-desktop-portal-gtk - # ]; + # home-manager = { + # extraSpecialArgs = {inherit inputs pkgs;}; + # users = { + # "rayandrew" = import ./home.nix; + # }; + # useGlobalPkgs = true; + # useUserPackages = true; # }; services.keyd = { @@ -161,7 +127,6 @@ main = { capslock = "layer(capslock)"; insert = "S-insert"; - # capslock = "layer(control)"; }; meta = { w = "macro(C-w)"; @@ -195,9 +160,21 @@ "CAP_SETGID" ]; - swapDevices = [ - { device = "/swap/swapfile"; } - ]; + # swapDevices = [ + # { device = "/swap/swapfile"; } + # ]; + + systemd.services = { + # https://github.com/openzfs/zfs/issues/10891 + systemd-udev-settle.enable = false; + # snapshot dirs sometimes not accessible + # https://github.com/NixOS/nixpkgs/issues/257505#issuecomment-2348313665 + zfs-mount = { + serviceConfig = { + ExecStart = [ "${lib.getExe' pkgs.util-linux "mount"} -t zfs zroot/persist -o remount" ]; + }; + }; + }; system.stateVersion = "24.11"; } diff --git a/src/hosts/pickwick/disko.nix b/src/hosts/pickwick/disko.nix new file mode 100644 index 0000000..83e747d --- /dev/null +++ b/src/hosts/pickwick/disko.nix @@ -0,0 +1,119 @@ +{ + device ? throw "Set this to your disk device, e.g. /dev/sda", + ... +}: +{ + disko.devices = { + nodev = { + "/" = { + fsType = "tmpfs"; + mountOptions = [ + "defaults" + "size=1G" + "mode=755" + ]; + }; + # "/home" = { + # fsType = "tmpfs"; + # mountOptions = [ + # "defaults" + # "size=1G" + # "mode=755" + # ]; + # }; + }; + + disk.main = { + type = "disk"; + inherit device; + + content = { + type = "gpt"; + partitions = { + boot = { + name = "boot"; + size = "1M"; + type = "EF02"; + }; + esp = { + priority = 1; + size = "512M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ + "defaults" + "umask=0077" + ]; + extraArgs = [ "-n" "BOOT" ]; + }; + }; + swap = { + size = "108G"; + content = { + type = "swap"; + discardPolicy = "both"; + resumeDevice = true; + extraArgs = [ "--label" "SWAP" ]; + }; + }; + zfs = { + size = "100%"; + content = { + type = "zfs"; + pool = "zroot"; + }; + }; + }; + }; + }; + zpool = { + zroot = { + type = "zpool"; + # mode = "mirror"; + options = { + cachefile = "none"; + ashift = "12"; + autotrim = "on"; + }; + rootFsOptions = { + compression = "zstd"; + acltype = "posixacl"; + xattr = "sa"; + mountpoint = "none"; + encryption = "aes-256-gcm"; + keyformat = "passphrase"; + keylocation = "prompt"; + normalization = "formD"; + "com.sun:auto-snapshot" = "false"; + }; + mountpoint = null; + postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^zroot@blank$' || zfs snapshot zroot@blank"; + datasets = { + nix = { + type = "zfs_fs"; + options.mountpoint = "legacy"; + mountpoint = "/nix"; + }; + cache = { + type = "zfs_fs"; + options.mountpoint = "legacy"; + mountpoint = "/cache"; + }; + persist = { + type = "zfs_fs"; + options.mountpoint = "legacy"; + mountpoint = "/persist"; + }; + tmp = { + type = "zfs_fs"; + options.mountpoint = "legacy"; + mountpoint = "/tmp"; + }; + }; + }; + }; + }; +} diff --git a/src/hosts/pickwick/hardware.nix b/src/hosts/pickwick/hardware.nix new file mode 100644 index 0000000..bfd6a08 --- /dev/null +++ b/src/hosts/pickwick/hardware.nix @@ -0,0 +1,63 @@ +# 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. +{ inputs, config, lib, pkgs, modulesPath, ... }: + +{ + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + (import ./disko.nix { device = "/dev/nvme0n1"; }) + inputs.nixos-hardware.nixosModules.framework-13-7040-amd + ]; + + boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "usbhid" "sd_mod" ]; + boot.initrd.kernelModules = [ "dm-snapshot" ]; + boot.kernelModules = [ "kvm-amd" ]; + 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.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; + + boot.supportedFilesystems.zfs = true; + boot.zfs = { + devNodes ="/dev/disk/by-partuuid"; + package = pkgs.zfs_unstable; + requestEncryptionCredentials = true; + }; + # boot.kernelPackages = + # assert lib.assertMsg (lib.versionOlder pkgs.zfs_unstable.version "2.3") + # "zfs 2.3 supports kernel 6.11 or greater"; + # pkgs.linuxPackagesFor ( + # pkgs.linux_xanmod_latest.override { + # argsOverride = rec { + # version = "6.10.11"; + # modDirVersion = lib.versions.pad 3 "${version}-xanmod1"; + # src = pkgs.fetchFromGitHub { + # owner = "xanmod"; + # repo = "linux"; + # rev = modDirVersion; + # hash = "sha256-FDWFpiN0VvzdXcS3nZHm1HFgASazNX5+pL/8UJ3hkI8="; + # }; + # }; + # } + # ); + + boot.kernelParams = [ ]; + # boot.resumeDevice = "/dev/pool/root"; + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + swapDevices = [ { device = "/dev/disk/by-label/SWAP"; } ]; + zramSwap.enable = true; + + # filesystems + fileSystems."/cache".neededForBoot = true; + fileSystems."/persist".neededForBoot = true; +} diff --git a/src/hosts/pickwick/home.nix b/src/hosts/pickwick/home.nix new file mode 100644 index 0000000..2b2c72e --- /dev/null +++ b/src/hosts/pickwick/home.nix @@ -0,0 +1,59 @@ +{ config, pkgs, inputs, lib, ... }: + +{ + imports = [ + inputs.impermanence.nixosModules.home-manager.impermanence + ]; + + # home.persistence."/persist/home/rayandrew/common" = { + # directories = [ + # "Downloads" + # "Music" + # "Pictures" + # "Documents" + # "Videos" + # "Code" + # ".gnupg" + # # ".ssh" + # ".local/share/keyrings" + # ".local/share/direnv" + # ".config/1Password" + # ".zoom" + # ".config/Slack" + # ".config/skypeforlinux" + # ]; + # files = [ + # ".bash_history" + # ".config/zoomus.conf" + # ]; + # allowOther = true; + # }; + + # home.persistence."/persist/home/rayandrew/dotfiles" = { + # removePrefixDirectory = true; + # allowOther = true; + # directories = [ + # "scripts/bin" + # "ssh/.ssh" + # ]; + # files = [ + # ]; + # }; + + programs.zathura = { + enable = true; + }; + + # systemd.user.services.keyd-application-mapper = { + # Install.WantedBy = [ "default.target" ]; + # Unit = { Description = "keyd-application-mapper"; }; + # Service = { + # ExecStart = "${pkgs.keyd}/bin/keyd-application-mapper"; + # }; + # }; + + # Wayland, X, etc. support for session vars + systemd.user.sessionVariables = config.home.sessionVariables; + + home.stateVersion = "24.11"; +} diff --git a/src/lib.nix b/src/lib.nix new file mode 100644 index 0000000..9fb4299 --- /dev/null +++ b/src/lib.nix @@ -0,0 +1,4 @@ +{ lib, pkgs, ... }: + +lib.extend (_: libprev: { +}) diff --git a/src/nixos/default.nix b/src/nixos/default.nix new file mode 100644 index 0000000..3fe9fb3 --- /dev/null +++ b/src/nixos/default.nix @@ -0,0 +1,13 @@ +{ + config, + lib, + pkgs, + ... +}: + +{ + imports = [ + ./users.nix + ./impermanence.nix + ]; +} diff --git a/src/nixos/impermanence.nix b/src/nixos/impermanence.nix new file mode 100644 index 0000000..aa33aec --- /dev/null +++ b/src/nixos/impermanence.nix @@ -0,0 +1,136 @@ +{ + config, + lib, + pkgs, + user, + ... +}: +let + cfg = config.custom.persist; + hmPersistCfg = config.hm.custom.persist; + assertNoHomeDirs = + paths: + assert (lib.assertMsg (!lib.any (lib.hasPrefix "/home") paths) "/home used in a root persist!"); + paths; +in +{ + options.custom = with lib; { + persist = { + root = { + directories = mkOption { + type = types.listOf types.str; + default = [ ]; + apply = assertNoHomeDirs; + description = "Directories to persist in root filesystem"; + }; + files = mkOption { + type = types.listOf types.str; + default = [ ]; + apply = assertNoHomeDirs; + description = "Files to persist in root filesystem"; + }; + cache = { + directories = mkOption { + type = types.listOf types.str; + default = [ ]; + apply = assertNoHomeDirs; + description = "Directories to persist, but not to snapshot"; + }; + files = mkOption { + type = types.listOf types.str; + default = [ ]; + apply = assertNoHomeDirs; + description = "Files to persist, but not to snapshot"; + }; + }; + }; + home = { + directories = mkOption { + type = types.listOf types.str; + default = [ ]; + description = "Directories to persist in home directory"; + }; + files = mkOption { + type = types.listOf types.str; + default = [ ]; + description = "Files to persist in home directory"; + }; + }; + }; + }; + + config = { + boot.tmp.cleanOnBoot = true; + + # root and home on tmpfs + fileSystems."/" = lib.mkForce { + device = "tmpfs"; + fsType = "tmpfs"; + neededForBoot = true; + options = [ + "defaults" + "size=1G" + "mode=755" + ]; + }; + + # shut sudo up + security.sudo.extraConfig = "Defaults lecture=never"; + + # setup persistence + environment.persistence = { + "/persist" = { + hideMounts = true; + files = [ "/etc/machine-id" ] ++ cfg.root.files; + directories = [ + "/var/log" # systemd journal is stored in /var/log/journal + "/var/lib/nixos" # for persisting user uids and gids + "/etc/NetworkManager/system-connections" + ] ++ cfg.root.directories; + + users.${user} = { + files = cfg.home.files ++ hmPersistCfg.home.files; + directories = lib.unique ( + [ + "Code" + ".cache/dconf" + ".config/dconf" + ] + ++ cfg.home.directories + ++ hmPersistCfg.home.directories + ); + }; + }; + + # cache are files that should be persisted, but not to snapshot + # e.g. npm, cargo cache etc, that could always be redownloaded + "/cache" = { + hideMounts = true; + inherit (cfg.root.cache) directories files; + + users.${user} = { + inherit (hmPersistCfg.home.cache) directories files; + }; + }; + }; + + hm.xdg.stateFile."impermanence.json".text = + let + getDirPath = prefix: d: "${prefix}${d.dirPath}"; + getFilePath = prefix: f: "${prefix}${f.filePath}"; + persistCfg = config.environment.persistence."/persist"; + persistCacheCfg = config.environment.persistence."/cache"; + allDirectories = + map (getDirPath "/persist") (persistCfg.directories) + ++ map (getDirPath "/cache") (persistCacheCfg.directories); + allFiles = + map (getFilePath "/persist") (persistCfg.files) + ++ map (getFilePath "/cache") (persistCacheCfg.files); + sort-uniq = arr: lib.sort lib.lessThan (lib.unique arr); + in + lib.strings.toJSON { + directories = sort-uniq allDirectories; + files = sort-uniq allFiles; + }; + }; +} diff --git a/src/nixos/users.nix b/src/nixos/users.nix new file mode 100644 index 0000000..6245b5e --- /dev/null +++ b/src/nixos/users.nix @@ -0,0 +1,36 @@ +{ + config, + lib, + user, + ... +}: + +{ + config = lib.mkMerge [ + { + users = { + mutableUsers = false; + # setup users with persistent passwords + # https://reddit.com/r/NixOS/comments/o1er2p/tmpfs_as_root_but_without_hardcoding_your/h22f1b9/ + # create a password with for root and $user with: + # mkpasswd -m sha-512 'PASSWORD' | sudo tee -a /persist/etc/shadow/root + users = { + root = { + # initialPassword = "password"; + hashedPasswordFile = "/persist/etc/shadow/root"; + }; + ${user} = { + isNormalUser = true; + createHome = true; + # initialPassword = "password"; + hashedPasswordFile = "/persist/etc/shadow/${user}"; + extraGroups = [ + "networkmanager" + "wheel" + ]; + }; + }; + }; + } + ]; +}