diff options
author | sadbeast <sadbeast@sadbeast.com> | 2024-05-30 00:47:47 +0000 |
---|---|---|
committer | sadbeast <sadbeast@sadbeast.com> | 2024-10-05 16:44:14 -0700 |
commit | 09513b5c4e4babfaefdd06c592ef34c0908dc572 (patch) | |
tree | 5a9af6ef0407346c223334e295adc8012654f112 | |
download | nix-config-09513b5c4e4babfaefdd06c592ef34c0908dc572.tar.gz nix-config-09513b5c4e4babfaefdd06c592ef34c0908dc572.tar.bz2 |
42 files changed, 2464 insertions, 0 deletions
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8536856 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +nixos/hosts/*/secrets/*.yaml diff=sopsdiffer diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b2be92b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +result diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 0000000..58cd2ad --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,16 @@ +keys: + - &users: + - &sadbeast age1a6k6lwndk7w5ck3w8vydw72af3q8appm6jyxj7amwp6fmqnylywsy7ay0e + - &hosts: + - &crystalpalace age16qcn9298rk3eav38442zw2ejhqac6uvdj0m86qf4ggnjgug8efgsp9lwcd + - &joshua age1hls0h26tcls67ukcpt7e0ztua8mwzheaqkuuwl4anv8zstq8regqd7nqv9 + - &wopr age1dg0dxg6nf5rm05py3da3yz8tkg7xtgustuehxwn37cm8mdrf93ysn9n622 + +creation_rules: + - path_regex: hosts/common/secrets.ya?ml$ + key_groups: + - age: + - *crystalpalace + - *joshua + - *wopr + - *sadbeast diff --git a/README.md b/README.md new file mode 100644 index 0000000..8844787 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# Installation + +1. Follow the [installation guide](https://nixos.org/manual/nixos/stable/#sec-installation-manual-installing) and run `nixos-install --flake .#hostname` in this directory, instead of `nixos-install`. + +# Usage + +To rebuild the system after changes in `hosts/`: +``` +sudo nixos-rebuild switch --flake .#hostname +``` + +After making changes in `home/`: + +``` +home-manager switch --flake .#sadbeast@hostname +``` + +# References +This was intitially setup using [https://github.com/Misterio77/nix-starter-configs](https://github.com/Misterio77/nix-starter-configs) + +[Encypted Btrfs Root with Opt-in State on NixOS](https://mt-caret.github.io/blog/posts/2020-06-29-optin-state.html) diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..7d27faa --- /dev/null +++ b/flake.lock @@ -0,0 +1,188 @@ +{ + "nodes": { + "firefox-addons": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "dir": "pkgs/firefox-addons", + "lastModified": 1728100995, + "narHash": "sha256-d5DeaW4zN2qADEGXt7c6pMApRRP/tmFneCMPKeC9lrc=", + "owner": "rycee", + "repo": "nur-expressions", + "rev": "c0179f5534ee6a12e475842f6865c91719320b14", + "type": "gitlab" + }, + "original": { + "dir": "pkgs/firefox-addons", + "owner": "rycee", + "repo": "nur-expressions", + "type": "gitlab" + } + }, + "flake-utils": { + "locked": { + "lastModified": 1629284811, + "narHash": "sha256-JHgasjPR0/J1J3DRm4KxM4zTyAj4IOJY8vIl75v/kPI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "c5d161cc0af116a2e17f54316f0bf43f0819785c", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1728041527, + "narHash": "sha256-03liqiJtk9UP7YQHW4r8MduKCK242FQzud8iWvvlK+o=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "509dbf8d45606b618e9ec3bbe4e936b7c5bc6c1e", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "impermanence": { + "locked": { + "lastModified": 1727649413, + "narHash": "sha256-FA53of86DjFdeQzRDVtvgWF9o52rWK70VHGx0Y8fElQ=", + "owner": "nix-community", + "repo": "impermanence", + "rev": "d0b38e550039a72aff896ee65b0918e975e6d48e", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "impermanence", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1728018373, + "narHash": "sha256-NOiTvBbRLIOe5F6RbHaAh6++BNjsb149fGZd1T4+KBg=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "bc947f541ae55e999ffdb4013441347d83b00feb", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1728067476, + "narHash": "sha256-/uJcVXuBt+VFCPQIX+4YnYrHaubJSx4HoNsJVNRgANM=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "6e6b3dd395c3b1eb9be9f2d096383a8d05add030", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable_2": { + "locked": { + "lastModified": 1725762081, + "narHash": "sha256-vNv+aJUW5/YurRy1ocfvs4q/48yVESwlC/yHzjkZSP8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "dc454045f5b5d814e5862a6d057e7bb5c29edc05", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "release-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1725534445, + "narHash": "sha256-Yd0FK9SkWy+ZPuNqUgmVPXokxDgMJoGuNpMEtkfcf84=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9bb1e7571aadf31ddb4af77fc64b2d59580f9a39", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "firefox-addons": "firefox-addons", + "home-manager": "home-manager", + "impermanence": "impermanence", + "nixpkgs": "nixpkgs", + "nixpkgs-stable": "nixpkgs-stable", + "sops-nix": "sops-nix", + "systems": "systems" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": "nixpkgs_2", + "nixpkgs-stable": "nixpkgs-stable_2" + }, + "locked": { + "lastModified": 1727734513, + "narHash": "sha256-i47LQwoGCVQq4upV2YHV0OudkauHNuFsv306ualB/Sw=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "3198a242e547939c5e659353551b0668ec150268", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", + "owner": "nix-systems", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default-linux", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..e118890 --- /dev/null +++ b/flake.nix @@ -0,0 +1,137 @@ +{ + description = "my nix config"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + # You can access packages and modules from different nixpkgs revs + # at the same time. Here's a working example: + nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.05"; + # Also see the 'stable-packages' overlay at 'overlays/default.nix'. + + # Third party programs, packaged with nix + firefox-addons = { + url = "gitlab:rycee/nur-expressions?dir=pkgs/firefox-addons"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + impermanence.url = "github:nix-community/impermanence"; + + sops-nix.url = "github:Mic92/sops-nix"; + + systems.url = "github:nix-systems/default-linux"; + }; + + outputs = { + self, + nixpkgs, + home-manager, + systems, + ... + } @ inputs: let + inherit (self) outputs; + lib = nixpkgs.lib // home-manager.lib; + forEachSystem = f: lib.genAttrs (import systems) (system: f pkgsFor.${system}); + pkgsFor = lib.genAttrs (import systems) ( + system: + import nixpkgs { + inherit system; + config.allowUnfree = true; + } + ); + in { + inherit lib; + # Your custom packages + # Accessible through 'nix build', 'nix shell', etc + packages = forEachSystem (pkgs: import ./pkgs {inherit pkgs;}); + + # Formatter for your nix files, available through 'nix fmt' + # Other options beside 'alejandra' include 'nixpkgs-fmt' + formatter = forEachSystem (pkgs: pkgs.alejandra); + + # Your custom packages and modifications, exported as overlays + overlays = import ./overlays {inherit inputs outputs;}; + # Reusable nixos modules you might want to export + # These are usually stuff you would upstream into nixpkgs + nixosModules = import ./modules/nixos; + # Reusable home-manager modules you might want to export + # These are usually stuff you would upstream into home-manager + homeManagerModules = import ./modules/home-manager; + + devShells = forEachSystem (pkgs: { + shell = pkgs.mkShell { + name = "nix-config"; + nativeBuildInputs = [pkgs.sops]; + }; + }); + + # NixOS configuration entrypoint + # Available through 'nixos-rebuild --flake .#your-hostname' + nixosConfigurations = { + wopr = nixpkgs.lib.nixosSystem { + specialArgs = {inherit inputs outputs;}; + modules = [ + ./hosts/wopr + ]; + }; + joshua = nixpkgs.lib.nixosSystem { + specialArgs = {inherit inputs outputs;}; + modules = [ + ./hosts/joshua + ]; + }; + norad = nixpkgs.lib.nixosSystem { + specialArgs = {inherit inputs outputs;}; + modules = [ + ./hosts/norad + ]; + }; + work = nixpkgs.lib.nixosSystem { + specialArgs = {inherit inputs outputs;}; + modules = [ + ./hosts/work + ]; + }; + }; + + # Standalone home-manager configuration entrypoint + # Available through 'home-manager --flake .#your-username@your-hostname' + homeConfigurations = { + "sadbeast@wopr" = home-manager.lib.homeManagerConfiguration { + pkgs = pkgsFor.x86_64-linux; + extraSpecialArgs = {inherit inputs outputs;}; + modules = [ + ./home/sadbeast/wopr.nix + ]; + }; + + "sadbeast@joshua" = home-manager.lib.homeManagerConfiguration { + pkgs = pkgsFor.x86_64-linux; + extraSpecialArgs = {inherit inputs outputs;}; + modules = [ + ./home/sadbeast/joshua.nix + ]; + }; + + "sadbeast@norad" = home-manager.lib.homeManagerConfiguration { + pkgs = pkgsFor.x86_64-linux; + extraSpecialArgs = {inherit inputs outputs;}; + modules = [ + ./home/sadbeast/norad.nix + ]; + }; + + "sadbeast@work" = home-manager.lib.homeManagerConfiguration { + pkgs = pkgsFor.x86_64-linux; + extraSpecialArgs = {inherit inputs outputs;}; + modules = [ + ./home/sadbeast/work.nix + ]; + }; + }; + }; +} diff --git a/fs-diff.sh b/fs-diff.sh new file mode 100755 index 0000000..3c10bec --- /dev/null +++ b/fs-diff.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +sudo mkdir /mnt +sudo mount -o subvol=/ /dev/mapper/enc /mnt +#sudo mount -o subvol=/ /dev/sdb3 /mnt + +set -euo pipefail + +OLD_TRANSID=$(sudo btrfs subvolume find-new /mnt/root-blank 9999999) +OLD_TRANSID=${OLD_TRANSID#transid marker was } + +sudo btrfs subvolume find-new "/mnt/root" "$OLD_TRANSID" | +sed '$d' | +cut -f17- -d' ' | +sort | +uniq | +while read path; do + path="/$path" + if [ -L "$path" ]; then + : # The path is a symbolic link, so is probably handled by NixOS already + elif [ -d "$path" ]; then + : # The path is a directory, ignore + else + echo "$path" + fi +done + +sudo umount /mnt +sudo rmdir /mnt diff --git a/home/sadbeast/features/desktop/default.nix b/home/sadbeast/features/desktop/default.nix new file mode 100644 index 0000000..d393fff --- /dev/null +++ b/home/sadbeast/features/desktop/default.nix @@ -0,0 +1,21 @@ +{ + pkgs, + config, + lib, + ... +}: { + imports = [ + ./firefox.nix + ./foot.nix + ./sway.nix + ./waybar.nix + ]; + + home = { + packages = with pkgs; [ + galculator + pavucontrol + wine + ]; + }; +} diff --git a/home/sadbeast/features/desktop/firefox.nix b/home/sadbeast/features/desktop/firefox.nix new file mode 100644 index 0000000..08ec448 --- /dev/null +++ b/home/sadbeast/features/desktop/firefox.nix @@ -0,0 +1,127 @@ +{ + pkgs, + inputs, + lib, + config, + ... +}: let + addons = inputs.firefox-addons.packages.${pkgs.system}; +in { + programs.browserpass.enable = true; + programs.firefox = { + enable = true; + profiles.sadbeast = { + search = { + force = true; + default = "Google"; + privateDefault = "DuckDuckGo"; + order = ["Google" "DuckDuckGo"]; + }; + bookmarks = {}; + extensions = with addons; [ + ublock-origin + browserpass + ]; + bookmarks = {}; + settings = { + "browser.startup.homepage" = "about:home"; + + # Disable irritating first-run stuff + "browser.disableResetPrompt" = true; + "browser.download.panel.shown" = true; + "browser.feeds.showFirstRunUI" = false; + "browser.messaging-system.whatsNewPanel.enabled" = false; + "browser.rights.3.shown" = true; + "browser.shell.checkDefaultBrowser" = false; + "browser.shell.defaultBrowserCheckCount" = 1; + "browser.startup.homepage_override.mstone" = "ignore"; + "browser.uitour.enabled" = false; + "startup.homepage_override_url" = ""; + "trailhead.firstrun.didSeeAboutWelcome" = true; + "browser.bookmarks.restore_default_bookmarks" = false; + "browser.bookmarks.addedImportButton" = true; + + # Don't ask for download dir + "browser.download.useDownloadDir" = false; + + # Disable crappy home activity stream page + "browser.newtabpage.activity-stream.feeds.topsites" = false; + "browser.newtabpage.activity-stream.showSponsoredTopSites" = false; + "browser.newtabpage.activity-stream.improvesearch.topSiteSearchShortcuts" = false; + "browser.newtabpage.blocked" = lib.genAttrs [ + # Youtube + "26UbzFJ7qT9/4DhodHKA1Q==" + # Facebook + "4gPpjkxgZzXPVtuEoAL9Ig==" + # Wikipedia + "eV8/WsSLxHadrTL1gAxhug==" + # Reddit + "gLv0ja2RYVgxKdp0I5qwvA==" + # Amazon + "K00ILysCaEq8+bEqV/3nuw==" + # Twitter + "T9nJot5PurhJSy8n038xGA==" + ] (_: 1); + + # Disable some telemetry + "app.shield.optoutstudies.enabled" = false; + "browser.discovery.enabled" = false; + "browser.newtabpage.activity-stream.feeds.telemetry" = false; + "browser.newtabpage.activity-stream.telemetry" = false; + "browser.ping-centre.telemetry" = false; + "datareporting.healthreport.service.enabled" = false; + "datareporting.healthreport.uploadEnabled" = false; + "datareporting.policy.dataSubmissionEnabled" = false; + "datareporting.sessions.current.clean" = true; + "devtools.onboarding.telemetry.logged" = false; + "toolkit.telemetry.archive.enabled" = false; + "toolkit.telemetry.bhrPing.enabled" = false; + "toolkit.telemetry.enabled" = false; + "toolkit.telemetry.firstShutdownPing.enabled" = false; + "toolkit.telemetry.hybridContent.enabled" = false; + "toolkit.telemetry.newProfilePing.enabled" = false; + "toolkit.telemetry.prompted" = 2; + "toolkit.telemetry.rejected" = true; + "toolkit.telemetry.reportingpolicy.firstRun" = false; + "toolkit.telemetry.server" = ""; + "toolkit.telemetry.shutdownPingSender.enabled" = false; + "toolkit.telemetry.unified" = false; + "toolkit.telemetry.unifiedIsOptIn" = false; + "toolkit.telemetry.updatePing.enabled" = false; + + # Disable fx accounts + "identity.fxaccounts.enabled" = false; + # Disable "save password" prompt + "signon.rememberSignons" = false; + # Harden + "privacy.trackingprotection.enabled" = true; + "dom.security.https_only_mode" = true; + # Layout + "browser.uiCustomization.state" = builtins.toJSON { + currentVersion = 20; + newElementCount = 5; + dirtyAreaCache = ["nav-bar" "PersonalToolbar" "toolbar-menubar" "TabsToolbar" "widget-overflow-fixed-list"]; + placements = { + PersonalToolbar = ["personal-bookmarks"]; + TabsToolbar = ["tabbrowser-tabs" "new-tab-button" "alltabs-button"]; + nav-bar = ["back-button" "forward-button" "stop-reload-button" "urlbar-container" "downloads-button" "ublock0_raymondhill_net-browser-action" "browserpass_maximbaz_com-browser-action" "reset-pbm-toolbar-button" "unified-extensions-button"]; + toolbar-menubar = ["menubar-items"]; + unified-extensions-area = []; + widget-overflow-fixed-list = []; + }; + seen = ["save-to-pocket-button" "developer-button" "ublock0_raymondhill_net-browser-action" "browserpass_maximbaz_com-browser-action"]; + }; + }; + }; + }; + + # home = { + # persistence = { + # # Not persisting is safer + # "/persistent${config.home.homeDirectory}" = { + # directories = [ ".mozilla/firefox" ]; + # allowOther = true; + # }; + # }; + # }; +} diff --git a/home/sadbeast/features/desktop/foot.nix b/home/sadbeast/features/desktop/foot.nix new file mode 100644 index 0000000..d6bb965 --- /dev/null +++ b/home/sadbeast/features/desktop/foot.nix @@ -0,0 +1,21 @@ +{ + inputs, + outputs, + ... +}: { + programs.foot = { + enable = true; + + # server.enable = true; + + settings = { + main = { + font = "Iosevka-11:style=Medium,Regular, JoyPixels"; + font-bold = "Iosevka-11:style=Bold"; + font-italic = "Iosevka-11:style=Italic"; + + underline-offset = 1; + }; + }; + }; +} diff --git a/home/sadbeast/features/desktop/sway.nix b/home/sadbeast/features/desktop/sway.nix new file mode 100644 index 0000000..39e9834 --- /dev/null +++ b/home/sadbeast/features/desktop/sway.nix @@ -0,0 +1,132 @@ +{ + config, + lib, + pkgs, + ... +}: { + home.packages = with pkgs; [ + grim + iosevka + (nerdfonts.override {fonts = ["Iosevka"];}) + light + slurp + swayimg + wl-clipboard + dmenu-wayland + ]; + + fonts.fontconfig.enable = true; + + home.sessionVariables = { + XDG_CURRENT_DESKTOP = "sway"; + MOZ_ENABLE_WAYLAND = 1; + QT_QPA_PLATFORM = "wayland"; + LIBSEAT_BACKEND = "logind"; + SDL_VIDEODRIVER = "wayland"; + }; + + gtk = { + enable = true; + theme = { + package = pkgs.gnome-themes-extra; + # name = "Adwaita-dark"; + name = "Adwaita"; + }; + }; + + home.pointerCursor = { + gtk.enable = true; + package = pkgs.vanilla-dmz; + name = "Vanilla-DMZ"; + size = 22; + }; + + wayland.windowManager.sway = { + enable = true; + + config = { + modifier = "Mod4"; + + bars = []; + + fonts = { + names = ["Iosevka"]; + size = 11.0; + }; + + gaps = { + smartGaps = true; + outer = 0; + }; + + input = { + "*" = { + xkb_layout = "us"; + xkb_options = "ctrl:nocaps"; + tap = "enabled"; + }; + }; + + keybindings = let + modifier = config.wayland.windowManager.sway.config.modifier; + in + lib.mkOptionDefault { + "${modifier}+p" = "exec passmenu"; + "${modifier}+Shift+Return" = "exec qutebrowser"; + "${modifier}+y" = "exec grim ~/scrn-$(date +\"%Y-%m-%d-%H-%M-%S\").png"; + "${modifier}+Shift+y" = "exec slurp | grim -g - ~/scrn-$(date +\"%Y-%m-%d-%H-%M-%S\").png"; + "XF86AudioRaiseVolume" = "exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 2%+ && wpctl get-volume @DEFAULT_AUDIO_SINK@ | sed 's/[^0-9]//g' > $XDG_RUNTIME_DIR/wob.sock"; + "XF86AudioLowerVolume" = "exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 2%- && wpctl get-volume @DEFAULT_AUDIO_SINK@ | sed 's/[^0-9]//g' > $XDG_RUNTIME_DIR/wob.sock"; + "XF86AudioMute" = "exec wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle && (wpctl get-volume @DEFAULT_AUDIO_SINK@ | grep -q MUTED && echo 0 > $XDG_RUNTIME_DIR/wob.sock) || wpctl get-volume @DEFAULT_AUDIO_SINK@ > $XDG_RUNTIME_DIR/wob.sock"; + + "XF86MonBrightnessUp" = "exec light -A 5 && light -G | cut -d'.' -f1 > $XDG_RUNTIME_DIR/wob.sock"; + "XF86MonBrightnessDown" = "exec light -U 5 && light -G | cut -d'.' -f1 > $XDG_RUNTIME_DIR/wob.sock"; + }; + + startup = [ + { + command = "systemctl --user restart waybar"; + always = true; + } + ]; + + terminal = "${pkgs.foot}/bin/foot"; + }; + + extraConfig = '' + # Window borders + default_border pixel 1 + default_floating_border normal + hide_edge_borders smart + ''; + }; + + services = { + mako = { + enable = true; + + extraConfig = '' + [mode=do-not-disturb] + invisible=1 + ''; + }; + + swayidle = { + enable = true; + + events = [ + # { event = "timeout 300"; command = "${pkgs.swaylock}/bin/swaylock -fF -c 000000"; } + # { event = "timeout 600"; command = "swaymsg \"output * dpms off\""; } + { + event = "after-resume"; + command = "swaymsg \"output * dpms on\""; + } + { + event = "before-sleep"; + command = "${pkgs.swaylock}/bin/swaylock -fF -c 000000"; + } + ]; + }; + wob.enable = true; + }; +} diff --git a/home/sadbeast/features/desktop/waybar.css b/home/sadbeast/features/desktop/waybar.css new file mode 100644 index 0000000..725514c --- /dev/null +++ b/home/sadbeast/features/desktop/waybar.css @@ -0,0 +1,70 @@ +* { + border: none; + border-radius: 0; + font-family: Iosevka; + font-size: 13px; + min-height: 0; +} + +window#waybar { + background: rgba(43, 48, 59, 0.5); + border-bottom: 2px solid rgba(100, 114, 125, 0.5); + color: white; +} + +#workspaces { + margin-right: 5px; +} + +#workspaces button { + padding: 0 5px; + background: transparent; + color: white; + border-bottom: 2px solid transparent; +} + +#workspaces button.focused { + background: #64727D; + border-bottom: 2px solid white; +} + +#mode, #clock, #battery { + padding: 0 10px; + margin: 0 5px; +} + +#mode { + background: #64727D; + border-bottom: 2px solid white; +} + +#clock { + background-color: #64727D; +} + +#battery { + background-color: #ffffff; + color: black; +} + +#battery.charging { + color: white; + background-color: #26A65B; +} + +@keyframes blink { + to { + background-color: #ffffff; + color: black; + } +} + +#battery.warning:not(.charging) { + background: #f53c3c; + color: white; + animation-name: blink; + animation-duration: 0.5s; + animation-timing-function: linear; + animation-iteration-count: infinite; + animation-direction: alternate; +} diff --git a/home/sadbeast/features/desktop/waybar.nix b/home/sadbeast/features/desktop/waybar.nix new file mode 100644 index 0000000..02410b4 --- /dev/null +++ b/home/sadbeast/features/desktop/waybar.nix @@ -0,0 +1,57 @@ +{ + programs.waybar = { + enable = true; + systemd.enable = true; + + settings = { + mainBar = { + layer = "bottom"; + position = "top"; + height = 20; + + modules-left = ["sway/workspaces" "sway/mode" "sway/window"]; + modules-right = ["tray" "battery" "clock"]; + + "sway/workspaces" = { + format = "{name}"; + disable-scroll = true; + }; + + "sway/mode" = { + format = " {}"; + }; + + "sway/window" = { + max-length = 80; + tooltip = false; + }; + + clock = { + format = "{:%a %d %I:%M}"; + tooltip = false; + }; + + battery = { + format = "{capacity}% {icon}"; + format-alt = "{time} {icon}"; + format-icons = ["" "" "" "" ""]; + format-charging = "{capacity}% "; + interval = 30; + + states = { + warning = 25; + critical = 10; + }; + + tooltip = false; + }; + + tray = { + icon-size = 18; + }; + }; + }; + + style = ./waybar.css; + }; +} diff --git a/home/sadbeast/features/git.nix b/home/sadbeast/features/git.nix new file mode 100644 index 0000000..477265b --- /dev/null +++ b/home/sadbeast/features/git.nix @@ -0,0 +1,28 @@ +{ + config, + lib, + ... +}: { + programs.git = { + enable = true; + userName = lib.mkDefault config.home.username; + userEmail = lib.mkDefault "sadbeast@sadbeast.com"; + + aliases = { + p = "pull --ff-only"; + ff = "merge --ff-only"; + graph = "log --decorate --oneline --graph"; + add-nowhitespace = "!git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero -"; + # for "last branch", shows the most recently accessed branches + lb = "!git reflog show --pretty=format:'%gs ~ %gd' --date=relative | grep 'checkout:' | grep -oE '[^ ]+ ~ .*' | awk -F~ '!seen[$1]++' | head -n 15 | awk -F' ~ HEAD@{' '{printf(\" \\033[33m%s: \\033[37m %s\\033[0m\\n\", substr($2, 1, length($2)-1), $1)}'"; + }; + + extraConfig = { + init.defaultBranch = "main"; + push.autoSetupRemote = true; + # Reuse merge conflict fixes when rebasing + rerere.enabled = true; + }; + ignores = [".direnv"]; + }; +} diff --git a/home/sadbeast/features/gpg.nix b/home/sadbeast/features/gpg.nix new file mode 100644 index 0000000..5af4838 --- /dev/null +++ b/home/sadbeast/features/gpg.nix @@ -0,0 +1,67 @@ +{ + pkgs, + config, + lib, + ... +}: { + services.gpg-agent = { + enable = true; + # enableSshSupport = true; + # sshKeys = [""]; + enableExtraSocket = true; + pinentryPackage = + if config.gtk.enable + then pkgs.pinentry-gnome3 + else pkgs.pinentry-tty; + }; + + home.packages = lib.optional config.gtk.enable pkgs.gcr; + + programs = let + fixGpg = + /* + bash + */ + '' + gpgconf --launch gpg-agent + ''; + in { + # Start gpg-agent if it's not running or tunneled in + # SSH does not start it automatically, so this is needed to avoid having to use a gpg command at startup + # https://www.gnupg.org/faq/whats-new-in-2.1.html#autostart + bash.profileExtra = fixGpg; + zsh.loginExtra = fixGpg; + + gpg = { + enable = true; + settings = { + trust-model = "tofu+pgp"; + }; + # publicKeys = [ + # { + # source = ../../pgp.asc; + # trust = 5; + # } + # ]; + }; + }; + + systemd.user.services = { + # Link /run/user/$UID/gnupg to ~/.gnupg-sockets + # So that SSH config does not have to know the UID + link-gnupg-sockets = { + Unit = { + Description = "link gnupg sockets from /run to /home"; + }; + Service = { + Type = "oneshot"; + ExecStart = "${pkgs.coreutils}/bin/ln -Tfs /run/user/%U/gnupg %h/.gnupg-sockets"; + ExecStop = "${pkgs.coreutils}/bin/rm $HOME/.gnupg-sockets"; + RemainAfterExit = true; + }; + Install.WantedBy = ["default.target"]; + }; + }; +} +# vim: filetype=nix + diff --git a/home/sadbeast/features/pass.nix b/home/sadbeast/features/pass.nix new file mode 100644 index 0000000..0a64f41 --- /dev/null +++ b/home/sadbeast/features/pass.nix @@ -0,0 +1,17 @@ +{ + pkgs, + config, + ... +}: { + programs.password-store = { + enable = true; + settings = { + PASSWORD_STORE_DIR = "$HOME/.password-store"; + }; + package = pkgs.pass.withExtensions (p: [p.pass-otp]); + }; + + # home.persistence = { + # "/persistent${config.home.homeDirectory}".directories = [".password-store"]; + # }; +} diff --git a/home/sadbeast/features/services.nix b/home/sadbeast/features/services.nix new file mode 100644 index 0000000..71ef7d8 --- /dev/null +++ b/home/sadbeast/features/services.nix @@ -0,0 +1,21 @@ +{pkgs, ...}: { + services = { + swayidle = { + enable = true; + + events = [ + # { event = "timeout 300"; command = "${pkgs.swaylock}/bin/swaylock -fF -c 000000"; } + # { event = "timeout 600"; command = "swaymsg \"output * dpms off\""; } + { + event = "after-resume"; + command = "swaymsg \"output * dpms on\""; + } + { + event = "before-sleep"; + command = "${pkgs.swaylock}/bin/swaylock -fF -c 000000"; + } + ]; + }; + wob.enable = true; + }; +} diff --git a/home/sadbeast/features/ssh.nix b/home/sadbeast/features/ssh.nix new file mode 100644 index 0000000..aeace3c --- /dev/null +++ b/home/sadbeast/features/ssh.nix @@ -0,0 +1,26 @@ +{ + programs.ssh = { + enable = true; + + matchBlocks = { + "falken" = { + hostname = "sadbeast.com"; + port = 6973; + }; + + "crystalpalace" = { + hostname = "192.168.0.2"; + port = 6973; + }; + + "joshua" = { + hostname = "192.168.0.3"; + }; + + "teamdraft" = { + hostname = "teamdraft.net"; + port = 6973; + }; + }; + }; +} diff --git a/home/sadbeast/features/vim.nix b/home/sadbeast/features/vim.nix new file mode 100644 index 0000000..173304d --- /dev/null +++ b/home/sadbeast/features/vim.nix @@ -0,0 +1,245 @@ +{pkgs, ...}: { + programs.vim = { + enable = true; + defaultEditor = true; + + plugins = with pkgs.vimPlugins; [ + # ale + asyncomplete-vim + asyncomplete-lsp-vim + base16-vim + copilot-vim + lightline-vim + # lightline-ale + lightline-lsp + fugitive + fzf-vim + vim-commentary + vim-dadbod + vim-dispatch + vim-dotenv + vim-eunuch + vim-lsp + # vim-lsp-ale + vim-lsp-settings + vim-mustache-handlebars + vim-rails + vim-signify + vim-wayland-clipboard + vim-vsnip + vim-vsnip-integ + zig-vim + ]; + + settings = { + hidden = true; + ignorecase = true; + # mouse = "a"; + number = true; + relativenumber = true; + smartcase = true; + }; + + extraConfig = '' + set nocompatible + set encoding=utf-8 + set wildmenu + set showcmd + set hlsearch + " Use visual bell instead of beeping when doing something wrong + set visualbell + + " And reset the terminal code for the visual bell. If visualbell is set, and + " this line is also included, vim will neither flash nor beep. If visualbell + " is unset, this does nothing. + set t_vb= + set backspace=indent,eol,start + set autoindent + set nostartofline + set ruler + set confirm + " Quickly time out on keycodes, but never time out on mappings + set notimeout ttimeout ttimeoutlen=200 + set pastetoggle=<F11> + " automatically leave paste mode so I don't forget + autocmd InsertLeave * set nopaste + " Indentation settings for using 4 spaces instead of tabs. + " Do not change 'tabstop' from its default value of 8 with this setup. + set shiftwidth=4 + set softtabstop=4 + set expandtab + " Don't update the screen when executing macros + set lazyredraw + + " Easier to reach than \ + let mapleader=" " + + " fzf + nmap <leader>p :Files<cr> + nmap <leader>bb :Buffers<cr> + + " dadbod + autocmd FileType sql let b:dispatch = 'pgcli %' + vnoremap <leader>d :DB<cr> + nmap <leader>d :DB<cr> + + set formatoptions=ctqrn1 + + " Show matching brackets. + set showmatch + + " Bracket blinking. + set matchtime=5 + + " start scrolling when we're 8 lines away from margins + set scrolloff=8 + set sidescrolloff=15 + set sidescroll=1 + + set noswapfile + set nobackup + set nowb + + " Automatically insert the current comment leader after hitting 'o' or 'O' in Normal mode. + "set fo+=o + " Do not automatically insert a comment leader after an enter + "set fo-=r + " Do no auto-wrap text using textwidth (does not apply to comments) + "set fo-=t + + set wildignore+=*/tmp/*,*.so,*.swp,*.zip,*/vendor/*,*/bin/*,*/node_modules/* + + " quicker async update time + set updatetime=100 + + " taller vertical bar for vsplits + set fillchars+=vert:│ + + set ttymouse = "sgr"; + + " Enable 24-bit colors + set termguicolors + let &t_8f = "\<Esc>[38:2::%lu:%lu:%lum" + let &t_8b = "\<Esc>[48:2::%lu:%lu:%lum" + + " Workaround bug in vim, where it incorrectly thinks modifyOtherKeys level 2 is + " enabled, even when it's not. The snippets below ensure modifyOtherKeys=2 is + " enabled. https://github.com/vim/vim/issues/9014 + let &t_TI = "\<Esc>[>4;2m" + let &t_TE = "\<Esc>[>4;m" + + set undodir=~/.vim/backups + set undofile + + " When opening a file, always jump to the last cursor position + autocmd BufReadPost * + \ if line("'\"") > 0 && line ("'\"") <= line("$") | + \ exe "normal g'\"" | + \ endif + + " remove annoying help window + inoremap <F1> <nop> + nnoremap <F1> <nop> + vnoremap <F1> <nop> + + " better window navigation + nnoremap <c-j> <c-w>j + nnoremap <c-k> <c-w>k + nnoremap <c-h> <c-w>h + nnoremap <c-l> <c-w>l + + " quickfix + nnoremap <c-n> :cnext<CR> + nnoremap <c-b> :cprevious<CR> + + " command line autocomplete + set wildchar=<Tab> wildmenu wildmode=full + + " scroll through buffers + noremap <left> :bp<CR> + noremap <right> :bn<CR> + + " show menu to switch buffers + set wildcharm=<C-Z> + nnoremap <F10> :b <C-Z> + + " unhighlight search results + noremap <silent><Leader>/ :nohls<CR> + + " reselect visual block after indent/outdent + vnoremap < <gv + vnoremap > >gv + + " force saving files that require root permission + cmap w!! %!sudo tee > /dev/null % + + " Close the current buffer and move to the previous one + " This replicates the idea of closing a tab + nmap <leader>bq :bp <BAR> bd #<CR> + + colorscheme base16-default-dark + + let g:termdebug_popup = 0 + let g:termdebug_wide = 163 + + " vim-lsp + function! s:on_lsp_buffer_enabled() abort + setlocal omnifunc=lsp#complete + setlocal signcolumn=yes + if exists('+tagfunc') | setlocal tagfunc=lsp#tagfunc | endif + nmap <buffer> gd <plug>(lsp-definition) + nmap <buffer> gs <plug>(lsp-document-symbol-search) + nmap <buffer> gS <plug>(lsp-workspace-symbol-search) + nmap <buffer> gr <plug>(lsp-references) + nmap <buffer> gi <plug>(lsp-implementation) + nmap <buffer> gt <plug>(lsp-type-definition) + nmap <buffer> <leader>rn <plug>(lsp-rename) + nmap <buffer> [g <plug>(lsp-previous-diagnostic) + nmap <buffer> ]g <plug>(lsp-next-diagnostic) + nmap <buffer> K <plug>(lsp-hover) + " nnoremap <buffer> <expr><c-f> lsp#scroll(+4) + " nnoremap <buffer> <expr><c-d> lsp#scroll(-4) + + let g:lsp_format_sync_timeout = 1000 + autocmd! BufWritePre *.rs,*.go call execute('LspDocumentFormatSync') + + " refer to doc to add more commands + endfunction + + augroup lsp_install + au! + " call s:on_lsp_buffer_enabled only for languages that has the server registered. + autocmd User lsp_buffer_enabled call s:on_lsp_buffer_enabled() + augroup END + + "if executable('solargraph') + " " gem install solargraph + " au User lsp_setup call lsp#register_server({ + " \ 'name': 'solargraph', + " \ 'cmd': {server_info->[&shell, &shellcmdflag, 'solargraph stdio']}, + " \ 'initialization_options': {"diagnostics": "true"}, + " \ 'whitelist': ['ruby'], + " \ }) + "endif + + " asyncomplete + inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>" + inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>" + inoremap <expr> <cr> pumvisible() ? asyncomplete#close_popup() : "\<cr>" + + imap <c-@> <Plug>(asyncomplete_force_refresh) + + " vim-vsnip + " Expand + imap <expr> <C-j> vsnip#expandable() ? '<Plug>(vsnip-expand)' : '<C-j>' + smap <expr> <C-j> vsnip#expandable() ? '<Plug>(vsnip-expand)' : '<C-j>' + + " Expand or jump + imap <expr> <C-l> vsnip#available(1) ? '<Plug>(vsnip-expand-or-jump)' : '<C-l>' + smap <expr> <C-l> vsnip#available(1) ? '<Plug>(vsnip-expand-or-jump)' : '<C-l>' + + " Copilot ugh + " let g:copilot_node_command = "/usr/bin/env node" + ''; + }; +} diff --git a/home/sadbeast/features/zsh.nix b/home/sadbeast/features/zsh.nix new file mode 100644 index 0000000..db568e6 --- /dev/null +++ b/home/sadbeast/features/zsh.nix @@ -0,0 +1,67 @@ +{ + pkgs, + config, + ... +}: { + programs.zsh = { + enable = true; + autocd = true; + enableCompletion = true; + enableVteIntegration = true; + autosuggestion.enable = true; + syntaxHighlighting.enable = true; + + loginExtra = '' + if [ "$(tty)" = "/dev/tty1" ]; then + exec sway + fi + ''; + + initExtra = '' + precmd() { + print -Pn "\e]133;A\e\\" + } + + function osc7-pwd() { + emulate -L zsh # also sets localoptions for us + setopt extendedglob + local LC_ALL=C + printf '\e]7;file://%s%s\e\' $HOST ''${PWD//(#m)([^@-Za-z&-;_~])/%''${(l:2::0:)$(([##16]#MATCH))}} + } + + function chpwd-osc7-pwd() { + (( ZSH_SUBSHELL )) || osc7-pwd + } + add-zsh-hook -Uz chpwd chpwd-osc7-pwd + ''; + + defaultKeymap = "emacs"; + + history = { + size = 10000; + path = "${config.xdg.dataHome}/zsh/zsh_history"; + }; + + shellAliases = { + ll = "ls -l"; + }; + + sessionVariables = { + EDITOR = "vim"; + }; + + # TODO: this causes a 2 second delay + # plugins = [ + # { + # name = "zsh-nix-shell"; + # file = "nix-shell.plugin.zsh"; + # src = pkgs.fetchFromGitHub { + # owner = "chisui"; + # repo = "zsh-nix-shell"; + # rev = "v0.8.0"; + # sha256 = "1lzrn0n4fxfcgg65v0qhnj7wnybybqzs4adz7xsrkgmcsr0ii8b7"; + # }; + # } + # ]; + }; +} diff --git a/home/sadbeast/global/default.nix b/home/sadbeast/global/default.nix new file mode 100644 index 0000000..e811b6f --- /dev/null +++ b/home/sadbeast/global/default.nix @@ -0,0 +1,211 @@ +{ + inputs, + outputs, + lib, + config, + pkgs, + ... +}: { + # You can import other home-manager modules here + imports = [ + # If you want to use modules your own flake exports (from modules/home-manager): + # outputs.homeManagerModules.example + + # Or modules exported from other flakes (such as nix-colors): + # inputs.nix-colors.homeManagerModules.default + inputs.impermanence.nixosModules.home-manager.impermanence + + # You can also split up your configuration and import pieces of it here: + ../features/git.nix + ../features/gpg.nix + ../features/pass.nix + ../features/ssh.nix + ../features/vim.nix + ../features/zsh.nix + ]; + + nix = { + package = lib.mkDefault pkgs.nix; + settings = { + experimental-features = [ + "nix-command" + "flakes" + "ca-derivations" + ]; + warn-dirty = false; + }; + }; + + nixpkgs = { + overlays = [ + # Add overlays your own flake exports (from overlays and pkgs dir): + outputs.overlays.additions + # outputs.overlays.modifications + outputs.overlays.stable-packages + + # You can also add overlays exported from other flakes: + # neovim-nightly-overlay.overlays.default + + # Or define it inline, for example: + # (final: prev: { + # hi = final.hello.overrideAttrs (oldAttrs: { + # patches = [ ./change-hello-to-hi.patch ]; + # }); + # }) + ]; + + config = { + allowUnfree = true; + allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ + "joypixels" + ]; + joypixels.acceptLicense = true; + }; + }; + + home = { + username = "sadbeast"; + homeDirectory = "/home/${config.home.username}"; + }; + + programs = { + # browserpass = { + # enable = true; + # browsers = [ "firefox" ]; + # }; + + btop.enable = true; + fd.enable = true; + firefox = { + package = pkgs.wrapFirefox (pkgs.firefox-unwrapped.override {pipewireSupport = true;}) {}; + enable = true; + }; + gpg.enable = true; + home-manager.enable = true; + qutebrowser.enable = true; + ripgrep.enable = true; + starship.enable = true; + swaylock.enable = true; + + tmux = { + enable = true; + shortcut = "a"; + escapeTime = 0; + + plugins = with pkgs; [ + tmuxPlugins.better-mouse-mode + tmuxPlugins.pain-control + ]; + + extraConfig = '' + # https://old.reddit.com/r/tmux/comments/mesrci/tmux_2_doesnt_seem_to_use_256_colors/ + set -g default-terminal "xterm-256color" + set -ga terminal-overrides ",*256col*:Tc" + set -ga terminal-overrides '*:Ss=\E[%p1%d q:Se=\E[ q' + set-environment -g COLORTERM "truecolor" + + # Mouse works as expected + set-option -g mouse on + # easy-to-remember split pane commands + bind | split-window -h -c "#{pane_current_path}" + bind - split-window -v -c "#{pane_current_path}" + bind c new-window -c "#{pane_current_path}" + ''; + }; + + direnv = { + enable = true; + enableZshIntegration = true; + nix-direnv.enable = true; + }; + + fzf = { + enable = true; + defaultCommand = "fd -H -E .git --type f"; + changeDirWidgetCommand = "fd --type d"; + fileWidgetCommand = "fd --type f"; + historyWidgetOptions = [ + "--sort" + "--exact" + ]; + }; + + keychain = { + enable = true; + enableZshIntegration = true; + keys = ["id_ed25519"]; + extraFlags = ["--quiet"]; + }; + }; + + home = { + packages = with pkgs; [ + httpie + jq + joypixels + sops + unzip + uxn + zig + ]; + + # persistence = { + # "${config.home.homeDirectory}" = { + # directories = [ + # { + # directory = "docs"; + # method = "symlink"; + # } + # { + # directory = "projects"; + # method = "symlink"; + # } + # { + # directory = ".local/share/qutebrowser"; + # method = "symlink"; + # } + # { + # directory = ".local/share/vim-lsp-settings"; + # method = "symlink"; + # } + # ".password-store" + # ".local/share/direnv" + # ".local/share/zsh" + # ".gnupg" + # ".ssh" + # ]; + # allowOther = true; + # }; + # }; + }; + + xdg.userDirs = let + homeDir = config.home.homeDirectory; + in { + enable = true; + createDirectories = false; + + desktop = "${homeDir}"; + documents = "${homeDir}/docs"; + download = "${homeDir}/downloads"; + pictures = "${homeDir}/pics"; + }; + + xdg.mimeApps = { + enable = true; + + defaultApplications = { + "text/html" = "org.qutebrowser.qutebrowser.desktop"; + "x-scheme-handler/http" = "org.qutebrowser.qutebrowser.desktop"; + "x-scheme-handler/https" = "org.qutebrowser.qutebrowser.desktop"; + "x-scheme-handler/about" = "org.qutebrowser.qutebrowser.desktop"; + "x-scheme-handler/unknown" = "org.qutebrowser.qutebrowser.desktop"; + }; + }; + + # Nicely reload system units when changing configs + systemd.user.startServices = "sd-switch"; + + # https://nixos.wiki/wiki/FAQ/When_do_I_update_stateVersion + home.stateVersion = "24.05"; +} diff --git a/home/sadbeast/joshua.nix b/home/sadbeast/joshua.nix new file mode 100644 index 0000000..44c3a47 --- /dev/null +++ b/home/sadbeast/joshua.nix @@ -0,0 +1,26 @@ +{ + pkgs, + config, + lib, + ... +}: { + imports = [ + ./global + ./features/desktop + ]; + + # ---------- --------- + # | HDMI-A-1 | | DVI-D-1 | + # ---------- --------- + + wayland.windowManager.sway.config.output = { + HDMI-A-1 = { + resolution = "1920x1080"; + position = "0,0"; + }; + DVI-D-1 = { + resolution = "1920x1080"; + position = "1920,0"; + }; + }; +} diff --git a/home/sadbeast/norad.nix b/home/sadbeast/norad.nix new file mode 100644 index 0000000..477930c --- /dev/null +++ b/home/sadbeast/norad.nix @@ -0,0 +1,11 @@ +{ + pkgs, + config, + lib, + ... +}: { + imports = [ + ./global + ./features/desktop + ]; +} diff --git a/home/sadbeast/wopr.nix b/home/sadbeast/wopr.nix new file mode 100644 index 0000000..477930c --- /dev/null +++ b/home/sadbeast/wopr.nix @@ -0,0 +1,11 @@ +{ + pkgs, + config, + lib, + ... +}: { + imports = [ + ./global + ./features/desktop + ]; +} diff --git a/home/sadbeast/work.nix b/home/sadbeast/work.nix new file mode 100644 index 0000000..5d253e8 --- /dev/null +++ b/home/sadbeast/work.nix @@ -0,0 +1,64 @@ +{ + pkgs, + config, + lib, + ... +}: { + imports = [ + ./global + ./features/desktop + ]; + + home = { + sessionVariables = { + BUNDLE_PATH = "vendor/bundle"; + }; + + packages = with pkgs; [ + aws-sam-cli + awscli2 + gcc + google-chrome + ruby + nodejs + slack + ruby-lsp + ssm-session-manager-plugin + ]; + }; + + programs = { + git = { + userName = "Kent Smith"; + userEmail = "kent.smith@andros.co"; + + extraConfig = { + core.sshCommand = "ssh -i ~/.ssh/id_rsa -o IdentitiesOnly=yes"; + }; + }; + + obs-studio = { + enable = true; + plugins = with pkgs.obs-studio-plugins; [ + wlrobs + obs-backgroundremoval + obs-pipewire-audio-capture + ]; + }; + }; + + wayland.windowManager.sway.config.output = { + eDP-1 = { + resolution = "1920x1080"; + position = "0,0"; + }; + HDMI-A-1 = { + resolution = "1920x1080"; + position = "0,1080"; + }; + DP-1 = { + resolution = "1920x1080"; + position = "1920,1080"; + }; + }; +} diff --git a/hosts/common/global/default.nix b/hosts/common/global/default.nix new file mode 100644 index 0000000..3f33d55 --- /dev/null +++ b/hosts/common/global/default.nix @@ -0,0 +1,174 @@ +# This holds configuration common across hosts +{ + inputs, + outputs, + lib, + config, + pkgs, + ... +}: { + # You can import other NixOS modules here + imports = [ + inputs.home-manager.nixosModules.home-manager + inputs.impermanence.nixosModules.impermanence + ./sops.nix + ]; + + #home-manager.useGlobalPkgs = true; + home-manager.backupFileExtension = "backup"; + home-manager.extraSpecialArgs = { + inherit inputs outputs; + }; + + nixpkgs = { + # You can add overlays here + overlays = [ + # Add overlays your own flake exports (from overlays and pkgs dir): + outputs.overlays.additions + # outputs.overlays.modifications + + outputs.overlays.stable-packages + + # You can also add overlays exported from other flakes: + # neovim-nightly-overlay.overlays.default + + # Or define it inline, for example: + # (final: prev: { + # hi = final.hello.overrideAttrs (oldAttrs: { + # patches = [ ./change-hello-to-hi.patch ]; + # }); + # }) + ]; + config = { + allowUnfree = true; + }; + }; + + nix = let + flakeInputs = lib.filterAttrs (_: lib.isType "flake") inputs; + in { + settings = { + # Enable flakes and new 'nix' command + experimental-features = "nix-command flakes ca-derivations"; + # Opinionated: disable global registry + flake-registry = ""; + # Workaround for https://github.com/NixOS/nix/issues/9574 + nix-path = config.nix.nixPath; + }; + gc = { + automatic = true; + dates = "daily"; + options = "--delete-older-than 7d"; + }; + # Opinionated: disable channels + channel.enable = false; + + # Opinionated: make flake registry and nix path match flake inputs + registry = lib.mapAttrs (_: flake: {inherit flake;}) flakeInputs; + nixPath = lib.mapAttrsToList (n: _: "${n}=flake:${n}") flakeInputs; + }; + + time.timeZone = "America/Los_Angeles"; + + i18n.defaultLocale = "en_US.UTF-8"; + console = { + font = "Lat2-Terminus16"; + keyMap = "emacs2"; + }; + + programs = { + sway.enable = true; + zsh.enable = true; + git.enable = true; + + fuse.userAllowOther = true; + }; + + users.mutableUsers = false; + + users.users.sadbeast = { + hashedPasswordFile = config.sops.secrets.sadbeast-password.path; + isNormalUser = true; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINGpEusv/bS34Q1JQxZXikdcwnq1vToz2d+HgV+E8NRX" + ]; + + extraGroups = ["wheel" "audio" "docker"]; + shell = pkgs.zsh; + packages = [pkgs.home-manager]; + }; + + sops.secrets.sadbeast-password = { + sopsFile = ../secrets.yaml; + neededForUsers = true; + }; + + home-manager.users.sadbeast = import ../../../home/sadbeast/${config.networking.hostName}.nix; + + # This setups a SSH server. Very important if you're setting up a headless system. + # Feel free to remove if you don't need it. + services = { + avahi = { + enable = true; + nssmdns4 = true; + openFirewall = true; + }; + + openssh = { + enable = true; + settings = { + # Opinionated: forbid root login through SSH. + PermitRootLogin = "no"; + # Opinionated: use keys only. + # Remove if you want to SSH using passwords + PasswordAuthentication = false; + }; + }; + + pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + }; + + printing.enable = true; + }; + security = { + polkit.enable = true; + # rtkit is optional but recommended + rtkit.enable = true; + sudo.wheelNeedsPassword = false; + + pam.services = { + swaylock = {}; + }; + }; + + # environment.persistence."/persistent" = { + # hideMounts = true; + # directories = [ + # "/var/log" + # "/var/lib/nixos" + # "/var/lib/systemd" + # ]; + # files = [ + # "/etc/machine-id" + # "/var/lib/sops-nix/keys.txt" + # ]; + # }; + + # system.activationScripts.persistent-dirs.text = let + # mkHomePersist = user: + # lib.optionalString user.createHome '' + # mkdir -p /persistent/${user.home} + # chown ${user.name}:${user.group} /persistent/${user.home} + # chmod ${user.homeMode} /persistent/${user.home} + # ''; + # users = lib.attrValues config.users.users; + # in + # lib.concatLines (map mkHomePersist users); + + # https://nixos.wiki/wiki/FAQ/When_do_I_update_stateVersion + system.stateVersion = "24.05"; +} diff --git a/hosts/common/global/sops.nix b/hosts/common/global/sops.nix new file mode 100644 index 0000000..9d1d42b --- /dev/null +++ b/hosts/common/global/sops.nix @@ -0,0 +1,17 @@ +{ + inputs, + lib, + config, + ... +}: { + imports = [inputs.sops-nix.nixosModules.sops]; + + sops = { + age = { + #keyFile = "/persistent/var/lib/sops-nix/keys.txt"; + keyFile = "/var/lib/sops-nix/keys.txt"; + sshKeyPaths = []; + }; + gnupg.sshKeyPaths = []; + }; +} diff --git a/hosts/common/optional/wireless.nix b/hosts/common/optional/wireless.nix new file mode 100644 index 0000000..ce66419 --- /dev/null +++ b/hosts/common/optional/wireless.nix @@ -0,0 +1,35 @@ +{config, ...}: { + # Wireless secrets stored through sops + sops.secrets.wireless = { + sopsFile = ../secrets.yaml; + neededForUsers = true; + }; + + networking.wireless = { + enable = true; + fallbackToWPA2 = false; + + # Declarative + secretsFile = config.sops.secrets.wireless.path; + networks = { + "Black Vulture" = { + pskRaw = "ext:home_psk"; + }; + }; + + # Imperative + allowAuxiliaryImperativeNetworks = true; + userControlled = { + enable = true; + group = "network"; + }; + extraConfig = '' + update_config=1 + ''; + }; + + # Ensure group exists + users.groups.network = {}; + + systemd.services.wpa_supplicant.preStart = "touch /etc/wpa_supplicant.conf"; +} diff --git a/hosts/common/secrets.yaml b/hosts/common/secrets.yaml new file mode 100644 index 0000000..d0dc065 --- /dev/null +++ b/hosts/common/secrets.yaml @@ -0,0 +1,50 @@ +sadbeast-password: ENC[AES256_GCM,data:Oy3x2JbsX/iTHSYd//sScEfpK2AcW9mfAD/jHR1zymkZ/hMgrK/pfzWiCiLSrCoV38lcaBsFHdv80Bf7TRhYkUQZ6F6EPtaVYg==,iv:/cEQPob8z5fzsUIo1unv7zT8h2MsdKMTVBxnSMlCgaM=,tag:afhjGiTXdPjiZVpzAKUvwA==,type:str] +work-password: ENC[AES256_GCM,data:6gcVp0kW+6sHg/9KxqjtnGa6ycfSitlAAAzgc2teE2mmgh9DBfP+0IiTGk0XrHjLZCrGCa/zyrIDKq3jdXE+E42laH7H68SrpA==,iv:LvRc7Uj5MJ3RMxIbp5s2U5qx50RLKe6o8mZSqwbrktk=,tag:ZpIaOfTWtt/6w93O/B2drw==,type:str] +wireless: ENC[AES256_GCM,data:aeetnjjKGbt0wudRuIY5ruemnxlhm5Iw808G5D9BO1dTYi0EbA7JrXHz3wXh737WsPMOXL0S9NaeRH4w,iv:NIoIJ6CjXWGesoEraRoSH2hmF2JpRvpV8fCpwNi06/c=,tag:/aS84d4H0jEHCBZd/CCOCg==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age16qcn9298rk3eav38442zw2ejhqac6uvdj0m86qf4ggnjgug8efgsp9lwcd + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBndG9RVWpCZXlsanhTbUky + N1drL1RlZVpZbElCaDljVWx6ZG9Vc3JsbTBRCk0rclJkUCtzdVF5NDdKTFRsamZR + UXpleTFWcU9CWlRyL0JLVVJCNnNzL2MKLS0tIHNISSsvTllQaFZ5dGk2VTJ0Vkxq + enh2dmxhcDgyNjlKRDFRZnlWTndYZjgK8aRkrdMx+SaZBnc2HFVdmwGm8K5T19Aa + UsoeqXyCPA1rxUFA6eCzy9y9sst/susfkwgRwFucP9W8lE3+kglMNg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1hls0h26tcls67ukcpt7e0ztua8mwzheaqkuuwl4anv8zstq8regqd7nqv9 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPa1RucTA0UnVSQkhtdE9P + c2wzS01ucWN5M3A2QjRYZ1h4Y00wSjJvUkJjCktGck9JRFVYcGQyQ0plQ1B6dDNU + Zit2MmpDRExTU1NwR0pxc0dyaXdJUjAKLS0tIGE5YXFoRW1MU2VyL2N3ZGFmQSti + dFAvNEtTYlgzMUJZQjhZK3VvWGNvTWsKzafclExVkycuEnq5lsloVYSpUd+1SfQS + rj5xDJV8E37+q7lsizRhKMtjJNv/raeLXicsBwL2vmnY6RoYsPSfCw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1dg0dxg6nf5rm05py3da3yz8tkg7xtgustuehxwn37cm8mdrf93ysn9n622 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArVEZZaXQ0TjU1RFVZMnQr + MWQzbXEyV25RZmhVRFZlUzdjamNYR2hWcjBZCkRSSWMrSVpVV3pETkJUY1AyZTRZ + SVZkZDhnMkhaUUxWYklTdUszVlM2VHMKLS0tIFNrL0crZExQV3p2ZGxScmo1aXlK + Y3BLSkFyVkpUalRjSkxHMFpLVTJabTAKW2ydqX5ZulhSyiFCaNW3rMFncNBGllZU + v2HET4US1eUzT8suMWzfhjm7GA6D7KD3pJICglhtumk9sihRL3TrQg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1a6k6lwndk7w5ck3w8vydw72af3q8appm6jyxj7amwp6fmqnylywsy7ay0e + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUeFlOb093ekpDanBiZEl0 + TGo4T2w4aHk4Zjl6eUdrS0diQzBWM1ltUDN3ClpVemlBN1YvVmNuZFlGWEVhSktv + SHNOZFBzWm5DTzJyNEhiSVRTampjR0UKLS0tIFFVODY0L1h0bThIclgxRnhVZmtk + Njl4U3h2UmZUOVhnQ0lqb3NnbUcwME0KfEhBK4MnSGDwQZYztvWKl5k4zRZD+kDT + t2yCzytfW3wcWmnqnbtBqFGFiZhtBaN1GhlJhHJY16JClJ/c8dhQ6g== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-09-17T23:15:06Z" + mac: ENC[AES256_GCM,data:ojX6Ec9XP2MMnBQUkxlvmJYL+q9RGgwNZbtu7HObbXKXwozk68r//A2BwMFILcuFaSi1y1TOfgs1xdSr8wZPqLsGxLLSkruhmNnjO2fbYPYc33FW4OYoloTFeGZuL7Z1RGXUwDDZ59nqzH8DwKqfAmorJ2opyWS/igmEf1plWHQ=,iv:0+za47Ga2yfPcOlV4a8WniQ4wQma+k0+xqFqWvDXdGQ=,tag:Yoz3TvK7QtqwgZMVLJweoA==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.0 diff --git a/hosts/joshua/default.nix b/hosts/joshua/default.nix new file mode 100644 index 0000000..f2cdd3a --- /dev/null +++ b/hosts/joshua/default.nix @@ -0,0 +1,18 @@ +{ + imports = [ + ./hardware-configuration.nix + + ../common/global + ]; + + # Use the systemd-boot EFI boot loader. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + networking.hostName = "joshua"; + + sound.enable = true; + + # https://nixos.wiki/wiki/FAQ/When_do_I_update_stateVersion + system.stateVersion = "24.05"; +} diff --git a/hosts/joshua/hardware-configuration.nix b/hosts/joshua/hardware-configuration.nix new file mode 100644 index 0000000..fd53e13 --- /dev/null +++ b/hosts/joshua/hardware-configuration.nix @@ -0,0 +1,98 @@ +# 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" "ahci" "usbhid" "usb_storage" "sd_mod" "sr_mod"]; + boot.initrd.kernelModules = []; + boot.kernelModules = []; + boot.extraModulePackages = []; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/32a45644-86e5-42c0-96e9-343e8078349e"; + fsType = "btrfs"; + options = ["subvol=root" "noatime"]; + }; + + # Note `lib.mkBefore` is used instead of `lib.mkAfter` here. + #boot.initrd.postDeviceCommands = pkgs.lib.mkBefore '' + # mkdir -p /mnt + + # # We first mount the btrfs root to /mnt + # # so we can manipulate btrfs subvolumes. + # mount -o subvol=/ /dev/mapper/enc /mnt + + # # While we're tempted to just delete /root and create + # # a new snapshot from /root-blank, /root is already + # # populated at this point with a number of subvolumes, + # # which makes `btrfs subvolume delete` fail. + # # So, we remove them first. + # # + # # /root contains subvolumes: + # # - /root/var/lib/portables + # # - /root/var/lib/machines + # # + # # I suspect these are related to systemd-nspawn, but + # # since I don't use it I'm not 100% sure. + # # Anyhow, deleting these subvolumes hasn't resulted + # # in any issues so far, except for fairly + # # benign-looking errors from systemd-tmpfiles. + # btrfs subvolume list -o /mnt/root | + # cut -f9 -d' ' | + # while read subvolume; do + # echo "deleting /$subvolume subvolume..." + # btrfs subvolume delete "/mnt/$subvolume" + # done && + # echo "deleting /root subvolume..." && + # btrfs subvolume delete /mnt/root + + # echo "restoring blank /root subvolume..." + # btrfs subvolume snapshot /mnt/root-blank /mnt/root + + # # Once we're done rolling back to a blank snapshot, + # # we can unmount /mnt and continue on the boot process. + # umount /mnt + #''; + + fileSystems."/nix" = { + device = "/dev/disk/by-uuid/32a45644-86e5-42c0-96e9-343e8078349e"; + fsType = "btrfs"; + options = ["subvol=nix" "noatime"]; + }; + + fileSystems."/persistent" = { + device = "/dev/disk/by-uuid/32a45644-86e5-42c0-96e9-343e8078349e"; + fsType = "btrfs"; + neededForBoot = true; + options = ["subvol=persist" "noatime"]; + }; + + fileSystems."/boot" = { + device = "/dev/disk/by-uuid/323A-5741"; + fsType = "vfat"; + options = ["fmask=0022" "dmask=0022"]; + }; + + swapDevices = [ + {device = "/dev/disk/by-uuid/1962cd0f-4063-4996-a33c-8ebaa9ecea1d";} + ]; + + # 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.<interface>.useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.enp0s31f6.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/norad/default.nix b/hosts/norad/default.nix new file mode 100644 index 0000000..c1126b2 --- /dev/null +++ b/hosts/norad/default.nix @@ -0,0 +1,26 @@ +{ + imports = [ + ./hardware-configuration.nix + + ../common/global + ../common/optional/wireless.nix + ]; + + # Use the systemd-boot EFI boot loader. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + networking.hostName = "norad"; + + # Slows down write operations considerably + nix.settings.auto-optimise-store = false; + + services = { + logind.extraConfig = '' + HandleLidSwitchExternalPower=ignore + ''; + }; + + # https://nixos.wiki/wiki/FAQ/When_do_I_update_stateVersion + system.stateVersion = "24.05"; +} diff --git a/hosts/norad/hardware-configuration.nix b/hosts/norad/hardware-configuration.nix new file mode 100644 index 0000000..f9b6a44 --- /dev/null +++ b/hosts/norad/hardware-configuration.nix @@ -0,0 +1,102 @@ +{ + config, + lib, + pkgs, + modulesPath, + ... +}: { + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = ["ehci_pci" "ahci" "firewire_ohci" "usb_storage" "sd_mod" "sr_mod" "sdhci_pci"]; + boot.initrd.kernelModules = []; + boot.kernelModules = ["kvm-intel"]; + boot.extraModulePackages = []; + + boot.initrd.luks.devices."enc".device = "/dev/disk/by-uuid/088d061d-7a81-4a91-9d97-c5958d5d4b6c"; + + # Note `lib.mkBefore` is used instead of `lib.mkAfter` here. + #boot.initrd.postDeviceCommands = pkgs.lib.mkBefore '' + # mkdir -p /mnt + + # # We first mount the btrfs root to /mnt + # # so we can manipulate btrfs subvolumes. + # mount -o subvol=/ /dev/mapper/enc /mnt + + # # While we're tempted to just delete /root and create + # # a new snapshot from /root-blank, /root is already + # # populated at this point with a number of subvolumes, + # # which makes `btrfs subvolume delete` fail. + # # So, we remove them first. + # # + # # /root contains subvolumes: + # # - /root/var/lib/portables + # # - /root/var/lib/machines + # # + # # I suspect these are related to systemd-nspawn, but + # # since I don't use it I'm not 100% sure. + # # Anyhow, deleting these subvolumes hasn't resulted + # # in any issues so far, except for fairly + # # benign-looking errors from systemd-tmpfiles. + # btrfs subvolume list -o /mnt/root | + # cut -f9 -d' ' | + # while read subvolume; do + # echo "deleting /$subvolume subvolume..." + # btrfs subvolume delete "/mnt/$subvolume" + # done && + # echo "deleting /root subvolume..." && + # btrfs subvolume delete /mnt/root + + # echo "restoring blank /root subvolume..." + # btrfs subvolume snapshot /mnt/root-blank /mnt/root + + # # Once we're done rolling back to a blank snapshot, + # # we can unmount /mnt and continue on the boot process. + # umount /mnt + #''; + + fileSystems."/boot" = { + device = "/dev/disk/by-uuid/2990-A0D7"; + fsType = "vfat"; + options = ["fmask=0022" "dmask=0022"]; + }; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/8bcaf4f2-c648-420d-8605-72407206244c"; + + fsType = "btrfs"; + options = ["subvol=root" "compress=zstd" "noatime"]; + }; + + fileSystems."/nix" = { + device = "/dev/disk/by-uuid/8bcaf4f2-c648-420d-8605-72407206244c"; + fsType = "btrfs"; + options = ["subvol=nix" "compress=zstd" "noatime"]; + }; + + fileSystems."/persistent" = { + device = "/dev/disk/by-uuid/8bcaf4f2-c648-420d-8605-72407206244c"; + fsType = "btrfs"; + neededForBoot = true; + options = ["subvol=persistent" "compress=zstd" "noatime"]; + }; + + # 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.<interface>.useDHCP`. + networking = { + useDHCP = lib.mkDefault true; + wireless = { + enable = true; + userControlled.enable = true; + }; + }; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware = { + cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; + graphics.enable = true; + }; +} diff --git a/hosts/wopr/default.nix b/hosts/wopr/default.nix new file mode 100644 index 0000000..bfd9de1 --- /dev/null +++ b/hosts/wopr/default.nix @@ -0,0 +1,23 @@ +{ + imports = [ + # Import your generated (nixos-generate-config) hardware configuration + ./hardware-configuration.nix + + ../common/global + ]; + + # Use the GRUB 2 boot loader. + boot.loader.grub.enable = true; + boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only + + networking.hostName = "wopr"; + + services = { + logind.extraConfig = '' + HandleLidSwitchExternalPower=ignore + ''; + }; + + # https://nixos.wiki/wiki/FAQ/When_do_I_update_stateVersion + system.stateVersion = "24.05"; +} diff --git a/hosts/wopr/hardware-configuration.nix b/hosts/wopr/hardware-configuration.nix new file mode 100644 index 0000000..02a1988 --- /dev/null +++ b/hosts/wopr/hardware-configuration.nix @@ -0,0 +1,103 @@ +{ + config, + lib, + pkgs, + modulesPath, + ... +}: { + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = ["ehci_pci" "ahci" "firewire_ohci" "usb_storage" "sd_mod" "sr_mod" "sdhci_pci"]; + boot.initrd.kernelModules = []; + boot.kernelModules = ["kvm-intel"]; + boot.extraModulePackages = []; + + boot.initrd.luks.devices."enc".device = "/dev/disk/by-uuid/e9671751-99d2-4a1c-84f1-1f58dc117fc1"; + + # Note `lib.mkBefore` is used instead of `lib.mkAfter` here. + boot.initrd.postDeviceCommands = pkgs.lib.mkBefore '' + mkdir -p /mnt + + # We first mount the btrfs root to /mnt + # so we can manipulate btrfs subvolumes. + mount -o subvol=/ /dev/mapper/enc /mnt + + # While we're tempted to just delete /root and create + # a new snapshot from /root-blank, /root is already + # populated at this point with a number of subvolumes, + # which makes `btrfs subvolume delete` fail. + # So, we remove them first. + # + # /root contains subvolumes: + # - /root/var/lib/portables + # - /root/var/lib/machines + # + # I suspect these are related to systemd-nspawn, but + # since I don't use it I'm not 100% sure. + # Anyhow, deleting these subvolumes hasn't resulted + # in any issues so far, except for fairly + # benign-looking errors from systemd-tmpfiles. + btrfs subvolume list -o /mnt/root | + cut -f9 -d' ' | + while read subvolume; do + echo "deleting /$subvolume subvolume..." + btrfs subvolume delete "/mnt/$subvolume" + done && + echo "deleting /root subvolume..." && + btrfs subvolume delete /mnt/root + + echo "restoring blank /root subvolume..." + btrfs subvolume snapshot /mnt/root-blank /mnt/root + + # Once we're done rolling back to a blank snapshot, + # we can unmount /mnt and continue on the boot process. + umount /mnt + ''; + + fileSystems."/boot" = { + device = "/dev/disk/by-label/boot"; + neededForBoot = true; + fsType = "btrfs"; + }; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/0ceef315-a8bb-4899-b037-4ad4b6d094a7"; + + fsType = "btrfs"; + options = ["subvol=root" "noatime"]; + }; + + fileSystems."/nix" = { + device = "/dev/disk/by-uuid/0ceef315-a8bb-4899-b037-4ad4b6d094a7"; + fsType = "btrfs"; + options = ["subvol=nix" "noatime"]; + }; + + fileSystems."/persistent" = { + device = "/dev/disk/by-uuid/0ceef315-a8bb-4899-b037-4ad4b6d094a7"; + fsType = "btrfs"; + neededForBoot = true; + options = ["subvol=persistent" "noatime"]; + }; + + swapDevices = [ + {device = "/dev/disk/by-label/swap";} + ]; + + # 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.<interface>.useDHCP`. + networking = { + useDHCP = lib.mkDefault true; + wireless = { + enable = true; + userControlled.enable = true; + }; + }; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/work/default.nix b/hosts/work/default.nix new file mode 100644 index 0000000..c419fd9 --- /dev/null +++ b/hosts/work/default.nix @@ -0,0 +1,62 @@ +{config, ...}: { + imports = [ + ./hardware-configuration.nix + + ../common/global + ../common/optional/wireless.nix + ]; + + # Use the systemd-boot EFI boot loader. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + networking.hostName = "work"; + + # Slows down write operations considerably + nix.settings.auto-optimise-store = false; + + services = { + logind.extraConfig = '' + HandleLidSwitchExternalPower=ignore + ''; + }; + + virtualisation.docker = { + enable = true; + + daemon.settings = { + userland-proxy = false; + experimental = true; + metrics-addr = "0.0.0.0:9323"; + ipv6 = true; + fixed-cidr-v6 = "fd00::/80"; + }; + # rootless = { + # enable = true; + # setSocketVariable = true; + # }; + storageDriver = "btrfs"; + }; + + users.users.sadbeast = { + hashedPasswordFile = config.sops.secrets.sadbeast-password.path; + + extraGroups = ["docker"]; + + subUidRanges = [ + { + startUid = 100000; + count = 65536; + } + ]; + subGidRanges = [ + { + startGid = 100000; + count = 65536; + } + ]; + }; + + # https://nixos.wiki/wiki/FAQ/When_do_I_update_stateVersion + system.stateVersion = "24.05"; +} diff --git a/hosts/work/hardware-configuration.nix b/hosts/work/hardware-configuration.nix new file mode 100644 index 0000000..f174382 --- /dev/null +++ b/hosts/work/hardware-configuration.nix @@ -0,0 +1,64 @@ +{ + config, + lib, + pkgs, + modulesPath, + ... +}: { + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "rtsx_usb_sdmmc"]; + boot.initrd.kernelModules = []; + boot.kernelModules = ["kvm-intel"]; + boot.extraModulePackages = []; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/0ac2bd64-7a06-4972-af6e-beffa6567ba7"; + fsType = "btrfs"; + options = ["subvol=root"]; + }; + + boot.initrd.luks.devices."work".device = "/dev/disk/by-uuid/7ce450be-7739-476e-9a8d-e25e57d8707f"; + + fileSystems."/nix" = { + device = "/dev/disk/by-uuid/0ac2bd64-7a06-4972-af6e-beffa6567ba7"; + fsType = "btrfs"; + options = ["subvol=nix"]; + }; + + fileSystems."/persistent" = { + device = "/dev/disk/by-uuid/0ac2bd64-7a06-4972-af6e-beffa6567ba7"; + fsType = "btrfs"; + options = ["subvol=persistent"]; + }; + + fileSystems."/boot" = { + device = "/dev/disk/by-uuid/A468-9833"; + fsType = "vfat"; + options = ["fmask=0022" "dmask=0022"]; + }; + + swapDevices = [ + {device = "/dev/disk/by-label/swap";} + ]; + + # 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.<interface>.useDHCP`. + networking = { + useDHCP = lib.mkDefault true; + wireless = { + enable = true; + userControlled.enable = true; + }; + }; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware = { + cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; + graphics.enable = true; + }; +} @@ -0,0 +1,24 @@ +# Build: +# nix-build '<nixpkgs/nixos>' -A config.system.build.isoImage -I nixos-config=iso.nix +# +# Test: +# $ nix-shell -p qemu --run "qemu-system-x86_64 -enable-kvm -m 256 -cdrom result/iso/nixos-*.iso" +{ + config, + pkgs, + ... +}: { + imports = [ + <nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix> + + # Provide an initial copy of the NixOS channel so that the user + # doesn't need to run "nix-channel --update" first. + <nixpkgs/nixos/modules/installer/cd-dvd/channel.nix> + ]; + environment.systemPackages = [pkgs.git pkgs.sops]; + + # The build process is slow because of compression - use a faster compressor + isoImage.squashfsCompression = "gzip -Xcompression-level 1"; + + console.keyMap = "emacs2"; +} diff --git a/modules/home-manager/default.nix b/modules/home-manager/default.nix new file mode 100644 index 0000000..45aae31 --- /dev/null +++ b/modules/home-manager/default.nix @@ -0,0 +1,6 @@ +# Add your reusable home-manager modules to this directory, on their own file (https://nixos.wiki/wiki/Module). +# These should be stuff you would like to share with others, not your personal configurations. +{ + # List your module files here + # my-module = import ./my-module.nix; +} diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix new file mode 100644 index 0000000..8605069 --- /dev/null +++ b/modules/nixos/default.nix @@ -0,0 +1,6 @@ +# Add your reusable NixOS modules to this directory, on their own file (https://nixos.wiki/wiki/Module). +# These should be stuff you would like to share with others, not your personal configurations. +{ + # List your module files here + # my-module = import ./my-module.nix; +} diff --git a/overlays/default.nix b/overlays/default.nix new file mode 100644 index 0000000..63b9906 --- /dev/null +++ b/overlays/default.nix @@ -0,0 +1,37 @@ +{ + inputs, + outputs, +}: { + # For every flake input, aliases 'pkgs.inputs.${flake}' to + # 'inputs.${flake}.packages.${pkgs.system}' or + # 'inputs.${flake}.legacyPackages.${pkgs.system}' + flake-inputs = final: _: { + inputs = + builtins.mapAttrs ( + _: flake: let + legacyPackages = (flake.legacyPackages or {}).${final.system} or {}; + packages = (flake.packages or {}).${final.system} or {}; + in + if legacyPackages != {} + then legacyPackages + else packages + ) + inputs; + }; + + # Adds pkgs.stable == inputs.nixpkgs-stable.legacyPackages.${pkgs.system} + stable = final: _: { + stable = inputs.nixpkgs-stable.legacyPackages.${final.system}; + }; + # This one brings our custom packages from the 'pkgs' directory + additions = final: _prev: import ../pkgs final.pkgs; + + # When applied, the unstable nixpkgs set (declared in the flake inputs) will + # be accessible through 'pkgs.unstable' + stable-packages = final: _prev: { + stable = import inputs.nixpkgs-stable { + system = final.system; + config.allowUnfree = true; + }; + }; +} diff --git a/pkgs/default.nix b/pkgs/default.nix new file mode 100644 index 0000000..3d9e23c --- /dev/null +++ b/pkgs/default.nix @@ -0,0 +1,5 @@ +# Custom packages, that can be defined similarly to ones from nixpkgs +# You can build them using 'nix build .#example' +pkgs: { + # example = pkgs.callPackage ./example { }; +} |