├── .envrc ├── .github ├── dependabot.yml └── workflows │ ├── cache.yml │ ├── deploy.yml │ ├── format.yml │ ├── pull_request.yaml │ └── update.yml ├── .gitignore ├── .statix.toml ├── .yamllint ├── LICENSE ├── Makefile ├── README.md ├── data.nix ├── flake.lock ├── flake.nix ├── hosts ├── desktop-elis │ ├── configuration.nix │ ├── disko.nix │ └── hardware.nix ├── laptop-private-caroline │ ├── configuration.nix │ ├── disko.nix │ └── hardware.nix ├── laptop-private-elis │ ├── configuration.nix │ ├── disko.nix │ └── hardware.nix ├── laptop-work-elis │ ├── configuration.nix │ ├── disko.nix │ └── hardware.nix ├── live-iso │ └── configuration.nix ├── server-main-elis │ ├── configuration.nix │ ├── hardware.nix │ ├── network-wait-hook.nix │ └── services │ │ ├── cfdyndns.nix │ │ ├── empty-dirs-cleaner.nix │ │ ├── guest-users.nix │ │ ├── hass.nix │ │ ├── home-nginx.nix │ │ ├── homepage.nix │ │ ├── nextcloud.nix │ │ ├── svtplay.nix │ │ └── usenet.nix ├── server-sparv │ ├── configuration.nix │ └── hardware.nix └── vps06 │ ├── configuration.nix │ ├── hardware.nix │ ├── networking.nix │ └── services │ ├── forgejo.nix │ ├── matrix.nix │ ├── misc.nix │ └── postgres.nix ├── modules ├── base │ ├── default.nix │ ├── emacs │ │ ├── config.el │ │ └── default.nix │ ├── fish │ │ └── default.nix │ ├── htop │ │ └── default.nix │ ├── nix │ │ └── default.nix │ ├── sanoid │ │ └── default.nix │ ├── spell │ │ └── default.nix │ ├── sshd │ │ └── default.nix │ ├── syncoid │ │ └── default.nix │ ├── tailscale │ │ └── default.nix │ ├── tmux │ │ └── default.nix │ └── zfs │ │ └── default.nix ├── default.nix ├── development │ ├── default.nix │ ├── direnv │ │ └── default.nix │ ├── flipper-zero │ │ └── default.nix │ ├── git │ │ └── default.nix │ ├── php │ │ └── default.nix │ ├── rtl-sdr │ │ └── default.nix │ ├── vscode │ │ └── default.nix │ └── zed │ │ └── default.nix ├── dotfiles │ ├── bin │ │ ├── git-branchclean │ │ ├── git-git │ │ ├── git-lol │ │ ├── git-refetch-tags │ │ ├── keep │ │ ├── restow │ │ └── spacecolors │ ├── stupidterm.ini │ └── tmux.conf ├── games │ ├── default.nix │ ├── minecraft │ │ └── default.nix │ ├── mumble │ │ └── default.nix │ ├── steam-controller │ │ └── default.nix │ ├── steam │ │ └── default.nix │ └── wowup │ │ └── default.nix ├── graphical │ ├── default.nix │ ├── fdm-printing │ │ └── default.nix │ ├── firefox │ │ └── default.nix │ ├── flatpak │ │ └── default.nix │ ├── gnupg │ │ └── default.nix │ ├── hamradio │ │ └── default.nix │ ├── signal │ │ └── default.nix │ ├── sway │ │ └── default.nix │ ├── telegram │ │ └── default.nix │ ├── terminal │ │ └── default.nix │ ├── theme │ │ └── default.nix │ ├── virtualbox │ │ └── default.nix │ ├── window-managers │ │ ├── default.nix │ │ ├── kanshi │ │ │ └── default.nix │ │ ├── mako │ │ │ └── default.nix │ │ └── waybar │ │ │ ├── default.nix │ │ │ └── style.css │ └── xkb-keymap │ │ └── default.nix ├── services │ ├── beszel │ │ └── default.nix │ ├── default.nix │ ├── freshrss │ │ └── default.nix │ ├── jellyfin │ │ └── default.nix │ ├── netdata │ │ └── default.nix │ └── nfs │ │ └── default.nix ├── theme │ └── default.nix ├── user │ └── default.nix └── work │ └── default.nix ├── packages └── spaceWallpapers │ └── default.nix ├── secrets.nix └── secrets ├── any ├── hashed-etu-password-file.age ├── hashed-root-password-file.age └── netdata-claim-token-file.age ├── laptop-private-caroline ├── hashed-concate-password-file.age └── hashed-root-password-file.age ├── laptop-private-elis ├── etu_at_aarch64.nixos.community.age └── etu_at_aarch64.nixos.community.pub.age ├── server-main-elis ├── beszel-ssh-ec.age ├── cloudflare-api-env.age ├── etu-freshrss-password.age ├── homepage-dashboard-environment.age ├── initrd-sshd-ec.age ├── nextcloud-admin-password.age └── syncoid-ssh-ec.age ├── server-sparv ├── enshrouded-server-env.age ├── project-zomboid-env.age └── valheim-server-env.age └── workstations └── syncoid-ssh-ec.age /.envrc: -------------------------------------------------------------------------------- 1 | use flake 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | updates: 4 | - package-ecosystem: github-actions 5 | directory: / 6 | schedule: 7 | interval: weekly 8 | open-pull-requests-limit: 10 9 | reviewers: 10 | - etu 11 | -------------------------------------------------------------------------------- /.github/workflows/cache.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Cache 📝 3 | 4 | 'on': 5 | push: 6 | branches: 7 | - main 8 | - cache 9 | 10 | paths: 11 | - '**.nix' 12 | - '**.age' 13 | - 'flake.lock' 14 | 15 | concurrency: 16 | group: ci-${{ github.ref }}-cache 17 | cancel-in-progress: true 18 | 19 | jobs: 20 | cache: 21 | name: Cache 📝 22 | runs-on: ubuntu-22.04 23 | strategy: 24 | matrix: 25 | hostname: 26 | - server-main-elis 27 | - server-sparv 28 | - vps06 29 | 30 | steps: 31 | - uses: actions/checkout@v4 32 | - uses: DeterminateSystems/nix-installer-action@v17 33 | - uses: cachix/cachix-action@v16 34 | with: 35 | name: etu 36 | extraPullNames: 'nix-community' 37 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 38 | # Build systems. 39 | - name: Build system derivation 40 | run: 'nix build .#nixosConfigurations.${{ matrix.hostname }}.config.system.build.toplevel' 41 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Deploy 🚀 3 | 4 | 'on': 5 | push: 6 | branches: 7 | - main 8 | 9 | paths: 10 | - '**.nix' 11 | - '**.age' 12 | - 'flake.lock' 13 | 14 | concurrency: 15 | group: ci-${{ github.ref }}-deploy 16 | cancel-in-progress: true 17 | 18 | jobs: 19 | check: 20 | name: Check ✔️ 21 | runs-on: ubuntu-22.04 22 | steps: 23 | - uses: actions/checkout@v4 24 | - uses: DeterminateSystems/nix-installer-action@v17 25 | - uses: cachix/cachix-action@v16 26 | with: 27 | name: etu 28 | extraPullNames: 'nix-community' 29 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 30 | 31 | - name: Check the flake 32 | run: 'nix flake check' 33 | 34 | deploy: 35 | name: Deploy 🚀 36 | runs-on: ubuntu-22.04 37 | needs: check 38 | # Don't cancel jobs if one job fails 39 | continue-on-error: true 40 | strategy: 41 | matrix: 42 | hostname: 43 | - server-main-elis 44 | - server-sparv 45 | - vps06 46 | 47 | steps: 48 | - uses: actions/checkout@v4 49 | - uses: DeterminateSystems/nix-installer-action@v17 50 | - uses: cachix/cachix-action@v16 51 | with: 52 | name: etu 53 | extraPullNames: 'nix-community' 54 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 55 | 56 | # Build systems. 57 | - name: Build system derivation 58 | run: 'nix build .#nixosConfigurations.${{ matrix.hostname }}.config.system.build.toplevel' 59 | 60 | # Configure SSH key 61 | - uses: shimataro/ssh-key-action@v2 62 | with: 63 | key: ${{ secrets.SSH_PRIVATE_KEY }} 64 | name: id_ed25519 65 | known_hosts: ${{ secrets.SSH_KNOWN_HOSTS }} 66 | 67 | # Connect to tailscale 68 | - uses: tailscale/github-action@v3 69 | with: 70 | oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }} 71 | oauth-secret: ${{ secrets.TS_OAUTH_SECRET }} 72 | tags: tag:ci 73 | 74 | # Deploy systems 75 | - name: Deploy system 76 | run: 'nix develop -c deploy --skip-checks --targets .#${{ matrix.hostname }}' 77 | -------------------------------------------------------------------------------- /.github/workflows/format.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Format 🔎 3 | 4 | 'on': 5 | push: 6 | pull_request: 7 | 8 | concurrency: 9 | group: ci-${{ github.ref }}-format 10 | cancel-in-progress: true 11 | 12 | jobs: 13 | format: 14 | name: Format 🔎 15 | runs-on: ubuntu-22.04 16 | steps: 17 | - uses: actions/checkout@v4 18 | - uses: DeterminateSystems/nix-installer-action@v17 19 | - uses: DeterminateSystems/flake-checker-action@v10 20 | 21 | - name: Check nix file formatting ❄️ 22 | run: 'nix fmt . -- --check' 23 | - name: Check yaml file formatting 📂 24 | run: 'nix run nixpkgs#yamllint -- --strict --format github .' 25 | - name: Check deadnix file formatting ❄️ 26 | run: 'nix run nixpkgs#deadnix -- --fail hosts/ modules/ packages/' 27 | - name: Check statix file formatting ❄️ 28 | run: 'nix run nixpkgs#statix -- check --config .statix.toml' 29 | -------------------------------------------------------------------------------- /.github/workflows/pull_request.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Pull Request 3 | 4 | 'on': 5 | pull_request: 6 | branches: 7 | - main 8 | 9 | jobs: 10 | build: 11 | name: Build systems 12 | runs-on: ubuntu-22.04 13 | strategy: 14 | matrix: 15 | hostname: 16 | - server-main-elis 17 | - server-sparv 18 | - vps06 19 | 20 | steps: 21 | - uses: actions/checkout@v4 22 | - uses: DeterminateSystems/nix-installer-action@v17 23 | - uses: cachix/cachix-action@v16 24 | with: 25 | name: etu 26 | extraPullNames: 'nix-community' 27 | skipPush: true 28 | 29 | # Build systems. 30 | - name: Build system derivation 31 | run: 'nix build .#nixosConfigurations.${{ matrix.hostname }}.config.system.build.toplevel' 32 | 33 | build-shell: 34 | name: Cache nix shell 35 | runs-on: ubuntu-22.04 36 | steps: 37 | - uses: actions/checkout@v4 38 | - uses: DeterminateSystems/nix-installer-action@v17 39 | - uses: cachix/cachix-action@v16 40 | with: 41 | name: etu 42 | extraPullNames: 'nix-community' 43 | 44 | - name: Check the flake 45 | run: 'nix build .#devShells.x86_64-linux.default' 46 | 47 | check: 48 | name: Check flake 49 | runs-on: ubuntu-22.04 50 | needs: build 51 | steps: 52 | - uses: actions/checkout@v4.1.1 53 | - uses: DeterminateSystems/nix-installer-action@v17 54 | - uses: cachix/cachix-action@v16 55 | with: 56 | name: etu 57 | extraPullNames: 'nix-community' 58 | skipPush: true 59 | 60 | - name: Check the flake 61 | run: 'nix flake check' 62 | -------------------------------------------------------------------------------- /.github/workflows/update.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Update ⬆️ 3 | 4 | 'on': 5 | schedule: 6 | - cron: '30 4 * * 1' # At 04:30 on Monday. 7 | workflow_dispatch: 8 | 9 | jobs: 10 | update: 11 | name: Update dependencies 12 | runs-on: ubuntu-22.04 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: DeterminateSystems/nix-installer-action@v17 16 | - uses: cachix/cachix-action@v16 17 | with: 18 | name: etu 19 | extraPullNames: 'nix-community' 20 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 21 | 22 | # Update flake 23 | - name: Update flake inputs 24 | run: 'nix flake update' 25 | env: 26 | github_token: '${{ secrets.GITHUB_TOKEN }}' 27 | 28 | # Pre-fetch deps 29 | - name: Pre-fetch deps 30 | run: 'nix develop --command true' 31 | env: 32 | github_token: '${{ secrets.GITHUB_TOKEN }}' 33 | 34 | # Do updates of nixpkgs and other dependencies. 35 | - name: Update all dependencies 36 | run: 'nix develop --command make update-all' 37 | env: 38 | github_token: '${{ secrets.GITHUB_TOKEN }}' 39 | 40 | # Commit the updated dependencies to temporary branch 41 | - uses: stefanzweifel/git-auto-commit-action@v5 42 | with: 43 | commit_message: 'cron(treewide): Upgrade systems' 44 | branch: tmp-updater-branch 45 | create_branch: true 46 | push_options: '--force' 47 | 48 | cache: 49 | name: Cache system 50 | runs-on: ubuntu-22.04 51 | needs: update 52 | strategy: 53 | matrix: 54 | hostname: 55 | - server-main-elis 56 | - server-sparv 57 | - vps06 58 | 59 | steps: 60 | # Clone the code from the temporary branch 61 | - uses: actions/checkout@v4 62 | with: 63 | ref: tmp-updater-branch 64 | - uses: DeterminateSystems/nix-installer-action@v17 65 | - uses: cachix/cachix-action@v16 66 | with: 67 | name: etu 68 | extraPullNames: 'nix-community' 69 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 70 | 71 | # Build systems. 72 | - name: Build system derivation 73 | run: 'nix build .#nixosConfigurations.${{ matrix.hostname }}.config.system.build.toplevel' 74 | 75 | cache-shell: 76 | name: Cache nix shell 77 | runs-on: ubuntu-22.04 78 | needs: update 79 | steps: 80 | # Clone the code from the temporary branch 81 | - uses: actions/checkout@v4 82 | with: 83 | ref: tmp-updater-branch 84 | - uses: DeterminateSystems/nix-installer-action@v17 85 | - uses: cachix/cachix-action@v16 86 | with: 87 | name: etu 88 | extraPullNames: 'nix-community' 89 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 90 | 91 | - name: Check the flake 92 | run: 'nix build .#devShells.x86_64-linux.default' 93 | 94 | check: 95 | name: Check flake 96 | runs-on: ubuntu-22.04 97 | needs: cache 98 | steps: 99 | # Clone the code from the temporary branch 100 | - uses: actions/checkout@v4 101 | with: 102 | ref: tmp-updater-branch 103 | - uses: DeterminateSystems/nix-installer-action@v17 104 | - uses: cachix/cachix-action@v16 105 | with: 106 | name: etu 107 | extraPullNames: 'nix-community' 108 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 109 | 110 | - name: Check the flake 111 | run: 'nix flake check' 112 | 113 | promote: 114 | name: Promote to main branch 115 | runs-on: ubuntu-22.04 116 | needs: check 117 | steps: 118 | - uses: actions/checkout@v4 119 | with: 120 | ref: main 121 | 122 | - name: Get remote branch data 123 | run: 'git fetch' 124 | 125 | - name: Get the tmp-updater-branch branch 126 | run: 'git checkout tmp-updater-branch' 127 | 128 | - name: Push temporary branch to main branch 129 | run: 'git push origin tmp-updater-branch:main' 130 | 131 | - name: Delete the temporary branch 132 | run: 'git push origin --delete tmp-updater-branch' 133 | 134 | deploy: 135 | name: Deploy systems 136 | runs-on: ubuntu-22.04 137 | needs: promote 138 | # Don't cancel jobs if one job fails 139 | continue-on-error: true 140 | strategy: 141 | matrix: 142 | hostname: 143 | - server-main-elis 144 | - server-sparv 145 | - vps06 146 | 147 | steps: 148 | - uses: actions/checkout@v4 149 | - run: | 150 | git pull 151 | - uses: DeterminateSystems/nix-installer-action@v17 152 | - uses: cachix/cachix-action@v16 153 | with: 154 | name: etu 155 | extraPullNames: 'nix-community' 156 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 157 | 158 | # Build systems. 159 | - name: Build system derivation 160 | run: 'nix build .#nixosConfigurations.${{ matrix.hostname }}.config.system.build.toplevel' 161 | 162 | # Configure SSH key 163 | - uses: shimataro/ssh-key-action@v2 164 | with: 165 | key: ${{ secrets.SSH_PRIVATE_KEY }} 166 | name: id_ed25519 167 | known_hosts: ${{ secrets.SSH_KNOWN_HOSTS }} 168 | 169 | # Connect to tailscale 170 | - uses: tailscale/github-action@v3 171 | with: 172 | oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }} 173 | oauth-secret: ${{ secrets.TS_OAUTH_SECRET }} 174 | tags: tag:ci 175 | 176 | # Deploy systems 177 | - name: Deploy system 178 | run: 'nix develop -c deploy --skip-checks --targets .#${{ matrix.hostname }}' 179 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore configurable file with secrets 2 | .data-secrets.nix 3 | 4 | # Ignore build symlinks 5 | result* 6 | .tmp 7 | 8 | # Ignore direnv cache 9 | .direnv/ 10 | -------------------------------------------------------------------------------- /.statix.toml: -------------------------------------------------------------------------------- 1 | # Ignore repeated keys validation by statix check 2 | disabled = [ 3 | "repeated_keys" 4 | ] 5 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | yaml-files: 3 | - '*.yaml' 4 | - '*.yml' 5 | - '.yamllint' 6 | 7 | rules: 8 | # This is my only change over the remaining default values 9 | line-length: disable 10 | 11 | # Default values 12 | braces: enable 13 | brackets: enable 14 | colons: enable 15 | commas: enable 16 | comments: 17 | level: warning 18 | comments-indentation: 19 | level: warning 20 | document-end: disable 21 | document-start: 22 | level: warning 23 | empty-lines: enable 24 | empty-values: disable 25 | float-values: disable 26 | hyphens: enable 27 | indentation: enable 28 | key-duplicates: enable 29 | key-ordering: disable 30 | new-line-at-end-of-file: enable 31 | new-lines: enable 32 | octal-values: disable 33 | quoted-strings: disable 34 | trailing-spaces: enable 35 | truthy: 36 | level: warning 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Elis Hirwing 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Helpers to build things 3 | # 4 | desktop-elis: 5 | nix run nixpkgs#nix-output-monitor -- build .#nixosConfigurations.desktop-elis.config.system.build.toplevel 6 | 7 | laptop-private-elis: 8 | nix run nixpkgs#nix-output-monitor -- build .#nixosConfigurations.laptop-private-elis.config.system.build.toplevel 9 | 10 | laptop-private-caroline: 11 | nix run nixpkgs#nix-output-monitor -- build .#nixosConfigurations.laptop-private-caroline.config.system.build.toplevel 12 | 13 | laptop-work-elis: 14 | nix run nixpkgs#nix-output-monitor -- build .#nixosConfigurations.laptop-work-elis.config.system.build.toplevel 15 | 16 | live-iso: 17 | nix run nixpkgs#nix-output-monitor -- build .#iso 18 | 19 | server-main-elis: 20 | nix run nixpkgs#nix-output-monitor -- build .#nixosConfigurations.server-main-elis.config.system.build.toplevel 21 | 22 | server-sparv: 23 | nix run nixpkgs#nix-output-monitor -- build .#nixosConfigurations.server-sparv.config.system.build.toplevel 24 | 25 | vps06: 26 | nix run nixpkgs#nix-output-monitor -- build .#nixosConfigurations.vps06.config.system.build.toplevel 27 | 28 | # 29 | # Helpers to format the code 30 | # 31 | nix-fmt: 32 | @echo "Format nix files" 33 | nix fmt . 34 | 35 | yaml-fmt: 36 | @echo "Format yaml files" 37 | nix run nixpkgs#yamllint -- --strict --format github . 38 | 39 | # 40 | # Helpers to check formatting of code 41 | # 42 | nix-fmt-check: 43 | @echo "Check nix file formatting ❄️" 44 | nix fmt . -- --check 45 | 46 | yaml-fmt-check: 47 | @echo "Check yaml file formatting 📂" 48 | nix run nixpkgs#yamllint -- --strict --format github . 49 | 50 | deadnix-fmt-check: 51 | @echo "Check deadnix file formatting ❄️" 52 | nix run nixpkgs#deadnix -- --fail hosts/ modules/ packages/ 53 | 54 | statix-fmt-check: 55 | @echo "Check statix file formatting ❄️" 56 | nix run nixpkgs#statix -- check --config .statix.toml 57 | 58 | all-fmt-check: nix-fmt-check yaml-fmt-check deadnix-fmt-check statix-fmt-check 59 | 60 | # 61 | # Helpers to update containers 62 | # 63 | update-all: update-hass update-zwavejs2mqtt update-mosquitto 64 | 65 | update-hass: 66 | @echo "Updating to latest home assistant container" 67 | @sed -i -r 's#(ghcr.io/home-assistant/home-assistant):[0-9]{4}\.[0-9]{1,2}\.[0-9]{1,2}#\1:'`git ls-remote --tags 'https://github.com/home-assistant/core.git' | cut -d '/' -f 3 | grep -e '^20' | grep -v b | sort -V | tail -n 1`'#' hosts/server-main-elis/services/hass.nix 68 | 69 | update-zwavejs2mqtt: 70 | @echo "Updating to latest zwavejs2mqtt container" 71 | @sed -i -r 's#(zwavejs/zwavejs2mqtt):[1-9]+\.[0-9]+\.[0-9]+#\1:'`git ls-remote --tags 'https://github.com/zwave-js/zwavejs2mqtt.git' | cut -d 'v' -f 2 | grep -v '\^{}' | sort -V | tail -n 1`'#' hosts/server-main-elis/services/hass.nix 72 | 73 | update-mosquitto: 74 | @echo "Updating to latest mosquitto container" 75 | @sed -i -r 's#(eclipse-mosquitto):[1-9]+\.[0-9]+\.?[0-9]*#\1:'`git ls-remote --tags 'https://github.com/eclipse/mosquitto.git' | cut -d 'v' -f 2 | grep -v '\^{}' | sort -V | tail -n 1`'#' hosts/server-main-elis/services/hass.nix 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Cache 📝](https://github.com/etu/nixconfig/actions/workflows/cache.yml/badge.svg)](https://github.com/etu/nixconfig/actions/workflows/cache.yml) 2 | [![Deploy 🚀](https://github.com/etu/nixconfig/actions/workflows/deploy.yml/badge.svg)](https://github.com/etu/nixconfig/actions/workflows/deploy.yml) 3 | [![Format 🔎](https://github.com/etu/nixconfig/actions/workflows/format.yml/badge.svg)](https://github.com/etu/nixconfig/actions/workflows/format.yml) 4 | [![Update ⬆️](https://github.com/etu/nixconfig/actions/workflows/update.yml/badge.svg)](https://github.com/etu/nixconfig/actions/workflows/update.yml) 5 | 6 | # My NixOS configs 7 | 8 | ## Files and Directories in this repository 9 | 10 | ### `data.nix` 11 | 12 | This file doesn't contain any secrets at all, it's just miscellaneous 13 | public data that I need to be able to access from many places. 14 | 15 | It also contains public SSH keys for all the systems I have and care 16 | about, but also for trusted users that should have access to accounts 17 | on different systems. This becomes a central place to manage said keys 18 | for said users. 19 | 20 | ### `hosts/` 21 | 22 | #### `hosts/laptop-private-elis/` 23 | 24 | Private laptop, deployed like a normal NixOS system using 25 | `nixos-rebuild` to build new generations. ZFS snapshots are pushed 26 | from this system to `server-main-elis` whenever this system is online. 27 | 28 | #### `hosts/laptop-work-elis/` 29 | 30 | Work laptop, deployed like a normal NixOS system using `nixos-rebuild` 31 | to build new generations. ZFS snapshots are pushed from this system to 32 | `server-main-elis` whenever this system is online. 33 | 34 | #### `hosts/server-main-elis/` 35 | 36 | Home file server, deployed using `deploy .#server-main-elis`. Also 37 | used as build machines for the laptops. It's also my primary location 38 | to store ZFS snapshots that I backup from all of the other systems. It 39 | runs home assistant and some other things. 40 | 41 | #### `hosts/server-sparv/` 42 | 43 | On location server for http://speliarvika.se, will be used for LAN 44 | cache among other things. 45 | 46 | #### `hosts/vps06/` 47 | 48 | System that runs Gitea, [ip.failar.nu](https://ip.failar.nu/), and a 49 | Matrix home server among some other things. Deployed using `deploy 50 | .#vps06`. 51 | 52 | #### `hosts/live-iso/` 53 | 54 | If you're adventurous and want to run a clone of my configuration from 55 | a live-iso, it can be built locally: 56 | 57 | ```sh 58 | nix build github:etu/nixconfig#iso 59 | ``` 60 | 61 | ### `modules/` 62 | 63 | This directory contains a whole bunch of modules that I've come up 64 | with to make it easier for me to quickly configure multiple systems to 65 | do similar things. So I've made my own modules with my own options. 66 | 67 | Here's things like Emacs, 68 | [home-manager](https://github.com/nix-community/home-manager), sway 69 | configuration, the list goes on. 70 | 71 | ### `secrets.nix` and `secrets/` 72 | 73 | This is the directory with real secrets managed with 74 | [agenix](https://github.com/ryantm/agenix) which 75 | [age](https://github.com/FiloSottile/age) encrypt files using the 76 | public SSH keys for my users on my primary laptops and the public 77 | SSH-key on the host of intended use. This way I can see, edit and 78 | update encryption keys on my primary laptops and commit these files to 79 | the repository. But then also the target system of intended use can 80 | decrypt it with it's stateful private SSH key. 81 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "etu/nixpkgs"; 3 | 4 | inputs = { 5 | # Main nixpkgs channel 6 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 7 | 8 | # Older nixpkgs for certain things. 9 | nixpkgs-22-11.url = "github:NixOS/nixpkgs/nixos-22.11"; 10 | 11 | # Main flake-utils 12 | flake-utils.url = "github:numtide/flake-utils"; 13 | 14 | # Catppuccin themes 15 | catppuccin.url = "github:catppuccin/nix"; 16 | 17 | # Import deploy-rs for deployments 18 | deploy-rs.url = "github:serokell/deploy-rs"; 19 | deploy-rs.inputs.flake-compat.follows = "flake-compat"; 20 | deploy-rs.inputs.nixpkgs.follows = "nixpkgs"; 21 | deploy-rs.inputs.utils.follows = "flake-utils"; 22 | 23 | # Import disko for disk partitioning 24 | disko.url = "github:nix-community/disko"; 25 | disko.inputs.nixpkgs.follows = "nixpkgs"; 26 | 27 | # Import flake-compat for follow of others that use it 28 | flake-compat.url = "github:edolstra/flake-compat"; 29 | 30 | # Import nixos hardware quirks settings 31 | nixos-hardware.url = "github:nixos/nixos-hardware"; 32 | 33 | # Import impermanence modules for peristence 34 | impermanence.url = "github:nix-community/impermanence"; 35 | 36 | # Import home-manager modules 37 | home-manager.url = "github:nix-community/home-manager"; 38 | home-manager.inputs.nixpkgs.follows = "nixpkgs"; 39 | 40 | # Import agenix modules 41 | agenix.url = "github:ryantm/agenix"; 42 | agenix.inputs.nixpkgs.follows = "nixpkgs"; 43 | agenix.inputs.home-manager.follows = "home-manager"; 44 | 45 | # Import emacs-overlay 46 | emacs-overlay.url = "github:nix-community/emacs-overlay"; 47 | emacs-overlay.inputs.nixpkgs.follows = "nixpkgs"; 48 | 49 | # Import ip-failar-nu 50 | ip-failar-nu.url = "github:etu/ip.failar.nu"; 51 | ip-failar-nu.inputs.nixpkgs.follows = "nixpkgs"; 52 | ip-failar-nu.inputs.flake-utils.follows = "flake-utils"; 53 | 54 | # Import NUR 55 | nur.url = "nur"; 56 | }; 57 | 58 | outputs = { 59 | flake-utils, 60 | self, 61 | nixpkgs, 62 | ... 63 | } @ inputs: let 64 | myData = import ./data.nix; 65 | 66 | mkArmSystem = { 67 | name, 68 | extraArgs ? {}, 69 | extraModules ? [], 70 | }: 71 | mkSystem { 72 | inherit name extraArgs extraModules; 73 | system = "aarch64-linux"; 74 | }; 75 | 76 | mkSystem = { 77 | name, 78 | system ? "x86_64-linux", 79 | extraArgs ? {}, 80 | extraModules ? [], 81 | }: let 82 | pkgs-22-11 = import inputs.nixpkgs-22-11 { 83 | inherit system; 84 | config.allowUnfree = true; 85 | }; 86 | in 87 | nixpkgs.lib.nixosSystem { 88 | inherit system; 89 | 90 | modules = 91 | [ 92 | ./hosts/${name}/configuration.nix 93 | self.nixosModules.default 94 | inputs.agenix.nixosModules.age 95 | inputs.catppuccin.nixosModules.catppuccin 96 | inputs.disko.nixosModules.disko 97 | inputs.home-manager.nixosModules.home-manager 98 | inputs.impermanence.nixosModules.impermanence 99 | inputs.ip-failar-nu.nixosModules.${system}.default 100 | inputs.nur.modules.nixos.default 101 | ] 102 | ++ extraModules; 103 | 104 | specialArgs = 105 | { 106 | inherit (inputs) catppuccin; 107 | inherit (pkgs-22-11.nodejs-14_x.pkgs) intelephense; 108 | inherit (pkgs-22-11) chefdk vagrant; 109 | inherit (self.packages.${system}) spaceWallpapers; 110 | inherit myData; 111 | 112 | emacs-overlay = inputs.emacs-overlay.overlay; 113 | emacsWayland = nixpkgs.legacyPackages.${system}.emacs30-pgtk; 114 | } 115 | // extraArgs; 116 | }; 117 | 118 | mkArmDeploy = { 119 | name, 120 | hostname, 121 | sshUser ? "root", 122 | }: 123 | mkDeploy { 124 | inherit name hostname sshUser; 125 | system = "aarch64-linux"; 126 | }; 127 | 128 | mkDeploy = { 129 | name, 130 | hostname, 131 | sshUser ? "root", 132 | system ? "x86_64-linux", 133 | }: { 134 | inherit sshUser hostname; 135 | profiles.system.path = inputs.deploy-rs.lib.${system}.activate.nixos self.nixosConfigurations.${name}; 136 | }; 137 | in 138 | { 139 | # Declare systems 140 | nixosConfigurations = { 141 | desktop-elis = mkSystem {name = "desktop-elis";}; 142 | laptop-private-caroline = mkSystem {name = "laptop-private-caroline";}; 143 | laptop-private-elis = mkSystem {name = "laptop-private-elis";}; 144 | laptop-work-elis = mkSystem {name = "laptop-work-elis";}; 145 | server-main-elis = mkSystem {name = "server-main-elis";}; 146 | vps06 = mkSystem {name = "vps06";}; 147 | server-sparv = mkSystem {name = "server-sparv";}; 148 | live-iso = mkSystem {name = "live-iso";}; 149 | }; 150 | 151 | # Specify deploy-rs deployments 152 | deploy.nodes = { 153 | server-main-elis = mkDeploy { 154 | name = "server-main-elis"; 155 | hostname = "server-main-elis"; 156 | }; 157 | server-sparv = mkDeploy { 158 | name = "server-sparv"; 159 | hostname = "server-sparv"; 160 | }; 161 | vps06 = mkDeploy { 162 | name = "vps06"; 163 | hostname = "vps06"; 164 | }; 165 | }; 166 | 167 | # Expose my modules as a nixos module 168 | nixosModules.default = ./modules; 169 | 170 | # This is highly advised, and will prevent many possible mistakes 171 | checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) inputs.deploy-rs.lib; 172 | } 173 | // flake-utils.lib.eachSystem ["x86_64-linux"] (system: let 174 | pkgs = nixpkgs.legacyPackages.${system}; 175 | in { 176 | # Specify formatter package for "nix fmt ." and "nix fmt . -- --check" 177 | formatter = pkgs.alejandra; 178 | 179 | # Set up nix develop shell environment 180 | devShells.default = pkgs.mkShell { 181 | buildInputs = [ 182 | pkgs.cacert # Install certs for curl to work in pure shells 183 | pkgs.curl 184 | pkgs.jq # For parsing json downloaded with curl 185 | 186 | # Linters 187 | pkgs.deadnix 188 | pkgs.statix 189 | pkgs.yamllint 190 | 191 | # Secrets managing 192 | inputs.agenix.packages.${system}.agenix 193 | 194 | # Deploy util 195 | inputs.deploy-rs.packages.${system}.deploy-rs 196 | ]; 197 | }; 198 | 199 | # Build packages 200 | packages.spaceWallpapers = pkgs.callPackage ./packages/spaceWallpapers {}; 201 | packages.iso = self.nixosConfigurations.live-iso.config.system.build.isoImage; 202 | }); 203 | } 204 | -------------------------------------------------------------------------------- /hosts/desktop-elis/configuration.nix: -------------------------------------------------------------------------------- 1 | # Edit this configuration file to define what should be installed on 2 | # your system. Help is available in the configuration.nix(5) man page 3 | # and in the NixOS manual (accessible by running ‘nixos-help’). 4 | # 5 | # Initial deployment: 6 | # 1. Put filesystem password in /tmp/secret.key 7 | # 2. Deploy it from a remote system 8 | # $ nix run github:numtide/nixos-anywhere -- --flake .#desktop-elis root@192.168.999.999 9 | # 3. Reboot back into install system 10 | # 4. sudo zpool import -f zroot 11 | # 5. sudo zfs load-key -a -L prompt 12 | # 6. sudo zfs change-key -o keylocation=prompt zroot 13 | # 14 | # Later deployments: 15 | # $ deploy --skip-checks --targets .#desktop-elis 16 | { 17 | config, 18 | myData, 19 | pkgs, 20 | ... 21 | }: { 22 | imports = [ 23 | # Include my hardware settings. 24 | ./hardware.nix 25 | ]; 26 | 27 | # Set hostname 28 | networking.hostName = "desktop-elis"; 29 | 30 | # Settings needed for ZFS 31 | networking.hostId = "38527063"; 32 | 33 | # Otherwise IWD doesn't work with my network card. 34 | networking.wireless.iwd.settings.General.ControlPortOverNL80211 = false; 35 | 36 | # My module settings 37 | etu = { 38 | stateVersion = "24.05"; 39 | 40 | base.fish.enableUserZoxideCd = true; 41 | development.enable = true; 42 | development.flipper-zero.enable = true; 43 | games.enable = false; 44 | games.minecraft.enable = true; 45 | games.wowup.enable = true; 46 | games.steam.enable = true; 47 | games.steam-controller.enable = true; 48 | graphical.enable = true; 49 | graphical.sway.enable = true; 50 | graphical.fdm-printing.enable = true; 51 | graphical.hamradio.enable = true; 52 | graphical.signal.enable = true; 53 | graphical.flatpak.enablePersistence = true; 54 | services.netdata.enable = true; 55 | theme.enable = true; 56 | user.enable = true; 57 | user.extraGroups = ["video" "libvirtd"]; 58 | 59 | # Allow home fileserver to connect to fetch snapshots. 60 | user.extraRootAuthorizedKeys = myData.pubkeys.etu.syncoid.server-main-elis; 61 | 62 | user.extraUserPackages = [ 63 | pkgs.nvtopPackages.amd 64 | ]; 65 | 66 | # Add some fish abbreviations 67 | base.fish.shellAbbrs = [ 68 | { 69 | name = "sway-wow-resize"; 70 | value = "swaymsg '[title=\"World of Warcraft\"] resize set height 1791px'"; 71 | } 72 | ]; 73 | 74 | base.sanoid.datasets = { 75 | # Enable snapshotting for some filesystems 76 | "zroot/safe/data".use_template = ["data"]; 77 | "zroot/safe/home".use_template = ["home"]; 78 | }; 79 | }; 80 | 81 | # Set up virt-manager 82 | virtualisation.libvirtd.enable = true; 83 | programs.dconf.enable = true; 84 | environment.systemPackages = with pkgs; [virt-manager]; 85 | virtualisation.spiceUSBRedirection.enable = true; 86 | 87 | # Enable blueman. 88 | services.blueman.enable = true; 89 | 90 | # Add community server to known hosts 91 | programs.ssh.knownHosts."aarch64.nixos.community".publicKey = myData.pubkeys.systems."aarch64.nixos.community"; 92 | 93 | age.secrets = { 94 | inherit (myData.ageModules) "etu@aarch64.nixos.community" "etu@aarch64.nixos.community.pub"; 95 | inherit (myData.ageModules) syncoid-workstations-ssh-ec; 96 | }; 97 | 98 | # Set up remote builds 99 | nix.distributedBuilds = true; 100 | nix.buildMachines = [ 101 | { 102 | hostName = "aarch64.nixos.community"; 103 | maxJobs = 64; 104 | sshKey = config.age.secrets."etu@aarch64.nixos.community".path; 105 | sshUser = "etu"; 106 | system = "aarch64-linux"; 107 | supportedFeatures = ["big-parallel"]; 108 | } 109 | ]; 110 | } 111 | -------------------------------------------------------------------------------- /hosts/desktop-elis/disko.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | disko.devices = { 3 | disk = { 4 | nvme0n1 = { 5 | type = "disk"; 6 | device = "/dev/nvme0n1"; 7 | content = { 8 | type = "gpt"; 9 | partitions = { 10 | ESP = { 11 | size = "1024M"; 12 | type = "EF00"; 13 | content = { 14 | type = "filesystem"; 15 | format = "vfat"; 16 | mountpoint = "/boot"; 17 | mountOptions = ["defaults" "noexec" "noauto" "x-systemd.automount"]; 18 | }; 19 | }; 20 | zfs = { 21 | size = "100%"; 22 | content = { 23 | type = "zfs"; 24 | pool = "zroot"; 25 | }; 26 | }; 27 | }; 28 | }; # END disk.nvme0n1.content 29 | }; # END disk.nvme0n1 30 | nvme1n1 = { 31 | type = "disk"; 32 | device = "/dev/nvme1n1"; 33 | content = { 34 | type = "gpt"; 35 | partitions = { 36 | ESP = { 37 | size = "1024M"; 38 | type = "EF00"; 39 | content = { 40 | type = "filesystem"; 41 | format = "vfat"; 42 | mountpoint = "/boot-fallback"; 43 | mountOptions = ["defaults" "noexec" "noauto" "x-systemd.automount"]; 44 | }; 45 | }; 46 | zfs = { 47 | size = "100%"; 48 | content = { 49 | type = "zfs"; 50 | pool = "zroot"; 51 | }; 52 | }; 53 | }; 54 | }; # END disk.nvme1n1.content 55 | }; # END disk.nvme1n1 56 | }; # END disk 57 | nodev."/" = { 58 | fsType = "tmpfs"; 59 | mountOptions = ["size=64G" "defaults" "mode=755"]; 60 | }; 61 | zpool = { 62 | zroot = { 63 | type = "zpool"; 64 | 65 | # Make a mirror pool 66 | mode.topology = { 67 | type = "topology"; 68 | vdev = [ 69 | { 70 | mode = "mirror"; 71 | members = [ 72 | "nvme0n1" 73 | "nvme1n1" 74 | ]; 75 | } 76 | ]; 77 | }; 78 | 79 | mountpoint = null; 80 | rootFsOptions = { 81 | compression = "lz4"; # To enable file system compression. 82 | mountpoint = "none"; # Disable ZFS automatic mounting. 83 | atime = "off"; # Disable writing access time. 84 | acltype = "posixacl"; # This is more or less required for certain things to not break. 85 | xattr = "sa"; # Improve performance of certain extended attributes. 86 | 87 | # These should work under datasets."name".options.{} 88 | encryption = "aes-256-gcm"; 89 | keyformat = "passphrase"; 90 | keylocation = "file:///tmp/secret.key"; 91 | }; 92 | 93 | options = { 94 | ashift = "12"; # Use 4K sectors on the drive, otherwise you can get really bad performance. 95 | }; 96 | 97 | datasets = { 98 | "local/nix" = { 99 | type = "zfs_fs"; 100 | mountpoint = "/nix"; 101 | options.mountpoint = "legacy"; 102 | }; 103 | "local/var-log" = { 104 | type = "zfs_fs"; 105 | mountpoint = "/var/log"; 106 | options.mountpoint = "legacy"; 107 | }; 108 | "local/var-lib-docker" = { 109 | type = "zfs_fs"; 110 | options.mountpoint = "/var/lib/docker"; 111 | }; 112 | "local/data" = { 113 | type = "zfs_fs"; 114 | mountpoint = "/data/local"; 115 | options.mountpoint = "legacy"; 116 | }; 117 | "safe/data" = { 118 | type = "zfs_fs"; 119 | mountpoint = "/data"; 120 | options.mountpoint = "legacy"; 121 | }; 122 | "safe/home" = { 123 | type = "zfs_fs"; 124 | mountpoint = "/data/home"; 125 | options.mountpoint = "legacy"; 126 | }; 127 | }; 128 | }; # END zpool.zroot 129 | }; # END zpool 130 | }; 131 | } 132 | -------------------------------------------------------------------------------- /hosts/desktop-elis/hardware.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | pkgs, 4 | modulesPath, 5 | ... 6 | }: { 7 | imports = [ 8 | (modulesPath + "/installer/scan/not-detected.nix") 9 | ./disko.nix 10 | ]; 11 | 12 | # Configure boot loader. 13 | boot.loader.systemd-boot.enable = true; 14 | boot.loader.efi.canTouchEfiVariables = true; 15 | 16 | # Set boot loader timeout to longer than 5s to give me more time to choose. 17 | boot.loader.timeout = 15; 18 | 19 | boot.initrd.availableKernelModules = ["nvme" "xhci_pci" "thunderbolt" "usbhid" "usb_storage" "sd_mod"]; 20 | boot.initrd.kernelModules = []; 21 | 22 | boot.kernelModules = ["kvm-amd"]; 23 | 24 | # Wifi needs at least 6.11, system works overall well with 6.12 25 | # (with a separate network card) and built in ethernet works 26 | # starting with 6.13. Then bluetooth audio starts to work in 6.14, 27 | # interestingly, Wifi stops working on 6.14. 28 | # 29 | # Network Card: 30 | # $ lspci -s 10:00.0 -nn -k 31 | # 10:00.0 Network controller [0280]: Qualcomm Technologies, Inc WCN785x Wi-Fi 7(802.11be) 320MHz 2x2 [FastConnect 7800] [17cb:1107] (rev 01) 32 | # Subsystem: Foxconn International, Inc. Device [105b:e0fb] 33 | # Kernel driver in use: ath12k_pci 34 | # Kernel modules: ath12k 35 | # 36 | # Logs on 6.13.12: 37 | # May 17 14:32:49 desktop-elis kernel: ath12k_pci 0000:10:00.0: BAR 0 [mem 0xa0000000-0xa01fffff 64bit]: assigned 38 | # May 17 14:32:50 desktop-elis kernel: ath12k_pci 0000:10:00.0: enabling device (0000 -> 0002) 39 | # May 17 14:32:50 desktop-elis kernel: ath12k_pci 0000:10:00.0: MSI vectors: 16 40 | # May 17 14:32:50 desktop-elis kernel: ath12k_pci 0000:10:00.0: Hardware name: wcn7850 hw2.0 41 | # May 17 14:33:00 desktop-elis kernel: ath12k_pci 0000:10:00.0: chip_id 0x2 chip_family 0x4 board_id 0xff soc_id 0x40170200 42 | # May 17 14:33:00 desktop-elis kernel: ath12k_pci 0000:10:00.0: fw_version 0x1105811c fw_build_timestamp 2025-03-11 07:08 fw_build_id QC_IMAGE_VERSION_STRING=WLAN.HMT.1.1.c5-00284-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 43 | # 44 | # Logs on 6.14.6: 45 | # May 17 14:36:00 desktop-elis kernel: ath12k_pci 0000:10:00.0: BAR 0 [mem 0xa0000000-0xa01fffff 64bit]: assigned 46 | # May 17 14:36:00 desktop-elis kernel: ath12k_pci 0000:10:00.0: enabling device (0000 -> 0002) 47 | # May 17 14:36:00 desktop-elis kernel: ath12k_pci 0000:10:00.0: MSI vectors: 16 48 | # May 17 14:36:00 desktop-elis kernel: ath12k_pci 0000:10:00.0: Hardware name: wcn7850 hw2.0 49 | # May 17 14:36:01 desktop-elis kernel: ath12k_pci 0000:10:00.0: chip_id 0x2 chip_family 0x4 board_id 0xff soc_id 0x40170200 50 | # May 17 14:36:01 desktop-elis kernel: ath12k_pci 0000:10:00.0: fw_version 0x1105811c fw_build_timestamp 2025-03-11 07:08 fw_build_id QC_IMAGE_VERSION_STRING=WLAN.HMT.1.1.c5-00284-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 51 | # May 17 14:36:01 desktop-elis kernel: ath12k_pci 0000:10:00.0: ignore reset dev flags 0x200 52 | # May 17 14:36:06 desktop-elis kernel: ath12k_pci 0000:10:00.0: failed to receive wmi unified ready event: -110 53 | # May 17 14:36:06 desktop-elis kernel: ath12k_pci 0000:10:00.0: failed to start core: -110 54 | # May 17 14:36:06 desktop-elis kernel: ath12k_pci 0000:10:00.0: qmi failed to send mode request, mode: 4, err = -5 55 | # May 17 14:36:06 desktop-elis kernel: ath12k_pci 0000:10:00.0: qmi failed to send wlan mode off 56 | boot.kernelPackages = pkgs.linuxPackages_6_14; 57 | 58 | # Enable a nice boot splash screen. 59 | boot.initrd.systemd.enable = true; # needed for ZFS password prompt with plymouth. 60 | boot.plymouth.enable = true; 61 | 62 | # Enable ZFS. 63 | boot.supportedFilesystems = ["zfs"]; 64 | 65 | # Enable ZFS scrubbing. 66 | services.zfs.autoScrub.enable = true; 67 | 68 | # Enable bluetooth 69 | hardware.bluetooth.enable = true; 70 | 71 | # Install firmware for hardware. 72 | hardware.enableRedistributableFirmware = true; 73 | 74 | # Test to use OpenRGB to see if it works with my RGB 75 | services.hardware.openrgb.enable = true; 76 | services.hardware.openrgb.motherboard = "amd"; 77 | 78 | # Set video driver. 79 | services.xserver.videoDrivers = ["modesetting"]; 80 | 81 | # Enable fwupd for firmware updates etc. 82 | services.fwupd.enable = true; 83 | 84 | # Mark filesystems as needed for boot 85 | fileSystems.${config.etu.dataPrefix}.neededForBoot = true; 86 | fileSystems."${config.etu.dataPrefix}/home".neededForBoot = true; 87 | fileSystems.${config.etu.localPrefix}.neededForBoot = true; 88 | fileSystems."/nix".neededForBoot = true; 89 | 90 | # Bind mount for persistent libvirt state. 91 | etu.base.zfs.system.directories = [ 92 | "/var/lib/libvirt" 93 | ]; 94 | 95 | # Swap devices. 96 | swapDevices = []; 97 | 98 | # Set max jobs in nix. 99 | #nix.settings.max-jobs = lib.mkDefault 8; 100 | 101 | # Set CPU Frequency Governor. 102 | #powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; 103 | } 104 | -------------------------------------------------------------------------------- /hosts/laptop-private-caroline/configuration.nix: -------------------------------------------------------------------------------- 1 | # Edit this configuration file to define what should be installed on 2 | # your system. Help is available in the configuration.nix(5) man page 3 | # and in the NixOS manual (accessible by running ‘nixos-help’). 4 | # 5 | # Initial deployment: 6 | # 1. Put filesystem password in /tmp/secret.key 7 | # 2. Deploy it from a remote system 8 | # $ nix run github:numtide/nixos-anywhere -- --flake .#laptop-private-caroline root@10.69.0.55 9 | # 3. Reboot back into install system 10 | # 4. sudo zpool import -f zroot 11 | # 5. sudo zfs load-key -a -L prompt 12 | # 6. sudo zfs change-key -o keylocation=prompt zroot 13 | # 14 | # Later deployments: 15 | # $ deploy --skip-checks --targets .#laptop-private-caroline 16 | { 17 | pkgs, 18 | myData, 19 | ... 20 | }: { 21 | imports = [ 22 | # Include my hardware settings. 23 | ./hardware.nix 24 | ]; 25 | 26 | # Set hostname 27 | networking.hostName = "laptop-private-caroline"; 28 | 29 | # Settings needed for ZFS 30 | networking.hostId = "36522517"; 31 | 32 | # My module settings 33 | etu = { 34 | stateVersion = "24.05"; 35 | 36 | # This is to make the openssh identity files to be located in a 37 | # reasonable place. 38 | dataPrefix = "/data"; 39 | 40 | # Enable my user account. 41 | user.enable = true; 42 | user.username = "concate"; 43 | user.realname = "Caroline Hirwing"; 44 | user.email = "caroline@hirwing.se"; 45 | user.extraGroups = ["video"]; 46 | 47 | # Don't set a password for root / user depending on agenix. 48 | user.userPasswordAgeModule = myData.ageModules.hashed-caroline-laptop-concate-password; 49 | user.rootPasswordAgeModule = myData.ageModules.hashed-caroline-laptop-root-password; 50 | 51 | # Enable a graphical system. 52 | graphical.enable = true; 53 | graphical.sway.enable = true; 54 | graphical.fdm-printing.enable = true; 55 | 56 | # Do not enable Elis configs for certain things. 57 | base.emacs.enable = false; 58 | graphical.firefox.enable = false; 59 | graphical.gnupg.enable = false; 60 | graphical.telegram.enable = false; 61 | graphical.flatpak.enablePersistence = true; 62 | theme.enable = true; 63 | 64 | games.minecraft.enable = true; 65 | games.wowup.enable = true; 66 | 67 | # Install packages 68 | user.extraUserPackages = [ 69 | # Other packages to have installed 70 | pkgs.firefox-bin 71 | pkgs.git 72 | pkgs.vscodium 73 | pkgs.evince 74 | pkgs.unzip 75 | pkgs.inkscape 76 | pkgs.libreoffice 77 | pkgs.blender 78 | pkgs.gnumake 79 | ]; 80 | 81 | # Allow home fileserver to connect to fetch snapshots. 82 | user.extraRootAuthorizedKeys = myData.pubkeys.etu.syncoid.server-main-elis; 83 | 84 | # Configure sanoid snapshotting. 85 | base.sanoid.datasets = { 86 | # Enable snapshotting for some filesystems 87 | "zroot/safe/data".use_template = ["data"]; 88 | "zroot/safe/home".use_template = ["home"]; 89 | }; 90 | }; 91 | 92 | # Enable blueman. 93 | services.blueman.enable = true; 94 | } 95 | -------------------------------------------------------------------------------- /hosts/laptop-private-caroline/disko.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | disk = { 3 | nvme0n1 = { 4 | type = "disk"; 5 | device = "/dev/nvme0n1"; 6 | content = { 7 | type = "gpt"; 8 | partitions = { 9 | ESP = { 10 | size = "512M"; 11 | type = "EF00"; 12 | content = { 13 | type = "filesystem"; 14 | format = "vfat"; 15 | mountpoint = "/boot"; 16 | mountOptions = ["defaults" "noexec" "noauto" "x-systemd.automount"]; 17 | }; 18 | }; 19 | zroot = { 20 | size = "100%"; 21 | content = { 22 | type = "zfs"; 23 | pool = "zroot"; 24 | }; 25 | }; 26 | }; 27 | }; # END disk.nvme0n1.content 28 | }; # END disk.nvme0n1 29 | }; # END disk 30 | 31 | zpool = { 32 | zroot = { 33 | type = "zpool"; 34 | mountpoint = null; 35 | rootFsOptions = { 36 | compression = "lz4"; # To enable file system compression. 37 | mountpoint = "none"; # Disable ZFS automatic mounting. 38 | atime = "off"; # Disable writing access time. 39 | acltype = "posixacl"; # This is more or less required for certain things to not break. 40 | xattr = "sa"; # Improve performance of certain extended attributes. 41 | copies = "2"; # Set copies 2 for the entire pool. 42 | 43 | # These should work under datasets."name".options.{} 44 | encryption = "aes-256-gcm"; 45 | keyformat = "passphrase"; 46 | keylocation = "file:///tmp/secret.key"; 47 | }; 48 | 49 | options = { 50 | ashift = "12"; # Use 4K sectors on the drive, otherwise you can get really bad performance. 51 | }; 52 | 53 | # Create an initial empty snapshot 54 | postCreateHook = '' 55 | zfs snapshot zroot/local/root@blank 56 | zfs snapshot zroot/safe/data@blank 57 | ''; 58 | 59 | datasets = { 60 | "local/root" = { 61 | type = "zfs_fs"; 62 | mountpoint = "/"; 63 | options.mountpoint = "legacy"; 64 | }; 65 | "local/nix" = { 66 | type = "zfs_fs"; 67 | mountpoint = "/nix"; 68 | options.mountpoint = "legacy"; 69 | }; 70 | "local/data" = { 71 | type = "zfs_fs"; 72 | mountpoint = "/data/local"; 73 | options.mountpoint = "legacy"; 74 | options.copies = "1"; # Override the pool setting 75 | }; 76 | "local/var-log" = { 77 | type = "zfs_fs"; 78 | mountpoint = "/var/log"; 79 | options.mountpoint = "legacy"; 80 | }; 81 | "safe/data" = { 82 | type = "zfs_fs"; 83 | mountpoint = "/data"; 84 | options.mountpoint = "legacy"; 85 | }; 86 | "safe/home" = { 87 | type = "zfs_fs"; 88 | mountpoint = "/home"; 89 | options.mountpoint = "legacy"; 90 | }; 91 | }; 92 | }; # END zpool.zroot 93 | }; # END zpool 94 | } 95 | -------------------------------------------------------------------------------- /hosts/laptop-private-caroline/hardware.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | modulesPath, 5 | ... 6 | }: { 7 | imports = [ 8 | (modulesPath + "/installer/scan/not-detected.nix") 9 | ]; 10 | 11 | # Configure boot loader. 12 | boot.loader.systemd-boot.enable = true; 13 | boot.loader.efi.canTouchEfiVariables = true; 14 | 15 | boot.initrd.availableKernelModules = ["nvme" "ehci_pci" "thunderbolt" "usb_storage" "sd_mod"]; 16 | boot.initrd.kernelModules = []; 17 | boot.kernelModules = ["kvm-amd"]; 18 | 19 | # Install thinkpad modules for TLP. 20 | boot.extraModulePackages = with config.boot.kernelPackages; [acpi_call]; 21 | 22 | # Enable a nice boot splash screen. 23 | boot.initrd.systemd.enable = true; # needed for ZFS password prompt with plymouth. 24 | boot.plymouth.enable = true; 25 | 26 | # Enable ZFS. 27 | boot.supportedFilesystems = ["zfs"]; 28 | 29 | # Enable ZFS scrubbing. 30 | services.zfs.autoScrub.enable = true; 31 | 32 | # Enable bluetooth 33 | hardware.bluetooth.enable = true; 34 | 35 | # Install firmware for hardware. 36 | hardware.enableRedistributableFirmware = true; 37 | hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 38 | 39 | # Include udev rules to give permissions to the video group to change 40 | # backlight using acpilight. 41 | hardware.acpilight.enable = true; 42 | 43 | # Set video driver. 44 | services.xserver.videoDrivers = ["modesetting"]; 45 | 46 | # Enable fwupd for firmware updates etc. 47 | services.fwupd.enable = true; 48 | 49 | # Enable TLP. 50 | services.tlp.enable = true; 51 | services.tlp.settings.START_CHARGE_THRESH_BAT0 = 40; 52 | services.tlp.settings.STOP_CHARGE_THRESH_BAT0 = 70; 53 | 54 | # Disko config 55 | disko.devices = import ./disko.nix {}; 56 | 57 | fileSystems."/".neededForBoot = true; 58 | fileSystems."/home".neededForBoot = true; 59 | fileSystems."/nix".neededForBoot = true; 60 | fileSystems.${config.etu.dataPrefix}.neededForBoot = true; 61 | fileSystems.${config.etu.localPrefix}.neededForBoot = true; 62 | 63 | # Swap devices. 64 | swapDevices = []; 65 | 66 | # Set max jobs in nix. 67 | nix.settings.max-jobs = lib.mkDefault 8; 68 | 69 | # Set CPU Frequency Governor. 70 | powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; 71 | } 72 | -------------------------------------------------------------------------------- /hosts/laptop-private-elis/configuration.nix: -------------------------------------------------------------------------------- 1 | # Edit this configuration file to define what should be installed on 2 | # your system. Help is available in the configuration.nix(5) man page 3 | # and in the NixOS manual (accessible by running ‘nixos-help’). 4 | # 5 | # Initial deployment: 6 | # 1. Put filesystem password in /tmp/secret.key 7 | # 2. Deploy it from a remote system 8 | # $ nix run github:numtide/nixos-anywhere -- --flake .#laptop-private-elis root@10.69.0.55 9 | # 3. Reboot back into install system 10 | # 4. sudo zpool import -f zroot 11 | # 5. sudo zfs load-key -a -L prompt 12 | # 6. sudo zfs change-key -o keylocation=prompt zroot 13 | # 14 | # Later deployments: 15 | # $ deploy --skip-checks --targets .#laptop-private-elis 16 | { 17 | config, 18 | myData, 19 | pkgs, 20 | ... 21 | }: { 22 | imports = [ 23 | # Include my hardware settings. 24 | ./hardware.nix 25 | ]; 26 | 27 | # Set hostname 28 | networking.hostName = "laptop-private-elis"; 29 | 30 | # Settings needed for ZFS 31 | networking.hostId = "27416952"; 32 | 33 | # My module settings 34 | etu = { 35 | stateVersion = "24.05"; 36 | 37 | base.fish.enableUserZoxideCd = true; 38 | development.enable = true; 39 | development.flipper-zero.enable = true; 40 | games.enable = false; 41 | games.minecraft.enable = true; 42 | games.wowup.enable = true; 43 | games.steam.enable = true; 44 | games.steam-controller.enable = true; 45 | graphical.enable = true; 46 | graphical.sway.enable = true; 47 | graphical.fdm-printing.enable = true; 48 | graphical.hamradio.enable = true; 49 | graphical.signal.enable = true; 50 | graphical.flatpak.enablePersistence = true; 51 | services.netdata.enable = true; 52 | theme.enable = true; 53 | user.enable = true; 54 | user.extraGroups = ["video" "docker" "libvirtd"]; 55 | 56 | # Allow home fileserver to connect to fetch snapshots. 57 | user.extraRootAuthorizedKeys = myData.pubkeys.etu.syncoid.server-main-elis; 58 | 59 | base.sanoid.datasets = { 60 | # Enable snapshotting for some filesystems 61 | "zroot/safe/data".use_template = ["data"]; 62 | "zroot/safe/home".use_template = ["home"]; 63 | }; 64 | }; 65 | 66 | # Set up docker 67 | virtualisation.docker.enable = true; 68 | virtualisation.docker.storageDriver = "zfs"; 69 | 70 | # Set up virt-manager 71 | virtualisation.libvirtd.enable = true; 72 | programs.dconf.enable = true; 73 | environment.systemPackages = with pkgs; [virt-manager]; 74 | virtualisation.spiceUSBRedirection.enable = true; 75 | 76 | # Enable blueman. 77 | services.blueman.enable = true; 78 | 79 | # Add community server to known hosts 80 | programs.ssh.knownHosts."aarch64.nixos.community".publicKey = myData.pubkeys.systems."aarch64.nixos.community"; 81 | 82 | age.secrets = { 83 | inherit (myData.ageModules) "etu@aarch64.nixos.community" "etu@aarch64.nixos.community.pub"; 84 | inherit (myData.ageModules) syncoid-workstations-ssh-ec; 85 | }; 86 | 87 | # Set up remote builds 88 | nix.distributedBuilds = true; 89 | nix.buildMachines = [ 90 | { 91 | hostName = "aarch64.nixos.community"; 92 | maxJobs = 64; 93 | sshKey = config.age.secrets."etu@aarch64.nixos.community".path; 94 | sshUser = "etu"; 95 | system = "aarch64-linux"; 96 | supportedFeatures = ["big-parallel"]; 97 | } 98 | ]; 99 | } 100 | -------------------------------------------------------------------------------- /hosts/laptop-private-elis/disko.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | disko.devices = { 3 | disk = { 4 | nvme0n1 = { 5 | type = "disk"; 6 | device = "/dev/nvme0n1"; 7 | content = { 8 | type = "gpt"; 9 | partitions = { 10 | ESP = { 11 | size = "1024M"; 12 | type = "EF00"; 13 | content = { 14 | type = "filesystem"; 15 | format = "vfat"; 16 | mountpoint = "/boot"; 17 | mountOptions = ["defaults" "noexec" "noauto" "x-systemd.automount"]; 18 | }; 19 | }; 20 | zroot = { 21 | size = "100%"; 22 | content = { 23 | type = "zfs"; 24 | pool = "zroot"; 25 | }; 26 | }; 27 | }; 28 | }; # END disk.nvme0n1.content 29 | }; # END disk.nvme0n1 30 | }; # END disk 31 | nodev."/" = { 32 | fsType = "tmpfs"; 33 | mountOptions = ["size=10G" "defaults" "mode=755"]; 34 | }; 35 | zpool = { 36 | zroot = { 37 | type = "zpool"; 38 | mountpoint = null; 39 | rootFsOptions = { 40 | compression = "lz4"; # To enable file system compression. 41 | mountpoint = "none"; # Disable ZFS automatic mounting. 42 | atime = "off"; # Disable writing access time. 43 | acltype = "posixacl"; # This is more or less required for certain things to not break. 44 | xattr = "sa"; # Improve performance of certain extended attributes. 45 | copies = "2"; # Set copies 2 for the entire pool . 46 | 47 | # These should work under datasets."name".options.{} 48 | encryption = "aes-256-gcm"; 49 | keyformat = "passphrase"; 50 | keylocation = "file:///tmp/secret.key"; 51 | }; 52 | 53 | options = { 54 | ashift = "12"; # Use 4K sectors on the drive, otherwise you can get really bad performance. 55 | }; 56 | 57 | datasets = { 58 | "local/nix" = { 59 | type = "zfs_fs"; 60 | mountpoint = "/nix"; 61 | options.mountpoint = "legacy"; 62 | }; 63 | "local/var-log" = { 64 | type = "zfs_fs"; 65 | mountpoint = "/var/log"; 66 | options.mountpoint = "legacy"; 67 | }; 68 | "local/var-lib-docker" = { 69 | type = "zfs_fs"; 70 | options.mountpoint = "/var/lib/docker"; 71 | options.copies = "1"; # Override the pool setting 72 | }; 73 | "local/data" = { 74 | type = "zfs_fs"; 75 | mountpoint = "/data/local"; 76 | options.mountpoint = "legacy"; 77 | options.copies = "1"; # Override the pool setting 78 | }; 79 | "safe/data" = { 80 | type = "zfs_fs"; 81 | mountpoint = "/data"; 82 | options.mountpoint = "legacy"; 83 | }; 84 | "safe/home" = { 85 | type = "zfs_fs"; 86 | mountpoint = "/data/home"; 87 | options.mountpoint = "legacy"; 88 | }; 89 | }; 90 | }; # END zpool.zroot 91 | }; # END zpool 92 | }; 93 | } 94 | -------------------------------------------------------------------------------- /hosts/laptop-private-elis/hardware.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | modulesPath, 5 | ... 6 | }: { 7 | imports = [ 8 | (modulesPath + "/installer/scan/not-detected.nix") 9 | ./disko.nix 10 | ]; 11 | 12 | # Configure boot loader. 13 | boot.loader.systemd-boot.enable = true; 14 | boot.loader.efi.canTouchEfiVariables = true; 15 | 16 | boot.initrd.availableKernelModules = ["nvme" "xhci_pci" "thunderbolt" "usb_storage" "sd_mod"]; 17 | boot.initrd.kernelModules = []; 18 | 19 | boot.kernelModules = ["kvm-amd"]; 20 | 21 | # Install thinkpad modules for TLP. 22 | boot.extraModulePackages = with config.boot.kernelPackages; [acpi_call]; 23 | 24 | # Enable a nice boot splash screen. 25 | boot.initrd.systemd.enable = true; # needed for ZFS password prompt with plymouth. 26 | boot.plymouth.enable = true; 27 | 28 | # Enable ZFS. 29 | boot.supportedFilesystems = ["zfs"]; 30 | 31 | # Enable ZFS scrubbing. 32 | services.zfs.autoScrub.enable = true; 33 | 34 | # Enable bluetooth 35 | hardware.bluetooth.enable = true; 36 | 37 | # Install firmware for hardware. 38 | hardware.enableRedistributableFirmware = true; 39 | 40 | # Include udev rules to give permissions to the video group to change 41 | # backlight using acpilight. 42 | hardware.acpilight.enable = true; 43 | 44 | # Set video driver. 45 | services.xserver.videoDrivers = ["modesetting"]; 46 | 47 | # Enable fwupd for firmware updates etc. 48 | services.fwupd.enable = true; 49 | 50 | # Enable TLP. 51 | services.tlp.enable = true; 52 | services.tlp.settings.START_CHARGE_THRESH_BAT0 = 40; 53 | services.tlp.settings.STOP_CHARGE_THRESH_BAT0 = 70; 54 | 55 | # Mark filesystems as needed for boot 56 | fileSystems.${config.etu.dataPrefix}.neededForBoot = true; 57 | fileSystems."${config.etu.dataPrefix}/home".neededForBoot = true; 58 | fileSystems.${config.etu.localPrefix}.neededForBoot = true; 59 | fileSystems."/nix".neededForBoot = true; 60 | 61 | # Bind mount for persistent libvirt state. 62 | etu.base.zfs.system.directories = [ 63 | "/var/lib/libvirt" 64 | ]; 65 | 66 | # Swap devices. 67 | swapDevices = []; 68 | 69 | # Set max jobs in nix. 70 | nix.settings.max-jobs = lib.mkDefault 8; 71 | 72 | # Set CPU Frequency Governor. 73 | powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; 74 | } 75 | -------------------------------------------------------------------------------- /hosts/laptop-work-elis/configuration.nix: -------------------------------------------------------------------------------- 1 | # Edit this configuration file to define what should be installed on 2 | # your system. Help is available in the configuration.nix(5) man page 3 | # and in the NixOS manual (accessible by running ‘nixos-help’). 4 | { 5 | config, 6 | myData, 7 | ... 8 | }: { 9 | imports = [ 10 | # Include my hardware settings. 11 | ./hardware.nix 12 | ]; 13 | 14 | # Set hostname 15 | networking.hostName = "laptop-work-elis"; 16 | 17 | # Settings needed for ZFS 18 | networking.hostId = "18582528"; 19 | 20 | # My module settings 21 | etu = { 22 | stateVersion = "24.05"; 23 | 24 | base.fish.enableUserZoxideCd = true; 25 | development.enable = true; 26 | development.rtl-sdr.enable = false; 27 | development.vscode.enableWork = true; 28 | graphical.enable = true; 29 | graphical.sway.enable = true; 30 | graphical.virtualbox.enable = true; 31 | graphical.flatpak.enablePersistence = true; 32 | services.nfs.enable = true; 33 | services.nfs.exports = '' 34 | ${config.etu.dataPrefix}/home/etu/tvnu/projects 192.168.5.102(rw,no_subtree_check,all_squash,anonuid=1000,anongid=100) 35 | ''; 36 | services.netdata.enable = true; 37 | theme.enable = true; 38 | user.enable = true; 39 | user.extraGroups = ["video" "docker"]; 40 | 41 | # Allow home fileserver to connect to fetch snapshots. 42 | user.extraRootAuthorizedKeys = myData.pubkeys.etu.syncoid.server-main-elis; 43 | 44 | # Install extra modes for work. 45 | base.emacs.extraConfig = [ 46 | '' 47 | ;; Install Elasticsearch mode 48 | (use-package es-mode :ensure t) 49 | 50 | ;; Install Jenkinsfile mode 51 | (use-package jenkinsfile-mode :ensure t) 52 | 53 | ;; Install VCL mode 54 | (use-package vcl-mode :ensure t) 55 | '' 56 | ]; 57 | 58 | base.sanoid.datasets = { 59 | # Enable snapshotting for some filesystems 60 | "zroot/safe/data".use_template = ["data"]; 61 | "zroot/safe/home".use_template = ["home"]; 62 | }; 63 | 64 | # Enable work modules 65 | work.enable = true; 66 | }; 67 | 68 | # Enable docker deamon 69 | virtualisation.docker.enable = true; 70 | virtualisation.docker.storageDriver = "zfs"; 71 | 72 | # Include agenix encripted secret for secret password file 73 | age.secrets = { 74 | inherit (myData.ageModules) syncoid-workstations-ssh-ec; 75 | }; 76 | 77 | # Enable ClamAV. 78 | services.clamav.daemon.enable = true; 79 | services.clamav.updater.enable = true; 80 | 81 | # Enable blueman. 82 | services.blueman.enable = true; 83 | } 84 | -------------------------------------------------------------------------------- /hosts/laptop-work-elis/disko.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | disko.devices = { 3 | disk = { 4 | nvme0n1 = { 5 | type = "disk"; 6 | device = "/dev/nvme0n1"; 7 | content = { 8 | type = "gpt"; 9 | partitions = { 10 | ESP = { 11 | size = "1024M"; 12 | type = "EF00"; 13 | content = { 14 | type = "filesystem"; 15 | format = "vfat"; 16 | mountpoint = "/boot"; 17 | mountOptions = ["defaults" "noexec" "noauto" "x-systemd.automount"]; 18 | }; 19 | }; 20 | zroot = { 21 | size = "100%"; 22 | content = { 23 | type = "zfs"; 24 | pool = "zroot"; 25 | }; 26 | }; 27 | }; 28 | }; # END disk.nvme0n1.content 29 | }; # END disk.nvme0n1 30 | }; # END disk 31 | nodev."/" = { 32 | fsType = "tmpfs"; 33 | mountOptions = ["size=3G" "defaults" "mode=755"]; 34 | }; 35 | zpool = { 36 | zroot = { 37 | type = "zpool"; 38 | mountpoint = null; 39 | rootFsOptions = { 40 | compression = "lz4"; # To enable file system compression. 41 | mountpoint = "none"; # Disable ZFS automatic mounting. 42 | atime = "off"; # Disable writing access time. 43 | acltype = "posixacl"; # This is more or less required for certain things to not break. 44 | xattr = "sa"; # Improve performance of certain extended attributes. 45 | copies = "2"; # Set copies 2 for the entire pool . 46 | 47 | # These should work under datasets."name".options.{} 48 | encryption = "aes-256-gcm"; 49 | keyformat = "passphrase"; 50 | keylocation = "file:///tmp/secret.key"; 51 | }; 52 | 53 | options = { 54 | ashift = "12"; # Use 4K sectors on the drive, otherwise you can get really bad performance. 55 | }; 56 | 57 | datasets = { 58 | "local/nix" = { 59 | type = "zfs_fs"; 60 | mountpoint = "/nix"; 61 | options.mountpoint = "legacy"; 62 | }; 63 | "local/var-log" = { 64 | type = "zfs_fs"; 65 | mountpoint = "/var/log"; 66 | options.mountpoint = "legacy"; 67 | }; 68 | "local/var-lib-docker" = { 69 | type = "zfs_fs"; 70 | options.mountpoint = "/var/lib/docker"; 71 | options.copies = "1"; # Override the pool setting 72 | }; 73 | "local/data" = { 74 | type = "zfs_fs"; 75 | mountpoint = "/data/local"; 76 | options.mountpoint = "legacy"; 77 | options.copies = "1"; # Override the pool setting 78 | }; 79 | "safe/data" = { 80 | type = "zfs_fs"; 81 | mountpoint = "/data"; 82 | options.mountpoint = "legacy"; 83 | }; 84 | "safe/home" = { 85 | type = "zfs_fs"; 86 | mountpoint = "/data/home"; 87 | options.mountpoint = "legacy"; 88 | }; 89 | }; 90 | }; # END zpool.zroot 91 | }; # END zpool 92 | }; 93 | } 94 | -------------------------------------------------------------------------------- /hosts/laptop-work-elis/hardware.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | modulesPath, 5 | pkgs, 6 | ... 7 | }: { 8 | imports = [ 9 | (modulesPath + "/installer/scan/not-detected.nix") 10 | ./disko.nix 11 | ]; 12 | 13 | # Configure boot loader. 14 | boot.loader.systemd-boot.enable = true; 15 | boot.loader.efi.canTouchEfiVariables = true; 16 | 17 | boot.initrd.availableKernelModules = ["nvme" "xhci_pci" "thunderbolt" "usb_storage" "sd_mod"]; 18 | boot.initrd.kernelModules = []; 19 | 20 | boot.kernelModules = ["kvm-amd"]; 21 | 22 | # Install thinkpad modules for TLP. 23 | boot.extraModulePackages = with config.boot.kernelPackages; [acpi_call]; 24 | 25 | # Enable a nice boot splash screen. 26 | boot.initrd.systemd.enable = true; # needed for ZFS password prompt with plymouth. 27 | boot.plymouth.enable = true; 28 | 29 | # Enable ZFS. 30 | boot.supportedFilesystems = ["zfs"]; 31 | 32 | # Add hack to make wifi work at the office. 33 | boot.extraModprobeConfig = "options iwlwifi disable_11ax=Y"; 34 | 35 | # Enable ZFS scrubbing. 36 | services.zfs.autoScrub.enable = true; 37 | 38 | # Enable bluetooth 39 | hardware.bluetooth.enable = true; 40 | 41 | # Install firmware for hardware. 42 | hardware.enableRedistributableFirmware = true; 43 | 44 | # Include udev rules to give permissions to the video group to change 45 | # backlight using acpilight. 46 | hardware.acpilight.enable = true; 47 | 48 | # Set video driver 49 | services.xserver.videoDrivers = ["modesetting"]; 50 | 51 | # Enable fwupd for firmware updates etc. 52 | services.fwupd.enable = true; 53 | 54 | # Enable TLP. 55 | services.tlp.enable = true; 56 | services.tlp.settings.START_CHARGE_THRESH_BAT0 = 40; 57 | services.tlp.settings.STOP_CHARGE_THRESH_BAT0 = 70; 58 | 59 | # Mark filesystems as needed for boot 60 | fileSystems.${config.etu.dataPrefix}.neededForBoot = true; 61 | fileSystems."${config.etu.dataPrefix}/home".neededForBoot = true; 62 | fileSystems.${config.etu.localPrefix}.neededForBoot = true; 63 | fileSystems."/nix".neededForBoot = true; 64 | 65 | # Additional work directories 66 | etu.base.zfs.user.directories = [ 67 | "tvnu" 68 | ]; 69 | 70 | # Swap devices. 71 | swapDevices = []; 72 | 73 | # Set max jobs in nix. 74 | nix.settings.max-jobs = lib.mkDefault 8; 75 | 76 | # Set CPU Frequency Governor. 77 | powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; 78 | 79 | # High-DPI console. 80 | console.font = lib.mkDefault "${pkgs.terminus_font}/share/consolefonts/ter-u28n.psf.gz"; 81 | } 82 | -------------------------------------------------------------------------------- /hosts/live-iso/configuration.nix: -------------------------------------------------------------------------------- 1 | # 2 | # This definition is used to build a live-iso using my graphical environment. 3 | # 4 | # Build by running the following command: 5 | # $ nix build .#nixosConfigurations.live-iso.config.system.build.isoImage 6 | # 7 | # Then dd the resulting image: 8 | # $ sudo dd if=result/iso/ of=/dev/ status=progress bs=16M 9 | # 10 | { 11 | lib, 12 | modulesPath, 13 | ... 14 | }: { 15 | imports = [ 16 | # Import base settings for live isos 17 | (modulesPath + "/installer/cd-dvd/installation-cd-base.nix") 18 | ]; 19 | 20 | # My module settings 21 | etu = { 22 | stateVersion = "24.05"; 23 | 24 | # This is to make the openssh identity files to be located in a 25 | # reasonable place. 26 | dataPrefix = "/"; 27 | 28 | # Enable my user account. 29 | user.enable = true; 30 | 31 | # Don't set a password for root / user depending on agenix. 32 | user.setEmptyPassword = true; 33 | user.setEmptyRootPassword = true; 34 | 35 | # Enable a graphical system. 36 | graphical.enable = true; 37 | graphical.sway.enable = true; 38 | 39 | # Fore disable some graphical components unused on the live iso. 40 | graphical.gnupg.enable = false; 41 | graphical.telegram.enable = false; 42 | 43 | # Force disable persistence modules since this system doesn't 44 | # use ZFS. 45 | base.zfs.enable = false; 46 | 47 | # Force disable sanoid modules since this system doesn't use ZFS. 48 | base.sanoid.enable = false; 49 | 50 | # There's no need to run tailscale on the live-iso. 51 | base.tailscale.enable = false; 52 | }; 53 | 54 | networking.wireless.enable = false; 55 | services.openssh.settings.PermitRootLogin = lib.mkForce "prohibit-password"; 56 | } 57 | -------------------------------------------------------------------------------- /hosts/server-main-elis/hardware.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | pkgs, 4 | lib, 5 | modulesPath, 6 | myData, 7 | ... 8 | }: { 9 | imports = [ 10 | (modulesPath + "/installer/scan/not-detected.nix") 11 | ]; 12 | 13 | # Configure boot loader. 14 | boot.loader.grub.enable = true; 15 | boot.loader.grub.efiSupport = true; 16 | boot.loader.grub.device = "nodev"; 17 | boot.loader.grub.extraInstallCommands = '' 18 | mkdir -p /boot/EFI/Microsoft/Boot/ /boot-fallback/EFI/Microsoft/Boot/ 19 | cp /boot/EFI/grub/grubx64.efi /boot/EFI/Microsoft/Boot/bootmgfw.efi 20 | cp /boot-fallback/EFI/grub/grubx64.efi /boot-fallback/EFI/Microsoft/Boot/bootmgfw.efi 21 | ''; 22 | 23 | boot.loader.grub.mirroredBoots = [ 24 | { 25 | devices = ["/dev/disk/by-uuid/6258-01A0"]; 26 | path = "/boot-fallback"; 27 | } 28 | ]; 29 | 30 | boot.kernelModules = []; 31 | boot.extraModulePackages = []; 32 | 33 | # Enable graphics drivers for the graphics card. 34 | hardware.graphics.enable = true; 35 | hardware.graphics.extraPackages = [ 36 | # for newer GPUs on NixOS >24.05 or unstable 37 | pkgs.vpl-gpu-rt 38 | ]; 39 | 40 | # Additonal intel things 41 | environment.systemPackages = [ 42 | pkgs.pciutils 43 | pkgs.nvtopPackages.intel 44 | ]; 45 | 46 | age.secrets = { 47 | inherit (myData.ageModules) server-main-elis-initrd-sshd; 48 | inherit (myData.ageModules) syncoid-server-main-elis-ssh-ec; 49 | }; 50 | 51 | # Remote unlocking of encrypted ZFS 52 | boot.initrd = { 53 | availableKernelModules = ["xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "nvme" "thunderbolt"]; 54 | kernelModules = ["kvm-amd" "r8169"]; 55 | network.enable = true; 56 | # Listen to ssh to let me decrypt zfs 57 | network.ssh = { 58 | enable = true; 59 | port = 2222; 60 | hostKeys = [ 61 | myData.ageModules.server-main-elis-initrd-sshd.path 62 | ]; 63 | authorizedKeys = config.users.users.etu.openssh.authorizedKeys.keys; 64 | }; 65 | # Prompt me for password to decrypt zfs 66 | # 67 | # This was fun, the reason it looks like this is because of the 68 | # initramfs that firsts imports a pool, then it stalls on running 69 | # "zfs load-key -a" on the terminal, but we never input data there 70 | # since it's on SSH. So I have to run that command when I log in, 71 | # then it has to kill the other zfs command to continue the init 72 | # script, that script will then import the second pool and the 73 | # same dance starts over. 74 | network.postCommands = '' 75 | echo "zfs load-key -a; killall zfs; sleep 5; zfs load-key -a; killall zfs;" >> /root/.profile 76 | ''; 77 | }; 78 | 79 | # Roll back certain filesystems to empty state on boot 80 | boot.initrd.postDeviceCommands = lib.mkAfter '' 81 | zfs rollback -r zroot/local/var-lib-nzbget-dst@empty 82 | ''; 83 | 84 | # Enable ZFS. 85 | boot.supportedFilesystems = ["zfs"]; 86 | 87 | # Enable ZFS scrubbing. 88 | services.zfs.autoScrub.enable = true; 89 | 90 | # Filesystem mounts. 91 | fileSystems."/" = { 92 | device = "none"; 93 | fsType = "tmpfs"; 94 | options = ["defaults" "size=10G" "mode=755"]; 95 | }; 96 | 97 | fileSystems."/nix" = { 98 | device = "zroot/local/nix"; 99 | fsType = "zfs"; 100 | }; 101 | 102 | fileSystems.${config.etu.dataPrefix} = { 103 | device = "zroot/safe/data"; 104 | fsType = "zfs"; 105 | neededForBoot = true; 106 | }; 107 | 108 | fileSystems.${config.etu.localPrefix} = { 109 | device = "zroot/local/data"; 110 | fsType = "zfs"; 111 | neededForBoot = true; 112 | options = ["defaults" "noexec"]; 113 | }; 114 | 115 | fileSystems."${config.etu.dataPrefix}/home" = { 116 | device = "zroot/safe/home"; 117 | fsType = "zfs"; 118 | neededForBoot = true; 119 | }; 120 | 121 | fileSystems."/var/log" = { 122 | device = "zroot/local/var-log"; 123 | fsType = "zfs"; 124 | }; 125 | 126 | fileSystems."/var/lib/nzbget-dst" = { 127 | device = "zroot/local/var-lib-nzbget-dst"; 128 | fsType = "zfs"; 129 | }; 130 | 131 | fileSystems."/boot" = { 132 | device = "/dev/disk/by-uuid/6241-1BC1"; 133 | fsType = "vfat"; 134 | options = ["noauto" "x-systemd.automount"]; 135 | }; 136 | 137 | fileSystems."/boot-fallback" = { 138 | device = "/dev/disk/by-uuid/6258-01A0"; 139 | fsType = "vfat"; 140 | options = ["noauto" "x-systemd.automount"]; 141 | }; 142 | 143 | fileSystems."/media/zstorage/files" = { 144 | device = "zstorage/files"; 145 | fsType = "zfs"; 146 | neededForBoot = true; 147 | }; 148 | 149 | # Storage related mounts 150 | fileSystems."/media/zstorage/files/audio" = { 151 | device = "zstorage/files/audio"; 152 | fsType = "zfs"; 153 | options = ["noauto" "x-systemd.automount"]; 154 | #noCheck = true; 155 | }; 156 | 157 | fileSystems."/media/zstorage/files/ebooks" = { 158 | device = "zstorage/files/ebooks"; 159 | fsType = "zfs"; 160 | options = ["noauto" "x-systemd.automount"]; 161 | #noCheck = true; 162 | }; 163 | 164 | fileSystems."/media/zstorage/files/software" = { 165 | device = "zstorage/files/software"; 166 | fsType = "zfs"; 167 | options = ["noauto" "x-systemd.automount"]; 168 | #noCheck = true; 169 | }; 170 | 171 | fileSystems."/media/zstorage/files/upload" = { 172 | device = "zstorage/files/upload"; 173 | fsType = "zfs"; 174 | options = ["noauto" "x-systemd.automount"]; 175 | #noCheck = true; 176 | }; 177 | 178 | fileSystems."/media/zstorage/files/video" = { 179 | device = "zstorage/files/video"; 180 | fsType = "zfs"; 181 | options = ["noauto" "x-systemd.automount"]; 182 | #noCheck = true; 183 | }; 184 | 185 | # Persistence of certain hosts paths and home directory paths. 186 | etu.base.zfs.user.directories = [ 187 | "backups" 188 | ]; 189 | 190 | # Persistence of certificates for nginx 191 | etu.base.zfs.system.directories = [ 192 | "/var/lib/acme" 193 | ]; 194 | 195 | # Swap devices. 196 | swapDevices = []; 197 | 198 | # Set max jobs in nix. 199 | nix.settings.max-jobs = lib.mkDefault 8; 200 | 201 | # Set CPU Frequency Governor. 202 | powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; 203 | } 204 | -------------------------------------------------------------------------------- /hosts/server-main-elis/network-wait-hook.nix: -------------------------------------------------------------------------------- 1 | {config, ...}: let 2 | preStart = '' 3 | echo "Checking for nameservers to appear in /etc/resolv.conf"; 4 | while ! grep nameserver /etc/resolv.conf > /dev/null; do 5 | echo "Waiting for nameservers to appear in /etc/resolv.conf"; 6 | sleep 1; 7 | done 8 | ''; 9 | in { 10 | # Add a pre start check for network to be up for certain services. 11 | config.systemd.services."cloudflare-dyndns".preStart = preStart; 12 | config.systemd.services."container@usenet".preStart = preStart; 13 | config.systemd.services."freshrss-config".preStart = preStart; 14 | config.systemd.services."freshrss-updater".preStart = preStart; 15 | config.systemd.services."podman-home-assistant".preStart = preStart; 16 | config.systemd.services."podman-mqtt".preStart = preStart; 17 | config.systemd.services."podman-zwavejs2mqtt".preStart = preStart; 18 | } 19 | -------------------------------------------------------------------------------- /hosts/server-main-elis/services/cfdyndns.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | myData, 4 | pkgs, 5 | ... 6 | }: { 7 | # Decrypt secret to expected location. 8 | age.secrets = { 9 | inherit (myData.ageModules) cloudflare-api-env; 10 | }; 11 | 12 | systemd.services.cloudflare-dyndns = { 13 | description = "Cloudflare dyndns updater"; 14 | after = ["network-online.target"]; 15 | wantedBy = ["multi-user.target"]; 16 | requires = ["network-online.target"]; 17 | startAt = "hourly"; 18 | serviceConfig = { 19 | Type = "oneshot"; 20 | ExecStart = pkgs.writeScript "cloudflare-dyndns" '' 21 | #!${pkgs.bash}/bin/bash 22 | set -euo pipefail 23 | 24 | source ${config.age.secrets.cloudflare-api-env.path} 25 | 26 | export CURRENT_IP_ADDRESS="$(${pkgs.curl}/bin/curl -s4 ip.failar.nu)" 27 | ${pkgs.coreutils}/bin/echo "Current IP is: $CURRENT_IP_ADDRESS" 28 | 29 | export CURRENT_DNS_VALUE=$(${pkgs.curl}/bin/curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$DNS_ZONE/dns_records/$DNS_RECORD" -H "Authorization: Bearer $AUTH_KEY" -H "Content-Type:application/json" | ${pkgs.jq}/bin/jq -r '.result["content"]') 30 | ${pkgs.coreutils}/bin/echo "Current DNS value is: $CURRENT_DNS_VALUE" 31 | 32 | if test "$CURRENT_DNS_VALUE" != "$CURRENT_IP_ADDRESS"; then 33 | ${pkgs.coreutils}/bin/echo "Updating DNS record" 34 | ${pkgs.curl}/bin/curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$DNS_ZONE/dns_records/$DNS_RECORD" -H "Authorization: Bearer $AUTH_KEY" -H "Content-Type:application/json" --data '{"type":"A","name":"'$DNS_RECORD_NAME'","content":"'$CURRENT_IP_ADDRESS'"}' 35 | else 36 | ${pkgs.coreutils}/bin/echo "No update needed" 37 | fi 38 | ''; 39 | }; 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /hosts/server-main-elis/services/empty-dirs-cleaner.nix: -------------------------------------------------------------------------------- 1 | {pkgs, ...}: { 2 | systemd.services.media-empty-dirs-cleaner = { 3 | description = "Remove empty directories from /media/zstorage/files/{audio,video}"; 4 | wantedBy = ["multi-user.target"]; 5 | startAt = "hourly"; 6 | serviceConfig = { 7 | Type = "oneshot"; 8 | ExecStart = pkgs.writeScript "media-empty-dirs-cleaner" '' 9 | #!${pkgs.bash}/bin/bash 10 | set -euo pipefail 11 | 12 | ${pkgs.findutils}/bin/find /media/zstorage/files/audio /media/zstorage/files/video \ 13 | -type d -empty -print -delete 14 | ''; 15 | }; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /hosts/server-main-elis/services/guest-users.nix: -------------------------------------------------------------------------------- 1 | {myData, ...}: let 2 | # home / chroot path 3 | path = "/home/guests"; 4 | in { 5 | users.users.guests = { 6 | isNormalUser = true; 7 | createHome = false; 8 | uid = 1002; 9 | home = path; 10 | openssh.authorizedKeys.keys = myData.pubkeys.guests; 11 | }; 12 | 13 | services.openssh.extraConfig = '' 14 | Match User guests 15 | ChrootDirectory ${path} 16 | AllowTCPForwarding no 17 | X11Forwarding no 18 | ForceCommand internal-sftp 19 | ''; 20 | 21 | # Read only filesystems 22 | fileSystems."${path}/files" = { 23 | device = "/media/zstorage/files"; 24 | options = ["ro" "bind"]; 25 | depends = ["/media/zstorage/files"]; 26 | noCheck = true; 27 | }; 28 | 29 | fileSystems."${path}/files/audio" = { 30 | device = "/media/zstorage/files/audio"; 31 | options = ["ro" "bind"]; 32 | depends = ["/media/zstorage/files" "${path}/files"]; 33 | noCheck = true; 34 | }; 35 | 36 | fileSystems."${path}/files/ebooks" = { 37 | device = "/media/zstorage/files/ebooks"; 38 | options = ["ro" "bind"]; 39 | depends = ["/media/zstorage/files" "${path}/files"]; 40 | noCheck = true; 41 | }; 42 | 43 | fileSystems."${path}/files/software" = { 44 | device = "/media/zstorage/files/software"; 45 | options = ["ro" "bind"]; 46 | depends = ["/media/zstorage/files" "${path}/files"]; 47 | noCheck = true; 48 | }; 49 | 50 | fileSystems."${path}/files/video" = { 51 | device = "/media/zstorage/files/video"; 52 | options = ["ro" "bind"]; 53 | depends = ["/media/zstorage/files" "${path}/files"]; 54 | noCheck = true; 55 | }; 56 | 57 | # Read write upload directory 58 | fileSystems."${path}/files/upload" = { 59 | device = "/media/zstorage/files/upload"; 60 | options = ["rw" "bind"]; 61 | depends = ["/media/zstorage/files" "${path}/files"]; 62 | noCheck = true; 63 | }; 64 | } 65 | -------------------------------------------------------------------------------- /hosts/server-main-elis/services/hass.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | pkgs, 4 | ... 5 | }: { 6 | # Garbage collect podman images 7 | systemd.services.podman-system-prune = { 8 | description = "Garbage collect podman"; 9 | after = ["podman.service"]; 10 | wantedBy = ["multi-user.target"]; 11 | startAt = "05:30"; 12 | serviceConfig = { 13 | Type = "oneshot"; 14 | User = "root"; 15 | Group = "root"; 16 | ExecStart = "${pkgs.podman}/bin/podman system prune -a -f"; 17 | }; 18 | }; 19 | 20 | virtualisation.oci-containers.containers = { 21 | home-assistant = { 22 | environment.TZ = config.time.timeZone; 23 | image = "ghcr.io/home-assistant/home-assistant:2025.5.3"; 24 | ports = ["8123"]; 25 | extraOptions = [ 26 | "--network=host" 27 | "--device=/dev/serial/by-id/usb-dresden_elektronik_ingenieurtechnik_GmbH_ConBee_II_DE2124653-if00:/dev/ttyACM0" 28 | "--device=/dev/serial/by-id/usb-Nabu_Casa_SkyConnect_v1.0_46eea243d3b3ed11bf5a46aca7669f5d-if00-port0:/dev/ttyZigbee" 29 | "--device=/dev/serial/by-id/usb-Silicon_Labs_CP2102N_USB_to_UART_Bridge_Controller_041c5694bebaed119e51ad8238a92db5-if00-port0:/dev/ttyUSB0" 30 | ]; 31 | volumes = [ 32 | "${config.etu.dataPrefix}/var/lib/hass:/config" 33 | "/media/zstorage/files/video/svt-series:/media:ro" 34 | ]; 35 | dependsOn = ["mqtt" "zwavejs2mqtt"]; 36 | }; 37 | mqtt = { 38 | image = "eclipse-mosquitto:2.0.21"; 39 | ports = ["1883:1883"]; 40 | extraOptions = [ 41 | "--network=host" 42 | ]; 43 | volumes = [ 44 | "${config.etu.dataPrefix}/var/lib/mqtt/config:/mosquitto/config:ro" 45 | "${config.etu.dataPrefix}/var/lib/mqtt/data:/mosquitto/data" 46 | "${config.etu.dataPrefix}/var/lib/mqtt/log:/mosquitto/log" 47 | ]; 48 | }; 49 | zwavejs2mqtt = { 50 | image = "zwavejs/zwavejs2mqtt:10.1.0"; 51 | ports = [ 52 | "3000:3000" 53 | # "8091:8091" # Admin interface port 54 | ]; 55 | extraOptions = [ 56 | "--device=/dev/serial/by-id/usb-0658_0200-if00:/dev/zwave" 57 | "--network=host" 58 | ]; 59 | volumes = [ 60 | "${config.etu.dataPrefix}/var/lib/zwavejs2mqtt:/usr/src/app/store" 61 | ]; 62 | }; 63 | }; 64 | } 65 | -------------------------------------------------------------------------------- /hosts/server-main-elis/services/home-nginx.nix: -------------------------------------------------------------------------------- 1 | {config, ...}: { 2 | # Make sure to have nginx enabled 3 | services.nginx.enable = true; 4 | services.nginx.virtualHosts."misc.elis.nu" = { 5 | default = true; 6 | root = "${config.etu.dataPrefix}/var/www/misc.elis.nu"; 7 | 8 | locations."/".extraConfig = "autoindex on;"; 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /hosts/server-main-elis/services/homepage.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | myData, 4 | ... 5 | }: { 6 | age.secrets = { 7 | inherit (myData.ageModules) homepage-dashboard-environment; 8 | }; 9 | 10 | services.homepage-dashboard = { 11 | enable = true; 12 | environmentFile = config.age.secrets.homepage-dashboard-environment.path; 13 | bookmarks = [ 14 | { 15 | Bookmarks = [ 16 | { 17 | Beszel = [ 18 | { 19 | icon = "beszel.svg"; 20 | href = "http://server-main-elis:6432"; 21 | description = "Beszel"; 22 | } 23 | ]; 24 | } 25 | { 26 | Bazarr = [ 27 | { 28 | icon = "bazarr.svg"; 29 | href = "/bazarr"; 30 | description = "Subtitles"; 31 | } 32 | ]; 33 | } 34 | { 35 | Lidarr = [ 36 | { 37 | icon = "lidarr.svg"; 38 | href = "/lidarr"; 39 | description = "Music"; 40 | } 41 | ]; 42 | } 43 | { 44 | Radarr = [ 45 | { 46 | icon = "radarr.svg"; 47 | href = "/radarr"; 48 | description = "Movies"; 49 | } 50 | ]; 51 | } 52 | { 53 | Sonarr = [ 54 | { 55 | icon = "sonarr.svg"; 56 | href = "/sonarr"; 57 | description = "Series"; 58 | } 59 | ]; 60 | } 61 | { 62 | NZBGet = [ 63 | { 64 | icon = "nzbget.svg"; 65 | href = "/nzbget"; 66 | description = "NZBGet"; 67 | } 68 | ]; 69 | } 70 | ]; 71 | } 72 | ]; 73 | services = [ 74 | { 75 | Calendar = [ 76 | { 77 | Calendar = { 78 | icon = "google-calendar.svg"; 79 | description = "Media Calendar"; 80 | widget = { 81 | type = "calendar"; 82 | view = "monthly"; 83 | showTime = "true"; 84 | timezone = "Europe/Stockholm"; 85 | integrations = [ 86 | { 87 | type = "sonarr"; 88 | service_group = "Media"; 89 | service_name = "Sonarr"; 90 | } 91 | { 92 | type = "radarr"; 93 | service_group = "Media"; 94 | service_name = "Radarr"; 95 | } 96 | ]; 97 | }; 98 | }; 99 | } 100 | ]; 101 | } 102 | { 103 | Beszel = [ 104 | { 105 | Beszel = { 106 | icon = "beszel.svg"; 107 | description = "Overview"; 108 | widget = { 109 | type = "beszel"; 110 | url = "http://localhost:6432"; 111 | username = "{{HOMEPAGE_VAR_BESZEL_USERNAME}}"; 112 | password = "{{HOMEPAGE_VAR_BESZEL_PASSWORD}}"; 113 | version = 2; 114 | }; 115 | }; 116 | } 117 | { 118 | Beszel = { 119 | icon = "beszel.svg"; 120 | description = "server-main-elis"; 121 | widget = { 122 | type = "beszel"; 123 | url = "http://localhost:6432"; 124 | username = "{{HOMEPAGE_VAR_BESZEL_USERNAME}}"; 125 | password = "{{HOMEPAGE_VAR_BESZEL_PASSWORD}}"; 126 | systemId = "server-main-elis"; 127 | version = 2; 128 | fields = ["cpu" "memory" "disk" "network"]; 129 | }; 130 | }; 131 | } 132 | { 133 | Beszel = { 134 | icon = "beszel.svg"; 135 | description = "server-sparv"; 136 | widget = { 137 | type = "beszel"; 138 | url = "http://localhost:6432"; 139 | username = "{{HOMEPAGE_VAR_BESZEL_USERNAME}}"; 140 | password = "{{HOMEPAGE_VAR_BESZEL_PASSWORD}}"; 141 | systemId = "server-sparv"; 142 | version = 2; 143 | fields = ["cpu" "memory" "disk" "network"]; 144 | }; 145 | }; 146 | } 147 | { 148 | Beszel = { 149 | icon = "beszel.svg"; 150 | description = "vps06"; 151 | widget = { 152 | type = "beszel"; 153 | url = "http://localhost:6432"; 154 | username = "{{HOMEPAGE_VAR_BESZEL_USERNAME}}"; 155 | password = "{{HOMEPAGE_VAR_BESZEL_PASSWORD}}"; 156 | systemId = "vps06"; 157 | version = 2; 158 | fields = ["cpu" "memory" "disk" "network"]; 159 | }; 160 | }; 161 | } 162 | ]; 163 | } 164 | { 165 | Media = [ 166 | { 167 | Sonarr = { 168 | icon = "sonarr.svg"; 169 | description = "Series"; 170 | widget = { 171 | type = "sonarr"; 172 | url = "http://server-main-elis/sonarr"; 173 | key = "{{HOMEPAGE_VAR_SONARR_API_KEY}}"; 174 | }; 175 | }; 176 | } 177 | { 178 | Radarr = { 179 | icon = "radarr.svg"; 180 | description = "Movies"; 181 | widget = { 182 | type = "radarr"; 183 | url = "http://server-main-elis/radarr"; 184 | key = "{{HOMEPAGE_VAR_RADARR_API_KEY}}"; 185 | }; 186 | }; 187 | } 188 | { 189 | Lidarr = { 190 | icon = "lidarr.svg"; 191 | description = "Music"; 192 | widget = { 193 | type = "lidarr"; 194 | url = "http://server-main-elis/lidarr"; 195 | key = "{{HOMEPAGE_VAR_LIDARR_API_KEY}}"; 196 | }; 197 | }; 198 | } 199 | { 200 | Bazarr = { 201 | icon = "bazarr.svg"; 202 | description = "Subtitles"; 203 | widget = { 204 | type = "bazarr"; 205 | url = "http://server-main-elis/bazarr"; 206 | key = "{{HOMEPAGE_VAR_BAZARR_API_KEY}}"; 207 | }; 208 | }; 209 | } 210 | { 211 | NZBGet = { 212 | icon = "nzbget.svg"; 213 | description = "NZBGet"; 214 | widget = { 215 | type = "nzbget"; 216 | url = "http://server-main-elis/nzbget"; 217 | }; 218 | }; 219 | } 220 | ]; 221 | } 222 | ]; 223 | }; 224 | } 225 | -------------------------------------------------------------------------------- /hosts/server-main-elis/services/nextcloud.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | pkgs, 4 | myData, 5 | ... 6 | }: { 7 | services.nextcloud.enable = true; 8 | services.nextcloud.package = pkgs.nextcloud31; 9 | services.nextcloud.config.adminuser = "etu"; 10 | services.nextcloud.config.adminpassFile = config.age.secrets.nextcloud-admin-password.path; 11 | services.nextcloud.config.dbtype = "sqlite"; 12 | services.nextcloud.extraApps = { 13 | inherit (pkgs.nextcloud31Packages.apps) cookbook notes; 14 | }; 15 | services.nextcloud.hostName = "nextcloud.elis.nu"; 16 | services.nginx.enable = true; 17 | 18 | # Import secret 19 | age.secrets = { 20 | inherit (myData.ageModules) nextcloud-admin-password; 21 | }; 22 | 23 | etu.base.zfs.system.directories = [ 24 | # Bind mount for persistent data for freshrss 25 | "/var/lib/nextcloud" 26 | ]; 27 | } 28 | -------------------------------------------------------------------------------- /hosts/server-main-elis/services/svtplay.nix: -------------------------------------------------------------------------------- 1 | {pkgs, ...}: let 2 | buildSvtPlayService = svtSlug: { 3 | description = "${svtSlug} playlist updater"; 4 | wants = ["network-online.target"]; 5 | after = ["network-online.target"]; 6 | path = [pkgs.svtplay-dl]; 7 | script = "svtplay-dl --all-episodes --get-url --preferred DASH https://www.svtplay.se/${svtSlug} > ${svtSlug}.m3u"; 8 | serviceConfig = { 9 | Type = "simple"; 10 | User = "downloads"; 11 | Group = "downloads"; 12 | WorkingDirectory = "/data/var/www/misc.elis.nu/.svtplay"; 13 | }; 14 | }; 15 | buildSvtPlayTimer = svtSlug: { 16 | description = "${svtSlug} playlist updater timer"; 17 | after = ["network-online.target"]; 18 | wants = ["network-online.target"]; 19 | wantedBy = ["timers.target"]; 20 | timerConfig.OnCalendar = "daily"; 21 | }; 22 | in { 23 | systemd.services.svtplay-faret-shaun = buildSvtPlayService "faret-shaun"; 24 | systemd.timers.svtplay-faret-shaun = buildSvtPlayTimer "faret-shaun"; 25 | 26 | systemd.services.svtplay-mamma-mu = buildSvtPlayService "mamma-mu"; 27 | systemd.timers.svtplay-mamma-mu = buildSvtPlayTimer "mamma-mu"; 28 | 29 | systemd.services.svtplay-pettson-och-findus = buildSvtPlayService "pettson-och-findus"; 30 | systemd.timers.svtplay-pettson-och-findus = buildSvtPlayTimer "pettson-och-findus"; 31 | 32 | systemd.services.svtplay-filtis-och-fluff = buildSvtPlayService "filtis-och-fluff"; 33 | systemd.timers.svtplay-filtis-och-fluff = buildSvtPlayTimer "filtis-och-fluff"; 34 | 35 | systemd.services.svtplay-greta-gris = buildSvtPlayService "greta-gris"; 36 | systemd.timers.svtplay-greta-gris = buildSvtPlayTimer "greta-gris"; 37 | 38 | systemd.services.svtplay-minibods = buildSvtPlayService "minibods"; 39 | systemd.timers.svtplay-minibods = buildSvtPlayTimer "minibods"; 40 | } 41 | -------------------------------------------------------------------------------- /hosts/server-main-elis/services/usenet.nix: -------------------------------------------------------------------------------- 1 | {config, ...}: { 2 | # Make sure to have nginx enabled 3 | services.nginx.enable = true; 4 | services.nginx.virtualHosts.${config.networking.hostName}.locations = let 5 | onlyLan = '' 6 | allow 100.0.0.0/8; 7 | allow 127.0.0.1/24; 8 | allow ::1; 9 | deny all; 10 | ''; 11 | in { 12 | "/" = { 13 | proxyPass = "http://127.0.0.1:${toString config.services.homepage-dashboard.listenPort}"; 14 | recommendedProxySettings = true; 15 | extraConfig = onlyLan; 16 | }; 17 | "/bazarr" = { 18 | proxyPass = "http://127.0.0.1:6767/bazarr"; 19 | extraConfig = onlyLan; 20 | }; 21 | "/sonarr" = { 22 | proxyPass = "http://127.0.0.1:8989/sonarr"; 23 | extraConfig = onlyLan; 24 | }; 25 | "/radarr" = { 26 | proxyPass = "http://127.0.0.1:7878/radarr"; 27 | extraConfig = onlyLan; 28 | }; 29 | "/lidarr" = { 30 | proxyPass = "http://127.0.0.1:8686/lidarr"; 31 | extraConfig = onlyLan; 32 | }; 33 | "~ ^/nzbget($|./*)" = { 34 | proxyPass = "http://127.0.0.1:6789"; 35 | extraConfig = 36 | onlyLan 37 | + '' 38 | rewrite /nzbget/(.*) /$1 break; 39 | proxy_set_header Host $host; 40 | proxy_set_header X-Real-IP $remote_addr; 41 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 42 | ''; 43 | }; 44 | }; 45 | 46 | # Persistent directory mounts 47 | etu.base.zfs.system.directories = [ 48 | "/var/lib/bazarr" 49 | "/var/lib/lidarr" 50 | "/var/lib/nzbget" 51 | "/var/lib/radarr" 52 | "/var/lib/sonarr" 53 | ]; 54 | 55 | # nzbget needs unrar 56 | etu.base.nix.allowUnfree = ["unrar"]; 57 | 58 | # dotnet for sonarr seems to be very old 59 | nixpkgs.config.permittedInsecurePackages = [ 60 | "aspnetcore-runtime-6.0.36" 61 | "aspnetcore-runtime-wrapped-6.0.36" 62 | "dotnet-sdk-6.0.428" 63 | "dotnet-sdk-wrapped-6.0.428" 64 | ]; 65 | 66 | # Enable services 67 | services.bazarr = { 68 | enable = true; 69 | user = "downloads"; 70 | group = "downloads"; 71 | }; 72 | services.nzbget = { 73 | enable = true; 74 | user = "downloads"; 75 | group = "downloads"; 76 | }; 77 | services.sonarr = { 78 | enable = true; 79 | user = "downloads"; 80 | group = "downloads"; 81 | }; 82 | services.radarr = { 83 | enable = true; 84 | user = "downloads"; 85 | group = "downloads"; 86 | }; 87 | services.lidarr = { 88 | enable = true; 89 | user = "downloads"; 90 | group = "downloads"; 91 | }; 92 | 93 | # Enable service protections 94 | systemd.services = let 95 | perms = { 96 | CapabilityBoundingSet = ""; 97 | NoNewPrivileges = true; 98 | PrivateDevices = true; 99 | PrivateMounts = true; 100 | PrivateTmp = true; 101 | ProtectClock = true; 102 | ProtectHome = true; 103 | ProtectHostname = true; 104 | ProtectKernelModules = true; 105 | ProtectProc = "invisible"; 106 | ProtectSystem = "strict"; 107 | ReadOnlyPaths = ["/"]; 108 | RestrictAddressFamilies = ["AF_INET" "AF_INET6"]; 109 | RestrictNamespaces = true; 110 | RestrictSUIDSGID = true; 111 | SystemCallFilter = ["@system-service"]; 112 | }; 113 | in { 114 | bazarr.serviceConfig = 115 | perms 116 | // { 117 | ReadWritePaths = ["/var/lib/bazarr" "/media/zstorage/files/video/series" "/media/zstorage/files/video/movies"]; 118 | UMask = "0022"; # Make all files world readwrite by defaults 119 | }; 120 | nzbget.serviceConfig = 121 | perms 122 | // { 123 | ReadWritePaths = ["/var/lib/nzbget" "/var/lib/nzbget-dst"]; 124 | }; 125 | sonarr.serviceConfig = 126 | perms 127 | // { 128 | ReadWritePaths = ["/var/lib/sonarr" "/media/zstorage/files/video/series" "/var/lib/nzbget-dst"]; 129 | UMask = "0022"; # Make all files world readwrite by defaults 130 | }; 131 | radarr.serviceConfig = 132 | perms 133 | // { 134 | ReadWritePaths = ["/var/lib/radarr" "/media/zstorage/files/video/movies" "/var/lib/nzbget-dst"]; 135 | UMask = "0022"; # Make all files world readwrite by defaults 136 | }; 137 | lidarr.serviceConfig = 138 | perms 139 | // { 140 | ReadWritePaths = ["/var/lib/lidarr" "/media/zstorage/files/audio/music" "/var/lib/nzbget-dst"]; 141 | UMask = "0022"; # Make all files world readwrite by defaults 142 | }; 143 | }; 144 | } 145 | -------------------------------------------------------------------------------- /hosts/server-sparv/configuration.nix: -------------------------------------------------------------------------------- 1 | # Edit this configuration file to define what should be installed on 2 | # your system. Help is available in the configuration.nix(5) man page 3 | # and in the NixOS manual (accessible by running ‘nixos-help’). 4 | { 5 | config, 6 | myData, 7 | pkgs, 8 | ... 9 | }: { 10 | imports = [ 11 | # Include my hardware settings. 12 | ./hardware.nix 13 | ]; 14 | 15 | # Set hostname 16 | networking.hostName = "zparv-zerver"; 17 | 18 | # Settings needed for ZFS 19 | networking.hostId = "48a0ce30"; 20 | 21 | # Enable weekly garbage-collection and daily store optimization. 22 | nix.gc.automatic = true; 23 | nix.gc.dates = "weekly"; 24 | nix.gc.options = "--delete-older-than 7d"; 25 | nix.optimise.automatic = true; 26 | nix.optimise.dates = ["daily"]; 27 | 28 | # My module settings 29 | etu = { 30 | stateVersion = "24.05"; 31 | 32 | # Set data prefix so agenix can find the host keys. 33 | dataPrefix = "/"; 34 | 35 | # We do have a persistent root on this system, I know, it's 36 | # weird. So here I disable the persstence settings for this system 37 | # and just keep the files on / 38 | base.zfs.enable = false; # Disable emacs that is enabled by default. 39 | 40 | base.nix.allowUnfree = ["minecraft-server"]; 41 | 42 | base.emacs.enable = false; # Disable emacs that is enabled by default. 43 | base.sanoid.datasets = { 44 | # Enable snapshotting for some filesystems 45 | "zroot/safe/root".use_template = ["data"]; 46 | "zroot/safe/home".use_template = ["data"]; 47 | "zroot/local/minecraft".use_template = ["data"]; # Minecraft server 48 | "zroot/local/valheim".use_template = ["data"]; # Valheim server 49 | "zroot/local/project-zomboid".use_template = ["data"]; # Project Zomboid server 50 | }; 51 | 52 | # Allow github to deploy system 53 | user.extraRootAuthorizedKeys = myData.pubkeys.etu.github-actions; 54 | 55 | services.netdata.enable = true; 56 | 57 | # Allow beszel to monitor this system 58 | services.beszel-agent.enable = true; 59 | services.beszel-agent.extraFilesystems = [ 60 | "/boot" 61 | "/boot-fallback" 62 | "/data" 63 | "/data/local" 64 | "/home" 65 | "/media/zstorage" 66 | "/nix" 67 | ]; 68 | }; 69 | 70 | # Disable documentation to make the system smaller. 71 | documentation.enable = false; 72 | documentation.doc.enable = false; 73 | documentation.info.enable = false; 74 | documentation.man.enable = false; 75 | 76 | # Set cpupower governor to performance. 77 | powerManagement.cpuFreqGovernor = "performance"; 78 | 79 | # Set up docker. 80 | virtualisation.docker.enable = true; 81 | virtualisation.docker.storageDriver = "zfs"; 82 | 83 | # Set up lancache docker container. 84 | virtualisation.oci-containers.backend = "docker"; 85 | virtualisation.oci-containers.containers = { 86 | lancache = { 87 | image = "docker.io/lancachenet/monolithic:latest"; 88 | ports = [ 89 | "80:80/tcp" 90 | "443:443/tcp" 91 | ]; 92 | volumes = [ 93 | "/media/zstorage/lancache/data:/data/cache" 94 | "/media/zstorage/lancache/logs:/data/logs" 95 | ]; 96 | extraOptions = [ 97 | "--ulimit" 98 | "nofile=1048576:1048576" 99 | ]; 100 | }; 101 | lancache-dns = { 102 | image = "docker.io/lancachenet/lancache-dns:latest"; 103 | ports = [ 104 | "53:53/udp" 105 | ]; 106 | environment = { 107 | LANCACHE_IP = "10.69.0.3"; 108 | USE_GENERIC_CACHE = "true"; 109 | UPSTREAM_DNS = "1.1.1.2"; 110 | }; 111 | }; 112 | 113 | # Set up a valheim server 114 | valheim-server = { 115 | image = "ghcr.io/mbround18/valheim:latest"; 116 | ports = [ 117 | "2456-2458:2456-2458/udp" 118 | ]; 119 | environment = { 120 | PORT = "2456"; 121 | PUBLIC = "0"; 122 | ENABLE_CROSSPLAY = "1"; 123 | 124 | # Disable updates 125 | AUTO_UPDATE = "0"; 126 | UPDATE_ON_STARTUP = "0"; 127 | 128 | # Enable mods 129 | TYPE = "BepInEx"; 130 | MODS = '' 131 | CW_Jesse-BetterNetworking_Valheim-2.3.2 132 | ''; 133 | }; 134 | environmentFiles = [config.age.secrets.valheim-server-env.path]; 135 | volumes = [ 136 | "/var/lib/valheim/backups:/home/steam/backups" 137 | "/var/lib/valheim/saves:/home/steam/.config/unity3d/IronGate/Valheim" 138 | "/var/lib/valheim/server:/home/steam/valheim" 139 | ]; 140 | }; 141 | 142 | # Set up a project zomboid server 143 | project-zomboid = { 144 | image = "docker.io/danixu86/project-zomboid-dedicated-server:latest"; 145 | ports = [ 146 | "8766-8767:8766-8767/udp" 147 | "16261:16261/udp" 148 | "16262-16272:16262-16272/tcp" 149 | ]; 150 | environmentFiles = [config.age.secrets.project-zomboid-env.path]; 151 | volumes = [ 152 | "/var/lib/project-zomboid:/home/steam/Zomboid" 153 | ]; 154 | }; 155 | }; 156 | 157 | # Include secret 158 | age.secrets.valheim-server-env = myData.ageModules.valheim-server-env; 159 | age.secrets.project-zomboid-env = myData.ageModules.project-zomboid-env; 160 | 161 | # Restart valheim service every day 162 | systemd.services.restart-valheim-service = { 163 | description = "Restart valheim service"; 164 | after = ["docker.service"]; 165 | serviceConfig.Type = "simple"; 166 | script = "${pkgs.systemd}/bin/systemctl restart docker-valheim-server.service"; 167 | }; 168 | systemd.timers.restart-valheim-service = { 169 | wantedBy = ["timers.target"]; 170 | after = ["docker.service"]; 171 | timerConfig = { 172 | OnCalendar = "05:15"; 173 | Persistent = "yes"; 174 | }; 175 | }; 176 | 177 | # Set up a minecraft server 178 | services.minecraft-server = { 179 | enable = true; 180 | eula = true; 181 | openFirewall = true; 182 | declarative = true; 183 | 184 | serverProperties = { 185 | server-port = 25565; 186 | motd = "Välkommen till Sparv's Minecraft server!"; 187 | difficulty = "normal"; 188 | gamemode = "survival"; 189 | max-players = 10; 190 | snooper-enabled = false; 191 | 192 | enable-command-block = true; 193 | online-mode = true; 194 | white-list = true; 195 | 196 | # Disable spawn protection. 197 | spawn-protection = 0; 198 | 199 | # Enable password to allow to connect. 200 | # enable-rcon = true; 201 | # "rcon.password" = "hunter2"; 202 | }; 203 | 204 | # Enable to allow users to connect. 205 | # Example: 206 | # - "username" = "uuid" 207 | whitelist = { 208 | "etuetuetu" = "e5520c26-81b6-4683-9ed0-53dc8b5f4d3f"; 209 | "Angrontyr" = "5a88e4f6-56c1-4f16-93d7-34bd6aea3d74"; 210 | "PikabooSuprise" = "3357057f-77ee-45b5-a0c5-5f5b303b0e02"; 211 | "Eiydra" = "47fa8f5f-f7d3-441a-8c12-4306372ee81b"; 212 | "LightCatcher0_0" = "b1a5906a-2f2e-4a51-b273-2b0e164eafde"; 213 | "Steelwolf16" = "e0000732-519e-46ac-9d1c-b4b2f460534f"; 214 | "concate" = "776ddc3d-f182-4b8c-a07e-ae4b355994d8"; 215 | "ScarletHunter22" = "1cf53c7c-75c3-480a-b91a-8a64fe84a3cc"; 216 | "Pralin" = "72343c63-2442-4333-8e97-72c98d691905"; 217 | "gondelix" = "7e095af1-c96a-408d-ad22-334c64db9700"; 218 | "Slysor" = "e370b6b0-a470-4367-8d1c-51cf31432898"; 219 | "M1TTEN5" = "75e6ab27-5fb1-4fc3-aafb-c6f00c0d98e7"; 220 | }; 221 | }; 222 | } 223 | -------------------------------------------------------------------------------- /hosts/server-sparv/hardware.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | modulesPath, 5 | ... 6 | }: { 7 | imports = [ 8 | (modulesPath + "/installer/scan/not-detected.nix") 9 | ]; 10 | 11 | # Configure boot loader. 12 | boot.loader.grub.enable = true; 13 | boot.loader.grub.efiSupport = true; 14 | boot.loader.grub.device = "nodev"; 15 | boot.loader.efi.canTouchEfiVariables = true; 16 | 17 | boot.loader.grub.mirroredBoots = [ 18 | { 19 | devices = ["/dev/disk/by-uuid/ata-Samsung_SSD_850_EVO_250GB_S21PNSAFC51888N-part1"]; 20 | path = "/boot-fallback"; 21 | } 22 | ]; 23 | 24 | boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod"]; 25 | boot.initrd.kernelModules = []; 26 | boot.kernelModules = ["kvm-intel"]; 27 | boot.extraModulePackages = []; 28 | 29 | # Enable ZFS. 30 | boot.supportedFilesystems = ["zfs"]; 31 | 32 | # Tune some ZFS parameters to use more RAM. 33 | boot.kernelParams = [ 34 | # Enable a bigger ARC max size, reserve 30GiB. 35 | "zfs.zfs_arc_max=${builtins.toString (30 * 1024 * 1024 * 1024)}" 36 | # Enable a bigger ARC target size, reserve 28GiB. 37 | "zfs.zfs_arc_min=${builtins.toString (28 * 1024 * 1024 * 1024)}" 38 | ]; 39 | 40 | # Enable ZFS scrubbing. 41 | services.zfs.autoScrub.enable = true; 42 | 43 | fileSystems."/" = { 44 | device = "zroot/safe/root"; 45 | fsType = "zfs"; 46 | neededForBoot = true; 47 | }; 48 | 49 | fileSystems.${config.etu.localPrefix} = { 50 | device = "zroot/local/data"; 51 | fsType = "zfs"; 52 | neededForBoot = true; 53 | options = ["defaults" "noexec"]; 54 | }; 55 | 56 | fileSystems."/nix" = { 57 | device = "zroot/local/nix"; 58 | fsType = "zfs"; 59 | }; 60 | 61 | fileSystems."/home" = { 62 | device = "zroot/safe/home"; 63 | fsType = "zfs"; 64 | neededForBoot = true; 65 | }; 66 | 67 | fileSystems."/var/log" = { 68 | device = "zroot/local/var-log"; 69 | fsType = "zfs"; 70 | }; 71 | 72 | # Make sure to import ZFS pool for cache. 73 | fileSystems."/media/zstorage/lancache" = { 74 | device = "zstorage/lancache"; 75 | fsType = "zfs"; 76 | neededForBoot = true; 77 | }; 78 | 79 | fileSystems."/boot" = { 80 | device = "/dev/disk/by-uuid/2A9D-C192"; 81 | fsType = "vfat"; 82 | }; 83 | 84 | fileSystems."/boot-fallback" = { 85 | device = "/dev/disk/by-uuid/2AC0-C92B"; 86 | fsType = "vfat"; 87 | }; 88 | 89 | swapDevices = []; 90 | 91 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 92 | # (the default) this is the recommended approach. When using systemd-networkd it's 93 | # still possible to use this option, but it's recommended to use it in conjunction 94 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`. 95 | networking.useDHCP = lib.mkDefault true; 96 | # networking.interfaces.enp2s0.useDHCP = lib.mkDefault true; 97 | 98 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 99 | powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; 100 | hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 101 | } 102 | -------------------------------------------------------------------------------- /hosts/vps06/configuration.nix: -------------------------------------------------------------------------------- 1 | # Edit this configuration file to define what should be installed on 2 | # your system. Help is available in the configuration.nix(5) man page 3 | # and in the NixOS manual (accessible by running ‘nixos-help’). 4 | { 5 | config, 6 | lib, 7 | myData, 8 | ... 9 | }: { 10 | imports = [ 11 | # Include my hardware settings. 12 | ./hardware.nix 13 | 14 | # Include static network settings. 15 | ./networking.nix 16 | 17 | # Import matrix settings 18 | ./services/forgejo.nix 19 | ./services/matrix.nix 20 | ./services/misc.nix 21 | ./services/postgres.nix 22 | ]; 23 | 24 | # Set hostname 25 | networking.hostName = "vps06"; 26 | 27 | # Settings needed for ZFS 28 | networking.hostId = "77a4b2cc"; 29 | 30 | # Enable weekly garbage-collection and daily store optimization. 31 | nix.gc.automatic = true; 32 | nix.gc.dates = "weekly"; 33 | nix.gc.options = "--delete-older-than 7d"; 34 | nix.optimise.automatic = true; 35 | nix.optimise.dates = ["daily"]; 36 | 37 | # My module settings 38 | etu = { 39 | stateVersion = "24.05"; 40 | 41 | base.emacs.enable = lib.mkForce false; 42 | 43 | user.extraRootAuthorizedKeys = 44 | # Allow home server to pull backups 45 | myData.pubkeys.etu.syncoid.server-main-elis 46 | ++ 47 | # Allow github to deploy system 48 | myData.pubkeys.etu.github-actions; 49 | 50 | base.sanoid.datasets = { 51 | # Enable snapshotting for some filesystems 52 | "zroot/safe/data".use_template = ["data"]; 53 | }; 54 | services.netdata.enable = true; 55 | 56 | # Allow beszel to monitor this system 57 | services.beszel-agent.enable = true; 58 | services.beszel-agent.extraFilesystems = [ 59 | "/boot" 60 | "/data" 61 | "/data/local" 62 | "/nix" 63 | ]; 64 | }; 65 | 66 | # Disable documentation to make the system smaller. 67 | documentation.enable = false; 68 | documentation.doc.enable = false; 69 | documentation.info.enable = false; 70 | documentation.man.enable = false; 71 | 72 | # Set up Letsencrypt 73 | security.acme.defaults.email = config.etu.user.email; 74 | security.acme.acceptTerms = true; 75 | 76 | etu.base.zfs.system.directories = [ 77 | # Persistence of certificates for nginx 78 | "/var/lib/acme" 79 | ]; 80 | 81 | networking.firewall.allowedTCPPorts = [80 443]; 82 | 83 | services.nginx.enable = true; 84 | } 85 | -------------------------------------------------------------------------------- /hosts/vps06/hardware.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | modulesPath, 5 | ... 6 | }: { 7 | imports = [ 8 | (modulesPath + "/profiles/qemu-guest.nix") 9 | ]; 10 | 11 | # Configure boot loader. 12 | boot.loader.grub.enable = true; 13 | boot.loader.grub.device = "/dev/sda"; 14 | 15 | boot.initrd.availableKernelModules = ["ahci" "xhci_pci" "virtio_pci" "sd_mod" "sr_mod"]; 16 | boot.initrd.kernelModules = []; 17 | 18 | boot.kernelModules = []; 19 | boot.extraModulePackages = []; 20 | 21 | # Enable ZFS. 22 | boot.supportedFilesystems = ["zfs"]; 23 | 24 | # Enable ZFS scrubbing. 25 | services.zfs.autoScrub.enable = true; 26 | 27 | # Filesystem mounts. 28 | fileSystems."/" = { 29 | device = "none"; 30 | fsType = "tmpfs"; 31 | options = ["defaults" "size=1G" "mode=755"]; 32 | }; 33 | 34 | fileSystems."/nix" = { 35 | device = "zroot/local/nix"; 36 | fsType = "zfs"; 37 | }; 38 | 39 | fileSystems."/var/log" = { 40 | device = "zroot/local/var-log"; 41 | fsType = "zfs"; 42 | }; 43 | 44 | fileSystems.${config.etu.dataPrefix} = { 45 | device = "zroot/safe/data"; 46 | fsType = "zfs"; 47 | neededForBoot = true; 48 | }; 49 | 50 | fileSystems.${config.etu.localPrefix} = { 51 | device = "zroot/local/data"; 52 | fsType = "zfs"; 53 | neededForBoot = true; 54 | options = ["defaults" "noexec"]; 55 | }; 56 | 57 | fileSystems."/boot" = { 58 | device = "/dev/disk/by-uuid/2828bb52-e581-4820-989c-3c9ca18c2925"; 59 | fsType = "ext4"; 60 | }; 61 | 62 | etu.base.zfs.system.directories = [ 63 | # Persistence of roots dotfiles between boots 64 | "/root" 65 | ]; 66 | 67 | # Swap devices. 68 | swapDevices = []; 69 | 70 | # Set max jobs in nix. 71 | nix.settings.max-jobs = lib.mkDefault 1; 72 | } 73 | -------------------------------------------------------------------------------- /hosts/vps06/networking.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | # This file was populated at runtime with the networking 3 | # details gathered from the active system. 4 | networking = { 5 | useDHCP = false; 6 | nameservers = [ 7 | "2001:4860:4860::8888" 8 | "2001:4860:4860::8844" 9 | "8.8.8.8" 10 | "8.8.4.4" 11 | ]; 12 | defaultGateway = { 13 | address = "172.31.1.1"; 14 | interface = "eth0"; 15 | }; 16 | defaultGateway6 = { 17 | address = "fe80::1"; 18 | interface = "eth0"; 19 | }; 20 | interfaces.eth0 = { 21 | ipv4.addresses = [ 22 | { 23 | address = "49.12.203.105"; 24 | prefixLength = 32; 25 | } 26 | ]; 27 | ipv4.routes = [ 28 | { 29 | address = "172.31.1.1"; 30 | prefixLength = 32; 31 | } 32 | ]; 33 | ipv6.addresses = [ 34 | { 35 | address = "2a01:4f8:c0c:8d7b::1"; 36 | prefixLength = 64; 37 | } 38 | ]; 39 | }; 40 | }; 41 | services.udev.extraRules = '' 42 | ATTR{address}=="96:00:01:99:e6:ee", NAME="eth0" 43 | ''; 44 | } 45 | -------------------------------------------------------------------------------- /hosts/vps06/services/forgejo.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | pkgs, 4 | ... 5 | }: { 6 | etu.base.zfs.system.directories = [ 7 | # Persistence of forgejo data. 8 | "/var/lib/forgejo" 9 | ]; 10 | 11 | services.nginx.virtualHosts."git.elis.nu" = { 12 | forceSSL = true; 13 | enableACME = true; 14 | locations."/".proxyPass = "http://127.0.0.1:${builtins.toString config.services.forgejo.settings.server.HTTP_PORT}/"; 15 | locations."/robots.txt".root = pkgs.writeTextDir "robots.txt" '' 16 | User-agent: * 17 | Disallow: / 18 | ''; 19 | }; 20 | 21 | services.postgresql = { 22 | ensureDatabases = ["forgejo"]; 23 | ensureUsers = [ 24 | { 25 | name = "forgejo"; 26 | ensureDBOwnership = true; 27 | } 28 | ]; 29 | }; 30 | 31 | services.forgejo.enable = true; 32 | # Newer then LTS to work with gitea migration. 33 | services.forgejo.package = pkgs.forgejo; 34 | services.forgejo.database.type = "postgres"; 35 | services.forgejo.settings.DEFAULT.APP_NAME = "Elis Git Service"; 36 | services.forgejo.settings.server.DOMAIN = "git.elis.nu"; 37 | services.forgejo.settings.server.ROOT_URL = "https://git.elis.nu/"; 38 | services.forgejo.settings.service.DISABLE_REGISTRATION = true; 39 | services.forgejo.settings.service.REQUIRE_SIGNIN_VIEW = true; 40 | services.forgejo.settings.session.COOKIE_SECURE = true; 41 | } 42 | -------------------------------------------------------------------------------- /hosts/vps06/services/misc.nix: -------------------------------------------------------------------------------- 1 | {pkgs, ...}: { 2 | # Enable the ip-failar-nu service 3 | services.ip-failar-nu.enable = true; 4 | 5 | # This is to avoid nginx validation errors when upgrading tailscale 6 | # and restarting nginx at the same time. 7 | networking.hosts."100.100.6.114" = ["server-main-elis"]; 8 | 9 | services.nginx.virtualHosts = { 10 | "ip.failar.nu" = { 11 | addSSL = true; 12 | enableACME = true; 13 | locations."/".proxyPass = "http://127.0.0.1:8123/"; 14 | locations."/".extraConfig = "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;"; 15 | }; 16 | "sa.0b.se" = { 17 | forceSSL = true; 18 | enableACME = true; 19 | locations."/".proxyPass = "https://elis.nu/"; 20 | }; 21 | "sa4b.se" = { 22 | forceSSL = true; 23 | enableACME = true; 24 | locations."/".proxyPass = "https://elis.nu/"; 25 | }; 26 | "freshrss.elis.nu" = { 27 | forceSSL = true; 28 | enableACME = true; 29 | locations."/".proxyPass = "http://server-main-elis/"; 30 | locations."/".extraConfig = "proxy_set_header Host $host;"; 31 | }; 32 | "nextcloud.elis.nu" = { 33 | forceSSL = true; 34 | enableACME = true; 35 | locations."/".proxyPass = "http://server-main-elis/"; 36 | locations."/".extraConfig = "proxy_set_header Host $host;"; 37 | }; 38 | "hass.elis.nu" = { 39 | forceSSL = true; 40 | enableACME = true; 41 | locations."/".proxyWebsockets = true; 42 | locations."/".proxyPass = "http://server-main-elis:8123/"; 43 | locations."/".extraConfig = '' 44 | proxy_set_header Host $host; 45 | proxy_set_header X-Real-IP $remote_addr; 46 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 47 | proxy_set_header X-Forwarded-Host $host; 48 | proxy_read_timeout 300; 49 | proxy_connect_timeout 300; 50 | proxy_send_timeout 300; 51 | ''; 52 | }; 53 | "jellyfin.elis.nu" = { 54 | forceSSL = true; 55 | enableACME = true; 56 | locations."/" = { 57 | proxyPass = "http://server-main-elis:8096"; 58 | proxyWebsockets = true; 59 | }; 60 | }; 61 | "misc.elis.nu" = { 62 | forceSSL = true; 63 | enableACME = true; 64 | locations."/".proxyPass = "http://server-main-elis:80"; 65 | locations."/".extraConfig = "proxy_set_header Host $host;"; 66 | locations."/robots.txt".root = pkgs.writeTextDir "robots.txt" '' 67 | User-agent: * 68 | Disallow: / 69 | ''; 70 | }; 71 | }; 72 | 73 | services.nginx.clientMaxBodySize = "20m"; # Increase body size since we handle jellyfin. 74 | } 75 | -------------------------------------------------------------------------------- /hosts/vps06/services/postgres.nix: -------------------------------------------------------------------------------- 1 | {pkgs, ...}: { 2 | etu.base.zfs.system.directories = [ 3 | # Persistence of postgres database between boots. 4 | "/var/lib/postgresql" 5 | ]; 6 | 7 | services.postgresql = { 8 | enable = true; 9 | package = pkgs.postgresql_17; 10 | 11 | # From http://pgconfigurator.cybertec.at/; https://git.darmstadt.ccc.de/maralorn/nixos-config/-/blob/master/nixos/roles/matrix-synapse/postgres-tuning.nix 12 | settings = { 13 | # Connectivity; 14 | max_connections = 100; 15 | superuser_reserved_connections = 3; 16 | # Memory Settings; 17 | shared_buffers = "1024 MB"; 18 | work_mem = "32 MB"; 19 | maintenance_work_mem = "320 MB"; 20 | huge_pages = "off"; 21 | effective_cache_size = "2 GB"; 22 | effective_io_concurrency = 100; # concurrent IO only really activated if OS supports posix_fadvise function; 23 | random_page_cost = 1.25; # speed of random disk access relative to sequential access (1.0); 24 | # Monitoring; 25 | shared_preload_libraries = "pg_stat_statements,auto_explain"; # per statement resource usage stats & log explain statements for slow queries 26 | track_io_timing = "on"; # measure exact block IO times; 27 | track_functions = "pl"; # track execution times of pl-language procedures if any; 28 | # Replication; 29 | wal_level = "replica"; # consider using at least "replica"; 30 | max_wal_senders = 0; 31 | synchronous_commit = "on"; 32 | 33 | # Checkpointing: ; 34 | checkpoint_timeout = "15 min"; 35 | checkpoint_completion_target = 0.9; 36 | max_wal_size = "1024 MB"; 37 | min_wal_size = "512 MB"; 38 | 39 | # WAL writing; 40 | wal_compression = "on"; 41 | wal_buffers = -1; # auto-tuned by Postgres till maximum of segment size (16MB by default); 42 | wal_writer_delay = "200ms"; 43 | wal_writer_flush_after = "1MB"; 44 | 45 | # Background writer; 46 | bgwriter_delay = "200ms"; 47 | bgwriter_lru_maxpages = 100; 48 | bgwriter_lru_multiplier = 2.0; 49 | bgwriter_flush_after = 0; 50 | 51 | # Parallel queries: ; 52 | max_worker_processes = 6; 53 | max_parallel_workers_per_gather = 3; 54 | max_parallel_maintenance_workers = 3; 55 | max_parallel_workers = 6; 56 | parallel_leader_participation = "on"; 57 | 58 | # Advanced features ; 59 | enable_partitionwise_join = "on"; 60 | enable_partitionwise_aggregate = "on"; 61 | jit = "on"; 62 | 63 | jit_above_cost = 100000; 64 | jit_inline_above_cost = 150000; 65 | jit_optimize_above_cost = 500000; 66 | 67 | # log slow queries 68 | log_min_duration_statement = 100; 69 | "auto_explain.log_min_duration" = 100; 70 | }; 71 | }; 72 | } 73 | -------------------------------------------------------------------------------- /modules/base/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | imports = [ 8 | ./emacs 9 | ./fish 10 | ./htop 11 | ./nix 12 | ./tmux 13 | ./sshd 14 | ./sanoid 15 | ./syncoid 16 | ./spell 17 | ./tailscale 18 | ./zfs 19 | ]; 20 | 21 | options.etu = { 22 | stateVersion = lib.mkOption { 23 | type = lib.types.str; 24 | example = "22.05"; 25 | description = "The NixOS state version to use for this system"; 26 | }; 27 | dataPrefix = lib.mkOption { 28 | type = lib.types.str; 29 | default = "/data"; 30 | description = "The path to where persistent storage happens"; 31 | }; 32 | localPrefix = lib.mkOption { 33 | type = lib.types.str; 34 | default = "/data/local"; 35 | description = "The path to where persistent local storage happens"; 36 | }; 37 | }; 38 | 39 | config = { 40 | # Set the nixpkgs inputs path as channel in the NIX_PATH variable. 41 | nix.nixPath = ["nixpkgs=${pkgs.path}"]; 42 | 43 | # Enable base services. 44 | etu.base = { 45 | emacs.enable = lib.mkDefault true; 46 | fish.enable = lib.mkDefault true; 47 | htop.enable = lib.mkDefault true; 48 | tmux.enable = lib.mkDefault true; 49 | nix.enable = lib.mkDefault true; 50 | sshd.enable = lib.mkDefault true; 51 | sanoid.enable = lib.mkDefault true; 52 | spell.enable = lib.mkDefault true; 53 | tailscale.enable = lib.mkDefault true; 54 | zfs.enable = lib.mkDefault true; 55 | }; 56 | 57 | # Set your time zone. 58 | time.timeZone = "Europe/Stockholm"; 59 | 60 | # Select internationalisation properties. 61 | i18n = { 62 | defaultLocale = "en_US.UTF-8"; 63 | supportedLocales = [ 64 | "all" 65 | ]; 66 | }; 67 | 68 | # Set console font and keymap. 69 | console.font = "Lat2-Terminus16"; 70 | console.useXkbConfig = true; 71 | 72 | # Keyboard layout used by the console, X11 and other parts. 73 | services.xserver.xkb.model = config.etu.graphical.xkb-keymap.model; 74 | services.xserver.xkb.layout = config.etu.graphical.xkb-keymap.layout; 75 | services.xserver.xkb.options = config.etu.graphical.xkb-keymap.options; 76 | services.xserver.xkb.variant = config.etu.graphical.xkb-keymap.variant; 77 | 78 | # Enable experimental features in the nix command to make nix 79 | # search work. 80 | nix.settings.experimental-features = ["nix-command" "flakes"]; 81 | 82 | # Set system state version. 83 | system.stateVersion = config.etu.stateVersion; 84 | 85 | # Display a diff of installed packages on system activation. 86 | system.activationScripts.diff = { 87 | supportsDryActivation = true; 88 | text = '' 89 | NO_FORMAT="\033[0m" 90 | F_BOLD="\033[1m" 91 | C_LIME="\033[38;5;10m" 92 | 93 | if test -e /run/current-system; then 94 | echo -e "''${F_BOLD}''${C_LIME}==> diff to current-system ''${NO_FORMAT}" 95 | ${pkgs.nvd}/bin/nvd --nix-bin-dir=${config.nix.package}/bin diff /run/current-system "$systemConfig" 96 | fi 97 | ''; 98 | }; 99 | 100 | # Enable doas. 101 | security.doas.enable = true; 102 | 103 | # Install some command line tools I commonly want available 104 | environment.systemPackages = [ 105 | # Nice extra command line tools 106 | pkgs.bat # "bat - cat with wings", cat|less with language highlight 107 | pkgs.curl # curl duh 108 | pkgs.duf # nice disk usage output 109 | pkgs.fd # find util 110 | pkgs.file # file duh 111 | pkgs.fzf # fuzzy finder 112 | pkgs.jc # parse different formats and command outputs to json 113 | pkgs.jq # parse, format and query json documents 114 | pkgs.ncdu # disk usage navigator 115 | pkgs.pv # pipe viewer for progressbars in pipes 116 | pkgs.ripgrep # quick file searcher 117 | pkgs.testssl # print TLS certificate info 118 | pkgs.speedtest-cli # Speedtest command line util 119 | 120 | # Own tools: 121 | pkgs.nur.repos.etu.llr # llr, tool to cut long lines 122 | pkgs.nur.repos.etu.mkvcleaner # mkvcleaner, clean video files from unwanted tracks 123 | 124 | # Networking tools 125 | pkgs.dnsutils # dig etc 126 | pkgs.host # look up host info 127 | pkgs.whois # whois duh 128 | pkgs.prettyping # pretty ping output 129 | (pkgs.runCommand "prettyping-pp" {} '' 130 | mkdir -p $out/bin 131 | ln -s ${pkgs.prettyping}/bin/prettyping $out/bin/pp 132 | '') 133 | 134 | # Install some color test scripts from xterm 135 | (pkgs.runCommand "xterm-color-scripts" {} '' 136 | tar -xf ${pkgs.xterm.src} 137 | 138 | install -Dm755 xterm-${pkgs.xterm.version}/vttests/256colors2.pl $out/bin/256colors2.pl 139 | install -Dm755 xterm-${pkgs.xterm.version}/vttests/88colors2.pl $out/bin/88colors2.pl 140 | '') 141 | ]; 142 | 143 | # Set backup file extensions for conflicts on home manager activation. 144 | home-manager.backupFileExtension = "backup"; 145 | 146 | # Set state version for my users home-manager (if it's enabled). 147 | home-manager.users.${config.etu.user.username} = lib.mkIf config.etu.user.enable { 148 | home.stateVersion = config.etu.stateVersion; 149 | }; 150 | 151 | # Set state version for root users home-manager. 152 | home-manager.users.root.home.stateVersion = config.etu.stateVersion; 153 | }; 154 | } 155 | -------------------------------------------------------------------------------- /modules/base/emacs/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | emacs-overlay, 4 | emacsWayland, 5 | intelephense, 6 | lib, 7 | pkgs, 8 | ... 9 | }: let 10 | # Run my config trough substituteAll to replace font names from my 11 | # system font settings. 12 | emacsConfig = pkgs.runCommand "config.el" { 13 | inherit treesitGrammars; 14 | inherit (config.etu) dataPrefix; 15 | extraConfig = lib.concatStringsSep "\n\n" config.etu.base.emacs.extraConfig; 16 | fontname = config.etu.graphical.theme.fonts.monospace; 17 | fontsize = config.etu.graphical.theme.fonts.size; 18 | } "substituteAll ${./config.el} $out"; 19 | 20 | # Config to wrap loading of the emacs config file. 21 | emacsConfigInit = pkgs.writeText "${emacsConfig.name}-init.el" '' 22 | ;;; ${emacsConfig.name}-init.el -- starts here 23 | ;;; Commentary: 24 | ;;; Code: 25 | 26 | ;; Add a startup hook that logs the startup time to the messages buffer 27 | (add-hook 'emacs-startup-hook 28 | (lambda () 29 | (message "Emacs ready in %s with %d garbage collections." 30 | (format "%.2f seconds" 31 | (float-time 32 | (time-subtract after-init-time before-init-time))) 33 | gcs-done))) 34 | 35 | ;; Increase the threshold to reduce the amount of garbage collections made 36 | ;; during startups. 37 | (let ((gc-cons-threshold (* 50 1000 1000)) 38 | (gc-cons-percentage 0.6) 39 | (file-name-handler-alist nil)) 40 | 41 | ;; Load config 42 | (load-file "${emacsConfig}")) 43 | 44 | ;;; ${emacsConfig.name}-init.el ends here 45 | ''; 46 | 47 | # Define language servers to include in the wrapper for Emacs 48 | extraBinPaths = [ 49 | # Language Servers 50 | pkgs.go # Go language 51 | pkgs.gopls # Go language server 52 | pkgs.bash-language-server # Bash language server 53 | pkgs.nodePackages.dockerfile-language-server-nodejs # Docker language server 54 | intelephense # PHP language server 55 | pkgs.nodePackages.typescript-language-server # JS/TS language server 56 | pkgs.vscode-langservers-extracted # CSS/LESS/SASS language server 57 | pkgs.nodejs # For copilot.el 58 | 59 | # Other programs 60 | pkgs.gnuplot # For use with org mode 61 | pkgs.phpPackages.php-codesniffer # PHP codestyle checker 62 | pkgs.openscad # For use with scad and scad preview mode 63 | ]; 64 | 65 | # List custom treesitter grammars 66 | treesitGrammars = emacsPackages.${config.etu.base.emacs.package}.pkgs.treesit-grammars.with-grammars (g: 67 | with g; [ 68 | tree-sitter-bash 69 | tree-sitter-c 70 | tree-sitter-cmake 71 | tree-sitter-cpp 72 | tree-sitter-css 73 | tree-sitter-dockerfile 74 | tree-sitter-go 75 | tree-sitter-gomod 76 | tree-sitter-hcl 77 | tree-sitter-html 78 | tree-sitter-java 79 | tree-sitter-json 80 | tree-sitter-latex 81 | tree-sitter-make 82 | tree-sitter-nix 83 | tree-sitter-php 84 | tree-sitter-python 85 | tree-sitter-rust 86 | tree-sitter-sql 87 | tree-sitter-toml 88 | tree-sitter-yaml 89 | ]); 90 | 91 | # Function to wrap emacs to contain the path for language servers 92 | wrapEmacsWithExtraBinPaths = { 93 | emacs ? emacsPackages.${config.etu.base.emacs.package}, 94 | extraWrapperArgs ? "", 95 | }: 96 | pkgs.runCommand "${emacs.name}-with-extra-bin-paths" {nativeBuildInputs = [pkgs.makeWrapper];} 97 | '' 98 | makeWrapper ${buildEmacsPackage emacs}/bin/emacs $out/bin/emacs \ 99 | --prefix PATH : ${lib.makeBinPath extraBinPaths} ${extraWrapperArgs} 100 | 101 | mkdir -p $out/share/applications 102 | ln -vs ${emacs}/share/applications/emacs.desktop $out/share/applications 103 | ln -vs ${emacs}/share/icons $out/share/icons 104 | ln -vs ${emacs}/share/info $out/share/info 105 | ln -vs ${emacs}/share/man $out/share/man 106 | ''; 107 | 108 | buildEmacsPackage = emacsPackage: 109 | pkgs.emacsWithPackagesFromUsePackage { 110 | package = emacsPackage; 111 | 112 | # Don't assume ensuring of all use-package declarations, this is 113 | # the default behaviour, but this gets rid of the notice. 114 | alwaysEnsure = false; 115 | 116 | # config to be able to pull in use-package dependencies from there. 117 | config = builtins.readFile emacsConfig; 118 | 119 | # Extra packages to install 120 | extraEmacsPackages = _: [ 121 | # Add my config initializer as an emacs package 122 | (pkgs.runCommand "my-emacs-default-package" {} '' 123 | mkdir -p $out/share/emacs/site-lisp 124 | cp ${emacsConfigInit} $out/share/emacs/site-lisp/default.el 125 | '') 126 | ]; 127 | }; 128 | 129 | # Selection of emacs packages to choose from 130 | emacsPackages = { 131 | default = pkgs.emacs; 132 | nox = pkgs.emacs-nox; 133 | wayland = emacsWayland; 134 | }; 135 | in { 136 | options.etu.base.emacs = { 137 | enable = lib.mkEnableOption "Enable base emacs settings"; 138 | extraConfig = lib.mkOption { 139 | type = lib.types.listOf lib.types.str; 140 | default = []; 141 | description = "This allows to add strings that gets added to the emacs config file."; 142 | }; 143 | package = lib.mkOption { 144 | type = lib.types.str; 145 | default = "default"; 146 | defaultText = "default"; 147 | description = "Which emacs package to use."; 148 | }; 149 | }; 150 | 151 | config = lib.mkIf config.etu.base.emacs.enable { 152 | # Import the emacs overlay from nix community to get the latest 153 | # and greatest packages. 154 | nixpkgs.overlays = [ 155 | emacs-overlay 156 | ]; 157 | 158 | # Allow to install intelephense which is an unfree package. 159 | etu.base.nix.allowUnfree = ["intelephense" "copilot-language-server"]; 160 | 161 | # Install my emacs package system-wide. 162 | services.emacs = { 163 | enable = true; 164 | defaultEditor = true; 165 | package = wrapEmacsWithExtraBinPaths {}; 166 | }; 167 | 168 | # Install emacs icons symbols if we have any kind of graphical emacs 169 | fonts.packages = lib.mkIf (config.etu.base.emacs.package != "nox") [ 170 | pkgs.emacs-all-the-icons-fonts 171 | ]; 172 | 173 | # Configure emacs for my users home-manager (if it's enabled). 174 | home-manager.users.${config.etu.user.username} = lib.mkIf config.etu.user.enable { 175 | home.file.".emacs".text = "(setq-default inhibit-startup-screen t)"; 176 | }; 177 | 178 | # Configure emacs for root users home-manager. 179 | home-manager.users.root.home.file.".emacs".text = "(setq-default inhibit-startup-screen t)"; 180 | 181 | # Enable persistence for Emacs. 182 | etu.base.zfs.user.directories = [ 183 | ".config/github-copilot" 184 | ".local/share/emacs" 185 | ]; 186 | }; 187 | } 188 | -------------------------------------------------------------------------------- /modules/base/htop/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: let 7 | base = { 8 | programs.htop = { 9 | enable = true; 10 | settings = { 11 | hide_userland_threads = true; 12 | hide_kernel_threads = true; 13 | highlight_base_name = true; 14 | shadow_other_users = true; 15 | show_program_path = false; 16 | tree_view = true; 17 | 18 | left_meters = ["LeftCPUs" "Memory" "Swap" "ZFSARC" "ZFSCARC"]; 19 | left_meter_modes = [1 1 1 2 2]; 20 | 21 | right_meters = ["RightCPUs" "Tasks" "LoadAverage" "Uptime" "Battery"]; 22 | right_meter_modes = [1 2 2 2 2]; 23 | }; 24 | }; 25 | }; 26 | in { 27 | options.etu.base.htop.enable = lib.mkEnableOption "Enable base htop settings"; 28 | 29 | config = lib.mkIf config.etu.base.htop.enable { 30 | # Always install htop as well as having it enabled in home-manager. 31 | environment.systemPackages = [pkgs.htop]; 32 | 33 | # Configure htop for my users home-manager (if it's enabled). 34 | home-manager.users.${config.etu.user.username} = lib.mkIf config.etu.user.enable base; 35 | 36 | # Configure htop for root users home-manager. 37 | home-manager.users.root = base; 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /modules/base/nix/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: { 6 | options.etu.base.nix.enable = lib.mkEnableOption "Enable base nix settings"; 7 | options.etu.base.nix.allowUnfree = lib.mkOption { 8 | default = []; 9 | type = lib.types.listOf lib.types.str; 10 | description = "Enable base nix settings"; 11 | }; 12 | 13 | config = lib.mkIf config.etu.base.nix.enable { 14 | # If we allow certain unfree packages, enable the nix option to do so. 15 | nixpkgs.config.allowUnfreePredicate = (lib.mkIf ( 16 | (builtins.length config.etu.base.nix.allowUnfree) > 0 17 | )) (pkg: builtins.elem (lib.getName pkg) config.etu.base.nix.allowUnfree); 18 | 19 | # Extra binary caches 20 | nix.settings.substituters = [ 21 | "https://nix-community.cachix.org" 22 | "https://etu.cachix.org" 23 | ]; 24 | nix.settings.trusted-public-keys = [ 25 | "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" 26 | "etu.cachix.org-1:CeyfbMJZHZ95TScp8+I8+EeyzbncqPSj1xfCK9vOAFE=" 27 | ]; 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /modules/base/sanoid/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: { 6 | options.etu.base.sanoid = { 7 | enable = lib.mkEnableOption "Enable base sanoid settings"; 8 | datasets = lib.mkOption { 9 | default = {}; 10 | description = "services.sanoid.datasets to snapshot"; 11 | }; 12 | }; 13 | 14 | config = lib.mkIf config.etu.base.sanoid.enable { 15 | # Enable sanoid snapshoting with rules for creating snapshots. 16 | services.sanoid = { 17 | enable = true; 18 | interval = "*-*-* *:00,15,30,45:00"; 19 | 20 | inherit (config.etu.base.sanoid) datasets; 21 | 22 | # Home snapshotting rules 23 | templates.home = { 24 | autosnap = true; 25 | autoprune = true; 26 | frequently = 3; 27 | hourly = 23; 28 | daily = 6; 29 | weekly = 3; 30 | monthly = 2; 31 | }; 32 | 33 | # Data snapshotting rules 34 | templates.data = { 35 | autosnap = true; 36 | autoprune = true; 37 | frequently = 3; 38 | hourly = 12; 39 | daily = 6; 40 | weekly = 3; 41 | monthly = 2; 42 | }; 43 | 44 | # Bulk storage snapshotting rules 45 | templates.storage = { 46 | autosnap = true; 47 | autoprune = true; 48 | frequently = 0; 49 | hourly = 0; 50 | daily = 6; 51 | weekly = 3; 52 | monthly = 2; 53 | }; 54 | }; 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /modules/base/spell/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.base.spell.enable = lib.mkEnableOption "Enable base spell settings"; 8 | 9 | config = lib.mkIf config.etu.base.spell.enable { 10 | environment.systemPackages = [ 11 | pkgs.aspell 12 | 13 | # Dictionaries 14 | pkgs.aspellDicts.en 15 | pkgs.aspellDicts.en-computers 16 | pkgs.aspellDicts.en-science 17 | pkgs.aspellDicts.sv 18 | 19 | # Also install hunspell with dictionaries 20 | (pkgs.hunspellWithDicts [ 21 | pkgs.hunspellDicts.en-gb-ise 22 | pkgs.hunspellDicts.en-gb-ize 23 | pkgs.hunspellDicts.en-us 24 | pkgs.hunspellDicts.sv-se 25 | ]) 26 | ]; 27 | 28 | etu.base.nix.allowUnfree = [ 29 | "aspell-dict-en-science" 30 | ]; 31 | 32 | # Configure aspell system wide 33 | environment.etc."aspell.conf".text = '' 34 | master en_US 35 | extra-dicts en-computers.rws 36 | add-extra-dicts en_US-science.rws sv.rws 37 | ''; 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /modules/base/sshd/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | myData, 5 | ... 6 | }: { 7 | options.etu.base.sshd.enable = lib.mkEnableOption "Enable base sshd settings"; 8 | 9 | config = lib.mkIf config.etu.base.sshd.enable { 10 | # Enable the OpenSSH daemon. 11 | services.openssh.enable = true; 12 | 13 | # Default is true, let's disable password auth by default. 14 | services.openssh.settings.PasswordAuthentication = false; 15 | 16 | # This is default, but nice to make it clear in here. 17 | services.openssh.settings.PermitRootLogin = "prohibit-password"; 18 | 19 | # Enable mosh. 20 | programs.mosh.enable = true; 21 | 22 | # Override identity paths for agenix since the openssh default paths 23 | # relies on a symlink being created in /etc/ssh to point at the 24 | # right path to make it to work as it would be in the right place. 25 | age.identityPaths = [ 26 | "${config.etu.dataPrefix}/etc/ssh/ssh_host_ed25519_key" 27 | "${config.etu.dataPrefix}/etc/ssh/ssh_host_rsa_key" 28 | ]; 29 | 30 | # Persistence of ssh key files 31 | etu.base.zfs.system.files = [ 32 | "/etc/ssh/ssh_host_rsa_key" 33 | "/etc/ssh/ssh_host_rsa_key.pub" 34 | "/etc/ssh/ssh_host_ed25519_key" 35 | "/etc/ssh/ssh_host_ed25519_key.pub" 36 | ]; 37 | 38 | # Add known hosts for all of my systems that I access remotely to 39 | # they always are trusted. 40 | programs.ssh.knownHosts = { 41 | desktop-elis.publicKey = myData.pubkeys.systems.desktop-elis; 42 | laptop-private-caroline.publicKey = myData.pubkeys.systems.laptop-private-caroline; 43 | laptop-private-elis.publicKey = myData.pubkeys.systems.laptop-private-elis; 44 | laptop-work-elis.publicKey = myData.pubkeys.systems.laptop-work-elis; 45 | server-main-elis = { 46 | extraHostNames = ["home.elis.nu" "local.elis.nu" "192.168.1.101"]; 47 | publicKey = myData.pubkeys.systems.server-main-elis; 48 | }; 49 | server-main-elis-initrd = { 50 | extraHostNames = ["home.elis.nu" "local.elis.nu" "192.168.1.101"]; 51 | publicKey = myData.pubkeys.systems.server-main-elis-initrd; 52 | }; 53 | "sparv.failar.nu" = { 54 | extraHostNames = ["server-sparv"]; 55 | publicKey = myData.pubkeys.systems.server-sparv; 56 | }; 57 | "vps06.elis.nu" = { 58 | extraHostNames = ["vps06" "git.elis.nu"]; 59 | publicKey = myData.pubkeys.systems.vps06; 60 | }; 61 | }; 62 | }; 63 | } 64 | -------------------------------------------------------------------------------- /modules/base/syncoid/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: { 6 | options.etu.base.syncoid = { 7 | enable = lib.mkEnableOption "Enable base syncoid settings"; 8 | commands = lib.mkOption { 9 | default = {}; 10 | description = "services.syncoid.commands to sync"; 11 | }; 12 | }; 13 | 14 | config = lib.mkIf config.etu.base.syncoid.enable { 15 | # Enable syncoid for syncing snapshots. 16 | services.syncoid = { 17 | enable = true; 18 | interval = "*-*-* *:15:00"; 19 | commonArgs = ["--no-sync-snap"]; 20 | sshKey = "/var/lib/syncoid/.ssh/id_ed25519"; 21 | inherit (config.etu.base.syncoid) commands; 22 | }; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /modules/base/tailscale/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: { 6 | options.etu.base.tailscale.enable = lib.mkEnableOption "Enable tailscale settings"; 7 | 8 | config = lib.mkIf config.etu.base.tailscale.enable { 9 | services.tailscale.enable = true; 10 | 11 | # Always allow traffic from your Tailscale network 12 | networking.firewall.trustedInterfaces = ["tailscale0"]; 13 | 14 | # Persistence of state 15 | etu.base.zfs.system.directories = [ 16 | "/var/lib/tailscale" 17 | ]; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /modules/base/tmux/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: { 6 | options.etu.base.tmux.enable = lib.mkEnableOption "Enable base tmux settings"; 7 | 8 | config = lib.mkIf config.etu.base.htop.enable { 9 | # Install tmux 10 | programs.tmux.enable = true; 11 | programs.tmux.clock24 = true; 12 | 13 | # Configure tmux for my users home-manager (if it's enabled). 14 | home-manager.users.${config.etu.user.username} = lib.mkIf config.etu.user.enable { 15 | home.file.".tmux.conf".source = ../../dotfiles/tmux.conf; 16 | }; 17 | 18 | # Configure tmux for root users home-manager. 19 | home-manager.users.root.home.file.".tmux.conf".source = ../../dotfiles/tmux.conf; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /modules/base/zfs/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: { 6 | options.etu.base.zfs = let 7 | options = param: prefix: { 8 | directories = lib.mkOption { 9 | type = lib.types.listOf lib.types.str; 10 | default = []; 11 | description = "Directories to pass to environment.persistence attribute for ${param} under ${prefix}"; 12 | }; 13 | files = lib.mkOption { 14 | type = lib.types.listOf lib.types.str; 15 | default = []; 16 | description = "Files to pass to environment.persistence attribute for ${param} under ${prefix}"; 17 | }; 18 | }; 19 | in { 20 | enable = lib.mkEnableOption "Enable base zfs persistence settings"; 21 | local = options "local" config.etu.localPrefix; 22 | localUser = options "localUser" config.etu.localPrefix; 23 | system = options "system" config.etu.dataPrefix; 24 | user = options "user" config.etu.dataPrefix; 25 | root = options "root" config.etu.dataPrefix; 26 | }; 27 | 28 | config = lib.mkIf config.etu.base.zfs.enable { 29 | environment.etc."machine-id".source = "${config.etu.dataPrefix}/etc/machine-id"; 30 | 31 | environment.persistence.${config.etu.dataPrefix} = { 32 | # System persistence 33 | inherit (config.etu.base.zfs.system) files; 34 | directories = 35 | [ 36 | "/var/lib/nixos" 37 | ] 38 | ++ config.etu.base.zfs.system.directories; 39 | 40 | # Root user persistence 41 | users.root = { 42 | inherit (config.users.users.root) home; 43 | inherit (config.etu.base.zfs.root) directories files; 44 | }; 45 | 46 | # My user persistence 47 | users.${config.etu.user.username} = lib.mkIf config.etu.user.enable { 48 | inherit (config.etu.base.zfs.user) directories files; 49 | }; 50 | }; 51 | 52 | # Persistence for local files that may not be backed up 53 | environment.persistence.${config.etu.localPrefix} = { 54 | inherit (config.etu.base.zfs.local) directories files; 55 | 56 | # Local user persistence 57 | users.${config.etu.user.username} = lib.mkIf config.etu.user.enable { 58 | inherit (config.etu.base.zfs.localUser) directories files; 59 | }; 60 | }; 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /modules/default.nix: -------------------------------------------------------------------------------- 1 | {...}: { 2 | imports = [ 3 | # New module organization 4 | ./base 5 | ./development 6 | ./games 7 | ./graphical 8 | ./services 9 | ./theme 10 | ./user 11 | ./work 12 | ]; 13 | } 14 | -------------------------------------------------------------------------------- /modules/development/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: { 6 | imports = [ 7 | ./direnv 8 | ./flipper-zero 9 | ./git 10 | ./php 11 | ./rtl-sdr 12 | ./vscode 13 | ./zed 14 | ]; 15 | 16 | options.etu.development.enable = lib.mkEnableOption "Enable development settings"; 17 | 18 | config = lib.mkIf config.etu.development.enable { 19 | etu = { 20 | development.direnv.enable = lib.mkDefault true; 21 | development.git.enable = lib.mkDefault true; 22 | development.php.enable = lib.mkDefault true; 23 | development.rtl-sdr.enable = lib.mkDefault true; 24 | development.vscode.enable = lib.mkDefault true; 25 | 26 | # Define extra groups for user. 27 | user.extraGroups = ["dialout"]; 28 | }; 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /modules/development/direnv/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.development.direnv.enable = lib.mkEnableOption "Enable development direnv settings"; 8 | 9 | config = lib.mkIf config.etu.development.direnv.enable { 10 | # Enable lorri on all systems. 11 | services.lorri.enable = true; 12 | 13 | # If my user exists, enable home-manager configurations 14 | home-manager.users.${config.etu.user.username} = lib.mkIf config.etu.user.enable { 15 | home.file = { 16 | # Configure lorri to be backed by direnv 17 | ".direnvrc".text = '' 18 | use_nix() { 19 | eval "$(lorri direnv)" 20 | } 21 | ''; 22 | }; 23 | }; 24 | 25 | # Install direnv using home manager. 26 | etu.user.extraUserPackages = [ 27 | pkgs.direnv 28 | ]; 29 | 30 | # Enable persistence for direnv files. 31 | etu.base.zfs.user.directories = [ 32 | ".local/share/direnv" 33 | ]; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /modules/development/flipper-zero/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.development.flipper-zero.enable = lib.mkEnableOption "Enable flipper zero settings"; 8 | 9 | config = lib.mkIf config.etu.development.flipper-zero.enable { 10 | # Install flipper zero udev rules. 11 | services.udev.packages = [ 12 | pkgs.qFlipper 13 | ]; 14 | 15 | # Install flipper zero program using home manager. 16 | etu.user.extraUserPackages = [pkgs.qFlipper]; 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /modules/development/git/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.development.git.enable = lib.mkEnableOption "Enable development git settings"; 8 | 9 | config = lib.mkIf config.etu.development.git.enable { 10 | # Install git system wide. 11 | environment.systemPackages = [ 12 | pkgs.git 13 | ]; 14 | 15 | # Configure git for my users home-manager (if it's enabled). 16 | home-manager.users.${config.etu.user.username} = lib.mkIf config.etu.user.enable { 17 | home.file = { 18 | "bin/git-branchclean".source = ../../dotfiles/bin/git-branchclean; 19 | "bin/git-git".source = ../../dotfiles/bin/git-git; 20 | "bin/git-lol".source = ../../dotfiles/bin/git-lol; 21 | "bin/git-refetch-tags".source = ../../dotfiles/bin/git-refetch-tags; 22 | }; 23 | 24 | programs.git = { 25 | enable = true; 26 | 27 | # Default configs 28 | extraConfig = { 29 | commit.gpgSign = config.etu.graphical.gnupg.enable; 30 | 31 | user.name = config.etu.user.realname; 32 | user.email = config.etu.user.email; 33 | user.signingKey = config.etu.user.signingKey; 34 | 35 | # Set default "git pull" behaviour so it doesn't try to default to 36 | # either "git fetch; git merge" (default) or "git fetch; git rebase". 37 | pull.ff = "only"; 38 | 39 | # REuse REcorded REsolution to remember and resolve merge conflicts 40 | # better when you hit the several conflict several times. 41 | rerere.enabled = true; 42 | }; 43 | 44 | # Global ignores 45 | ignores = [".ac-php-conf.json" ".projectile-cache.eld"]; 46 | 47 | # Conditonally included configs 48 | includes = [ 49 | { 50 | condition = "gitdir:/home/${config.etu.user.username}/tvnu/"; 51 | contents = { 52 | commit.gpgSign = false; 53 | user.email = config.etu.user.workEmail; 54 | user.signingKey = ""; 55 | core.excludesFile = pkgs.writeTextFile { 56 | name = "tvnu-ignore"; 57 | text = '' 58 | .ac-php-conf.json 59 | .vscode/ 60 | ''; 61 | }; 62 | }; 63 | } 64 | { 65 | condition = "gitdir:/home/${config.etu.user.username}/code/TaserudConsulting/"; 66 | contents = { 67 | user.email = config.etu.user.companyEmail; 68 | }; 69 | } 70 | ]; 71 | }; 72 | }; 73 | }; 74 | } 75 | -------------------------------------------------------------------------------- /modules/development/php/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.development.php.enable = lib.mkEnableOption "Enable development php settings"; 8 | 9 | config = lib.mkIf config.etu.development.enable { 10 | # Install php utils using home manager. 11 | etu.user.extraUserPackages = [ 12 | # PHP utils 13 | pkgs.php 14 | pkgs.php.packages.composer 15 | pkgs.php.packages.php-codesniffer 16 | ]; 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /modules/development/rtl-sdr/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.development.rtl-sdr.enable = lib.mkEnableOption "Enable development rtl-sdr settings"; 8 | 9 | config = lib.mkIf config.etu.development.rtl-sdr.enable { 10 | hardware.rtl-sdr.enable = true; 11 | 12 | # Install rtl-sdr utils using home manager. 13 | etu.user.extraUserPackages = [ 14 | pkgs.cubicsdr 15 | pkgs.rtl-sdr 16 | pkgs.rtl_433 17 | ]; 18 | 19 | # Define extra groups for user. 20 | etu.user.extraGroups = ["plugdev"]; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /modules/development/zed/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.development.zed.enable = lib.mkEnableOption "Enable zed editor settings"; 8 | 9 | config = lib.mkIf config.etu.development.zed.enable { 10 | # Install zed editor program using home manager. 11 | etu.user.extraUserPackages = [pkgs.zed-editor]; 12 | 13 | # Enable persistence for vscode state files files. 14 | etu.base.zfs.user.directories = [ 15 | ".config/zed/" 16 | ".local/share/zed/" 17 | ]; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /modules/dotfiles/bin/git-branchclean: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | git fetch --prune 4 | 5 | if [ "x$(git branch --merged | grep -Ev '(^\*|main|master|release)')" != "x" ]; then 6 | git branch --merged | grep -Ev '(^\*|main|master|release)' | xargs git branch -d 7 | fi 8 | -------------------------------------------------------------------------------- /modules/dotfiles/bin/git-git: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec git $@ 4 | -------------------------------------------------------------------------------- /modules/dotfiles/bin/git-lol: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec git log --graph --decorate --pretty=format:'%C(yellow)%h %Cgreen%cd%C(bold red)%d%Creset %s' --abbrev-commit --date=short 4 | -------------------------------------------------------------------------------- /modules/dotfiles/bin/git-refetch-tags: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Drop all tags 4 | git tag -l | xargs git tag -d 5 | 6 | # Fetch all tags from remote 7 | git fetch --tags 8 | -------------------------------------------------------------------------------- /modules/dotfiles/bin/keep: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # 3 | # Shamelessly stolen from someone :-) 4 | # 5 | # keep - poor man's version control, make freshly numbered copies 6 | 7 | [[ $# = 0 ]] && exit 255 8 | 9 | for f; do 10 | f=$f:A 11 | v=($f.<->(nOnN[1])) 12 | if [[ -n "$v" ]] && cmp $v $f >/dev/null 2>&1; then 13 | print -u2 $v not modified 14 | else 15 | cp -va $f $f.$((${${v:-.0}##*.} + 1)) 16 | fi 17 | done 18 | -------------------------------------------------------------------------------- /modules/dotfiles/bin/restow: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Enter directory 4 | cd @dataPrefix@$HOME/.dotfiles 5 | 6 | # Update directory 7 | git pull 8 | 9 | case $(hostname) in 10 | desktop-elis|laptop-private-elis|laptop-work-elis) 11 | stow --dotfiles skeleton 12 | ;; 13 | 14 | *) 15 | echo "This computer is not recognized by restow." 16 | ;; 17 | esac 18 | -------------------------------------------------------------------------------- /modules/dotfiles/bin/spacecolors: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #ANSI color scheme script featuring Space Invaders 3 | # 4 | # Original: http://crunchbanglinux.org/forums/post/126921/#p126921 5 | # Modified by lolilolicon 6 | 7 | 8 | f=3 b=4 9 | for j in f b; do 10 | for i in {0..7}; do 11 | eval ${j}${i}=\$\'\\e\[${!j}${i}m\' 12 | done 13 | done 14 | bld=$'\e[1m' 15 | rst=$'\e[0m' 16 | 17 | cat << EOF 18 | 19 | $f0 ▄██▄ $f1 ▀▄ ▄▀ $f2 ▄▄▄████▄▄▄ $f3 ▄██▄ $f4 ▀▄ ▄▀ $f5 ▄▄▄████▄▄▄ $f6 ▄██▄ $rst 20 | $f0▄█▀██▀█▄ $f1 ▄█▀███▀█▄ $f2███▀▀██▀▀███ $f3▄█▀██▀█▄ $f4 ▄█▀███▀█▄ $f5███▀▀██▀▀███ $f6▄█▀██▀█▄ $rst 21 | $f0▀▀█▀▀█▀▀ $f1█▀███████▀█ $f2▀▀▀██▀▀██▀▀▀ $f3▀▀█▀▀█▀▀ $f4█▀███████▀█ $f5▀▀▀██▀▀██▀▀▀ $f6▀▀█▀▀█▀▀ $rst 22 | $f0▄▀▄▀▀▄▀▄ $f1▀ ▀▄▄ ▄▄▀ ▀ $f2▄▄▀▀ ▀▀ ▀▀▄▄ $f3▄▀▄▀▀▄▀▄ $f4▀ ▀▄▄ ▄▄▀ ▀ $f5▄▄▀▀ ▀▀ ▀▀▄▄ $f6▄▀▄▀▀▄▀▄ $rst 23 | 24 | $bld $f0 ▄██▄ $f1 ▀▄ ▄▀ $f2 ▄▄▄████▄▄▄ $f3 ▄██▄ $f4 ▀▄ ▄▀ $f5 ▄▄▄████▄▄▄ $f6 ▄██▄ $rst 25 | $bld $f0▄█▀██▀█▄ $f1 ▄█▀███▀█▄ $f2███▀▀██▀▀███ $f3▄█▀██▀█▄ $f4 ▄█▀███▀█▄ $f5███▀▀██▀▀███ $f6▄█▀██▀█▄$rst 26 | $bld $f0▀▀█▀▀█▀▀ $f1█▀███████▀█ $f2▀▀▀██▀▀██▀▀▀ $f3▀▀█▀▀█▀▀ $f4█▀███████▀█ $f5▀▀▀██▀▀██▀▀▀ $f6▀▀█▀▀█▀▀$rst 27 | $bld $f0▄▀▄▀▀▄▀▄ $f1▀ ▀▄▄ ▄▄▀ ▀ $f2▄▄▀▀ ▀▀ ▀▀▄▄ $f3▄▀▄▀▀▄▀▄ $f4▀ ▀▄▄ ▄▄▀ ▀ $f5▄▄▀▀ ▀▀ ▀▀▄▄ $f6▄▀▄▀▀▄▀▄$rst 28 | 29 | 30 | $f7▌$rst 31 | 32 | $f7▌$rst 33 | 34 | $f7 ▄█▄ $rst 35 | $f7▄█████████▄$rst 36 | $f7▀▀▀▀▀▀▀▀▀▀▀$rst 37 | 38 | EOF 39 | -------------------------------------------------------------------------------- /modules/dotfiles/stupidterm.ini: -------------------------------------------------------------------------------- 1 | [options] 2 | font = Liberation Mono 10 3 | lines = 1000 4 | allow-bold = true 5 | scroll-on-output = false 6 | scroll-on-keystroke = true 7 | mouse-autohide = true 8 | sync-clipboard = true 9 | urgent-on-bell = true 10 | 11 | [colors] 12 | foreground = #F8F8F2 13 | background = #282A36 14 | 15 | [urlmatch] 16 | program = /run/current-system/sw/bin/firefox 17 | regex = (((gopher|news|telnet|nntp|file|http|ftp|https)://)|(www|ftp)[-A-Za-z0-9]*\\.)[-A-Za-z0-9\\.]+(:[0-9]*)?(/[-A-Za-z0-9_\\$\\.\\+\\!\\*\\(\\),;:@&=\\?/~\\#\\%]*[^]'\\.}>\\) ,\\\"])? 18 | -------------------------------------------------------------------------------- /modules/dotfiles/tmux.conf: -------------------------------------------------------------------------------- 1 | # Unbind default C-b binding and bind C-q 2 | unbind C-b 3 | set -g prefix C-q 4 | bind C-q send-prefix 5 | 6 | # Remove keybindings to resize panes 7 | unbind C-Up 8 | unbind M-Up 9 | unbind C-Down 10 | unbind M-Down 11 | unbind C-Left 12 | unbind M-Left 13 | unbind C-Right 14 | unbind M-Right 15 | 16 | # Reload tmux config file 17 | unbind r 18 | bind r source-file ~/.tmux.conf 19 | 20 | # Bind pane selection 21 | unbind f 22 | unbind n 23 | unbind p 24 | bind b select-pane -L 25 | bind f select-pane -R 26 | bind n select-pane -D 27 | bind p select-pane -U 28 | 29 | # Set Terminal Emulator Window Title 30 | set -g set-titles on 31 | set -g set-titles-string '#S:#I.#P #W' 32 | 33 | # Status Bar styles 34 | set -g status-bg black 35 | set -g status-fg white 36 | set -g status-interval 1 37 | 38 | # Show hostname on left side 39 | set -g status-left-length 30 40 | set -g status-left '#[fg=colour2][ #[fg=colour10]#h#[fg=colour2] ][#[default] ' 41 | 42 | # Show load and date/time on right side 43 | set -g status-right-length 60 44 | set -g status-right '#[fg=colour2]][ #[fg=colour11]#(cut -d " " -f 1-4 /proc/loadavg)#[fg=colour2] ][ #[fg=colour14]%Y-%m-%d %H:%M:%S#[fg=colour2] ]#[default]' 45 | 46 | # Center the window list 47 | set -g status-justify centre 48 | 49 | # Format of window items 50 | set -g window-status-format ' #I-$ #W ' 51 | set -g window-status-current-format '#[bg=black]#[fg=red,bold](#[fg=white,bold]#I*$ #W#[fg=red,bold])#[default]' 52 | 53 | # Notifying if other windows has activities 54 | setw -g monitor-activity on 55 | set -g visual-activity off 56 | 57 | # Clock style 58 | setw -g clock-mode-colour green 59 | setw -g clock-mode-style 24 60 | 61 | # 256 Color terminals 62 | set -g default-terminal "screen-256color" 63 | -------------------------------------------------------------------------------- /modules/games/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: { 6 | imports = [ 7 | ./minecraft 8 | ./mumble 9 | ./steam 10 | ./steam-controller 11 | ./wowup 12 | ]; 13 | 14 | options.etu.games.enable = lib.mkEnableOption "Enable games settings"; 15 | 16 | config = lib.mkIf config.etu.games.enable { 17 | etu.games = { 18 | minecraft.enable = lib.mkDefault true; 19 | mumble.enable = lib.mkDefault true; 20 | steam.enable = lib.mkDefault true; 21 | steam-controller.enable = lib.mkDefault true; 22 | }; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /modules/games/minecraft/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.games.minecraft.enable = lib.mkEnableOption "Enable games minecraft settings"; 8 | 9 | config = lib.mkIf config.etu.games.minecraft.enable { 10 | # Install minecraft using home manager. 11 | etu.user.extraUserPackages = [pkgs.prismlauncher]; 12 | 13 | # Enable persistence for minecraft files. 14 | etu.base.zfs.user.directories = [ 15 | ".local/share/PrismLauncher" 16 | ]; 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /modules/games/mumble/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.games.mumble.enable = lib.mkEnableOption "Enable games mumble settings"; 8 | 9 | config = lib.mkIf config.etu.games.mumble.enable { 10 | # Install mumble using home manager. 11 | etu.user.extraUserPackages = [pkgs.mumble]; 12 | 13 | # Enable persistence for mumble files. 14 | etu.base.zfs.user.files = [ 15 | ".config/Mumble/Mumble.conf" 16 | ".local/share/Mumble/Mumble/mumble.sqlite" 17 | ]; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /modules/games/steam-controller/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.games.steam-controller.enable = lib.mkEnableOption "Enable games steam-controller settings"; 8 | 9 | config = lib.mkIf config.etu.games.steam-controller.enable { 10 | # Enable udev rules for steam controller 11 | services.udev.packages = [ 12 | pkgs.sc-controller 13 | ]; 14 | 15 | # Install steam using home manager. 16 | etu.user.extraUserPackages = [pkgs.sc-controller]; 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /modules/games/steam/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: { 6 | options.etu.games.steam.enable = lib.mkEnableOption "Enable games steam settings"; 7 | 8 | config = lib.mkIf config.etu.games.steam.enable { 9 | # Allow to install some unfree packages. 10 | etu.base.nix.allowUnfree = [ 11 | "steam" 12 | "steam-unwrapped" 13 | ]; 14 | 15 | # Enable steam settings. 16 | programs.steam = { 17 | enable = true; 18 | remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play 19 | dedicatedServer.openFirewall = true; # Open ports in the firewall for Source Dedicated Server 20 | localNetworkGameTransfers.openFirewall = true; # Open ports in the firewall for Steam Local Network Game Transfers 21 | }; 22 | 23 | # Enable persistence for steam files. 24 | etu.base.zfs.localUser.directories = [ 25 | ".steam" 26 | ".config/unity3d/" # To remember settings for Valheim 27 | ".local/share/Steam" 28 | ]; 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /modules/games/wowup/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.games.wowup.enable = lib.mkEnableOption "Enable games wowup settings"; 8 | 9 | config = lib.mkIf config.etu.games.wowup.enable { 10 | # Allow to install some unfree packages. 11 | etu.base.nix.allowUnfree = [ 12 | "wowup-cf" 13 | ]; 14 | # Install steam using home manager. 15 | etu.user.extraUserPackages = [pkgs.wowup-cf]; 16 | 17 | # Enable persistence for steam files. 18 | etu.base.zfs.user.directories = [ 19 | ".config/WowUpCf" 20 | ]; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /modules/graphical/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | imports = [ 8 | ./fdm-printing 9 | ./firefox 10 | ./flatpak 11 | ./gnupg 12 | ./hamradio 13 | ./signal 14 | ./sway 15 | ./telegram 16 | ./terminal 17 | ./theme 18 | ./virtualbox 19 | ./window-managers 20 | ./xkb-keymap 21 | ]; 22 | 23 | options.etu.graphical.enable = lib.mkEnableOption "Enable graphical settings"; 24 | 25 | config = lib.mkIf config.etu.graphical.enable { 26 | etu = { 27 | graphical.firefox.enable = lib.mkDefault true; 28 | graphical.flatpak.enable = lib.mkDefault true; 29 | graphical.gnupg.enable = lib.mkDefault true; 30 | graphical.telegram.enable = lib.mkDefault true; 31 | graphical.terminal.enable = lib.mkDefault true; 32 | graphical.theme.enable = lib.mkDefault true; 33 | 34 | # Define extra groups for user. 35 | user.extraGroups = ["networkmanager" "adbusers"]; 36 | 37 | # Install using home-manager. 38 | user.extraUserPackages = [ 39 | pkgs.chromium # Chromium browser 40 | pkgs.delfin # Jellyfin client 41 | pkgs.feh # Image display tool 42 | pkgs.imv # Image display tool 43 | pkgs.mpv # Media player 44 | pkgs.pavucontrol # Pulse audio volume control 45 | pkgs.sshfs-fuse # SSHFS client 46 | pkgs.stupidterm # Another terminal emulator 47 | pkgs.yt-dlp # Youtube download client 48 | ]; 49 | 50 | # Directories to mount persistent for my user on graphical sessions 51 | base.zfs.user.directories = [ 52 | ".config/delfin" 53 | ".config/pipewire/media-session.d" 54 | ".local/state/wireplumber" 55 | "Downloads" 56 | "code" 57 | "documents" 58 | "org" 59 | 60 | # Persist chromium config directory 61 | ".config/chromium" 62 | 63 | # Persist gnome online accounts and gnome keyrings directories. 64 | ".config/goa-1.0" 65 | ".local/share/keyrings" 66 | ]; 67 | 68 | # Persistence of certain hosts paths for graphical systems. 69 | base.zfs.system.directories = [ 70 | "/etc/nixos" 71 | "/etc/NetworkManager/system-connections" 72 | "/var/lib/bluetooth" 73 | "/var/lib/iwd" 74 | ]; 75 | }; 76 | 77 | # Mount the /etc/nixos directory in the home directory as well. 78 | fileSystems."/home/${config.etu.user.username}/code/nixos" = { 79 | device = "${config.etu.dataPrefix}/etc/nixos"; 80 | options = ["bind" "noauto" "x-systemd.automount" "x-systemd.requires-mounts-for=${config.etu.dataPrefix}"]; 81 | }; 82 | 83 | # Install adb and fastboot. 84 | programs.adb.enable = true; 85 | 86 | # Enable gnome keyring (related to ~/.config/goa-1.0 and ~/.local/share/keyrings). 87 | services.gnome.gnome-keyring.enable = true; 88 | 89 | # Enable networkmanager. 90 | networking.networkmanager.enable = true; 91 | networking.networkmanager.wifi.backend = "iwd"; 92 | networking.wireless.iwd.settings.Settings.AutoConnect = true; 93 | 94 | # 8000 is for random web sharing things. 95 | networking.firewall.allowedTCPPorts = [8000]; 96 | 97 | # Install some comand line tools I cummonly want available for my 98 | # home directory on graphical systems. 99 | home-manager.users.${config.etu.user.username} = lib.mkIf config.etu.user.enable { 100 | home.file = { 101 | # Mpv config file - Don't show images embedded in music files 102 | ".config/mpv/mpv.conf".text = "no-audio-display"; 103 | 104 | ".XCompose".text = '' 105 | include "%L" 106 | 107 | # Default already 108 | # : "å" 109 | # : "Å" 110 | 111 | # Some nice binds 112 | : "ä" 113 | : "Ä" 114 | : "ö" 115 | : "Ö" 116 | 117 | # Table flip multi key 118 | : "(ノಠ益ಠ)ノ彡┻━┻" 119 | 120 | # Shruggie 121 | : "¯\\_(ツ)_/¯" 122 | ''; 123 | }; 124 | }; 125 | }; 126 | } 127 | -------------------------------------------------------------------------------- /modules/graphical/fdm-printing/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.graphical.fdm-printing.enable = lib.mkEnableOption "Enable graphical 3d printing settings"; 8 | 9 | config = lib.mkIf config.etu.graphical.fdm-printing.enable { 10 | # Install using home-manager. 11 | etu.user.extraUserPackages = [ 12 | pkgs.freecad 13 | pkgs.openscad 14 | ]; 15 | 16 | # Enable persistence for fdm-printing related files. 17 | etu.base.zfs.user.directories = [ 18 | ".config/FreeCAD" 19 | ".config/OpenSCAD" 20 | ]; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /modules/graphical/firefox/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.graphical.firefox = { 8 | enable = lib.mkEnableOption "Enable graphical firefox settings"; 9 | package = lib.mkOption { 10 | type = lib.types.package; 11 | default = pkgs.firefox-bin; 12 | description = "Firefox package to use."; 13 | readOnly = true; 14 | }; 15 | }; 16 | 17 | config = lib.mkIf config.etu.graphical.firefox.enable { 18 | # Configure firefox for my users home-manager (if it's enabled). 19 | home-manager.users.${config.etu.user.username} = lib.mkIf config.etu.user.enable { 20 | # Make firefox the default browser 21 | xdg.mimeApps = { 22 | enable = true; 23 | defaultApplications = { 24 | "text/html" = ["firefox.desktop"]; 25 | "x-scheme-handler/http" = ["firefox.desktop"]; 26 | "x-scheme-handler/https" = ["firefox.desktop"]; 27 | "x-scheme-handler/about" = ["firefox.desktop"]; 28 | "x-scheme-handler/unknown" = ["firefox.desktop"]; 29 | }; 30 | }; # END xdg.mimeApps 31 | 32 | # Install my defined firefox package 33 | programs.firefox = { 34 | enable = true; 35 | inherit (config.etu.graphical.firefox) package; 36 | 37 | languagePacks = ["sv-SE" "en-GB"]; 38 | 39 | profiles.default = { 40 | # Install extensions. 41 | extensions.packages = [ 42 | pkgs.nur.repos.rycee.firefox-addons.bitwarden 43 | pkgs.nur.repos.rycee.firefox-addons.elasticvue 44 | pkgs.nur.repos.rycee.firefox-addons.facebook-container 45 | pkgs.nur.repos.rycee.firefox-addons.firefox-color 46 | pkgs.nur.repos.rycee.firefox-addons.multi-account-containers 47 | pkgs.nur.repos.rycee.firefox-addons.privacy-badger 48 | pkgs.nur.repos.rycee.firefox-addons.streetpass-for-mastodon 49 | pkgs.nur.repos.rycee.firefox-addons.swedish-dictionary 50 | pkgs.nur.repos.rycee.firefox-addons.terms-of-service-didnt-read 51 | pkgs.nur.repos.rycee.firefox-addons.ublock-origin 52 | ]; 53 | 54 | isDefault = true; 55 | search.default = "ddg"; 56 | search.force = true; 57 | search.engines = { 58 | bing.metaData.hidden = true; 59 | GitHub = { 60 | urls = [{template = "https://github.com/search?q={searchTerms}";}]; 61 | icon = "https://github.com/fluidicon.png"; 62 | updateInterval = 7 * 24 * 60 * 60 * 1000; 63 | definedAliases = ["@gh"]; 64 | }; 65 | google.metaData.alias = "@g"; 66 | "Nix Packages" = { 67 | urls = [{template = "https://search.nixos.org/packages?type=packages&query={searchTerms}";}]; 68 | icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; 69 | definedAliases = ["@np"]; 70 | }; 71 | "NixOS Wiki" = { 72 | urls = [{template = "https://wiki.nixos.org/w/index.php?search={searchTerms}";}]; 73 | icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; 74 | definedAliases = ["@nw"]; 75 | }; 76 | Perplexity = { 77 | urls = [{template = "https://www.perplexity.ai/?q={searchTerms}";}]; 78 | icon = "https://www.perplexity.ai/favicon.ico"; 79 | updateInterval = 7 * 24 * 60 * 60 * 1000; 80 | definedAliases = ["@p"]; 81 | }; 82 | }; 83 | settings = { 84 | # Extensions are managed with Nix, so don't update. 85 | "extensions.update.autoUpdateDefault" = false; 86 | "extensions.update.enabled" = false; 87 | 88 | # Sync 89 | "services.sync.username" = config.etu.user.email; 90 | 91 | # Do not sync extensions. 92 | "services.sync.engine.addons" = false; 93 | 94 | # Middle click to scroll 95 | "general.autoScroll" = true; 96 | 97 | # Restore previous windows and tabs. 98 | "browser.startup.page" = 3; 99 | 100 | # Never show bookmarks toolbar 101 | "browser.toolbars.bookmarks.visibility" = "never"; 102 | 103 | # Privacy enhancements 104 | "browser.newtabpage.activity-stream.feeds.telemetry" = false; 105 | "browser.newtabpage.activity-stream.telemetry" = false; 106 | "browser.newtabpage.activity-stream.feeds.snippets" = false; 107 | "browser.newtabpage.activity-stream.feeds.section.topstories" = false; 108 | "browser.newtabpage.activity-stream.section.highlights.includePocket" = false; 109 | "browser.newtabpage.activity-stream.showSponsored" = false; 110 | "browser.newtabpage.activity-stream.feeds.discoverystreamfeed" = false; 111 | "browser.newtabpage.activity-stream.showSponsoredTopSites" = false; 112 | 113 | # Improve performance 114 | "gfx.webrender.all" = true; 115 | 116 | # Enable browser debugging 117 | "devtools.chrome.enabled" = true; 118 | 119 | # Enable userChrome customisations 120 | "toolkit.legacyUserProfileCustomizations.stylesheets" = true; 121 | 122 | # Enable firefox built in vertical tabs 123 | "sidebar.verticalTabs" = true; 124 | }; 125 | }; 126 | }; 127 | }; 128 | 129 | # Enable persistence for firefox files. 130 | etu.base.zfs.user.directories = [ 131 | ".mozilla/firefox/default" 132 | ]; 133 | }; 134 | } 135 | -------------------------------------------------------------------------------- /modules/graphical/flatpak/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.graphical.flatpak.enable = lib.mkEnableOption "Enable graphical flatpak settings"; 8 | options.etu.graphical.flatpak.enablePersistence = lib.mkEnableOption "Enable graphical flatpak persistence settings"; 9 | 10 | config = lib.mkIf config.etu.graphical.flatpak.enable { 11 | # Install appcenter 12 | etu.user.extraUserPackages = [ 13 | pkgs.pantheon.appcenter 14 | ]; 15 | 16 | # Required for link opening to browsers to work in apps when on Sway 17 | xdg.portal.extraPortals = with pkgs; [xdg-desktop-portal-gtk]; 18 | 19 | # Mount flatpak persistence under flatpak data 20 | etu.base.zfs.local.directories = lib.mkIf config.etu.graphical.flatpak.enablePersistence [ 21 | "/var/lib/flatpak" 22 | ]; 23 | 24 | etu.base.zfs.localUser.directories = lib.mkIf config.etu.graphical.flatpak.enablePersistence [ 25 | ".cache/io.elementary.appcenter/" 26 | ".local/share/flatpak/" 27 | ".var/app/" 28 | ]; 29 | 30 | # Hack to make bind mount to allow exec since I don't allow it on 31 | # the parent filesystem. Otherwise it doesn't really work to 32 | # install or run things :'D 33 | fileSystems = lib.mkIf config.etu.graphical.flatpak.enablePersistence { 34 | "/var/lib/flatpak".options = ["exec"]; 35 | }; 36 | 37 | # Enable flatpak 38 | services.flatpak.enable = true; 39 | 40 | # Add the global override to allow reading the ~/.XCompose file in 41 | # all the flatpak applications. 42 | home-manager.users.${config.etu.user.username} = lib.mkIf config.etu.user.enable { 43 | home.file.".local/share/flatpak/overrides/com.slack.Slack".text = '' 44 | [Context] 45 | filesystems=~/.XCompose:ro 46 | ''; 47 | home.file.".local/share/flatpak/overrides/com.discordapp.Discord".text = '' 48 | [Context] 49 | filesystems=~/.XCompose:ro 50 | ''; 51 | home.file.".local/share/flatpak/overrides/dev.vencord.Vesktop".text = '' 52 | [Context] 53 | filesystems=~/.XCompose:ro 54 | ''; 55 | home.file.".local/share/flatpak/overrides/net.lutris.Lutris".text = '' 56 | [Context] 57 | filesystems=/data/local/home/${config.etu.user.username}/Games:rw 58 | ''; 59 | }; 60 | 61 | # Configure flathub 62 | systemd.services.flatpak-setup-flathub = { 63 | wantedBy = ["multi-user.target"]; 64 | path = [pkgs.flatpak]; 65 | script = '' 66 | flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo 67 | ''; 68 | }; 69 | }; 70 | } 71 | -------------------------------------------------------------------------------- /modules/graphical/gnupg/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.graphical.gnupg.enable = lib.mkEnableOption "Enable graphical gnupg settings"; 8 | 9 | config = lib.mkIf config.etu.graphical.gnupg.enable { 10 | # Enable smartcard deamon for yubikeys. 11 | services.pcscd.enable = true; 12 | 13 | # Enable gnupg agent. 14 | programs.gnupg.agent = { 15 | enable = true; 16 | enableSSHSupport = true; 17 | pinentryPackage = pkgs.pinentry-gnome3; 18 | }; 19 | 20 | # Install tools using home manager. 21 | etu.user.extraUserPackages = [ 22 | # Install gnupg 23 | pkgs.gnupg 24 | ]; 25 | 26 | # Enable persistence for gnupg and pass files. 27 | etu.base.zfs.user.directories = [ 28 | ".gnupg" 29 | ]; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /modules/graphical/hamradio/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.graphical.hamradio.enable = lib.mkEnableOption "Enable graphical hamradio settings"; 8 | 9 | config = lib.mkIf config.etu.graphical.hamradio.enable { 10 | # Install the software needed for operating FT-8 with my Xiegu G90. 11 | etu.user.extraUserPackages = [ 12 | pkgs.flrig # flrig to connect to the radio 13 | pkgs.wsjtx # wsjtx to run FT-8 14 | pkgs.nur.repos.etu.g90updatefw # Install g90 update fw for easy firmware updating on linux. 15 | ]; 16 | 17 | etu.base.zfs.user.files = [ 18 | # Enable persistence for files for flrig. 19 | ".flrig/flrig.prefs" 20 | ".flrig/Xiegu-G90.prefs" 21 | 22 | # Enable persistence for files for WSJTX. 23 | ".config/WSJT-X.ini" 24 | ]; 25 | 26 | etu.base.zfs.user.directories = [ 27 | # Enable persistence for directories for WSJTX. 28 | ".local/share/WSJT-X/" 29 | ]; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /modules/graphical/signal/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.graphical.signal.enable = lib.mkEnableOption "Enable graphical signal settings"; 8 | 9 | config = lib.mkIf config.etu.graphical.signal.enable { 10 | # Install signal desktop using home manager. 11 | etu.user.extraUserPackages = [pkgs.signal-desktop-bin]; 12 | 13 | # Enable persistence for signal files. 14 | etu.base.zfs.user.directories = [ 15 | ".config/Signal" 16 | ]; 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /modules/graphical/telegram/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.graphical.telegram.enable = lib.mkEnableOption "Enable graphical telegram settings"; 8 | 9 | config = lib.mkIf config.etu.graphical.telegram.enable { 10 | # Install the telegram chat client using home manager. 11 | etu.user.extraUserPackages = [pkgs.tdesktop]; 12 | 13 | # Enable persistence for telegram files. 14 | etu.base.zfs.user.directories = [ 15 | ".local/share/TelegramDesktop/tdata" 16 | ]; 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /modules/graphical/terminal/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.graphical.terminal = { 8 | enable = lib.mkEnableOption "Enable graphical terminal settings"; 9 | terminalPackage = lib.mkOption { 10 | type = lib.types.package; 11 | default = pkgs.alacritty; 12 | description = "Terminal package to use."; 13 | }; 14 | terminalPath = lib.mkOption { 15 | type = lib.types.str; 16 | default = "${config.etu.graphical.terminal.terminalPackage}/bin/${config.etu.graphical.terminal.terminalName}"; 17 | description = "Path to terminal binary."; 18 | readOnly = true; 19 | }; 20 | terminalName = lib.mkOption { 21 | type = lib.types.str; 22 | default = config.etu.graphical.terminal.terminalPackage.meta.mainProgram; 23 | description = "Binary name of the terminal."; 24 | readOnly = true; 25 | }; 26 | }; 27 | 28 | config = lib.mkIf config.etu.graphical.terminal.enable { 29 | # If my user exists, enable home-manager configurations 30 | home-manager.users.${config.etu.user.username} = lib.mkIf config.etu.user.enable { 31 | # Configure alacritty 32 | programs.alacritty = { 33 | enable = true; 34 | settings = { 35 | env.TERMINAL = config.etu.graphical.terminal.terminalName; 36 | env.TERM = "xterm-256color"; 37 | font.size = config.etu.graphical.theme.fonts.size; 38 | font.normal.family = config.etu.graphical.theme.fonts.monospace; 39 | }; 40 | }; # END alacritty 41 | 42 | programs.foot = { 43 | enable = true; 44 | settings = { 45 | main.term = "xterm-256color"; 46 | main.font = "${config.etu.graphical.theme.fonts.monospace}:size=${builtins.toString config.etu.graphical.theme.fonts.size}"; 47 | environment.TERMINAL = "foot"; 48 | }; 49 | }; # END foot 50 | }; # END home-manager 51 | }; 52 | } 53 | -------------------------------------------------------------------------------- /modules/graphical/theme/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.graphical.theme.enable = lib.mkEnableOption "Enable graphical theme settings"; 8 | options.etu.graphical.theme.fonts = { 9 | size = lib.mkOption { 10 | type = lib.types.int; 11 | default = 10; 12 | description = "Default font size"; 13 | }; 14 | biggerSize = lib.mkOption { 15 | type = lib.types.int; 16 | default = 13; 17 | description = "Bigger font size"; 18 | }; 19 | monospace = lib.mkOption { 20 | type = lib.types.str; 21 | default = "JetBrainsMono"; 22 | description = "Default monospace font to use"; 23 | }; 24 | normal = lib.mkOption { 25 | type = lib.types.str; 26 | default = "DejaVu Sans"; 27 | description = "Default font to use"; 28 | }; 29 | }; 30 | 31 | config = lib.mkIf config.etu.graphical.enable { 32 | # Set up default fonts 33 | fonts.enableDefaultPackages = true; 34 | fonts.enableGhostscriptFonts = true; 35 | 36 | # Allow to install microsoft fonts 37 | etu.base.nix.allowUnfree = [ 38 | "corefonts" 39 | ]; 40 | 41 | # Configure fontconfig to actually use more of Noto Color Emoji in 42 | # alacritty. 43 | fonts.fontconfig.defaultFonts.monospace = [ 44 | config.etu.graphical.theme.fonts.monospace 45 | "Noto Color Emoji" 46 | ]; 47 | 48 | # Install some extra fonts. 49 | fonts.packages = [ 50 | pkgs.jetbrains-mono 51 | 52 | # Cantarell fonts seems to be used by GTK applications (was mostly 53 | # noticable in Firefox UI elements). 54 | pkgs.cantarell-fonts 55 | 56 | # Install microsoft fonts 57 | pkgs.corefonts 58 | 59 | pkgs.nur.repos.etu.font-etuvetica # My own font 60 | pkgs.nur.repos.etu.font-talyznewroman # Install talyz's font 61 | ]; 62 | 63 | # If my user exists, enable home-manager configurations 64 | home-manager.users.${config.etu.user.username} = lib.mkIf config.etu.user.enable { 65 | # GTK theme configs 66 | gtk = { 67 | enable = true; 68 | font.name = config.etu.graphical.theme.fonts.normal; 69 | font.size = config.etu.graphical.theme.fonts.size; 70 | gtk3.extraConfig.gtk-application-prefer-dark-theme = 1; 71 | gtk4.extraConfig.gtk-application-prefer-dark-theme = 1; 72 | }; # END gtk 73 | 74 | # QT theme configs 75 | qt = { 76 | enable = true; 77 | platformTheme.name = "gtk"; 78 | }; # END qt 79 | }; 80 | }; 81 | } 82 | -------------------------------------------------------------------------------- /modules/graphical/virtualbox/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: { 6 | options.etu.graphical.virtualbox.enable = lib.mkEnableOption "Enable graphical virtualbox settings"; 7 | 8 | config = lib.mkIf config.etu.graphical.virtualbox.enable { 9 | # Enable virtualbox. 10 | virtualisation.virtualbox.host.enable = true; 11 | 12 | # Add user to group 13 | etu.user.extraGroups = ["vboxusers"]; 14 | 15 | # Enable persistence for virtualbox files. 16 | etu.base.zfs.user.directories = [ 17 | ".config/VirtualBox" 18 | "VirtualBox VMs" 19 | ]; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /modules/graphical/window-managers/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: { 6 | imports = [ 7 | ./kanshi 8 | ./mako 9 | ./waybar 10 | ]; 11 | 12 | config = lib.mkIf config.etu.graphical.sway.enable { 13 | # Set up kanshi (which kinda is an autorandr for wayland) 14 | etu.graphical.window-managers.kanshi.enable = true; 15 | 16 | # Set up mako, a notification deamon for wayland 17 | etu.graphical.window-managers.mako.enable = true; 18 | 19 | # Set up waybar, a bar for wayland 20 | etu.graphical.window-managers.waybar.enable = true; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /modules/graphical/window-managers/kanshi/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: { 6 | options.etu.graphical.window-managers.kanshi.enable = lib.mkEnableOption "Enable kanshi, kinda autorandr for wayland"; 7 | 8 | config = lib.mkIf config.etu.graphical.window-managers.kanshi.enable { 9 | # If my user exists, enable home-manager configurations 10 | home-manager.users.${config.etu.user.username} = lib.mkIf config.etu.user.enable { 11 | # Set up kanshi (which kinda is an autorandr for wayland) 12 | services.kanshi = { 13 | enable = true; 14 | settings = [ 15 | { 16 | profile.name = "undocked"; 17 | profile.outputs = [ 18 | { 19 | criteria = "eDP-1"; 20 | status = "enable"; 21 | } 22 | ]; 23 | } 24 | { 25 | profile.name = "elis-desktop"; 26 | profile.outputs = [ 27 | { 28 | criteria = "LG Electronics LG SDQHD 402NTGY0Z759"; 29 | mode = "2560x2880"; 30 | position = "0,0"; 31 | } 32 | { 33 | criteria = "LG Electronics LG SDQHD 402NTZN0Z757"; 34 | mode = "2560x2880"; 35 | position = "2560,110"; 36 | transform = "270"; 37 | } 38 | ]; 39 | } 40 | { 41 | profile.name = "elis-docked"; 42 | profile.outputs = [ 43 | { 44 | criteria = "LG Electronics LG SDQHD 402NTGY0Z759"; 45 | mode = "2560x2880"; 46 | position = "0,0"; 47 | } 48 | { 49 | criteria = "LG Electronics LG SDQHD 402NTZN0Z757"; 50 | mode = "2560x2880"; 51 | position = "2560,110"; 52 | transform = "270"; 53 | } 54 | { 55 | criteria = "eDP-1"; 56 | status = "disable"; 57 | } 58 | ]; 59 | } 60 | { 61 | profile.name = "caroline-docked"; 62 | profile.outputs = [ 63 | { 64 | criteria = "Ancor Communications Inc ASUS PB278 C9LMTF095084"; 65 | mode = "2560x1440"; 66 | position = "0,0"; 67 | } 68 | { 69 | criteria = "Ancor Communications Inc ASUS PB278 CALMTF116261"; 70 | mode = "2560x1440"; 71 | position = "2560,0"; 72 | } 73 | { 74 | criteria = "eDP-1"; 75 | status = "disable"; 76 | } 77 | ]; 78 | } 79 | { 80 | profile.name = "caroline-single-docked"; 81 | profile.outputs = [ 82 | { 83 | criteria = "Ancor Communications Inc ASUS PB278 C9LMTF095084"; 84 | mode = "1920x1080"; 85 | position = "0,0"; 86 | } 87 | { 88 | criteria = "eDP-1"; 89 | status = "disable"; 90 | } 91 | ]; 92 | } 93 | ]; 94 | }; # END kanshi 95 | }; 96 | }; 97 | } 98 | -------------------------------------------------------------------------------- /modules/graphical/window-managers/mako/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: { 6 | options.etu.graphical.window-managers.mako.enable = lib.mkEnableOption "Enable mako, a notification daemon for wayland"; 7 | 8 | config = lib.mkIf config.etu.graphical.window-managers.mako.enable { 9 | # If my user exists, enable home-manager configurations 10 | home-manager.users.${config.etu.user.username} = lib.mkIf config.etu.user.enable { 11 | # Set up mako, a notification deamon for wayland 12 | services.mako = { 13 | enable = true; 14 | settings = { 15 | border-size = 3; 16 | default-timeout = 6000; 17 | font = "${config.etu.graphical.theme.fonts.monospace} ${toString config.etu.graphical.theme.fonts.size}"; 18 | }; 19 | }; # END mako 20 | }; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /modules/graphical/window-managers/waybar/style.css: -------------------------------------------------------------------------------- 1 | @import "catppuccin.css"; 2 | 3 | * { 4 | font-family: FontAwesome, Roboto, Helvetica, Arial, sans-serif; 5 | font-size: 13px; 6 | } 7 | 8 | /* Base bar look */ 9 | window#waybar { 10 | background: @base; 11 | color: @text; 12 | /* catppuccin suggested: margin: 5px 5px */ 13 | } 14 | 15 | /* Reset how buttons looks */ 16 | button { 17 | border: none; 18 | border-radius: 0; 19 | } 20 | 21 | /* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */ 22 | button:hover { 23 | background: inherit; 24 | } 25 | 26 | /* Styles for the workspaces area and buttons */ 27 | #workspaces { 28 | background-color: @surface0; 29 | padding: 0; 30 | margin: 0; 31 | } 32 | 33 | #workspaces button { 34 | color: @lavender; 35 | background-color: transparent; 36 | padding: 0 5px; 37 | } 38 | 39 | #workspaces button:hover { 40 | background-color: @surface2; 41 | color: @yellow; 42 | box-shadow: inset 0 -3px @yellow; 43 | } 44 | 45 | #workspaces button.focused { 46 | background-color: @surface1; 47 | color: @sky; 48 | box-shadow: inset 0 -3px @sky; 49 | } 50 | 51 | #workspaces button.urgent { 52 | background-color: @surface2; 53 | color: @red; 54 | box-shadow: inset 0 -3px @red; 55 | } 56 | 57 | /* Base styles for the rest of the objects */ 58 | #backlight, 59 | #battery, 60 | #clock, 61 | #cpu, 62 | #custom-mxergo, 63 | #idle_inhibitor, 64 | #memory, 65 | #mode, 66 | #mpris, 67 | #network, 68 | #privacy, 69 | #pulseaudio, 70 | #scratchpad, 71 | #temperature, 72 | #tray { 73 | background-color: @surface0; 74 | color: @lavender; 75 | padding: 0 10px; 76 | } 77 | 78 | /* Override styles for the rest of the objects */ 79 | 80 | /* Backlight */ 81 | #backlight { 82 | color: @yellow; 83 | } 84 | 85 | /* Battery indicator */ 86 | #battery { 87 | color: @green; 88 | } 89 | 90 | #battery.charging, #battery.plugged { 91 | color: @green; 92 | box-shadow: inset 0 -3px @green; 93 | } 94 | 95 | #battery.warning:not(.charging) { 96 | color: @yellow; 97 | box-shadow: inset 0 -3px @yellow; 98 | } 99 | 100 | @keyframes blink { 101 | to { 102 | box-shadow: inset 0 -3px @surface0; 103 | } 104 | } 105 | 106 | /* Using steps() instead of linear as a timing function to limit cpu usage */ 107 | #battery.critical:not(.charging) { 108 | color: @red; 109 | box-shadow: inset 0 -3px @red; 110 | animation-name: blink; 111 | animation-duration: 0.5s; 112 | animation-timing-function: steps(12); 113 | animation-iteration-count: infinite; 114 | animation-direction: alternate; 115 | } 116 | 117 | /* Clock */ 118 | #clock { 119 | color: @blue; 120 | } 121 | 122 | /* CPU usage */ 123 | #cpu { 124 | color: @green; 125 | } 126 | 127 | /* Styles for my custom battery indicator for my MX Ergo */ 128 | #custom-mxergo.good { 129 | color: @green; 130 | } 131 | #custom-mxergo.moderate { 132 | color: @yellow; 133 | } 134 | #custom-mxergo.critical { 135 | color: @red; 136 | box-shadow: inset 0 -3px @red; 137 | } 138 | 139 | /* Idle inhibitor */ 140 | #idle_inhibitor.activated { 141 | box-shadow: inset 0 -3px @lavender; 142 | } 143 | 144 | /* Memory usage */ 145 | #memory { 146 | color: @mauve; 147 | } 148 | 149 | /* Mode inicator (resize mode for instance) */ 150 | #mode { 151 | box-shadow: inset 0 -3px @lavender; 152 | } 153 | 154 | /* Mpris music player indicator */ 155 | #mpris.firefox { 156 | color: @maroon; 157 | } 158 | 159 | #mpris.spotify { 160 | color: @green; 161 | } 162 | 163 | /* Network indicator */ 164 | #network { 165 | color: @green; 166 | } 167 | 168 | #network.disconnected { 169 | color: @red; 170 | box-shadow: inset 0 -3px @red; 171 | } 172 | 173 | /* Privacy module */ 174 | #privacy { 175 | padding: 0; 176 | } 177 | 178 | #privacy-item { 179 | padding: 0 5px; 180 | color: @text; 181 | } 182 | 183 | #privacy-item.screenshare { 184 | color: @red; 185 | box-shadow: inset 0 -3px @red; 186 | } 187 | 188 | #privacy-item.audio-out { 189 | color: @blue; 190 | } 191 | 192 | #privacy-item.audio-in { 193 | color: @yellow; 194 | box-shadow: inset 0 -3px @yellow; 195 | } 196 | 197 | /* Pulseaudio module */ 198 | #pulseaudio { 199 | color: @yellow; 200 | box-shadow: inset 0 -3px @yellow; 201 | } 202 | 203 | #pulseaudio:hover { 204 | color: @peach; 205 | box-shadow: inset 0 -3px @peach; 206 | } 207 | 208 | #pulseaudio.muted { 209 | color: @teal; 210 | box-shadow: inset 0 -3px @surface0; 211 | } 212 | 213 | #pulseaudio.muted:hover { 214 | color: @sky; 215 | box-shadow: inset 0 -3px @sky; 216 | } 217 | 218 | /* Temperature module */ 219 | #temperature { 220 | color: @peach; 221 | } 222 | 223 | #temperature.critical { 224 | color: @red; 225 | box-shadow: inset 0 -3px @red; 226 | } 227 | 228 | /* Tray module */ 229 | #tray > .passive { 230 | -gtk-icon-effect: dim; 231 | } 232 | 233 | #tray > .needs-attention { 234 | -gtk-icon-effect: highlight; 235 | box-shadow: inset 0 -3px @red; 236 | } 237 | -------------------------------------------------------------------------------- /modules/graphical/xkb-keymap/default.nix: -------------------------------------------------------------------------------- 1 | {lib, ...}: { 2 | options.etu.graphical.xkb-keymap.model = lib.mkOption { 3 | type = lib.types.str; 4 | default = "pc105"; 5 | description = "Physical keyboard of use"; 6 | }; 7 | 8 | options.etu.graphical.xkb-keymap.layout = lib.mkOption { 9 | type = lib.types.str; 10 | default = "us"; 11 | description = "Keyboard layout to use"; 12 | }; 13 | 14 | options.etu.graphical.xkb-keymap.variant = lib.mkOption { 15 | type = lib.types.str; 16 | default = "dvorak"; 17 | description = "Keyboard variant to use"; 18 | }; 19 | 20 | options.etu.graphical.xkb-keymap.options = lib.mkOption { 21 | type = lib.types.commas; 22 | default = lib.strings.concatStringsSep "," [ 23 | "compose:102" # Make the LSGT/"<>"/"< >" key a Compose key 24 | "compose:sclk" # Make the Scroll Lock key a Compose key 25 | "ctrl:nocaps" # Make the Caps Lock a Ctrl key 26 | "eurosign:e" # Make a Euro on E, third level 27 | "kpdl:dot" # Make the keypad comma key a dot 28 | "numpad:mac" # Numeric keypad always enters digits (as in macOS) 29 | "terminate:ctrl_alt_bksp" # Remove the Ctrl+Alt+Backspace behavior 30 | ]; 31 | description = "Additional options to include for layout"; 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /modules/services/beszel/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | myData, 4 | pkgs, 5 | lib, 6 | ... 7 | }: let 8 | beszelConfigFile = pkgs.writeTextFile { 9 | name = "beszel-config.yml"; 10 | text = lib.generators.toYAML {} { 11 | systems = config.etu.services.beszel-hub.settings; 12 | }; 13 | }; 14 | in { 15 | options.etu.services.beszel-hub = { 16 | enable = lib.mkEnableOption "Enable beszel-hub service"; 17 | settings = lib.mkOption { 18 | type = lib.types.listOf (lib.types.submodule { 19 | options = { 20 | name = lib.mkOption { 21 | type = lib.types.str; 22 | }; 23 | host = lib.mkOption { 24 | type = lib.types.str; 25 | }; 26 | port = lib.mkOption { 27 | type = lib.types.port; 28 | }; 29 | }; 30 | }); 31 | default = []; 32 | description = "Configuration of bezsel hub"; 33 | }; 34 | }; 35 | 36 | options.etu.services.beszel-agent = { 37 | enable = lib.mkEnableOption "Enable beszel-agent service"; 38 | extraFilesystems = lib.mkOption { 39 | type = lib.types.listOf lib.types.str; 40 | default = []; 41 | description = "Extra filesystems to monitor"; 42 | }; 43 | }; 44 | 45 | config = lib.mkIf (config.etu.services.beszel-hub.enable || config.etu.services.beszel-agent.enable) { 46 | # Include private ssh key as secret 47 | age.secrets = lib.mkIf config.etu.services.beszel-hub.enable { 48 | inherit (myData.ageModules) beszel-ssh-ec; 49 | }; 50 | 51 | # Make sure the bezsel hub home directory exists 52 | systemd.tmpfiles.rules = lib.mkIf config.etu.services.beszel-hub.enable [ 53 | "d /data/var/lib/beszel-hub/beszel_data 0700 root root -" 54 | ]; 55 | 56 | # Bind mount for persistent beszel hub state 57 | etu.base.zfs.system.directories = [ 58 | "/var/lib/beszel-hub" 59 | ]; 60 | 61 | # Enable the beszel hub 62 | systemd.services.beszel-hub = lib.mkIf config.etu.services.beszel-hub.enable { 63 | description = "Beszel Hub"; 64 | after = ["network.target"]; 65 | wantedBy = ["multi-user.target"]; 66 | restartTriggers = [ 67 | "/var/lib/beszel-hub/beszel_data/config.yml" 68 | config.age.secrets.beszel-ssh-ec.path 69 | ]; 70 | serviceConfig = { 71 | Type = "simple"; 72 | Restart = "always"; 73 | RestartSec = "3"; 74 | User = "root"; 75 | WorkingDirectory = "/var/lib/beszel-hub"; 76 | ExecStartPre = "${pkgs.coreutils}/bin/ln -sf ${beszelConfigFile} /var/lib/beszel-hub/beszel_data/config.yml"; 77 | ExecStart = "${pkgs.beszel}/bin/beszel-hub serve --http 0.0.0.0:6432"; 78 | }; 79 | }; 80 | 81 | # Enable the beszel agent 82 | systemd.services.beszel-agent = lib.mkIf config.etu.services.beszel-agent.enable { 83 | description = "Beszel Agent"; 84 | after = ["network.target"]; 85 | wantedBy = ["multi-user.target"]; 86 | environment = { 87 | PORT = "45876"; 88 | KEY = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKQNjvl2OsSmdglE7WHsU8CmEsGWJUx2uHfMOZ14ONFi"; 89 | EXTRA_FILESYSTEMS = lib.concatStringsSep "," config.etu.services.beszel-agent.extraFilesystems; 90 | }; 91 | serviceConfig = { 92 | Type = "simple"; 93 | Restart = "always"; 94 | RestartSec = "3"; 95 | User = "root"; 96 | ExecStart = "${pkgs.beszel}/bin/beszel-agent"; 97 | }; 98 | }; 99 | }; 100 | } 101 | -------------------------------------------------------------------------------- /modules/services/default.nix: -------------------------------------------------------------------------------- 1 | {...}: { 2 | imports = [ 3 | ./beszel 4 | ./freshrss 5 | ./jellyfin 6 | ./netdata 7 | ./nfs 8 | ]; 9 | } 10 | -------------------------------------------------------------------------------- /modules/services/freshrss/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | myData, 5 | ... 6 | }: { 7 | options.etu.services.freshrss = { 8 | enable = lib.mkEnableOption "Enable services freshrss service"; 9 | hostname = lib.mkOption { 10 | type = lib.types.str; 11 | default = "freshrss.elis.nu"; 12 | description = "Hostname to expose freshrss on"; 13 | }; 14 | }; 15 | 16 | config = lib.mkIf config.etu.services.freshrss.enable { 17 | # Make sure to have nginx enabled 18 | services.nginx.enable = true; 19 | 20 | age.secrets = { 21 | inherit (myData.ageModules) freshrss-password-etu; 22 | }; 23 | 24 | # Set up freshrss. 25 | services.freshrss = { 26 | enable = true; 27 | baseUrl = "http://${config.etu.services.freshrss.hostname}"; 28 | virtualHost = config.etu.services.freshrss.hostname; 29 | 30 | # Set up my user 31 | defaultUser = config.etu.user.username; 32 | passwordFile = config.age.secrets.freshrss-password-etu.path; 33 | }; 34 | 35 | etu.base.zfs.system.directories = [ 36 | # Bind mount for persistent data for freshrss 37 | "/var/lib/freshrss" 38 | ]; 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /modules/services/jellyfin/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | options.etu.services.jellyfin = { 8 | enable = lib.mkEnableOption "Enable services jellyfin service"; 9 | hostname = lib.mkOption { 10 | type = lib.types.str; 11 | default = "jellyfin.elis.nu"; 12 | description = "Hostname to expose jellyfin on"; 13 | }; 14 | }; 15 | 16 | config = lib.mkIf config.etu.services.jellyfin.enable { 17 | # Bind mount for persistent data for jellyfin 18 | etu.base.zfs.system.directories = [ 19 | "/var/lib/jellyfin" 20 | ]; 21 | 22 | # Enable vaapi on OS-level 23 | nixpkgs.config.packageOverrides = pkgs: { 24 | vaapiIntel = pkgs.vaapiIntel.override {enableHybridCodec = true;}; 25 | }; 26 | hardware.graphics = { 27 | enable = true; 28 | extraPackages = [ 29 | pkgs.intel-media-driver 30 | pkgs.vaapiIntel 31 | pkgs.vaapiVdpau 32 | pkgs.libvdpau-va-gl 33 | ]; 34 | }; 35 | 36 | # Allow jellyfin user to access the graphics card 37 | users.users.${config.services.jellyfin.user}.extraGroups = ["video" "render"]; 38 | 39 | # Override default hardening measure from NixOS 40 | systemd.services.jellyfin.serviceConfig.PrivateDevices = lib.mkForce false; 41 | systemd.services.jellyfin.serviceConfig.DeviceAllow = lib.mkForce ["/dev/dri/renderD128"]; 42 | 43 | # Enable jellyfin itself 44 | services.jellyfin.enable = true; 45 | 46 | # Open the port for local network access 47 | networking.firewall.allowedTCPPorts = [8096]; 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /modules/services/netdata/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | myData, 5 | pkgs, 6 | ... 7 | }: { 8 | options.etu.services.netdata = { 9 | enable = lib.mkEnableOption "Enable services netdata service"; 10 | }; 11 | 12 | config = lib.mkIf config.etu.services.netdata.enable { 13 | etu.base.zfs.local.directories = [ 14 | "/var/cache/netdata" 15 | ]; 16 | 17 | # Bind mount for persistent data for netdata 18 | etu.base.zfs.system.directories = [ 19 | "/var/lib/netdata" 20 | ]; 21 | 22 | # Allow to install netdata 23 | etu.base.nix.allowUnfree = [ 24 | "netdata" 25 | ]; 26 | 27 | # Include secret with token 28 | age.secrets.netdata-claim-token-file = myData.ageModules.netdata-claim-token-file; 29 | 30 | # Enable netdata 31 | services.netdata.enable = true; 32 | services.netdata.package = pkgs.netdataCloud; 33 | services.netdata.claimTokenFile = config.age.secrets.netdata-claim-token-file.path; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /modules/services/nfs/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: { 6 | options.etu.services.nfs = { 7 | enable = lib.mkEnableOption "Enable services nfs settings"; 8 | exports = lib.mkOption { 9 | type = lib.types.str; 10 | default = ""; 11 | description = "Exports for nfs"; 12 | }; 13 | }; 14 | 15 | config = lib.mkIf config.etu.services.nfs.enable { 16 | # Enable nfs server. 17 | services.nfs.server.enable = true; 18 | 19 | # Configure ports 20 | services.nfs.server.statdPort = 4000; 21 | services.nfs.server.lockdPort = 4001; 22 | 23 | # Configure NFSd to listen to UDP 24 | services.nfs.settings.nfsd.udp = "y"; 25 | 26 | # Open ports used by NFS 27 | networking.firewall.allowedTCPPorts = [2049 111 4000 4001 20048]; 28 | networking.firewall.allowedUDPPorts = [2049 111 4000 4001 20048]; 29 | 30 | services.nfs.server.exports = config.etu.services.nfs.exports; 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /modules/theme/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | catppuccin, 3 | config, 4 | lib, 5 | ... 6 | }: { 7 | options.etu.theme.enable = lib.mkEnableOption "Enable theme settings"; 8 | options.etu.theme.flavor = lib.mkOption { 9 | type = lib.types.str; 10 | default = "mocha"; 11 | }; 12 | 13 | config = lib.mkIf config.etu.theme.enable { 14 | # Globally enable catppuccin themes on system level. 15 | catppuccin.enable = true; 16 | catppuccin.flavor = config.etu.theme.flavor; 17 | 18 | # Set up themes for home manager for the main user. 19 | home-manager.users.${config.etu.user.username} = lib.mkIf config.etu.user.enable { 20 | # Import the catppuccin home manager modules. 21 | imports = [ 22 | catppuccin.homeModules.catppuccin 23 | ]; 24 | 25 | # Set Catppuccin flavor. 26 | catppuccin.flavor = config.etu.theme.flavor; 27 | 28 | # Enable catppuchin for on home manager level for different applications. 29 | catppuccin.alacritty.enable = true; 30 | catppuccin.foot.enable = true; 31 | catppuccin.fish.enable = true; 32 | catppuccin.rofi.enable = true; 33 | catppuccin.mako.enable = true; 34 | catppuccin.swaylock.enable = true; 35 | 36 | # Bat module and theme 37 | programs.bat.enable = true; 38 | catppuccin.bat.enable = true; 39 | 40 | # Fzf module and theme 41 | programs.fzf.enable = true; 42 | catppuccin.fzf.enable = true; 43 | 44 | # Imv module and theme 45 | programs.imv.enable = true; 46 | catppuccin.imv.enable = true; 47 | 48 | # Set up theme for sway. 49 | catppuccin.sway.enable = true; 50 | wayland.windowManager.sway.config.colors = let 51 | background = "$base"; 52 | focusedInactive = { 53 | background = "$base"; 54 | border = "$overlay0"; 55 | childBorder = "$overlay0"; 56 | indicator = "$rosewater"; 57 | text = "$text"; 58 | }; 59 | focused = { 60 | background = "$base"; 61 | border = "$lavender"; 62 | childBorder = "$lavender"; 63 | indicator = "$rosewater"; 64 | text = "$text"; 65 | }; 66 | urgent = { 67 | background = "$base"; 68 | border = "$peach"; 69 | childBorder = "$peach"; 70 | indicator = "$overlay0"; 71 | text = "$peach"; 72 | }; 73 | unfocused = focusedInactive; 74 | "placeholder" = focusedInactive; 75 | in { 76 | inherit background focused focusedInactive urgent unfocused "placeholder"; 77 | }; 78 | 79 | # Set up theme for waybar. 80 | catppuccin.waybar.enable = true; 81 | catppuccin.waybar.mode = "createLink"; 82 | }; 83 | }; 84 | } 85 | -------------------------------------------------------------------------------- /modules/user/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | myData, 5 | pkgs, 6 | ... 7 | }: { 8 | options.etu.user = { 9 | enable = lib.mkEnableOption "Enables my user"; 10 | uid = lib.mkOption { 11 | type = lib.types.nullOr lib.types.int; 12 | default = 1000; 13 | description = "My user id for this system."; 14 | }; 15 | username = lib.mkOption { 16 | type = lib.types.str; 17 | default = "etu"; 18 | description = "My username for this system."; 19 | }; 20 | realname = lib.mkOption { 21 | type = lib.types.str; 22 | default = "Elis Hirwing"; 23 | description = "My realname for this system."; 24 | }; 25 | email = lib.mkOption { 26 | type = lib.types.str; 27 | default = "elis@hirwing.se"; 28 | description = "My email for this system."; 29 | }; 30 | companyEmail = lib.mkOption { 31 | type = lib.types.str; 32 | default = "elis@taserud.net"; 33 | description = "My email for this system."; 34 | }; 35 | workEmail = lib.mkOption { 36 | type = lib.types.str; 37 | default = "elis.hirwing@schibsted.com"; 38 | description = "My email for this system."; 39 | }; 40 | signingKey = lib.mkOption { 41 | type = lib.types.str; 42 | default = "67FE98F28C44CF221828E12FD57EFA625C9A925F"; 43 | description = "My public signing key for this system."; 44 | }; 45 | extraGroups = lib.mkOption { 46 | type = lib.types.listOf lib.types.str; 47 | default = []; 48 | }; 49 | extraAuthorizedKeys = lib.mkOption { 50 | type = lib.types.listOf lib.types.str; 51 | default = []; 52 | description = "Additional authorized keys."; 53 | }; 54 | extraRootAuthorizedKeys = lib.mkOption { 55 | type = lib.types.listOf lib.types.str; 56 | default = []; 57 | description = "Additional authorized keys for root user."; 58 | }; 59 | extraUserPackages = lib.mkOption { 60 | type = lib.types.listOf lib.types.package; 61 | default = []; 62 | description = "Extra packages to install in my users profile."; 63 | }; 64 | userPasswordAgeModule = lib.mkOption { 65 | default = myData.ageModules.hashed-etu-password; 66 | description = "Age file to include to use as user password"; 67 | }; 68 | rootPasswordAgeModule = lib.mkOption { 69 | default = myData.ageModules.hashed-root-password; 70 | description = "Age file to include to use as root password"; 71 | }; 72 | setEmptyPassword = lib.mkEnableOption "If disabled, it will set a user password which requires agenix set up."; 73 | setEmptyRootPassword = lib.mkEnableOption "If disabled, it will set a root password which requires agenix set up."; 74 | }; 75 | 76 | config = { 77 | # Immutable users. 78 | users.mutableUsers = false; 79 | 80 | # Let ~/bin/ be in $PATH 81 | environment.homeBinInPath = config.etu.user.enable; 82 | 83 | # Load password files. 84 | age.secrets.hashed-user-password = lib.mkIf (!config.etu.user.setEmptyPassword && config.etu.user.enable) config.etu.user.userPasswordAgeModule; 85 | age.secrets.hashed-root-password = lib.mkIf (!config.etu.user.setEmptyRootPassword) config.etu.user.rootPasswordAgeModule; 86 | 87 | # Define my user account. 88 | users.users.${config.etu.user.username} = lib.mkIf config.etu.user.enable { 89 | description = "${config.etu.user.realname},,,,"; 90 | extraGroups = ["wheel"] ++ config.etu.user.extraGroups; 91 | hashedPasswordFile = lib.mkIf (!config.etu.user.setEmptyPassword) config.age.secrets.hashed-user-password.path; 92 | isNormalUser = true; 93 | openssh.authorizedKeys.keys = myData.pubkeys.etu.computers ++ config.etu.user.extraAuthorizedKeys; 94 | inherit (config.etu.user) uid; 95 | }; 96 | 97 | # Define password, authorized keys and shell for root user. 98 | users.users.root = { 99 | hashedPasswordFile = lib.mkIf (!config.etu.user.setEmptyRootPassword) config.age.secrets.hashed-root-password.path; 100 | openssh.authorizedKeys.keys = myData.pubkeys.etu.computers ++ config.etu.user.extraRootAuthorizedKeys; 101 | }; 102 | 103 | # Configure some miscellaneous dotfiles for my user. 104 | home-manager.users.${config.etu.user.username} = lib.mkIf config.etu.user.enable { 105 | home.file = { 106 | # Home nix config. 107 | ".config/nixpkgs/config.nix".text = "{ allowUnfree = true; }"; 108 | 109 | # Nano config 110 | ".nanorc".text = "set constantshow # Show linenumbers -c as default"; 111 | 112 | "bin/restow".source = 113 | pkgs.runCommand "restow" { 114 | inherit (config.etu) dataPrefix; 115 | } '' 116 | substituteAll ${../dotfiles/bin/restow} $out 117 | chmod +x $out 118 | ''; 119 | "bin/spacecolors".source = ../dotfiles/bin/spacecolors; 120 | 121 | "bin/keep".source = pkgs.runCommand "keep" {} '' 122 | cp ${../dotfiles/bin/keep} $out 123 | substituteInPlace $out --replace /bin/zsh ${pkgs.zsh}/bin/zsh 124 | ''; 125 | }; 126 | 127 | # Install some comand line tools I cummonly want available for 128 | # my home directory, as well as extra packages defined by the 129 | # system or other modules. 130 | home.packages = 131 | config.etu.user.extraUserPackages 132 | ++ [ 133 | pkgs.stow 134 | ]; 135 | 136 | # Set the environment variables. 137 | home.sessionVariables.EDITOR = 138 | if config.etu.base.emacs.enable 139 | then "emacs" 140 | else "nano"; 141 | }; 142 | 143 | # Directories to mount persistent for my user 144 | etu.base.zfs.user.directories = [ 145 | ".dotfiles" 146 | ".ssh" 147 | ]; 148 | }; 149 | } 150 | -------------------------------------------------------------------------------- /modules/work/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | chefdk, 4 | lib, 5 | pkgs, 6 | vagrant, 7 | ... 8 | }: { 9 | options.etu.work.enable = lib.mkEnableOption "Enables work module"; 10 | 11 | config = lib.mkIf config.etu.work.enable { 12 | # Configure PHP to be the correct version with the right extensions 13 | nixpkgs.overlays = [ 14 | (_self: _super: { 15 | php = pkgs.php81.withExtensions ( 16 | { 17 | all, 18 | enabled, 19 | }: 20 | enabled ++ (with all; [imagick memcached redis pcov protobuf]) 21 | ); 22 | }) 23 | ]; 24 | 25 | # Persist directories and files 26 | etu.base.zfs.user.directories = [ 27 | ".aws" 28 | ".chalet" 29 | ".chef" 30 | ".config/helm" 31 | ".config/tvnu" 32 | ".config/gh" 33 | ".vagrant.d" 34 | ]; 35 | 36 | etu.base.zfs.user.files = [ 37 | ".config/goprocmgr.json" 38 | ".docker/config.json" 39 | ".kube/config" 40 | ]; 41 | 42 | # Allow certain unfree packages. 43 | etu.base.nix.allowUnfree = [ 44 | "appgate-sdp" 45 | "vagrant" 46 | ]; 47 | 48 | etu.user.extraUserPackages = [ 49 | # Install chalet to manage running of containers 50 | pkgs.nur.repos.etu.goprocmgr 51 | pkgs.nur.repos.etu.chalet 52 | 53 | # Install github-markdown-toc to format README TOC's 54 | pkgs.nur.repos.etu.github-markdown-toc 55 | 56 | # Install make 57 | pkgs.gnumake 58 | 59 | # Install git crypt 60 | pkgs.git-crypt 61 | pkgs.git-lfs 62 | pkgs.github-cli 63 | 64 | # Install chef and vagrant for some legacy systems reasons 65 | chefdk 66 | vagrant 67 | 68 | # Kubernetes and Docker utils 69 | pkgs.docker-compose 70 | pkgs.kubectl 71 | pkgs.kubectx 72 | pkgs.kubetail 73 | pkgs.kubent 74 | pkgs.kubernetes-helm 75 | pkgs.minikube 76 | # pkgs.octant 77 | 78 | # Misc 79 | pkgs.mariadb 80 | pkgs.awscli2 81 | ]; 82 | 83 | # Enable appgate 84 | programs.appgate-sdp.enable = true; 85 | }; 86 | } 87 | -------------------------------------------------------------------------------- /packages/spaceWallpapers/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | runCommandNoCC, 3 | fetchurl, 4 | # Assorted images from: https://wallhaven.cc/search?q=space&atleast=2560x2880 5 | images ? 6 | [ 7 | (fetchurl { 8 | url = "https://w.wallhaven.cc/full/0w/wallhaven-0wryzq.jpg"; 9 | hash = "sha256-61DKr+YemXEraAfzxwddMzFCUZAXFn11LUqW2TdGi8w="; 10 | }) 11 | (fetchurl { 12 | url = "https://w.wallhaven.cc/full/6o/wallhaven-6ol5z7.jpg"; 13 | hash = "sha256-5cpf4DoaMcN96ZnQVmrNNxd5AZ6kxLDEqyrNRFoYxB4="; 14 | }) 15 | (fetchurl { 16 | url = "https://w.wallhaven.cc/full/e7/wallhaven-e78y9r.jpg"; 17 | hash = "sha256-kR9gmxcQavDlqD7jZYjOa7cWsfqK/sN6e7Q+aJ0jjJg="; 18 | }) 19 | (fetchurl { 20 | url = "https://w.wallhaven.cc/full/4d/wallhaven-4ddjr3.jpg"; 21 | hash = "sha256-k/d9fu5ZfjBibpdBE2ghna5JRTQ64fn8nlslr72cIfg="; 22 | }) 23 | (fetchurl { 24 | url = "https://w.wallhaven.cc/full/dp/wallhaven-dpl57g.png"; 25 | hash = "sha256-fUkbZwvm440MKVdro8X3+qx4jgYpjYWu9WkulL8C5Mo="; 26 | }) 27 | ] 28 | ++ extraImages, 29 | extraImages ? [], 30 | ... 31 | }: let 32 | # Build a list of ln commands to symlink the images. 33 | symlinkCommandList = map (image: "ln -vs ${image} $out/${image.name}") images; 34 | 35 | # Concat these for use in the shell script. 36 | symlinkCommands = builtins.concatStringsSep "\n" symlinkCommandList; 37 | in 38 | runCommandNoCC "spaceWallpapers" {} '' 39 | mkdir -p $out 40 | 41 | ${symlinkCommands} 42 | '' 43 | -------------------------------------------------------------------------------- /secrets.nix: -------------------------------------------------------------------------------- 1 | let 2 | # Import my ssh public keys 3 | keys = (import ./data.nix).pubkeys; 4 | 5 | # Assemble public keys for user-facing computers 6 | etu = keys.etu.desktop-elis ++ keys.etu.laptop-private-elis ++ keys.etu.laptop-work-elis; 7 | 8 | # Computers host keys 9 | hosts = let 10 | inherit (keys.systems) desktop-elis laptop-private-caroline laptop-private-elis laptop-work-elis server-main-elis server-sparv vps06; 11 | in { 12 | desktop-elis = [desktop-elis]; 13 | laptop-private-caroline = [laptop-private-caroline]; 14 | laptop-private-elis = [laptop-private-elis]; 15 | laptop-work-elis = [laptop-work-elis]; 16 | server-main-elis = [server-main-elis]; 17 | server-sparv = [server-sparv]; 18 | vps06 = [vps06]; 19 | 20 | all = [ 21 | desktop-elis 22 | laptop-private-elis 23 | laptop-work-elis 24 | server-main-elis 25 | server-sparv 26 | vps06 27 | ]; 28 | }; 29 | in { 30 | "secrets/any/hashed-etu-password-file.age".publicKeys = etu ++ hosts.desktop-elis ++ hosts.laptop-private-elis ++ hosts.laptop-work-elis ++ hosts.server-main-elis; 31 | "secrets/any/hashed-root-password-file.age".publicKeys = etu ++ hosts.all; 32 | "secrets/any/netdata-claim-token-file.age".publicKeys = etu ++ hosts.all; 33 | "secrets/laptop-private-caroline/hashed-concate-password-file.age".publicKeys = etu ++ hosts.laptop-private-caroline; 34 | "secrets/laptop-private-caroline/hashed-root-password-file.age".publicKeys = etu ++ hosts.laptop-private-caroline; 35 | "secrets/laptop-private-elis/etu_at_aarch64.nixos.community.age".publicKeys = etu ++ hosts.desktop-elis ++ hosts.laptop-private-elis; 36 | "secrets/laptop-private-elis/etu_at_aarch64.nixos.community.pub.age".publicKeys = etu ++ hosts.desktop-elis ++ hosts.laptop-private-elis; 37 | "secrets/server-main-elis/cloudflare-api-env.age".publicKeys = etu ++ hosts.server-main-elis; 38 | "secrets/server-main-elis/etu-freshrss-password.age".publicKeys = etu ++ hosts.server-main-elis; 39 | "secrets/server-main-elis/homepage-dashboard-environment.age".publicKeys = etu ++ hosts.server-main-elis; 40 | "secrets/server-main-elis/initrd-sshd-ec.age".publicKeys = etu ++ hosts.server-main-elis; 41 | "secrets/server-main-elis/nextcloud-admin-password.age".publicKeys = etu ++ hosts.server-main-elis; 42 | "secrets/server-main-elis/syncoid-ssh-ec.age".publicKeys = etu ++ hosts.server-main-elis; 43 | "secrets/server-main-elis/beszel-ssh-ec.age".publicKeys = etu ++ hosts.server-main-elis; 44 | "secrets/server-sparv/valheim-server-env.age".publicKeys = etu ++ hosts.server-sparv; 45 | "secrets/server-sparv/project-zomboid-env.age".publicKeys = etu ++ hosts.server-sparv; 46 | "secrets/workstations/syncoid-ssh-ec.age".publicKeys = etu ++ hosts.desktop-elis ++ hosts.laptop-private-elis ++ hosts.laptop-work-elis; 47 | } 48 | -------------------------------------------------------------------------------- /secrets/any/hashed-etu-password-file.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/any/hashed-etu-password-file.age -------------------------------------------------------------------------------- /secrets/any/hashed-root-password-file.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/any/hashed-root-password-file.age -------------------------------------------------------------------------------- /secrets/any/netdata-claim-token-file.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/any/netdata-claim-token-file.age -------------------------------------------------------------------------------- /secrets/laptop-private-caroline/hashed-concate-password-file.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/laptop-private-caroline/hashed-concate-password-file.age -------------------------------------------------------------------------------- /secrets/laptop-private-caroline/hashed-root-password-file.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/laptop-private-caroline/hashed-root-password-file.age -------------------------------------------------------------------------------- /secrets/laptop-private-elis/etu_at_aarch64.nixos.community.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/laptop-private-elis/etu_at_aarch64.nixos.community.age -------------------------------------------------------------------------------- /secrets/laptop-private-elis/etu_at_aarch64.nixos.community.pub.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/laptop-private-elis/etu_at_aarch64.nixos.community.pub.age -------------------------------------------------------------------------------- /secrets/server-main-elis/beszel-ssh-ec.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/server-main-elis/beszel-ssh-ec.age -------------------------------------------------------------------------------- /secrets/server-main-elis/cloudflare-api-env.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/server-main-elis/cloudflare-api-env.age -------------------------------------------------------------------------------- /secrets/server-main-elis/etu-freshrss-password.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/server-main-elis/etu-freshrss-password.age -------------------------------------------------------------------------------- /secrets/server-main-elis/homepage-dashboard-environment.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/server-main-elis/homepage-dashboard-environment.age -------------------------------------------------------------------------------- /secrets/server-main-elis/initrd-sshd-ec.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/server-main-elis/initrd-sshd-ec.age -------------------------------------------------------------------------------- /secrets/server-main-elis/nextcloud-admin-password.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/server-main-elis/nextcloud-admin-password.age -------------------------------------------------------------------------------- /secrets/server-main-elis/syncoid-ssh-ec.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/server-main-elis/syncoid-ssh-ec.age -------------------------------------------------------------------------------- /secrets/server-sparv/enshrouded-server-env.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/server-sparv/enshrouded-server-env.age -------------------------------------------------------------------------------- /secrets/server-sparv/project-zomboid-env.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/server-sparv/project-zomboid-env.age -------------------------------------------------------------------------------- /secrets/server-sparv/valheim-server-env.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/server-sparv/valheim-server-env.age -------------------------------------------------------------------------------- /secrets/workstations/syncoid-ssh-ec.age: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etu/nixconfig/62aee969ce5dbbc703cd603e7f525e872300a4a1/secrets/workstations/syncoid-ssh-ec.age --------------------------------------------------------------------------------