aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsadbeast <sadbeast@sadbeast.com>2024-05-30 00:47:47 +0000
committersadbeast <sadbeast@sadbeast.com>2024-10-05 16:44:14 -0700
commit09513b5c4e4babfaefdd06c592ef34c0908dc572 (patch)
tree5a9af6ef0407346c223334e295adc8012654f112
downloadnix-config-09513b5c4e4babfaefdd06c592ef34c0908dc572.tar.gz
nix-config-09513b5c4e4babfaefdd06c592ef34c0908dc572.tar.bz2
oh god what have i doneHEADmain
-rw-r--r--.gitattributes1
-rw-r--r--.gitignore1
-rw-r--r--.sops.yaml16
-rw-r--r--README.md21
-rw-r--r--flake.lock188
-rw-r--r--flake.nix137
-rwxr-xr-xfs-diff.sh28
-rw-r--r--home/sadbeast/features/desktop/default.nix21
-rw-r--r--home/sadbeast/features/desktop/firefox.nix127
-rw-r--r--home/sadbeast/features/desktop/foot.nix21
-rw-r--r--home/sadbeast/features/desktop/sway.nix132
-rw-r--r--home/sadbeast/features/desktop/waybar.css70
-rw-r--r--home/sadbeast/features/desktop/waybar.nix57
-rw-r--r--home/sadbeast/features/git.nix28
-rw-r--r--home/sadbeast/features/gpg.nix67
-rw-r--r--home/sadbeast/features/pass.nix17
-rw-r--r--home/sadbeast/features/services.nix21
-rw-r--r--home/sadbeast/features/ssh.nix26
-rw-r--r--home/sadbeast/features/vim.nix245
-rw-r--r--home/sadbeast/features/zsh.nix67
-rw-r--r--home/sadbeast/global/default.nix211
-rw-r--r--home/sadbeast/joshua.nix26
-rw-r--r--home/sadbeast/norad.nix11
-rw-r--r--home/sadbeast/wopr.nix11
-rw-r--r--home/sadbeast/work.nix64
-rw-r--r--hosts/common/global/default.nix174
-rw-r--r--hosts/common/global/sops.nix17
-rw-r--r--hosts/common/optional/wireless.nix35
-rw-r--r--hosts/common/secrets.yaml50
-rw-r--r--hosts/joshua/default.nix18
-rw-r--r--hosts/joshua/hardware-configuration.nix98
-rw-r--r--hosts/norad/default.nix26
-rw-r--r--hosts/norad/hardware-configuration.nix102
-rw-r--r--hosts/wopr/default.nix23
-rw-r--r--hosts/wopr/hardware-configuration.nix103
-rw-r--r--hosts/work/default.nix62
-rw-r--r--hosts/work/hardware-configuration.nix64
-rw-r--r--iso.nix24
-rw-r--r--modules/home-manager/default.nix6
-rw-r--r--modules/nixos/default.nix6
-rw-r--r--overlays/default.nix37
-rw-r--r--pkgs/default.nix5
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;
+ };
+}
diff --git a/iso.nix b/iso.nix
new file mode 100644
index 0000000..cfd9260
--- /dev/null
+++ b/iso.nix
@@ -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 { };
+}