├── .envrc ├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ ├── flake-update.yml │ └── pull-check.yml ├── .gitignore ├── .sops.yaml ├── LICENSE ├── README.md ├── checks ├── alejandra.nix ├── default.nix └── statix.nix ├── flake.lock ├── flake.nix ├── home ├── configurations │ ├── default.nix │ ├── nmelzer_at_mimas.nix │ └── nmelzer_at_phoebe.nix └── modules │ ├── default.nix │ ├── misc │ ├── awesome │ │ └── default.nix │ ├── home │ │ └── default.nix │ └── rofi │ │ ├── common.rasi │ │ └── default.nix │ ├── profiles │ ├── base │ │ ├── colums-fix.patch │ │ ├── default.nix │ │ └── nix-completions.sh │ ├── browsing │ │ └── default.nix │ ├── default.nix │ └── development │ │ └── default.nix │ ├── programs │ ├── advcp │ │ └── default.nix │ ├── eza │ │ └── default.nix │ ├── ghostty │ │ └── default.nix │ ├── nixpkgs │ │ └── default.nix │ ├── p10k │ │ ├── default.nix │ │ └── p10k-config │ │ │ └── p10k.zsh │ ├── rbw │ │ └── default.nix │ └── wezterm │ │ └── default.nix │ └── services │ ├── insync │ └── default.nix │ └── rustic │ └── default.nix ├── lefthook.yml ├── mixed ├── default.nix └── ip_addresses.nix ├── nixos ├── configurations │ ├── bootloader │ │ ├── enceladeus.nix │ │ ├── hyperion.nix │ │ ├── janus.nix │ │ └── mimas.nix │ ├── default.nix │ ├── hardware │ │ ├── enceladeus.nix │ │ ├── hyperion.nix │ │ ├── janus.nix │ │ └── mimas.nix │ ├── mimas.nix │ └── mimas │ │ ├── gitea.nix │ │ ├── paperless.nix │ │ ├── restic.nix │ │ ├── rustic-timers.nix │ │ └── vaultwarden.nix └── modules │ ├── cachix │ ├── caches │ │ ├── nix-community.nix │ │ ├── nobbz.nix │ │ └── ts-helper.nix │ └── default.nix │ ├── default.nix │ ├── distributed.nix │ ├── flake.nix │ ├── hostnames.nix │ ├── kernel.nix │ ├── moonlander.nix │ ├── nix.nix │ ├── prefer-local.patch │ ├── switcher.nix │ └── zerotier.nix ├── npins ├── default.nix └── sources.json ├── packages ├── advcp │ └── default.nix ├── default.nix └── rofi-unicode │ ├── default.nix │ └── rofi-unicode.json ├── parts ├── auxiliary.nix ├── home_configs.nix ├── home_modules.nix ├── module_helpers.nix ├── nixos_modules.nix └── system_configs.nix ├── secrets ├── mimas │ ├── default.yaml │ └── nmelzer │ │ └── default.yaml ├── phoebe │ └── nmelzer │ │ └── default.yaml └── users │ └── nmelzer │ ├── default.yaml │ ├── github │ ├── gitlab │ ├── nix-community │ └── nobbz_dev └── statix.toml /.envrc: -------------------------------------------------------------------------------- 1 | # -*- mode: shell-script -*- 2 | 3 | use_flake() { 4 | watch_file flake.lock 5 | watch_file flake.nix 6 | 7 | mkdir -p $(direnv_layout_dir) 8 | 9 | eval "$(nix print-dev-env \ 10 | --profile "$(direnv_layout_dir)/flake-profile" \ 11 | --option builders "")" 12 | } 13 | 14 | use flake 15 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.yaml diff=sopsdiffer 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "04:00" 8 | open-pull-requests-limit: 10 9 | reviewers: 10 | - NobbZ 11 | assignees: 12 | - NobbZ 13 | labels: 14 | - CI 15 | -------------------------------------------------------------------------------- /.github/workflows/flake-update.yml: -------------------------------------------------------------------------------- 1 | name: Updater 2 | 3 | on: 4 | schedule: 5 | - cron: "0 2 * * *" 6 | workflow_dispatch: {} 7 | 8 | jobs: 9 | generate_matrix: 10 | runs-on: ubuntu-24.04 11 | outputs: 12 | packages: ${{ steps.gen_packages.outputs.packages }} 13 | checks: ${{ steps.gen_checks.outputs.checks }} 14 | steps: 15 | - name: Clone repository 16 | uses: actions/checkout@v4 17 | with: 18 | token: "${{ secrets.TEST_TOKEN }}" 19 | - name: Install nix 20 | uses: cachix/install-nix-action@v31 21 | with: 22 | extra_nix_config: | 23 | auto-optimise-store = true 24 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 25 | experimental-features = nix-command flakes 26 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org 27 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= 28 | install_url: https://releases.nixos.org/nix/nix-2.25.0/install 29 | - name: Generate flake.json 30 | run: | 31 | nix flake show --json > flake.json 32 | - id: gen_packages 33 | run: | 34 | packages=$(jq -c '.packages."x86_64-linux" | keys' < flake.json) 35 | printf "::set-output name=packages::%s" "$packages" 36 | - id: gen_checks 37 | run: | 38 | checks=$(jq -c '.checks."x86_64-linux" | keys' < flake.json) 39 | printf "::set-output name=checks::%s" "$checks" 40 | 41 | update_flake: 42 | runs-on: ubuntu-24.04 43 | steps: 44 | - name: Clone repository 45 | uses: actions/checkout@v4 46 | with: 47 | token: "${{ secrets.TEST_TOKEN }}" 48 | - name: Install nix 49 | uses: cachix/install-nix-action@v31 50 | with: 51 | extra_nix_config: | 52 | auto-optimise-store = true 53 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 54 | experimental-features = nix-command flakes 55 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org 56 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= 57 | install_url: https://releases.nixos.org/nix/nix-2.25.0/install 58 | - name: Set up git 59 | run: | 60 | git config user.email gitbot@nobbz.dev 61 | git config user.name "Git Bot" 62 | - name: Update the flake 63 | run: nix flake update 64 | - name: Store flake.lock 65 | uses: actions/upload-artifact@v4 66 | with: 67 | name: flake_lock 68 | path: flake.lock 69 | 70 | build_flake: 71 | runs-on: ubuntu-24.04 72 | needs: [generate_matrix, update_flake] 73 | strategy: 74 | fail-fast: false 75 | max-parallel: 5 76 | matrix: 77 | package: ${{fromJson(needs.generate_matrix.outputs.packages)}} 78 | steps: 79 | # - name: Prepare store folder 80 | # run: sudo mkdir -p /nix 81 | - name: Free diskspace 82 | uses: easimon/maximize-build-space@master 83 | with: 84 | build-mount-path: /nix 85 | root-reserve-mb: 5120 86 | remove-dotnet: true 87 | remove-android: true 88 | remove-haskell: true 89 | - name: Clone repository 90 | uses: actions/checkout@v4 91 | with: 92 | token: "${{ secrets.TEST_TOKEN }}" 93 | - name: Install nix 94 | uses: cachix/install-nix-action@v31 95 | with: 96 | extra_nix_config: | 97 | auto-optimise-store = true 98 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 99 | experimental-features = nix-command flakes 100 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org 101 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= 102 | install_url: https://releases.nixos.org/nix/nix-2.25.0/install 103 | - name: Set up cachix 104 | uses: cachix/cachix-action@master # pathsToPush, please update once we have v11! 105 | with: 106 | name: nobbz 107 | signingKey: "${{ secrets.CACHIX_SIGNING_KEY }}" 108 | pathsToPush: result 109 | - name: Restore flake.lock 110 | uses: actions/download-artifact@v4 111 | with: 112 | name: flake_lock 113 | - name: Build everything 114 | run: nix build .#${{ matrix.package }} 115 | 116 | build_checks: 117 | runs-on: ubuntu-24.04 118 | needs: [generate_matrix, update_flake] 119 | strategy: 120 | fail-fast: false 121 | max-parallel: 5 122 | matrix: 123 | check: ${{fromJson(needs.generate_matrix.outputs.checks)}} 124 | steps: 125 | - name: Clone repository 126 | uses: actions/checkout@v4 127 | with: 128 | token: "${{ secrets.TEST_TOKEN }}" 129 | - name: Install nix 130 | uses: cachix/install-nix-action@v31 131 | with: 132 | extra_nix_config: | 133 | auto-optimise-store = true 134 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 135 | experimental-features = nix-command flakes 136 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org 137 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= 138 | install_url: https://releases.nixos.org/nix/nix-2.25.0/install 139 | - name: Set up cachix 140 | uses: cachix/cachix-action@master # pathsToPush, please update once we have v11! 141 | with: 142 | name: nobbz 143 | signingKey: "${{ secrets.CACHIX_SIGNING_KEY }}" 144 | skipPush: true 145 | - name: Restore flake.lock 146 | uses: actions/download-artifact@v4 147 | with: 148 | name: flake_lock 149 | - name: Build everything 150 | run: nix build .#checks.x86_64-linux.${{ matrix.check }} --no-link 151 | 152 | check_flake: 153 | runs-on: ubuntu-24.04 154 | needs: [update_flake] 155 | continue-on-error: true 156 | steps: 157 | - name: Clone repository 158 | uses: actions/checkout@v4 159 | with: 160 | token: "${{ secrets.TEST_TOKEN }}" 161 | - name: Install nix 162 | uses: cachix/install-nix-action@v31 163 | with: 164 | extra_nix_config: | 165 | auto-optimise-store = true 166 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 167 | experimental-features = nix-command flakes 168 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org 169 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= 170 | install_url: https://releases.nixos.org/nix/nix-2.25.0/install 171 | - name: Restore flake.lock 172 | uses: actions/download-artifact@v4 173 | with: 174 | name: flake_lock 175 | - name: Build everything 176 | run: | 177 | nix flake check --keep-going 178 | 179 | push_update: 180 | runs-on: ubuntu-24.04 181 | permissions: write-all 182 | needs: [update_flake, build_flake, build_checks, check_flake] 183 | steps: 184 | - name: Clone repository 185 | uses: actions/checkout@v4 186 | with: 187 | token: "${{ secrets.TEST_TOKEN }}" 188 | - name: Restore flake.lock 189 | uses: actions/download-artifact@v4 190 | with: 191 | name: flake_lock 192 | - name: Set up git 193 | run: | 194 | git config user.email gitbot@nobbz.dev 195 | git config user.name "Git Bot" 196 | - name: Create and merge PR 197 | run: | 198 | git switch -c updates-${{ github.run_id }} 199 | git commit -am "flake.lock: Update" 200 | git push -u origin updates-${{ github.run_id }} 201 | PR=$(gh pr create \ 202 | --assignee NobbZ \ 203 | --base main \ 204 | --body "Automatic flake update on $(date -I)" \ 205 | --fill \ 206 | --label bot \ 207 | --title "Auto update $(date -I)") 208 | gh pr merge $PR --merge --delete-branch 209 | env: 210 | GITHUB_TOKEN: ${{ secrets.TEST_TOKEN }} 211 | -------------------------------------------------------------------------------- /.github/workflows/pull-check.yml: -------------------------------------------------------------------------------- 1 | name: PullRequest checker 2 | 3 | on: 4 | pull_request: 5 | 6 | jobs: 7 | generate_matrix: 8 | runs-on: ubuntu-24.04 9 | outputs: 10 | packages: ${{ steps.gen_packages.outputs.packages }} 11 | checks: ${{ steps.gen_checks.outputs.checks }} 12 | steps: 13 | - name: Clone repository 14 | uses: actions/checkout@v4 15 | with: 16 | token: "${{ secrets.TEST_TOKEN }}" 17 | - name: Install nix 18 | uses: cachix/install-nix-action@v31 19 | with: 20 | extra_nix_config: | 21 | auto-optimise-store = true 22 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 23 | experimental-features = nix-command flakes 24 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org https://nobbz.cachix.org 25 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= nobbz.cachix.org-1:fODxpqE4ni+pFDSuj2ybYZbMUjmxNTjA7rtUNHW61Ok= 26 | install_url: https://releases.nixos.org/nix/nix-2.25.0/install 27 | - name: Generate flake.json 28 | run: | 29 | nix flake show --json > flake.json 30 | - id: gen_packages 31 | run: | 32 | packages=$(jq -c '.packages."x86_64-linux" | keys' < flake.json) 33 | printf "packages=%s" "$packages" >> $GITHUB_OUTPUT 34 | - id: gen_checks 35 | run: | 36 | checks=$(jq -c '.checks."x86_64-linux" | keys' < flake.json) 37 | printf "checks=%s" "$checks" >> $GITHUB_OUTPUT 38 | 39 | build_flake: 40 | runs-on: ubuntu-24.04 41 | needs: [generate_matrix] 42 | strategy: 43 | fail-fast: false 44 | max-parallel: 5 45 | matrix: 46 | package: ${{fromJson(needs.generate_matrix.outputs.packages)}} 47 | steps: 48 | - name: Free diskspace 49 | uses: easimon/maximize-build-space@master 50 | with: 51 | build-mount-path: /nix 52 | root-reserve-mb: 5120 53 | remove-dotnet: true 54 | remove-android: true 55 | remove-haskell: true 56 | - name: Clone repository 57 | uses: actions/checkout@v4 58 | with: 59 | token: "${{ secrets.TEST_TOKEN }}" 60 | - name: Install nix 61 | uses: cachix/install-nix-action@v31 62 | with: 63 | extra_nix_config: | 64 | auto-optimise-store = true 65 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 66 | experimental-features = nix-command flakes 67 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org https://nobbz.cachix.org 68 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= nobbz.cachix.org-1:fODxpqE4ni+pFDSuj2ybYZbMUjmxNTjA7rtUNHW61Ok= 69 | install_url: https://releases.nixos.org/nix/nix-2.25.0/install 70 | - name: Build everything 71 | run: nix build .#${{ matrix.package }} 72 | 73 | build_checks: 74 | runs-on: ubuntu-24.04 75 | needs: [generate_matrix] 76 | strategy: 77 | fail-fast: false 78 | max-parallel: 5 79 | matrix: 80 | check: ${{fromJson(needs.generate_matrix.outputs.checks)}} 81 | steps: 82 | - name: Clone repository 83 | uses: actions/checkout@v4 84 | with: 85 | token: "${{ secrets.TEST_TOKEN }}" 86 | - name: Install nix 87 | uses: cachix/install-nix-action@v31 88 | with: 89 | extra_nix_config: | 90 | auto-optimise-store = true 91 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 92 | experimental-features = nix-command flakes 93 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org https://nobbz.cachix.org 94 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= nobbz.cachix.org-1:fODxpqE4ni+pFDSuj2ybYZbMUjmxNTjA7rtUNHW61Ok= 95 | install_url: https://releases.nixos.org/nix/nix-2.25.0/install 96 | - name: Build everything 97 | run: nix build .#checks.x86_64-linux.${{ matrix.check }} --no-link 98 | 99 | check_flake: 100 | runs-on: ubuntu-24.04 101 | continue-on-error: true 102 | steps: 103 | - name: Clone repository 104 | uses: actions/checkout@v4 105 | with: 106 | token: "${{ secrets.TEST_TOKEN }}" 107 | - name: Install nix 108 | uses: cachix/install-nix-action@v31 109 | with: 110 | extra_nix_config: | 111 | auto-optimise-store = true 112 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 113 | experimental-features = nix-command flakes 114 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org https://nobbz.cachix.org 115 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= nobbz.cachix.org-1:fODxpqE4ni+pFDSuj2ybYZbMUjmxNTjA7rtUNHW61Ok= 116 | install_url: https://releases.nixos.org/nix/nix-2.25.0/install 117 | - name: run the checks 118 | run: | 119 | nix flake check --keep-going 120 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /result* 2 | -------------------------------------------------------------------------------- /.sops.yaml: -------------------------------------------------------------------------------- 1 | keys: 2 | - &admin_nobbz age1wpwkf2g475umw3wwns57r8ucykvy6lflpc7uphs0mx9exsj04quqpy7t6r 3 | - &host_mimas age10jl78vwyqk622dpn2890l9jl4et3p7lsr8wh8vusem3j8jdxle8qg000qa 4 | - &user_nmelzer_mimas age1w6xjgskpxnlpleswumdhtt7x8zx35qn329yz3x7ftqdcmcxrrvnqnuf9d6 5 | - &user_nmelzer_phoebe age1vr0uq6mwv844yvm8pe7qxjxpqrekgel3lqfzuuqtfzj0ehz3hphqzsxjna 6 | creation_rules: 7 | - path_regex: secrets/[^/]+\.yaml$ 8 | key_groups: 9 | - age: 10 | - *admin_nobbz 11 | - *host_mimas 12 | - path_regex: secrets/mimas/[^/]+\.yaml$ 13 | key_groups: 14 | - age: 15 | - *admin_nobbz 16 | - *host_mimas 17 | - path_regex: secrets/mimas/nmelzer/[^/]+\.yaml$ 18 | key_groups: 19 | - age: 20 | - *admin_nobbz 21 | - *user_nmelzer_mimas 22 | - path_regex: secrets/phoebe/nmelzer/[^/]+ 23 | key_groups: 24 | - age: 25 | - *admin_nobbz 26 | - *user_nmelzer_phoebe 27 | - path_regex: secrets/users/nmelzer/[^/]+$ 28 | key_groups: 29 | - age: 30 | - *admin_nobbz 31 | - *user_nmelzer_mimas 32 | - *user_nmelzer_phoebe 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Norbert Melzer 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Hosts 2 | ===== 3 | 4 | > [!CAUTION] 5 | > This hosts system and home configurations are public for your own learning and 6 | > research. They are not meant to be used with any hardware other than mine. 7 | > Trying to build and deploy them to other systems without appropriate changes 8 | > can render your machines unbootable and damage data. 9 | 10 | > [!NOTE] 11 | > I do not provide copy/pastable commands that would build/switch/install any 12 | > of these configurations because I mean what I wrote in the block before! 13 | 14 | A list of all hosts currently in use by me. this covers all the 15 | devices i can name on my behalf. Not all devices in this list are 16 | managed through nix or even run it. 17 | 18 | * `mimas`: My currently used main host. 19 | * ~~`enceladeus`~~: A secondary laptop, rarely used but still updated. 20 | * ~~`thetys`~~: A nixos VM solely used in the office for work related things, discontinued 21 | * ~~`dione`~~: company provided android phone, discontinued 22 | * `rhea`: self owned phone 23 | * ~~`titan`~~: MacOS VM to play and experiment with, discontinued 24 | * ~~`hyperion`~~: Linux-Aarch64 VM to play and experiment with, discontinued 25 | * `phoebe`: TuxedoOS (Ubuntu derivative) laptop, HM only. 26 | -------------------------------------------------------------------------------- /checks/alejandra.nix: -------------------------------------------------------------------------------- 1 | { 2 | runCommand, 3 | alejandra, 4 | self, 5 | }: 6 | runCommand "alejandra-run-${self.rev or "00000000"}" {} '' 7 | ${alejandra}/bin/alejandra --check ${self} < /dev/null | tee $out 8 | '' 9 | -------------------------------------------------------------------------------- /checks/default.nix: -------------------------------------------------------------------------------- 1 | inputs: let 2 | pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux; 3 | 4 | callPackage = pkgs.lib.callPackageWith (pkgs // {inherit (inputs) self;}); 5 | in { 6 | alejandra = callPackage ./alejandra.nix {}; 7 | statix = callPackage ./statix.nix {}; 8 | } 9 | -------------------------------------------------------------------------------- /checks/statix.nix: -------------------------------------------------------------------------------- 1 | { 2 | runCommand, 3 | statix, 4 | self, 5 | }: 6 | runCommand "statix-run-${self.rev or "00000000"}" {} '' 7 | cd ${self} 8 | ${statix}/bin/statix check | tee $out 9 | '' 10 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "cargo2nix": { 4 | "inputs": { 5 | "flake-compat": "flake-compat_3", 6 | "flake-utils": "flake-utils_3", 7 | "nixpkgs": [ 8 | "switcher", 9 | "nixpkgs" 10 | ], 11 | "rust-overlay": [ 12 | "switcher", 13 | "rust-overlay" 14 | ] 15 | }, 16 | "locked": { 17 | "lastModified": 1705129117, 18 | "narHash": "sha256-LgdDHibvimzYhxBK3kxCk2gAL7k4Hyigl5KI0X9cijA=", 19 | "owner": "cargo2nix", 20 | "repo": "cargo2nix", 21 | "rev": "ae19a9e1f8f0880c088ea155ab66cee1fa001f59", 22 | "type": "github" 23 | }, 24 | "original": { 25 | "owner": "cargo2nix", 26 | "repo": "cargo2nix", 27 | "type": "github" 28 | } 29 | }, 30 | "emacs": { 31 | "inputs": { 32 | "nixpkgs": [ 33 | "nixpkgs" 34 | ], 35 | "nixpkgs-stable": [ 36 | "nixpkgs" 37 | ] 38 | }, 39 | "locked": { 40 | "lastModified": 1749090069, 41 | "narHash": "sha256-uN3Mp+o7IfVT9H/OuwEtJ17NktCaF4t9Ond3TKt+BE4=", 42 | "owner": "nix-community", 43 | "repo": "emacs-overlay", 44 | "rev": "c17506666090e412a50b01c57944386ab81d2aa8", 45 | "type": "github" 46 | }, 47 | "original": { 48 | "owner": "nix-community", 49 | "repo": "emacs-overlay", 50 | "type": "github" 51 | } 52 | }, 53 | "flake-compat": { 54 | "flake": false, 55 | "locked": { 56 | "lastModified": 1733328505, 57 | "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", 58 | "owner": "edolstra", 59 | "repo": "flake-compat", 60 | "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", 61 | "type": "github" 62 | }, 63 | "original": { 64 | "owner": "edolstra", 65 | "repo": "flake-compat", 66 | "type": "github" 67 | } 68 | }, 69 | "flake-compat_2": { 70 | "flake": false, 71 | "locked": { 72 | "lastModified": 1696426674, 73 | "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", 74 | "owner": "edolstra", 75 | "repo": "flake-compat", 76 | "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", 77 | "type": "github" 78 | }, 79 | "original": { 80 | "owner": "edolstra", 81 | "repo": "flake-compat", 82 | "type": "github" 83 | } 84 | }, 85 | "flake-compat_3": { 86 | "flake": false, 87 | "locked": { 88 | "lastModified": 1696426674, 89 | "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", 90 | "owner": "edolstra", 91 | "repo": "flake-compat", 92 | "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", 93 | "type": "github" 94 | }, 95 | "original": { 96 | "owner": "edolstra", 97 | "repo": "flake-compat", 98 | "type": "github" 99 | } 100 | }, 101 | "flake-utils": { 102 | "locked": { 103 | "lastModified": 1659877975, 104 | "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", 105 | "owner": "numtide", 106 | "repo": "flake-utils", 107 | "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", 108 | "type": "github" 109 | }, 110 | "original": { 111 | "owner": "numtide", 112 | "repo": "flake-utils", 113 | "type": "github" 114 | } 115 | }, 116 | "flake-utils_2": { 117 | "inputs": { 118 | "systems": "systems" 119 | }, 120 | "locked": { 121 | "lastModified": 1681202837, 122 | "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", 123 | "owner": "numtide", 124 | "repo": "flake-utils", 125 | "rev": "cfacdce06f30d2b68473a46042957675eebb3401", 126 | "type": "github" 127 | }, 128 | "original": { 129 | "owner": "numtide", 130 | "repo": "flake-utils", 131 | "type": "github" 132 | } 133 | }, 134 | "flake-utils_3": { 135 | "inputs": { 136 | "systems": "systems_2" 137 | }, 138 | "locked": { 139 | "lastModified": 1694529238, 140 | "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", 141 | "owner": "numtide", 142 | "repo": "flake-utils", 143 | "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", 144 | "type": "github" 145 | }, 146 | "original": { 147 | "owner": "numtide", 148 | "repo": "flake-utils", 149 | "type": "github" 150 | } 151 | }, 152 | "gen-luarc": { 153 | "inputs": { 154 | "flake-parts": [ 155 | "nvim", 156 | "parts" 157 | ], 158 | "git-hooks": "git-hooks", 159 | "luvit-meta": "luvit-meta", 160 | "nixpkgs": [ 161 | "nvim", 162 | "nixpkgs" 163 | ] 164 | }, 165 | "locked": { 166 | "lastModified": 1724097937, 167 | "narHash": "sha256-Q4tgm8ZHAQUdvsNft86MqIbHQAm7OF7RT/wwYWXqSdY=", 168 | "owner": "mrcjkb", 169 | "repo": "nix-gen-luarc-json", 170 | "rev": "b36b69c4ded9f31b079523bc452e23458734cf00", 171 | "type": "github" 172 | }, 173 | "original": { 174 | "owner": "mrcjkb", 175 | "repo": "nix-gen-luarc-json", 176 | "type": "github" 177 | } 178 | }, 179 | "git-hooks": { 180 | "inputs": { 181 | "flake-compat": "flake-compat_2", 182 | "gitignore": "gitignore", 183 | "nixpkgs": [ 184 | "nvim", 185 | "gen-luarc", 186 | "nixpkgs" 187 | ], 188 | "nixpkgs-stable": "nixpkgs-stable" 189 | }, 190 | "locked": { 191 | "lastModified": 1723803910, 192 | "narHash": "sha256-yezvUuFiEnCFbGuwj/bQcqg7RykIEqudOy/RBrId0pc=", 193 | "owner": "cachix", 194 | "repo": "git-hooks.nix", 195 | "rev": "bfef0ada09e2c8ac55bbcd0831bd0c9d42e651ba", 196 | "type": "github" 197 | }, 198 | "original": { 199 | "owner": "cachix", 200 | "repo": "git-hooks.nix", 201 | "type": "github" 202 | } 203 | }, 204 | "git-hooks-nix": { 205 | "inputs": { 206 | "flake-compat": [ 207 | "nix" 208 | ], 209 | "gitignore": [ 210 | "nix" 211 | ], 212 | "nixpkgs": [ 213 | "nix", 214 | "nixpkgs" 215 | ], 216 | "nixpkgs-stable": [ 217 | "nix", 218 | "nixpkgs" 219 | ] 220 | }, 221 | "locked": { 222 | "lastModified": 1734279981, 223 | "narHash": "sha256-NdaCraHPp8iYMWzdXAt5Nv6sA3MUzlCiGiR586TCwo0=", 224 | "owner": "cachix", 225 | "repo": "git-hooks.nix", 226 | "rev": "aa9f40c906904ebd83da78e7f328cd8aeaeae785", 227 | "type": "github" 228 | }, 229 | "original": { 230 | "owner": "cachix", 231 | "repo": "git-hooks.nix", 232 | "type": "github" 233 | } 234 | }, 235 | "gitignore": { 236 | "inputs": { 237 | "nixpkgs": [ 238 | "nvim", 239 | "gen-luarc", 240 | "git-hooks", 241 | "nixpkgs" 242 | ] 243 | }, 244 | "locked": { 245 | "lastModified": 1709087332, 246 | "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", 247 | "owner": "hercules-ci", 248 | "repo": "gitignore.nix", 249 | "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", 250 | "type": "github" 251 | }, 252 | "original": { 253 | "owner": "hercules-ci", 254 | "repo": "gitignore.nix", 255 | "type": "github" 256 | } 257 | }, 258 | "home-manager": { 259 | "inputs": { 260 | "nixpkgs": [ 261 | "nixpkgs" 262 | ] 263 | }, 264 | "locked": { 265 | "lastModified": 1749062139, 266 | "narHash": "sha256-gGGLujmeWU+ZjFzfMvFMI0hp9xONsSbm88187wJr82Q=", 267 | "owner": "nix-community", 268 | "repo": "home-manager", 269 | "rev": "86b95fc1ed2b9b04a451a08ccf13d78fb421859c", 270 | "type": "github" 271 | }, 272 | "original": { 273 | "owner": "nix-community", 274 | "repo": "home-manager", 275 | "type": "github" 276 | } 277 | }, 278 | "luvit-meta": { 279 | "flake": false, 280 | "locked": { 281 | "lastModified": 1705776742, 282 | "narHash": "sha256-zAAptV/oLuLAAsa2zSB/6fxlElk4+jNZd/cPr9oxFig=", 283 | "owner": "Bilal2453", 284 | "repo": "luvit-meta", 285 | "rev": "ce76f6f6cdc9201523a5875a4471dcfe0186eb60", 286 | "type": "github" 287 | }, 288 | "original": { 289 | "owner": "Bilal2453", 290 | "repo": "luvit-meta", 291 | "type": "github" 292 | } 293 | }, 294 | "nix": { 295 | "inputs": { 296 | "flake-compat": "flake-compat", 297 | "flake-parts": [ 298 | "parts" 299 | ], 300 | "git-hooks-nix": "git-hooks-nix", 301 | "nixpkgs": "nixpkgs", 302 | "nixpkgs-23-11": "nixpkgs-23-11", 303 | "nixpkgs-regression": "nixpkgs-regression" 304 | }, 305 | "locked": { 306 | "lastModified": 1749012568, 307 | "narHash": "sha256-7IltFTct/oe6pGkwB6f/1WhWA65hFnsBY6XaGjodf3k=", 308 | "owner": "nixos", 309 | "repo": "nix", 310 | "rev": "4751cbef6303d10479f3db1b13db69197d9c3446", 311 | "type": "github" 312 | }, 313 | "original": { 314 | "owner": "nixos", 315 | "repo": "nix", 316 | "type": "github" 317 | } 318 | }, 319 | "nix-gl": { 320 | "inputs": { 321 | "flake-utils": "flake-utils", 322 | "nixpkgs": [ 323 | "nixpkgs" 324 | ] 325 | }, 326 | "locked": { 327 | "lastModified": 1713543440, 328 | "narHash": "sha256-lnzZQYG0+EXl/6NkGpyIz+FEOc/DSEG57AP1VsdeNrM=", 329 | "owner": "nix-community", 330 | "repo": "nixgl", 331 | "rev": "310f8e49a149e4c9ea52f1adf70cdc768ec53f8a", 332 | "type": "github" 333 | }, 334 | "original": { 335 | "owner": "nix-community", 336 | "repo": "nixgl", 337 | "type": "github" 338 | } 339 | }, 340 | "nixos-vscode-server": { 341 | "inputs": { 342 | "flake-utils": "flake-utils_2", 343 | "nixpkgs": [ 344 | "nixpkgs" 345 | ] 346 | }, 347 | "locked": { 348 | "lastModified": 1729422940, 349 | "narHash": "sha256-DlvJv33ml5UTKgu4b0HauOfFIoDx6QXtbqUF3vWeRCY=", 350 | "owner": "msteen", 351 | "repo": "nixos-vscode-server", 352 | "rev": "8b6db451de46ecf9b4ab3d01ef76e59957ff549f", 353 | "type": "github" 354 | }, 355 | "original": { 356 | "owner": "msteen", 357 | "repo": "nixos-vscode-server", 358 | "type": "github" 359 | } 360 | }, 361 | "nixpkgs": { 362 | "locked": { 363 | "lastModified": 1747179050, 364 | "narHash": "sha256-qhFMmDkeJX9KJwr5H32f1r7Prs7XbQWtO0h3V0a0rFY=", 365 | "owner": "NixOS", 366 | "repo": "nixpkgs", 367 | "rev": "adaa24fbf46737f3f1b5497bf64bae750f82942e", 368 | "type": "github" 369 | }, 370 | "original": { 371 | "owner": "NixOS", 372 | "ref": "nixos-unstable", 373 | "repo": "nixpkgs", 374 | "type": "github" 375 | } 376 | }, 377 | "nixpkgs-23-11": { 378 | "locked": { 379 | "lastModified": 1717159533, 380 | "narHash": "sha256-oamiKNfr2MS6yH64rUn99mIZjc45nGJlj9eGth/3Xuw=", 381 | "owner": "NixOS", 382 | "repo": "nixpkgs", 383 | "rev": "a62e6edd6d5e1fa0329b8653c801147986f8d446", 384 | "type": "github" 385 | }, 386 | "original": { 387 | "owner": "NixOS", 388 | "repo": "nixpkgs", 389 | "rev": "a62e6edd6d5e1fa0329b8653c801147986f8d446", 390 | "type": "github" 391 | } 392 | }, 393 | "nixpkgs-emmy": { 394 | "locked": { 395 | "lastModified": 1719675406, 396 | "narHash": "sha256-bZgaUZikDI7ZS1EY0jjZnbcO4vNeSRhIekb17FyUMf0=", 397 | "owner": "NixOS", 398 | "repo": "nixpkgs", 399 | "rev": "2feb215c297f2c9ae272336f55d54a962d71a9ff", 400 | "type": "github" 401 | }, 402 | "original": { 403 | "owner": "NixOS", 404 | "ref": "pull/323401/head", 405 | "repo": "nixpkgs", 406 | "type": "github" 407 | } 408 | }, 409 | "nixpkgs-pre-rust": { 410 | "locked": { 411 | "lastModified": 1723634395, 412 | "narHash": "sha256-K1ohl/M/HWXqieqNtsF39FbWqtaNX/mUgulrqcOO1KU=", 413 | "owner": "nixos", 414 | "repo": "nixpkgs", 415 | "rev": "57d0d4a8f3025e2b902d2b4403bcece26ad1ea74", 416 | "type": "github" 417 | }, 418 | "original": { 419 | "owner": "nixos", 420 | "ref": "57d0d4a8f302", 421 | "repo": "nixpkgs", 422 | "type": "github" 423 | } 424 | }, 425 | "nixpkgs-regression": { 426 | "locked": { 427 | "lastModified": 1643052045, 428 | "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", 429 | "owner": "NixOS", 430 | "repo": "nixpkgs", 431 | "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", 432 | "type": "github" 433 | }, 434 | "original": { 435 | "owner": "NixOS", 436 | "repo": "nixpkgs", 437 | "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", 438 | "type": "github" 439 | } 440 | }, 441 | "nixpkgs-stable": { 442 | "locked": { 443 | "lastModified": 1720386169, 444 | "narHash": "sha256-NGKVY4PjzwAa4upkGtAMz1npHGoRzWotlSnVlqI40mo=", 445 | "owner": "NixOS", 446 | "repo": "nixpkgs", 447 | "rev": "194846768975b7ad2c4988bdb82572c00222c0d7", 448 | "type": "github" 449 | }, 450 | "original": { 451 | "owner": "NixOS", 452 | "ref": "nixos-24.05", 453 | "repo": "nixpkgs", 454 | "type": "github" 455 | } 456 | }, 457 | "nixpkgs_2": { 458 | "locked": { 459 | "lastModified": 1748929857, 460 | "narHash": "sha256-lcZQ8RhsmhsK8u7LIFsJhsLh/pzR9yZ8yqpTzyGdj+Q=", 461 | "owner": "nixos", 462 | "repo": "nixpkgs", 463 | "rev": "c2a03962b8e24e669fb37b7df10e7c79531ff1a4", 464 | "type": "github" 465 | }, 466 | "original": { 467 | "owner": "nixos", 468 | "ref": "nixos-unstable", 469 | "repo": "nixpkgs", 470 | "type": "github" 471 | } 472 | }, 473 | "nixpkgs_3": { 474 | "locked": { 475 | "lastModified": 1744868846, 476 | "narHash": "sha256-5RJTdUHDmj12Qsv7XOhuospjAjATNiTMElplWnJE9Hs=", 477 | "owner": "NixOS", 478 | "repo": "nixpkgs", 479 | "rev": "ebe4301cbd8f81c4f8d3244b3632338bbeb6d49c", 480 | "type": "github" 481 | }, 482 | "original": { 483 | "owner": "NixOS", 484 | "ref": "nixpkgs-unstable", 485 | "repo": "nixpkgs", 486 | "type": "github" 487 | } 488 | }, 489 | "nixpkgs_4": { 490 | "locked": { 491 | "lastModified": 1728538411, 492 | "narHash": "sha256-f0SBJz1eZ2yOuKUr5CA9BHULGXVSn6miBuUWdTyhUhU=", 493 | "owner": "NixOS", 494 | "repo": "nixpkgs", 495 | "rev": "b69de56fac8c2b6f8fd27f2eca01dcda8e0a4221", 496 | "type": "github" 497 | }, 498 | "original": { 499 | "owner": "NixOS", 500 | "ref": "nixpkgs-unstable", 501 | "repo": "nixpkgs", 502 | "type": "github" 503 | } 504 | }, 505 | "nvim": { 506 | "inputs": { 507 | "gen-luarc": "gen-luarc", 508 | "nixpkgs": [ 509 | "nixpkgs" 510 | ], 511 | "nixpkgs-emmy": "nixpkgs-emmy", 512 | "parts": [ 513 | "parts" 514 | ], 515 | "wrapper-manager": "wrapper-manager" 516 | }, 517 | "locked": { 518 | "lastModified": 1748686149, 519 | "narHash": "sha256-RdLAPiha8lr1wQiL158p4DTFhLcWcjRv6ioCTd3athQ=", 520 | "owner": "nobbz", 521 | "repo": "nobbz-vim", 522 | "rev": "a22303075cac32d83edfd79ef79c0386a38b02ce", 523 | "type": "github" 524 | }, 525 | "original": { 526 | "owner": "nobbz", 527 | "repo": "nobbz-vim", 528 | "type": "github" 529 | } 530 | }, 531 | "parts": { 532 | "inputs": { 533 | "nixpkgs-lib": [ 534 | "nixpkgs" 535 | ] 536 | }, 537 | "locked": { 538 | "lastModified": 1748821116, 539 | "narHash": "sha256-F82+gS044J1APL0n4hH50GYdPRv/5JWm34oCJYmVKdE=", 540 | "owner": "hercules-ci", 541 | "repo": "flake-parts", 542 | "rev": "49f0870db23e8c1ca0b5259734a02cd9e1e371a1", 543 | "type": "github" 544 | }, 545 | "original": { 546 | "owner": "hercules-ci", 547 | "repo": "flake-parts", 548 | "type": "github" 549 | } 550 | }, 551 | "programsdb": { 552 | "inputs": { 553 | "nixpkgs": [ 554 | "nixpkgs" 555 | ], 556 | "utils": "utils" 557 | }, 558 | "locked": { 559 | "lastModified": 1749055058, 560 | "narHash": "sha256-OgCTSX0WXPpEi/ukjbBRrElSo+TR2/pzCCcY5yfou58=", 561 | "owner": "wamserma", 562 | "repo": "flake-programs-sqlite", 563 | "rev": "78d23d728abddce902528922f93967f0630f1cfe", 564 | "type": "github" 565 | }, 566 | "original": { 567 | "owner": "wamserma", 568 | "repo": "flake-programs-sqlite", 569 | "type": "github" 570 | } 571 | }, 572 | "root": { 573 | "inputs": { 574 | "emacs": "emacs", 575 | "home-manager": "home-manager", 576 | "nix": "nix", 577 | "nix-gl": "nix-gl", 578 | "nixos-vscode-server": "nixos-vscode-server", 579 | "nixpkgs": "nixpkgs_2", 580 | "nixpkgs-insync-v3": [ 581 | "nixpkgs" 582 | ], 583 | "nixpkgs-pre-rust": "nixpkgs-pre-rust", 584 | "nvim": "nvim", 585 | "parts": "parts", 586 | "programsdb": "programsdb", 587 | "sops-nix": "sops-nix", 588 | "switcher": "switcher" 589 | } 590 | }, 591 | "rust-overlay": { 592 | "inputs": { 593 | "nixpkgs": "nixpkgs_4" 594 | }, 595 | "locked": { 596 | "lastModified": 1734402816, 597 | "narHash": "sha256-cgQ8mjUJz7J3fp97lnvl0dSJ6vLt8yzUSmw3B7QKw94=", 598 | "owner": "oxalica", 599 | "repo": "rust-overlay", 600 | "rev": "e38fbd6e56e8cd1d61c65a21bbb7785e966707b4", 601 | "type": "github" 602 | }, 603 | "original": { 604 | "owner": "oxalica", 605 | "repo": "rust-overlay", 606 | "type": "github" 607 | } 608 | }, 609 | "sops-nix": { 610 | "inputs": { 611 | "nixpkgs": "nixpkgs_3" 612 | }, 613 | "locked": { 614 | "lastModified": 1747603214, 615 | "narHash": "sha256-lAblXm0VwifYCJ/ILPXJwlz0qNY07DDYdLD+9H+Wc8o=", 616 | "owner": "Mic92", 617 | "repo": "sops-nix", 618 | "rev": "8d215e1c981be3aa37e47aeabd4e61bb069548fd", 619 | "type": "github" 620 | }, 621 | "original": { 622 | "owner": "Mic92", 623 | "repo": "sops-nix", 624 | "type": "github" 625 | } 626 | }, 627 | "switcher": { 628 | "inputs": { 629 | "cargo2nix": "cargo2nix", 630 | "flake-parts": [ 631 | "parts" 632 | ], 633 | "nixpkgs": [ 634 | "nixpkgs" 635 | ], 636 | "rust-overlay": "rust-overlay" 637 | }, 638 | "locked": { 639 | "lastModified": 1734435961, 640 | "narHash": "sha256-HIw4Naoc0Gcl9VOT4JkagzKDvAdBwyzlq2majy5pSks=", 641 | "owner": "nobbz", 642 | "repo": "nix-switcher", 643 | "rev": "6f12e77ff6b46d53a5e58567803f94708e15660e", 644 | "type": "github" 645 | }, 646 | "original": { 647 | "owner": "nobbz", 648 | "ref": "main", 649 | "repo": "nix-switcher", 650 | "type": "github" 651 | } 652 | }, 653 | "systems": { 654 | "locked": { 655 | "lastModified": 1681028828, 656 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 657 | "owner": "nix-systems", 658 | "repo": "default", 659 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 660 | "type": "github" 661 | }, 662 | "original": { 663 | "owner": "nix-systems", 664 | "repo": "default", 665 | "type": "github" 666 | } 667 | }, 668 | "systems_2": { 669 | "locked": { 670 | "lastModified": 1681028828, 671 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 672 | "owner": "nix-systems", 673 | "repo": "default", 674 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 675 | "type": "github" 676 | }, 677 | "original": { 678 | "owner": "nix-systems", 679 | "repo": "default", 680 | "type": "github" 681 | } 682 | }, 683 | "utils": { 684 | "locked": { 685 | "lastModified": 1678901627, 686 | "narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=", 687 | "owner": "numtide", 688 | "repo": "flake-utils", 689 | "rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6", 690 | "type": "github" 691 | }, 692 | "original": { 693 | "owner": "numtide", 694 | "repo": "flake-utils", 695 | "type": "github" 696 | } 697 | }, 698 | "wrapper-manager": { 699 | "inputs": { 700 | "nixpkgs": [ 701 | "nvim", 702 | "nixpkgs" 703 | ] 704 | }, 705 | "locked": { 706 | "lastModified": 1747562021, 707 | "narHash": "sha256-XfF+5zjoWbAcAiGNb++og6yDGJRwWYpADr9P6WuieQA=", 708 | "owner": "viperml", 709 | "repo": "wrapper-manager", 710 | "rev": "f2b0bec5140403cf24cae96f6764d97b5d59b0e2", 711 | "type": "github" 712 | }, 713 | "original": { 714 | "owner": "viperml", 715 | "repo": "wrapper-manager", 716 | "type": "github" 717 | } 718 | } 719 | }, 720 | "root": "root", 721 | "version": 7 722 | } 723 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | outputs = {parts, ...} @ inputs: 3 | parts.lib.mkFlake {inherit inputs;} { 4 | systems = ["x86_64-linux" "aarch64-linux" "aarch64-darwin"]; 5 | 6 | _module.args.npins = import ./npins; 7 | 8 | imports = [ 9 | ./parts/auxiliary.nix 10 | ./parts/home_configs.nix 11 | ./parts/home_modules.nix 12 | ./parts/nixos_modules.nix 13 | ./parts/system_configs.nix 14 | 15 | ./nixos/configurations 16 | ./home/configurations 17 | 18 | ./home/modules 19 | ./nixos/modules 20 | 21 | ./packages 22 | ]; 23 | 24 | flake = { 25 | mixedModules = import ./mixed inputs; 26 | 27 | checks.x86_64-linux = import ./checks inputs; 28 | }; 29 | }; 30 | 31 | inputs = { 32 | nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; 33 | # nixpkgs-insync-v3.url = "github:nixos/nixpkgs?ref=32fdc268e921994e3f38088486ddfe765d11df93"; 34 | nixpkgs-insync-v3.follows = "nixpkgs"; 35 | nixpkgs-pre-rust.url = "github:nixos/nixpkgs?ref=57d0d4a8f302"; 36 | 37 | nvim.url = "github:nobbz/nobbz-vim"; 38 | nvim.inputs.parts.follows = "parts"; 39 | nvim.inputs.nixpkgs.follows = "nixpkgs"; 40 | 41 | switcher.url = "github:nobbz/nix-switcher?ref=main"; 42 | switcher.inputs.nixpkgs.follows = "nixpkgs"; 43 | switcher.inputs.flake-parts.follows = "parts"; 44 | 45 | parts.url = "github:hercules-ci/flake-parts"; 46 | parts.inputs.nixpkgs-lib.follows = "nixpkgs"; 47 | 48 | programsdb.url = "github:wamserma/flake-programs-sqlite"; 49 | programsdb.inputs.nixpkgs.follows = "nixpkgs"; 50 | 51 | nix.url = "github:nixos/nix"; 52 | nix.inputs.flake-parts.follows = "parts"; 53 | # a libgit2 in the current version fails to build with the nix provided patches. 54 | # therefore using upstreams pin for now. 55 | # nix.inputs.nixpkgs.follows = "nixpkgs"; 56 | 57 | nix-gl.url = "github:nix-community/nixgl"; 58 | nix-gl.inputs.nixpkgs.follows = "nixpkgs"; 59 | 60 | home-manager.url = "github:nix-community/home-manager"; 61 | home-manager.inputs.nixpkgs.follows = "nixpkgs"; 62 | 63 | emacs.url = "github:nix-community/emacs-overlay"; 64 | emacs.inputs.nixpkgs.follows = "nixpkgs"; 65 | emacs.inputs.nixpkgs-stable.follows = "nixpkgs"; 66 | 67 | nixos-vscode-server.url = "github:msteen/nixos-vscode-server"; 68 | nixos-vscode-server.inputs.nixpkgs.follows = "nixpkgs"; 69 | 70 | sops-nix.url = "github:Mic92/sops-nix"; 71 | }; 72 | } 73 | -------------------------------------------------------------------------------- /home/configurations/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | nobbz.homeConfigurations."nmelzer@mimas".system = "x86_64-linux"; 3 | nobbz.homeConfigurations."nmelzer@phoebe".system = "x86_64-linux"; 4 | } 5 | -------------------------------------------------------------------------------- /home/configurations/nmelzer_at_mimas.nix: -------------------------------------------------------------------------------- 1 | {self, ...}: { 2 | config, 3 | pkgs, 4 | lib, 5 | ... 6 | }: { 7 | nixpkgs.allowedUnfree = ["google-chrome" "vscode" "discord" "obsidian"]; 8 | 9 | activeProfiles = ["browsing" "development"]; 10 | 11 | sops.age.sshKeyPaths = ["${config.home.homeDirectory}/.ssh/id_ed25519"]; 12 | sops.defaultSopsFile = "${self}/secrets/mimas/nmelzer/default.yaml"; 13 | 14 | sops.secrets.rustic.path = "${config.xdg.configHome}/rustic/password"; 15 | 16 | dconf.enable = true; 17 | 18 | home.packages = builtins.attrValues { 19 | inherit (pkgs) keybase-gui freerdp keepassxc nix-output-monitor discord; 20 | inherit (pkgs) obsidian; 21 | inherit (pkgs) gnome-tweaks; 22 | inherit (pkgs) vscode wezterm; 23 | }; 24 | 25 | programs.obs-studio.enable = true; 26 | programs.obs-studio.plugins = builtins.attrValues { 27 | inherit (pkgs.obs-studio-plugins) obs-backgroundremoval; 28 | }; 29 | programs.htop = { 30 | settings = { 31 | detailed_cpu_time = true; 32 | }; 33 | # meters.right = [ 34 | # { kind = "Battery"; mode = 1; } 35 | # "Tasks" 36 | # "LoadAverage" 37 | # "Uptime" 38 | # ]; 39 | }; 40 | 41 | programs.yazi.enable = true; 42 | 43 | xsession.windowManager.awesome.autostart = [ 44 | "${pkgs.blueman}/bin/blueman-applet" 45 | "${pkgs.networkmanagerapplet}/bin/nm-applet" 46 | ]; 47 | 48 | systemd.user.tmpfiles.rules = [ 49 | "d ${config.home.homeDirectory}/tmp 700 ${config.home.username} users 14d" 50 | ]; 51 | 52 | services = { 53 | keybase.enable = true; 54 | kbfs.enable = true; 55 | insync.enable = true; 56 | playerctld.enable = true; 57 | flameshot.enable = true; 58 | 59 | rustic = { 60 | enable = true; 61 | passwordFile = config.sops.secrets.rustic.path; 62 | globs = let 63 | mkHome = e: "${config.home.homeDirectory}/${e}"; 64 | mkIgnore = e: "!${e}"; 65 | 66 | home = map mkHome ["Downloads" ".cache" ".cabal" ".cargo" ".emacs.d/eln-cache" ".emacs.d/.cache" ".gem" ".gradle" ".hex" ".kube" ".local" ".m2" ".minikube" ".minishift" ".mix" ".mozilla" "npm" ".opam" ".rancher" ".vscode-oss" "go/pkg" "timmelzer@gmail.com/restic_repos" ".local/share/libvirt" ".bitmonero"]; 67 | patterns = ["_build" "Cache" "deps" "result" "target" ".elixir_ls" "ccls-cache" ".direnv" "direnv" "node_modules"]; 68 | in 69 | map mkIgnore (home ++ patterns); 70 | oneFileSystem = true; 71 | repo = "rest:https://restic.mimas.internal.nobbz.dev/nobbz"; 72 | }; 73 | }; 74 | 75 | systemd.user.services = { 76 | rustic.Unit.After = ["sops-nix.service"]; 77 | keybase-gui = { 78 | Unit = { 79 | Description = "Keybase GUI"; 80 | Requires = ["keybase.service" "kbfs.service"]; 81 | After = ["keybase.service" "kbfs.service"]; 82 | }; 83 | Service = { 84 | ExecStart = "${pkgs.keybase-gui}/share/keybase/Keybase"; 85 | PrivateTmp = true; 86 | # Slice = "keybase.slice"; 87 | }; 88 | }; 89 | }; 90 | 91 | xdg.configFile = { 92 | "rustic/mimas-hetzner.toml".text = 93 | # toml 94 | '' 95 | [repository] 96 | repository = "rclone:hetzner-restic:mimas" 97 | password-file = "${config.sops.secrets.rustic.path}" 98 | ''; 99 | "rustic/mimas.toml".text = 100 | # toml 101 | '' 102 | [repository] 103 | repository = "rest:https://restic.mimas.internal.nobbz.dev/mimas" 104 | password-file = "${config.sops.secrets.rustic.path}" 105 | 106 | [copy] 107 | targets = ["mimas-hetzner"] 108 | ''; 109 | 110 | "rustic/nobbz-hetzner.toml".text = 111 | # toml 112 | '' 113 | [repository] 114 | repository = "rclone:hetzner-restic:nobbz" 115 | password-file = "${config.sops.secrets.rustic.path}" 116 | ''; 117 | "rustic/nobbz.toml".text = 118 | # toml 119 | '' 120 | [repository] 121 | repository = "rest:https://restic.mimas.internal.nobbz.dev/nobbz" 122 | password-file = "${config.sops.secrets.rustic.path}" 123 | 124 | [copy] 125 | targets = ["nobbz-hetzner"] 126 | ''; 127 | }; 128 | 129 | home.stateVersion = "20.09"; 130 | } 131 | -------------------------------------------------------------------------------- /home/configurations/nmelzer_at_phoebe.nix: -------------------------------------------------------------------------------- 1 | { 2 | self, 3 | nix, 4 | ... 5 | }: { 6 | config, 7 | pkgs, 8 | lib, 9 | ... 10 | }: let 11 | sshConfigPath = "${config.home.homeDirectory}/.ssh"; 12 | inherit (lib.hm) dag; 13 | spkgs = self.packages.${pkgs.system}; 14 | in { 15 | nixpkgs.allowedUnfree = ["google-chrome" "vscode" "discord" "obsidian" "slack"]; 16 | nixpkgs.config.permittedInsecurePackages = ["electron-25.9.0"]; 17 | profiles.base.needsGL = true; 18 | 19 | nix.checkConfig = false; 20 | nix.settings.extra-experimental-features = ["flakes" "nix-command"]; 21 | nix.extraOptions = "!include ${config.sops.secrets."access-tokens".path}"; 22 | nix.package = nix.packages.${pkgs.system}.nix-cli; 23 | 24 | activeProfiles = ["development"]; 25 | 26 | sops.age.sshKeyPaths = ["${sshConfigPath}/id_ed25519"]; 27 | sops.defaultSopsFile = "${self}/secrets/phoebe/nmelzer/default.yaml"; 28 | 29 | sops.secrets.ssh.path = "${sshConfigPath}/nightwing_config"; 30 | 31 | sops.secrets."access-tokens" = { 32 | path = "${config.home.homeDirectory}/.config/nix/access-tokens.conf"; 33 | mode = "0400"; 34 | sopsFile = "${self}/secrets/users/nmelzer/default.yaml"; 35 | }; 36 | 37 | sops.secrets."github" = { 38 | path = "${sshConfigPath}/github"; 39 | mode = "0400"; 40 | sopsFile = "${self}/secrets/users/nmelzer/github"; 41 | format = "binary"; 42 | }; 43 | 44 | sops.secrets."gitlab" = { 45 | path = "${sshConfigPath}/gitlab"; 46 | mode = "0400"; 47 | sopsFile = "${self}/secrets/users/nmelzer/gitlab"; 48 | format = "binary"; 49 | }; 50 | 51 | sops.secrets."nobbz_dev" = { 52 | path = "${sshConfigPath}/nobbz_dev"; 53 | mode = "0400"; 54 | sopsFile = "${self}/secrets/users/nmelzer/nobbz_dev"; 55 | format = "binary"; 56 | }; 57 | 58 | dconf.enable = true; 59 | 60 | home.packages = builtins.attrValues { 61 | inherit (pkgs) keepassxc nix-output-monitor discord obsidian vscode slack; 62 | inherit (config.nix) package; 63 | inherit (spkgs) switcher; 64 | }; 65 | 66 | xsession.windowManager.awesome.enable = lib.mkForce false; 67 | xsession.enable = lib.mkForce false; 68 | 69 | services.playerctld.enable = true; 70 | 71 | gtk.gtk2.force = true; 72 | 73 | programs.ssh.includes = [ 74 | config.sops.secrets.ssh.path 75 | ]; 76 | 77 | programs.ssh.matchBlocks = { 78 | # TODO: properly use seperate key 79 | "gitlab.com-bravo" = dag.entryAfter ["gitlab.com"] { 80 | hostname = "gitlab.com"; 81 | addressFamily = "inet"; 82 | identityFile = "~/.ssh/id_ed25519"; 83 | }; 84 | 85 | # TODO: Make the actual hosts identity file configurable by other means. Actually moving all the logic over to `home/modules/profiles/base/default.nix`. 86 | "*.internal.nobbz.dev" = lib.mkForce (dag.entryAfter ["delly-nixos.adoring_suess.zerotier" "tux-nixos.adoring_suess.zerotier" "nixos.adoring_suess.zerotier"] { 87 | identityFile = "~/.ssh/id_ed25519"; 88 | user = "nmelzer"; 89 | }); 90 | }; 91 | 92 | home.stateVersion = "20.09"; 93 | } 94 | -------------------------------------------------------------------------------- /home/modules/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | nobbz.homeManagerModules = { 3 | "profiles" = ./profiles; 4 | "profiles/base" = ./profiles/base; 5 | "profiles/browsing" = ./profiles/browsing; 6 | "profiles/development" = ./profiles/development; 7 | 8 | "programs/advcp" = ./programs/advcp; 9 | "programs/eza" = ./programs/eza; 10 | "programs/ghostty" = ./programs/ghostty; 11 | "programs/nixpkgs" = ./programs/nixpkgs; 12 | "programs/p10k" = ./programs/p10k; 13 | "programs/rbw" = ./programs/rbw; 14 | "programs/wezterm" = ./programs/wezterm; 15 | 16 | "services/insync" = ./services/insync; 17 | "services/rustic" = ./services/rustic; 18 | 19 | "misc/awesome" = ./misc/awesome; 20 | "misc/home" = ./misc/home; 21 | "misc/rofi" = ./misc/rofi; 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /home/modules/misc/awesome/default.nix: -------------------------------------------------------------------------------- 1 | {self, ...}: { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: let 7 | cfg = config.xsession.windowManager.awesome; 8 | 9 | flameshot = lib.getExe pkgs.flameshot; 10 | 11 | bls = lib.getExe (pkgs.betterlockscreen.override {withDunst = false;}); 12 | scrot = lib.getExe pkgs.scrot; 13 | 14 | locker = pkgs.writeShellScript "betterlockscreen-with-screenshot" '' 15 | tmpf="$(mktemp -d)" 16 | file="$tmpf/screenshot.png" 17 | ${scrot} -z $file 18 | ${bls} -u $file --display 1 --span --fx blur --blur 1.0 19 | rm -rf $tmpf 20 | ${bls} -l blur --display 1 --span --off 30 21 | ''; 22 | 23 | mediaKeys = let 24 | keyMap = let 25 | amixer = "${pkgs.alsa-utils}/bin/amixer"; 26 | playerctl = "${pkgs.playerctl}/bin/playerctl"; 27 | in { 28 | "XF86AudioMute" = "${amixer} set Master 1+ toggle"; 29 | "XF86AudioLowerVolume" = "${amixer} set Master 4%-"; 30 | "XF86AudioRaiseVolume" = "${amixer} set Master 4%+"; 31 | "XF86AudioPlay" = "${playerctl} play-pause"; 32 | "XF86AudioPrev" = "${playerctl} previous"; 33 | "XF86AudioNext" = "${playerctl} next"; 34 | }; 35 | keyList = lib.attrsets.mapAttrsToList (key: command: ''awful.key({ }, "${key}", function () awful.util.spawn("${command}") end)'') keyMap; 36 | in 37 | lib.strings.concatStringsSep ",\n " keyList; 38 | 39 | autostartScript = let 40 | entries = builtins.map (e: "\"${e}\",") cfg.autostart; 41 | in '' 42 | -- Autorun programs 43 | autorunApps = { 44 | ${builtins.concatStringsSep "\n " entries} 45 | } 46 | 47 | for app = 1, #autorunApps do 48 | awful.util.spawn(autorunApps[app]) 49 | end 50 | -- }}} 51 | ''; 52 | 53 | errorHandling = '' 54 | -- {{{ Error handling 55 | if awesome.startup_errors then 56 | naughty.notify({ 57 | preset = naughty.config.presets.critical, 58 | title = "Oops, there were errors during startup!", 59 | text = awesome.startup_errors 60 | }) 61 | end 62 | 63 | do 64 | local in_error = false 65 | awesome.connect_signal( 66 | "debug::error", 67 | function (err) 68 | if in_error then return end 69 | in_error = true 70 | 71 | naughty.notify({ 72 | preset = naughty.config.presets.critical, 73 | title = "Oops, an error happened!", 74 | text = tostring(err) 75 | }) 76 | in_error = false 77 | end) 78 | end 79 | -- }}} 80 | ''; 81 | in { 82 | options.xsession.windowManager.awesome = { 83 | terminalEmulator = lib.mkOption { 84 | type = lib.types.str; 85 | default = "${lib.getExe pkgs.wezterm}"; 86 | }; 87 | 88 | lockCommand = lib.mkOption { 89 | type = lib.types.str; 90 | # default = "${lib.getExe pkgs.i3lock}"; 91 | default = "${locker}"; 92 | }; 93 | 94 | launcher = lib.mkOption { 95 | type = lib.types.str; 96 | default = "${pkgs.rofi}/bin/rofi -modi drun -show drun -show-icons"; 97 | }; 98 | 99 | windowSwitcher = lib.mkOption { 100 | type = lib.types.str; 101 | default = "${pkgs.rofi}/bin/rofi -modi window -show window -show-icons"; 102 | }; 103 | 104 | emojiPicker = lib.mkOption { 105 | type = lib.types.str; 106 | default = "${pkgs.rofi}/bin/rofi -modi drun -show drun -show-icons"; 107 | }; 108 | 109 | autostart = lib.mkOption { 110 | type = lib.types.listOf lib.types.str; 111 | default = []; 112 | }; 113 | }; 114 | 115 | config = lib.mkIf cfg.enable { 116 | xsession.enable = true; 117 | 118 | xsession.initExtra = '' 119 | unset XDG_CURRENT_DESKTOP 120 | unset DESKTOP_SESSION 121 | ''; 122 | 123 | home.file.".config/awesome/rc.lua".text = '' 124 | --[[ 125 | Awesome WM configuration 126 | by Norbert Melzer 127 | 128 | This file is generated by home-manager. 129 | --]] 130 | 131 | -- {{{ Loading libraries 132 | local gears = require("gears") 133 | local awful = require("awful") 134 | local autofocus = require("awful.autofocus") 135 | local wibox = require("wibox") 136 | local beautiful = require("beautiful") 137 | local naughty = require("naughty") 138 | local menubar = require("menubar") 139 | local hotkeys_popup = require("awful.hotkeys_popup").widget 140 | -- local volume_control = require("volume-control") 141 | -- }}} 142 | 143 | ${errorHandling} 144 | 145 | -- load the volume widget code 146 | -- volumecfg = volume_control({}) 147 | 148 | beautiful.notification_icon_size = 100 149 | 150 | -- {{{ Variable definitions and initialisations 151 | local hostname = io.popen("hostname"):read() 152 | local modkey = "Mod4" 153 | local theme_path = gears.filesystem.get_themes_dir() .. "default/theme.lua" 154 | local terminal = "${cfg.terminalEmulator}" -- sets the default terminal 155 | local editor = os.getenv("EDITOR") or "emacsclient -t" -- sets the default editor 156 | local editor_cmd = terminal .. " -e " .. editor -- sets the default command that is used to start the editor 157 | 158 | beautiful.init(theme_path) 159 | 160 | -- Table of layouts to cover with awful.layout.inc, order matters. 161 | awful.layout.layouts = { 162 | awful.layout.suit.floating, 163 | awful.layout.suit.tile, 164 | awful.layout.suit.tile.left, 165 | awful.layout.suit.tile.bottom, 166 | awful.layout.suit.tile.top, 167 | awful.layout.suit.fair, 168 | awful.layout.suit.fair.horizontal, 169 | awful.layout.suit.spiral, 170 | awful.layout.suit.spiral.dwindle, 171 | awful.layout.suit.max, 172 | awful.layout.suit.max.fullscreen, 173 | awful.layout.suit.magnifier, 174 | awful.layout.suit.corner.nw, 175 | -- awful.layout.suit.corner.ne, 176 | -- awful.layout.suit.corner.sw, 177 | -- awful.layout.suit.corner.se, 178 | } 179 | -- }}} 180 | 181 | -- {{{ Helper functions 182 | local function client_menu_toggle_fn() 183 | local instance = nil 184 | 185 | return function () 186 | if instance and instance.wibox.visible then 187 | instance:hide() 188 | instance = nil 189 | else 190 | instance = awful.menu.clients({ theme = { width = 250 } }) 191 | end 192 | end 193 | end 194 | -- }}} 195 | 196 | -- {{{ Menu 197 | -- Create a launcher widget and a main menu 198 | myawesomemenu = { 199 | { "launcher", '${cfg.launcher}' }, 200 | { "windows", '${cfg.windowSwitcher}' }, 201 | { "emoji", '${cfg.emojiPicker}' }, 202 | { "hotkeys", function() return false, hotkeys_popup.show_help end}, 203 | { "manual", terminal .. " -e man awesome" }, 204 | { "edit config", editor_cmd .. " " .. awesome.conffile }, 205 | { "lock session", '${cfg.lockCommand}' }, 206 | { "restart", awesome.restart }, 207 | { "quit", function() awesome.quit() end} 208 | } 209 | 210 | mymainmenu = awful.menu({ 211 | items = { 212 | { "awesome", myawesomemenu, beautiful.awesome_icon }, 213 | { "open terminal", terminal } 214 | } 215 | }) 216 | 217 | mylauncher = awful.widget.launcher({ 218 | image = beautiful.awesome_icon, 219 | menu = mymainmenu 220 | }) 221 | 222 | -- Menubar configuration 223 | menubar.utils.terminal = terminal -- Set the terminal for applications that require it 224 | -- }}} 225 | 226 | -- Keyboard map indicator and switcher 227 | mykeyboardlayout = awful.widget.keyboardlayout() 228 | 229 | -- {{{ Wibar 230 | -- Create a textclock widget 231 | mytextclock = wibox.widget.textclock() 232 | 233 | -- Create a wibox for each screen and add it 234 | local taglist_buttons = gears.table.join( 235 | awful.button({ }, 1, function(t) t:view_only() end), 236 | awful.button({ modkey }, 1, function(t) 237 | if client.focus then 238 | client.focus:move_to_tag(t) 239 | end 240 | end), 241 | awful.button({ }, 3, awful.tag.viewtoggle), 242 | awful.button({ modkey }, 3, function(t) 243 | if client.focus then 244 | client.focus:toggle_tag(t) 245 | end 246 | end), 247 | awful.button({ }, 4, function(t) awful.tag.viewnext(t.screen) end), 248 | awful.button({ }, 5, function(t) awful.tag.viewprev(t.screen) end) 249 | ) 250 | 251 | local tasklist_buttons = gears.table.join( 252 | awful.button({ }, 1, function (c) 253 | if c == client.focus then 254 | c.minimized = true 255 | else 256 | -- Without this, the following 257 | -- :isvisible() makes no sense 258 | c.minimized = false 259 | if not c:isvisible() and c.first_tag then 260 | c.first_tag:view_only() 261 | end 262 | -- This will also un-minimize 263 | -- the client, if needed 264 | client.focus = c 265 | c:raise() 266 | end 267 | end), 268 | awful.button({ }, 3, client_menu_toggle_fn()), 269 | awful.button({ }, 4, function () 270 | awful.client.focus.byidx(1) 271 | end), 272 | awful.button({ }, 5, function () 273 | awful.client.focus.byidx(-1) 274 | end)) 275 | 276 | local function set_wallpaper(s) 277 | -- Wallpaper 278 | if beautiful.wallpaper then 279 | local wallpaper = beautiful.wallpaper 280 | -- If wallpaper is a function, call it with the screen 281 | if type(wallpaper) == "function" then 282 | wallpaper = wallpaper(s) 283 | end 284 | gears.wallpaper.maximized(wallpaper, s, true) 285 | end 286 | end 287 | 288 | -- Re-set wallpaper when a screen's geometry changes (e.g. different resolution) 289 | screen.connect_signal("property::geometry", set_wallpaper) 290 | 291 | awful.screen.connect_for_each_screen(function(s) 292 | -- Wallpaper 293 | set_wallpaper(s) 294 | 295 | -- Each screen has its own tag table. 296 | local names = { "1:main", "2:web", "3", "4", "5", "6", "7", "8", "9" } 297 | local l = awful.layout.suit 298 | local layouts = { l.tile, l.tile, l.tile, l.tile, l.tile, l.tile, l.tile, l.tile, l.tile } 299 | awful.tag(names, s, layouts) 300 | 301 | -- Create a promptbox for each screen 302 | s.mypromptbox = awful.widget.prompt() 303 | -- Create an imagebox widget which will contain an icon indicating which layout we're using. 304 | -- We need one layoutbox per screen. 305 | s.mylayoutbox = awful.widget.layoutbox(s) 306 | s.mylayoutbox:buttons( 307 | gears.table.join( 308 | awful.button({ }, 1, function () awful.layout.inc( 1) end), 309 | awful.button({ }, 3, function () awful.layout.inc(-1) end), 310 | awful.button({ }, 4, function () awful.layout.inc( 1) end), 311 | awful.button({ }, 5, function () awful.layout.inc(-1) end))) 312 | -- Create a taglist widget 313 | s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, taglist_buttons) 314 | 315 | -- Create a tasklist widget 316 | s.mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, tasklist_buttons) 317 | 318 | -- Create the wibox 319 | s.mywibox = awful.wibar({ position = "top", screen = s }) 320 | 321 | -- Add widgets to the wibox 322 | s.mywibox:setup { 323 | layout = wibox.layout.align.horizontal, 324 | { -- Left widgets 325 | layout = wibox.layout.fixed.horizontal, 326 | mylauncher, 327 | s.mytaglist, 328 | s.mypromptbox, 329 | }, 330 | s.mytasklist, -- Middle widget 331 | { -- Right widgets 332 | layout = wibox.layout.fixed.horizontal, 333 | mykeyboardlayout, 334 | wibox.widget.systray(), 335 | -- require("battery-widget") {}, 336 | -- volumecfg.widget, 337 | mytextclock, 338 | s.mylayoutbox, 339 | }, 340 | } 341 | end) 342 | -- }}} 343 | 344 | -- {{{ Mouse bindings 345 | root.buttons(gears.table.join( 346 | awful.button({ }, 3, function () mymainmenu:toggle() end), 347 | awful.button({ }, 4, awful.tag.viewnext), 348 | awful.button({ }, 5, awful.tag.viewprev) 349 | )) 350 | -- }}} 351 | 352 | -- {{{ Key bindings 353 | globalkeys = gears.table.join( 354 | awful.key({ modkey, }, "s", hotkeys_popup.show_help, 355 | {description="show help", group="awesome"}), 356 | awful.key({ modkey, }, "Left", awful.tag.viewprev, 357 | {description = "view previous", group = "tag"}), 358 | awful.key({ modkey, }, "Right", awful.tag.viewnext, 359 | {description = "view next", group = "tag"}), 360 | awful.key({ modkey, }, "Escape", awful.tag.history.restore, 361 | {description = "go back", group = "tag"}), 362 | 363 | awful.key({ modkey, }, "j", 364 | function () 365 | awful.client.focus.byidx( 1) 366 | end, 367 | {description = "focus next by index", group = "client"} 368 | ), 369 | awful.key({ modkey, }, "k", 370 | function () 371 | awful.client.focus.byidx(-1) 372 | end, 373 | {description = "focus previous by index", group = "client"} 374 | ), 375 | 376 | -- Layout manipulation 377 | awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end, 378 | {description = "swap with next client by index", group = "client"}), 379 | awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end, 380 | {description = "swap with previous client by index", group = "client"}), 381 | awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end, 382 | {description = "focus the next screen", group = "screen"}), 383 | awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end, 384 | {description = "focus the previous screen", group = "screen"}), 385 | awful.key({ modkey, }, "u", awful.client.urgent.jumpto, 386 | {description = "jump to urgent client", group = "client"}), 387 | awful.key({ modkey, }, "Tab", 388 | function () 389 | awful.client.focus.history.previous() 390 | if client.focus then 391 | client.focus:raise() 392 | end 393 | end, 394 | {description = "go back", group = "client"}), 395 | 396 | -- Standard program 397 | awful.key({ modkey, }, "Return", function () awful.spawn(terminal) end, 398 | {description = "open a terminal", group = "launcher"}), 399 | awful.key({ modkey, "Control" }, "r", awesome.restart, 400 | {description = "reload awesome", group = "awesome"}), 401 | awful.key({ modkey, "Shift" }, "q", awesome.quit, 402 | {description = "quit awesome", group = "awesome"}), 403 | 404 | awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end, 405 | {description = "increase master width factor", group = "layout"}), 406 | awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end, 407 | {description = "decrease master width factor", group = "layout"}), 408 | awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1, nil, true) end, 409 | {description = "increase the number of master clients", group = "layout"}), 410 | awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1, nil, true) end, 411 | {description = "decrease the number of master clients", group = "layout"}), 412 | awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1, nil, true) end, 413 | {description = "increase the number of columns", group = "layout"}), 414 | awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1, nil, true) end, 415 | {description = "decrease the number of columns", group = "layout"}), 416 | awful.key({ modkey, }, "space", function () awful.layout.inc( 1) end, 417 | {description = "select next", group = "layout"}), 418 | awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(-1) end, 419 | {description = "select previous", group = "layout"}), 420 | 421 | awful.key({ modkey, "Control" }, "n", 422 | function () 423 | local c = awful.client.restore() 424 | -- Focus restored client 425 | if c then 426 | client.focus = c 427 | c:raise() 428 | end 429 | end, 430 | {description = "restore minimized", group = "client"}), 431 | 432 | -- Prompt 433 | awful.key({ modkey }, "r", function () awful.screen.focused().mypromptbox:run() end, 434 | {description = "run prompt", group = "launcher"}), 435 | 436 | awful.key({ modkey }, "d", function () awful.util.spawn('${cfg.launcher}') end, {description = "open launcher", group = "launcher"}), 437 | awful.key({ modkey }, "w", function () awful.util.spawn('${cfg.windowSwitcher}') end, {description = "open window selecter", group = "launcher"}), 438 | awful.key({ modkey, "Shift" }, "e", function () awful.util.spawn('${cfg.emojiPicker}') end, {description = "open emoji picker", group = "launcher"}), 439 | 440 | awful.key({ modkey }, "y", function () awful.util.spawn('${cfg.lockCommand}') end, {description = "lock screen", group = "client" }), 441 | awful.key({ modkey }, "b", function () awful.util.spawn('${flameshot} gui') end, {description = "create screenshot", group = "client" }), 442 | 443 | awful.key({ modkey }, "x", 444 | function () 445 | awful.prompt.run { 446 | prompt = "Run Lua code: ", 447 | textbox = awful.screen.focused().mypromptbox.widget, 448 | exe_callback = awful.util.eval, 449 | history_path = awful.util.get_cache_dir() .. "/history_eval" 450 | } 451 | end, 452 | {description = "lua execute prompt", group = "awesome"}), 453 | -- Menubar 454 | awful.key({ modkey }, "p", function() menubar.show() end, 455 | {description = "show the menubar", group = "launcher"}) 456 | 457 | ${lib.optionalString config.services.playerctld.enable ",${mediaKeys}"} 458 | ) 459 | 460 | clientkeys = gears.table.join( 461 | awful.key({ modkey, }, "f", 462 | function (c) 463 | c.fullscreen = not c.fullscreen 464 | c:raise() 465 | end, 466 | {description = "toggle fullscreen", group = "client"}), 467 | awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end, 468 | {description = "close", group = "client"}), 469 | awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle , 470 | {description = "toggle floating", group = "client"}), 471 | awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end, 472 | {description = "move to master", group = "client"}), 473 | awful.key({ modkey, }, "o", function (c) c:move_to_screen() end, 474 | {description = "move to screen", group = "client"}), 475 | awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end, 476 | {description = "toggle keep on top", group = "client"}), 477 | awful.key({ modkey, }, "n", 478 | function (c) 479 | -- The client currently has the input focus, so it cannot be 480 | -- minimized, since minimized clients can't have the focus. 481 | c.minimized = true 482 | end , 483 | {description = "minimize", group = "client"}), 484 | awful.key({ modkey, }, "m", 485 | function (c) 486 | c.maximized = not c.maximized 487 | c:raise() 488 | end , 489 | {description = "(un)maximize", group = "client"}), 490 | awful.key({ modkey, "Control" }, "m", 491 | function (c) 492 | c.maximized_vertical = not c.maximized_vertical 493 | c:raise() 494 | end , 495 | {description = "(un)maximize vertically", group = "client"}), 496 | awful.key({ modkey, "Shift" }, "m", 497 | function (c) 498 | c.maximized_horizontal = not c.maximized_horizontal 499 | c:raise() 500 | end , 501 | {description = "(un)maximize horizontally", group = "client"}) 502 | ) 503 | 504 | -- Bind all key numbers to tags. 505 | -- Be careful: we use keycodes to make it work on any keyboard layout. 506 | -- This should map on the top row of your keyboard, usually 1 to 9. 507 | for i = 1, 9 do 508 | globalkeys = gears.table.join( 509 | globalkeys, 510 | -- View tag only. 511 | awful.key({ modkey }, "#" .. i + 9, 512 | function () 513 | local screen = awful.screen.focused() 514 | local tag = screen.tags[i] 515 | if tag then 516 | tag:view_only() 517 | end 518 | end, 519 | {description = "view tag #"..i, group = "tag"}), 520 | -- Toggle tag display. 521 | awful.key({ modkey, "Control" }, "#" .. i + 9, 522 | function () 523 | local screen = awful.screen.focused() 524 | local tag = screen.tags[i] 525 | if tag then 526 | awful.tag.viewtoggle(tag) 527 | end 528 | end, 529 | {description = "toggle tag #" .. i, group = "tag"}), 530 | -- Move client to tag. 531 | awful.key({ modkey, "Shift" }, "#" .. i + 9, 532 | function () 533 | if client.focus then 534 | local tag = client.focus.screen.tags[i] 535 | if tag then 536 | client.focus:move_to_tag(tag) 537 | end 538 | end 539 | end, 540 | {description = "move focused client to tag #"..i, group = "tag"}), 541 | -- Toggle tag on focused client. 542 | awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9, 543 | function () 544 | if client.focus then 545 | local tag = client.focus.screen.tags[i] 546 | if tag then 547 | client.focus:toggle_tag(tag) 548 | end 549 | end 550 | end, 551 | {description = "toggle focused client on tag #" .. i, group = "tag"}) 552 | ) 553 | end 554 | 555 | clientbuttons = gears.table.join( 556 | awful.button({ }, 1, function (c) client.focus = c; c:raise() end), 557 | awful.button({ modkey }, 1, awful.mouse.client.move), 558 | awful.button({ modkey }, 3, awful.mouse.client.resize)) 559 | 560 | -- Set keys 561 | root.keys(globalkeys) 562 | -- }}} 563 | 564 | -- {{{ Rules 565 | -- Rules to apply to new clients (through the "manage" signal). 566 | awful.rules.rules = { 567 | -- All clients will match this rule. 568 | { rule = { }, 569 | properties = { 570 | border_width = beautiful.border_width, 571 | border_color = beautiful.border_normal, 572 | focus = awful.client.focus.filter, 573 | raise = true, 574 | keys = clientkeys, 575 | buttons = clientbuttons, 576 | screen = awful.screen.preferred, 577 | placement = awful.placement.no_overlap+awful.placement.no_offscreen 578 | } 579 | }, 580 | 581 | -- Floating clients. 582 | { 583 | rule_any = { 584 | instance = { 585 | "DTA", -- Firefox addon DownThemAll. 586 | "copyq", -- Includes session name in class. 587 | }, 588 | class = { 589 | "Arandr", 590 | "Gpick", 591 | "Kruler", 592 | "MessageWin", -- kalarm. 593 | "Sxiv", 594 | "Wpa_gui", 595 | "pinentry", 596 | "veromix", 597 | "xtightvncviewer" 598 | }, 599 | name = { 600 | "Event Tester", -- xev. 601 | }, 602 | role = { 603 | "AlarmWindow", -- Thunderbird's calendar. 604 | "pop-up", -- e.g. Google Chrome's (detached) Developer Tools. 605 | } 606 | }, properties = { floating = true }}, 607 | 608 | -- Add titlebars to normal clients and dialogs 609 | { rule_any = { 610 | type = { "normal", "dialog" } 611 | }, properties = { titlebars_enabled = true } 612 | }, 613 | 614 | -- Set Firefox to always map on the tag named "2" on screen 1. 615 | -- { rule = { class = "Firefox" }, 616 | -- properties = { screen = 1, tag = "2" } }, 617 | } 618 | -- }}} 619 | 620 | -- {{{ Signals 621 | -- Signal function to execute when a new client appears. 622 | client.connect_signal( 623 | "manage", function (c) 624 | -- Set the windows at the slave, 625 | -- i.e. put it at the end of others instead of setting it master. 626 | -- if not awesome.startup then awful.client.setslave(c) end 627 | 628 | if awesome.startup and 629 | not c.size_hints.user_position 630 | and not c.size_hints.program_position then 631 | -- Prevent clients from being unreachable after screen count changes. 632 | awful.placement.no_offscreen(c) 633 | end 634 | end) 635 | 636 | -- Add a titlebar if titlebars_enabled is set to true in the rules. 637 | client.connect_signal( 638 | "request::titlebars", function(c) 639 | -- buttons for the titlebar 640 | local buttons = gears.table.join( 641 | awful.button({ }, 1, function() 642 | client.focus = c 643 | c:raise() 644 | awful.mouse.client.move(c) 645 | end), 646 | awful.button({ }, 3, function() 647 | client.focus = c 648 | c:raise() 649 | awful.mouse.client.resize(c) 650 | end) 651 | ) 652 | 653 | awful.titlebar(c) : setup { 654 | { -- Left 655 | awful.titlebar.widget.iconwidget(c), 656 | buttons = buttons, 657 | layout = wibox.layout.fixed.horizontal 658 | }, 659 | { -- Middle 660 | { -- Title 661 | align = "center", 662 | widget = awful.titlebar.widget.titlewidget(c) 663 | }, 664 | buttons = buttons, 665 | layout = wibox.layout.flex.horizontal 666 | }, 667 | { -- Right 668 | awful.titlebar.widget.floatingbutton (c), 669 | awful.titlebar.widget.maximizedbutton(c), 670 | awful.titlebar.widget.stickybutton (c), 671 | awful.titlebar.widget.ontopbutton (c), 672 | awful.titlebar.widget.closebutton (c), 673 | layout = wibox.layout.fixed.horizontal() 674 | }, 675 | layout = wibox.layout.align.horizontal 676 | } 677 | end) 678 | 679 | -- Enable sloppy focus, so that focus follows mouse. 680 | client.connect_signal( 681 | "mouse::enter", function(c) 682 | if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier 683 | and awful.client.focus.filter(c) then 684 | client.focus = c 685 | end 686 | end) 687 | 688 | client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end) 689 | client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end) 690 | -- }}} 691 | 692 | ${lib.optionalString (cfg.autostart != []) autostartScript} 693 | ''; 694 | }; 695 | } 696 | -------------------------------------------------------------------------------- /home/modules/misc/home/default.nix: -------------------------------------------------------------------------------- 1 | {self, ...}: { 2 | config, 3 | pkgs, 4 | lib, 5 | ... 6 | }: let 7 | self' = self.packages.${pkgs.system}; 8 | in { 9 | profiles.base.enable = true; 10 | fonts.fontconfig.enable = true; 11 | 12 | systemd.user = { 13 | # sessionVariables = { NIX_PATH = nixPath; }; 14 | }; 15 | 16 | xsession.windowManager.awesome.enable = true; 17 | 18 | home = { 19 | # sessionVariables = { NIX_PATH = nixPath; }; 20 | 21 | packages = let 22 | p = pkgs; 23 | in [ 24 | p.cachix 25 | p.exercism 26 | p.tmate 27 | 28 | # There is a conflict with the ZSH completion plugin, installed by default 29 | # therefore we need to override here 30 | (lib.setPrio 0 p.nixpkgs-review) 31 | 32 | p.fira-code 33 | p.cascadia-code 34 | 35 | p.lefthook 36 | 37 | (p.writeShellScriptBin "timew" '' 38 | export TIMEWARRIORDB="${config.home.homeDirectory}/timmelzer@gmail.com/timewarrior" 39 | exec ${p.timewarrior}/bin/timew "$@" 40 | '') 41 | ]; 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /home/modules/misc/rofi/common.rasi: -------------------------------------------------------------------------------- 1 | configuration { 2 | font: "Departure Mono 22"; 3 | terminal: "@TERMINAL@"; 4 | fixed-num-lines: false; 5 | show-icons: true; 6 | drun-show-actions: false; 7 | sidebar-mode: true; 8 | window-format: "{w}\t| {c}\t| {t}"; 9 | 10 | location: 2; 11 | width: 75; 12 | yoffset: 0; 13 | 14 | timeout { 15 | action: "kb-cancel"; 16 | delay: 0; 17 | } 18 | filebrowser { 19 | directories-first: true; 20 | sorting-method: "name"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /home/modules/misc/rofi/default.nix: -------------------------------------------------------------------------------- 1 | {self, ...}: { 2 | pkgs, 3 | lib, 4 | npins, 5 | ... 6 | }: let 7 | self' = self.packages.x86_64-linux; 8 | 9 | common_rasi = pkgs.runCommandNoCC "common.rasi" {preferLocalBuild = true;} '' 10 | substitute ${./common.rasi} $out \ 11 | --subst-var-by TERMINAL ${lib.getExe pkgs.wezterm} 12 | ''; 13 | 14 | catppuccin = pkgs.runCommandNoCC "catppuccin.rasi" {preferLocalBuild = true;} '' 15 | substitute ${npins.catppuccin-rofi}/catppuccin-default.rasi $out \ 16 | --replace-fail '"catppuccin-mocha"' '"${npins.catppuccin-rofi}/themes/catppuccin-mocha.rasi"' 17 | ''; 18 | 19 | writeConfig = name: body: 20 | pkgs.writeText name 21 | # rasi 22 | '' 23 | configuration { 24 | ${body} 25 | } 26 | @theme "${catppuccin}" 27 | @import "${common_rasi}" 28 | ''; 29 | 30 | windowSwitcherConfig = writeConfig "window-switcher-config" ''modes: "window";''; 31 | emojiConfig = writeConfig "emoji-config" ''modes: "emoji#unicode:${self'."rofi/unicode"}/bin/rofiunicode.sh";''; 32 | launcherConfig = writeConfig "launcher-config" '' 33 | modes: "drun#run#ssh"; 34 | ssh-command: "{terminal} ssh {host}"; 35 | ''; 36 | 37 | wrapper = rofi: config: 38 | pkgs.callPackage ({ 39 | rofi, 40 | runCommandNoCC, 41 | makeWrapper, 42 | }: 43 | runCommandNoCC "rofi" { 44 | nativeBuildInputs = [makeWrapper]; 45 | inherit (rofi) meta; 46 | } '' 47 | mkdir -p $out/bin 48 | makeWrapper ${lib.getExe rofi} $out/bin/rofi \ 49 | --add-flags "-config ${config}" 50 | '') {inherit rofi;}; 51 | 52 | launcherPkg = pkgs.rofi; 53 | windowSwitcherPkg = pkgs.rofi; 54 | emojiPkg = pkgs.rofi.override {plugins = [pkgs.rofi-emoji];}; 55 | 56 | launcher = wrapper launcherPkg launcherConfig; 57 | windowSwitcher = wrapper windowSwitcherPkg windowSwitcherConfig; 58 | emoji = wrapper emojiPkg emojiConfig; 59 | in { 60 | xsession.windowManager.awesome.launcher = "${lib.getExe launcher} -show drun"; 61 | xsession.windowManager.awesome.windowSwitcher = "${lib.getExe windowSwitcher} -show window"; 62 | xsession.windowManager.awesome.emojiPicker = "${lib.getExe emoji} -show emoji"; 63 | } 64 | -------------------------------------------------------------------------------- /home/modules/profiles/base/colums-fix.patch: -------------------------------------------------------------------------------- 1 | --- a/fzf-tab.zsh 2 | +++ b/fzf-tab.zsh 3 | @@ -102,7 +102,7 @@ builtin unalias -m '[^+]*' 4 | 5 | # must run with user options; don't move `emulate -L zsh` above this line 6 | (( $+builtins[fzf-tab-compcap-generate] )) && fzf-tab-compcap-generate -i 7 | - COLUMNS=500 _ftb__main_complete "$@" || ret=$? 8 | + _ftb__main_complete "$@" || ret=$? 9 | (( $+builtins[fzf-tab-compcap-generate] )) && fzf-tab-compcap-generate -o 10 | 11 | emulate -L zsh -o extended_glob 12 | -------------------------------------------------------------------------------- /home/modules/profiles/base/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | self, 3 | nix, 4 | nvim, 5 | nix-gl, 6 | ... 7 | }: { 8 | config, 9 | lib, 10 | pkgs, 11 | npins, 12 | ... 13 | }: let 14 | cfg = config.profiles.base; 15 | 16 | inherit (lib.hm) dag; 17 | 18 | # TODO: make these a bit more nice, so that repeating the hosts and individual config isn't necessary. 19 | zerotierHosts = ["delly-nixos.adoring_suess.zerotier" "tux-nixos.adoring_suess.zerotier" "nixos.adoring_suess.zerotier"]; 20 | 21 | zsh-complete = pkgs.stdenv.mkDerivation { 22 | pname = "nix-zsh-completion-with-flakes"; 23 | version = "git"; 24 | 25 | src = ./nix-completions.sh; 26 | 27 | phases = ["installPhase"]; 28 | 29 | installPhase = '' 30 | mkdir -p $out 31 | cp $src $out/_nix 32 | ''; 33 | }; 34 | 35 | fzf-tab = pkgs.stdenv.mkDerivation { 36 | pname = "fzf-tab"; 37 | version = "0-unstable-${npins.fzf-tab.revision}"; 38 | 39 | src = npins.fzf-tab; 40 | 41 | # we need this patch due to a bug between fzf-tab and p10k: 42 | # https://github.com/Aloxaf/fzf-tab/issues/176 43 | patches = [./colums-fix.patch]; 44 | 45 | installPhase = '' 46 | mkdir -p $out 47 | cp -rv . $out 48 | ''; 49 | }; 50 | in { 51 | options.profiles.base = { 52 | enable = lib.mkEnableOption "The base profile, should be always enabled"; 53 | 54 | needsGL = lib.mkEnableOption "nix-gl wrappers"; 55 | }; 56 | 57 | config = lib.mkIf cfg.enable { 58 | sops.secrets.nix-community = { 59 | path = "${config.home.homeDirectory}/.ssh/nix-community"; 60 | mode = "0400"; 61 | sopsFile = "${self}/secrets/users/nmelzer/nix-community"; 62 | format = "binary"; 63 | }; 64 | 65 | programs.rbw.enable = true; 66 | 67 | manual.manpages.enable = false; 68 | 69 | services.vscode-server.enable = lib.mkDefault pkgs.stdenv.isLinux; 70 | 71 | home.sessionVariables = { 72 | EDITOR = "nvim"; 73 | }; 74 | 75 | gtk.enable = true; 76 | gtk.theme.package = pkgs.gnome-themes-extra; 77 | gtk.theme.name = "Adwaita-dark"; 78 | 79 | services.pueue.enable = true; 80 | 81 | home.keyboard.layout = "de"; 82 | home.packages = let 83 | optisave = 84 | pkgs.resholve.writeScriptBin "optisave" { 85 | inputs = builtins.attrValues {inherit (pkgs) fd pv gawk coreutils gnused;}; 86 | interpreter = "${pkgs.bash}/bin/bash"; 87 | execer = [ 88 | # TODO: Make this `might` or `can` in the long run 89 | "cannot:${pkgs.fd}/bin/fd" 90 | ]; 91 | } '' 92 | count=$(fd . /nix/store/.links/ | pv -l | wc -l) 93 | 94 | # TODO: make resholve understant the call to `stat` 95 | saved=$(fd . /nix/store/.links/ -X ${pkgs.coreutils}/bin/stat --format='%h %s' {} \ 96 | | pv -altrpe -s $count \ 97 | | awk '{sum += ($1 - 2) * $2} END {print sum}') 98 | 99 | printf "Currently hardlinking saves %sB (%s B)\n" \ 100 | "$(numfmt --to=iec-i --format='%.2f' ''${saved} \ 101 | | sed -E 's/([0-9])([A-Za-z])/\1 \2/')" \ 102 | "$(numfmt --to=none --format="%'f" ''${saved})" 103 | ''; 104 | neovide = 105 | if cfg.needsGL 106 | then 107 | pkgs.writeShellScriptBin nvim.packages.x86_64-linux.neovide.meta.mainProgram '' 108 | exec ${lib.getExe nix-gl.packages.x86_64-linux.nixGLIntel} ${lib.getExe nvim.packages.x86_64-linux.neovide} "$@" 109 | '' 110 | else nvim.packages.x86_64-linux.neovide; 111 | in 112 | lib.mkMerge [ 113 | [optisave pkgs.departure-mono pkgs.hydra-check nvim.packages.x86_64-linux.neovim neovide] 114 | (lib.mkIf pkgs.stdenv.isLinux [pkgs.dconf]) 115 | ]; 116 | 117 | # dconf.enable = lib.mkMerge [ 118 | # (lib.mkIf pkgs.stdenv.isLinux true) 119 | # (lib.mkIf pkgs.stdenv.isDarwin false) 120 | # ]; 121 | 122 | xsession = { 123 | enable = true; 124 | numlock.enable = true; 125 | profileExtra = '' 126 | setxkbmap de 127 | ''; 128 | }; 129 | 130 | programs = { 131 | advancedCopy.enable = true; 132 | direnv.enable = true; 133 | direnv.nix-direnv.enable = true; 134 | direnv.nix-direnv.package = pkgs.nix-direnv.override {nix = nix.packages.${pkgs.system}.default;}; 135 | eza.enable = true; 136 | fzf.enable = true; 137 | home-manager.enable = true; 138 | htop.enable = true; 139 | jq.enable = true; 140 | p10k.enable = true; 141 | zoxide.enable = true; 142 | 143 | bat = { 144 | enable = true; 145 | 146 | config.theme = "mocha"; 147 | 148 | themes.mocha = { 149 | src = npins.catppuccin-bat; 150 | file = "themes/Catppuccin Mocha.tmTheme"; 151 | }; 152 | }; 153 | 154 | ssh = { 155 | enable = true; 156 | compression = true; 157 | controlMaster = "auto"; 158 | 159 | matchBlocks = { 160 | "*.internal.nobbz.dev" = dag.entryAfter zerotierHosts { 161 | identityFile = "~/.ssh/id_rsa"; 162 | user = "nmelzer"; 163 | }; 164 | 165 | "build-box.nix-community.org" = { 166 | identityFile = config.sops.secrets.nix-community.path; 167 | user = "nobbz"; 168 | }; 169 | 170 | "aarch64-build-box.nix-community.org" = { 171 | identityFile = config.sops.secrets.nix-community.path; 172 | user = "nobbz"; 173 | }; 174 | 175 | "ryzen-ubuntu.adoring_suess.zerotier" = { 176 | hostname = "172.24.237.73"; 177 | }; 178 | "mimas.internal.nobbz.dev" = { 179 | localForwards = [ 180 | { 181 | bind.port = 60080; 182 | host.address = "fritz.box"; 183 | host.port = 80; 184 | } 185 | ]; 186 | }; 187 | 188 | "*.nobbz.dev" = { 189 | identityFile = "~/.ssh/nobbz_dev"; 190 | user = "root"; 191 | }; 192 | 193 | "gitlab.com" = { 194 | addressFamily = "inet"; 195 | identityFile = "~/.ssh/gitlab"; 196 | }; 197 | 198 | "github.com" = { 199 | identityFile = "~/.ssh/github"; 200 | }; 201 | }; 202 | }; 203 | 204 | tmux = { 205 | enable = true; 206 | 207 | clock24 = true; 208 | historyLimit = 10000; 209 | terminal = "tmux-256color"; 210 | 211 | plugins = [ 212 | { 213 | plugin = pkgs.tmuxPlugins.catppuccin; 214 | extraConfig = '' 215 | set -g @catppuccin_flavor "mocha" 216 | set -g @catppuccin_window_status_style "rounded" 217 | ''; 218 | } 219 | ]; 220 | 221 | extraConfig = '' 222 | set -ag terminal-overrides ",xterm-256color:RGB" 223 | ''; 224 | }; 225 | 226 | zsh = { 227 | enable = true; 228 | 229 | enableCompletion = true; 230 | autosuggestion.enable = true; 231 | 232 | autocd = true; 233 | 234 | dotDir = ".config/zsh"; 235 | 236 | defaultKeymap = "emacs"; 237 | 238 | plugins = [ 239 | { 240 | name = "fzf-tab"; 241 | src = fzf-tab; 242 | } 243 | { 244 | name = "nix-zsh-complete.zsh"; 245 | src = zsh-complete; 246 | file = "_nix"; 247 | } 248 | { 249 | name = "zsh-syntax-highlighting"; 250 | src = npins.zsh-syntax-highlighting; 251 | } 252 | ]; 253 | 254 | initContent = '' 255 | bindkey "^[[1;5D" backward-word 256 | bindkey "^[[1;5C" forward-word 257 | 258 | ZSH_AUTOSUGGEST_STRATEGY=(completion history) 259 | ''; 260 | 261 | sessionVariables = { 262 | PROMPT_EOL_MARK = "%F{243}¶%f"; 263 | }; 264 | 265 | shellAliases.fixstore = "sudo nix-store --verify --check-contents --repair"; 266 | shellAliases.pq = "pueue"; 267 | }; 268 | }; 269 | }; 270 | } 271 | -------------------------------------------------------------------------------- /home/modules/profiles/base/nix-completions.sh: -------------------------------------------------------------------------------- 1 | 2 | function _nix() { 3 | local ifs_bk="$IFS" 4 | local input=("${(Q)words[@]}") 5 | IFS=$'\n' 6 | local res=($(NIX_GET_COMPLETIONS=$((CURRENT - 1)) "$input[@]")) 7 | IFS="$ifs_bk" 8 | local tpe="${${res[1]}%%> *}" 9 | local -a suggestions 10 | declare -a suggestions 11 | for suggestion in ${res:1}; do 12 | # FIXME: This doesn't work properly if the suggestion word contains a `:` 13 | # itself 14 | suggestions+="${suggestion/ /:}" 15 | done 16 | if [[ "$tpe" == filenames ]]; then 17 | compadd -f 18 | fi 19 | _describe 'nix' suggestions 20 | } 21 | 22 | compdef _nix nix 23 | -------------------------------------------------------------------------------- /home/modules/profiles/browsing/default.nix: -------------------------------------------------------------------------------- 1 | {self, ...}: { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: let 7 | cfg = config.profiles.browsing; 8 | in { 9 | options.profiles.browsing = { 10 | enable = 11 | lib.mkEnableOption 12 | "A profile that enables a browser for the GUI and the terminal"; 13 | }; 14 | 15 | config = lib.mkIf cfg.enable { 16 | nixpkgs.config = {google-chrome = {enableWideVine = true;};}; 17 | home.packages = with pkgs; [self.packages.${pkgs.system}.google-chrome lynx]; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /home/modules/profiles/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | config, 3 | lib, 4 | ... 5 | }: let 6 | profileEnabler = let 7 | reducer = l: r: {"${r}".enable = true;} // l; 8 | in 9 | builtins.foldl' reducer {} config.activeProfiles; 10 | in { 11 | options.activeProfiles = lib.mkOption { 12 | type = lib.types.listOf lib.types.str; 13 | default = []; 14 | }; 15 | 16 | config.profiles = profileEnabler; 17 | } 18 | -------------------------------------------------------------------------------- /home/modules/profiles/development/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | config, 3 | pkgs, 4 | lib, 5 | ... 6 | }: let 7 | cfg = config.profiles.development; 8 | in { 9 | options.profiles.development = { 10 | enable = 11 | lib.mkEnableOption 12 | "A profile that enables the system to be used for developing programs"; 13 | }; 14 | 15 | config = lib.mkIf cfg.enable { 16 | programs.jujutsu = { 17 | enable = true; 18 | settings = { 19 | user = { 20 | name = config.programs.git.userName; 21 | email = config.programs.git.userEmail; 22 | }; 23 | 24 | ui.diff.tool = [config.programs.git.extraConfig.diff.external "$left" "$right"]; 25 | }; 26 | }; 27 | 28 | programs.gh.enable = true; 29 | programs.git = { 30 | enable = true; 31 | 32 | userName = "Norbert Melzer"; 33 | userEmail = "timmelzer@gmail.com"; 34 | 35 | aliases = let 36 | mkFixupAlias = command: 37 | pkgs.resholve.writeScript "git-${command}" { 38 | inputs = builtins.attrValues {inherit (pkgs) git fzf ripgrep;}; 39 | interpreter = "${pkgs.bash}/bin/bash"; 40 | execer = ["cannot:${pkgs.git}/bin/git" "cannot:${pkgs.fzf}/bin/fzf"]; 41 | } 42 | # bash 43 | '' 44 | git log --graph --color=always --format="%C(auto)%h%d %s0x09%C(white)%C(bold)%cr" "$@" | 45 | fzf --ansi --no-sort --reverse --tiebreak=index \ 46 | --bind=ctrl-s:toggle-sort \ 47 | --bind="ctrl-m:execute:(rg -o '\b[a-f0-9]{6,}\b' | head -1 | xargs -I% sh -c 'git commit --${command}=% | less -R') </dev/null; then 67 | echo "commit" 68 | else 69 | echo "unknown" 70 | fi 71 | } 72 | 73 | # Function to select a ref using fzf 74 | function select_ref_with_fzf() { 75 | cat <(git branch --format='%(refname:short) [branch]') \ 76 | <(git tag --format='%(refname:short) [tag]') \ 77 | <(git log --pretty=format:'%h %s [commit]') \ 78 | | fzf 79 | } 80 | 81 | # If the first argument is -c or -C, forward the arguments as-is to git switch 82 | if [ "$#" -ge 2 ] && ([[ "$1" == "-c" ]] || [[ "$1" == "-C" ]]); then 83 | git switch "$@" 84 | else 85 | # If an argument is provided and it's not -c or -C, switch to the specified ref 86 | if [ "$#" -eq 1 ]; then 87 | ref_name="$1" 88 | ref_type=$(get_ref_type "$ref_name") 89 | 90 | if [ "$ref_type" == "unknown" ]; then 91 | echo "Invalid ref: $ref_name" >&2 92 | exit 1 93 | fi 94 | else 95 | # If no argument or only -c/-C is provided, use the fzf selection interface to select a ref 96 | selected_ref=$(select_ref_with_fzf) 97 | 98 | # Extract the ref name and type from the selected_ref string 99 | ref_name=$(echo "$selected_ref" | awk '{print $1}') 100 | ref_type=$(echo "$selected_ref" | awk '{print $NF}' | tr -d '[]') 101 | fi 102 | 103 | # Based on the ref type, issue the appropriate git switch command 104 | case "$ref_type" in 105 | branch) 106 | git switch "$ref_name" 107 | ;; 108 | tag) 109 | git switch --detach "$ref_name" 110 | ;; 111 | commit) 112 | git switch --detach "$ref_name" 113 | ;; 114 | *) 115 | # If an invalid ref type is encountered, print an error message and exit 116 | echo "Invalid ref type: $ref_type" >&2 117 | exit 1 118 | ;; 119 | esac 120 | fi 121 | ''; 122 | in { 123 | br = "branch"; 124 | co = "checkout"; 125 | vommit = "commit"; 126 | vomit = "commit"; 127 | graph = "log --graph --abbrev-commit --decorate --date=relative --format=format:'%C(bold cyan)%h%C(reset) - %C(green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n %C(white)%s%C(reset) %C(dim white)- %an%C(reset)' --all"; 128 | pl = "pull"; 129 | ps = "push"; 130 | psf = "push --force-with-lease"; 131 | root = "rev-parse --show-toplevel"; 132 | st = "status"; 133 | sw = "!${gitSwitchFzf}"; 134 | swag = ''!f() { if [ -z "$1" ]; then tag=$(git describe --abbrev=0 --tag); else tag=$(git describe --abbrev=0 --tag "$1"); fi; git switch --detach "''${tag}"; }; f''; 135 | hopbase = ''!f() { set -o nounset; tag=$(git describe --abbrev=0 --tag "$1") && git rebase -i "''${tag}"; }; f''; 136 | comfix = "!${mkFixupAlias "fixup"}"; 137 | comreb = "!${mkFixupAlias "rebase"}"; 138 | show = "show --ext-diff"; 139 | lp = "log -p --ext-diff"; 140 | }; 141 | 142 | extraConfig = { 143 | init.defaultBranch = "main"; 144 | diff.external = lib.getExe pkgs.difftastic; 145 | pull.rebase = false; 146 | rerere.enabled = true; 147 | }; 148 | 149 | ignores = [ 150 | # IntelliJ files and folders 151 | ".idea/" 152 | "*.iml" 153 | # backupfiles and shadow copies done by editors 154 | "*~" 155 | "\\#*\\#" 156 | ".#*" 157 | # Elixir language server 158 | "/.elixir_ls" 159 | # MyPy Cache 160 | ".mypy_cache" 161 | # Visual Studio Code project configuration 162 | "/.vscode" 163 | # Result folder for nix builds 164 | "result" 165 | "result-*" 166 | # direnv caches 167 | ".direnv/" 168 | # emacs/python stuff 169 | "flycheck_*.py" 170 | ]; 171 | 172 | includes = [ 173 | { 174 | condition = "gitdir:~/cloudseeds/**"; 175 | contents = { 176 | init.defaultBranch = "master"; 177 | user.email = "norbert.melzer@cloudseeds.de"; 178 | }; 179 | } 180 | { 181 | condition = "gitdir:~/Projects/BravoBike/**"; 182 | contents = { 183 | user.email = "norbert.melzer@bravobike.de"; 184 | }; 185 | } 186 | ]; 187 | }; 188 | 189 | home.packages = [pkgs.ripgrep pkgs.difftastic]; 190 | }; 191 | } 192 | -------------------------------------------------------------------------------- /home/modules/programs/advcp/default.nix: -------------------------------------------------------------------------------- 1 | {self, ...}: { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: let 7 | cfg = config.programs.advancedCopy; 8 | in { 9 | options.programs.advancedCopy = { 10 | enable = lib.mkEnableOption "CP and MV with a progressbar"; 11 | }; 12 | 13 | config = lib.mkIf cfg.enable { 14 | home.packages = [self.packages.${pkgs.system}.advcp]; 15 | 16 | programs.zsh.shellAliases = { 17 | cp = "advcp -g"; 18 | mv = "advmv -g"; 19 | }; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /home/modules/programs/eza/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: let 7 | cfg = config.programs.eza; 8 | in { 9 | config = lib.mkIf cfg.enable { 10 | programs.eza.package = pkgs.eza; 11 | programs.zsh.shellAliases = { 12 | ll = "eza --header --git --classify --long --binary --group --time-style=long-iso --links --all --all --group-directories-first --sort=name"; 13 | tree = "eza --tree"; 14 | }; 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /home/modules/programs/ghostty/default.nix: -------------------------------------------------------------------------------- 1 | _: {pkgs, ...}: { 2 | xdg.configFile."ghostty/config".text = 3 | # toml 4 | '' 5 | font-family = "Departure Mono" 6 | 7 | ## uncomment once keybindings have been set to something I am familiar 8 | ## with. The bar contains the menu, which I need for splits for now… 9 | # gtk-titlebar = false 10 | 11 | theme = "catppuccin-mocha" 12 | ''; 13 | 14 | home.packages = [pkgs.ghostty]; 15 | } 16 | -------------------------------------------------------------------------------- /home/modules/programs/nixpkgs/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | config, 3 | lib, 4 | ... 5 | }: let 6 | allowed = config.nixpkgs.allowedUnfree; 7 | in { 8 | options.nixpkgs.allowedUnfree = lib.mkOption { 9 | type = lib.types.listOf lib.types.str; 10 | default = []; 11 | description = '' 12 | Allows for unfree packages by their name. 13 | ''; 14 | }; 15 | 16 | config.nixpkgs.config.allowUnfreePredicate = 17 | if (allowed == []) 18 | then (_: false) 19 | else (pkg: builtins.elem (lib.getName pkg) allowed); 20 | } 21 | -------------------------------------------------------------------------------- /home/modules/programs/p10k/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | pkgs, 3 | lib, 4 | config, 5 | ... 6 | }: let 7 | cfg = config.programs.p10k; 8 | zsh = config.programs.zsh.enable; 9 | in { 10 | options = { 11 | programs.p10k.enable = lib.mkEnableOption "p10k"; 12 | }; 13 | 14 | config = lib.mkIf (cfg.enable && zsh) { 15 | programs.zsh.plugins = [ 16 | { 17 | name = "powerlevel10k"; 18 | src = pkgs.zsh-powerlevel10k; 19 | file = "share/zsh-powerlevel10k/powerlevel10k.zsh-theme"; 20 | } 21 | { 22 | name = "powerlevel10k-config"; 23 | src = ./p10k-config; 24 | file = "p10k.zsh"; 25 | } 26 | ]; 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /home/modules/programs/rbw/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: let 7 | cfg = config.programs.rbw; 8 | in { 9 | config = lib.mkIf cfg.enable { 10 | programs.rbw.settings = { 11 | inherit (pkgs) pinentry; 12 | 13 | email = "timmelzer@gmail.com"; 14 | base_url = "https://passwords.mimas.internal.nobbz.dev"; 15 | }; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /home/modules/programs/wezterm/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | config, 3 | pkgs, 4 | ... 5 | }: { 6 | home.packages = [pkgs.wezterm]; 7 | 8 | xdg.configFile."wezterm/wezterm.lua".text = 9 | # lua 10 | '' 11 | -- Pull in the wezterm API 12 | local wezterm = require 'wezterm' 13 | 14 | -- This table will hold the configuration. 15 | local config = {} 16 | 17 | -- In newer versions of wezterm, use the config_builder which will 18 | -- help provide clearer error messages 19 | if wezterm.config_builder then 20 | config = wezterm.config_builder() 21 | end 22 | 23 | -- This is where you actually apply your config choices 24 | 25 | -- bells 26 | config.audible_bell = "Disabled" 27 | config.visual_bell = { 28 | fade_in_function = "EaseIn", 29 | fade_in_duration_ms = 150, 30 | fade_out_function = "EaseOut", 31 | fade_out_duration_ms = 150, 32 | } 33 | 34 | -- For example, changing the color scheme: 35 | config.color_scheme = "Catppuccin Mocha" 36 | 37 | -- show a scrollbar 38 | config.enable_scroll_bar = true 39 | 40 | -- forbid window size change on change of fontsize 41 | config.adjust_window_size_when_changing_font_size = false 42 | 43 | -- disable ligatures 44 | config.harfbuzz_features = { 'calt=0', 'clig=0', 'liga=0' } 45 | 46 | -- set the font 47 | config.font_dirs = { '${pkgs.departure-mono}/share/fonts/otf' } 48 | config.font_size = 11.0 * 1.25 49 | config.font = wezterm.font("Departure Mono") 50 | 51 | -- setting up keybindings 52 | config.keys = { 53 | -- The default is `C-Z` (so also pressing SHIFT), I prefer to not have SHIFT pressed 54 | { key = 'z', mods = 'CTRL', action = wezterm.action.TogglePaneZoomState, }, 55 | } 56 | 57 | -- and finally, return the configuration to wezterm 58 | return config 59 | ''; 60 | } 61 | -------------------------------------------------------------------------------- /home/modules/services/insync/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | self, 3 | nixpkgs-insync-v3, 4 | ... 5 | }: { 6 | config, 7 | lib, 8 | pkgs, 9 | ... 10 | }: let 11 | cfg = config.services.insync; 12 | in { 13 | options.services.insync = { 14 | enable = lib.mkEnableOption "Insync cloud sync tool"; 15 | 16 | package = lib.mkOption { 17 | type = lib.types.package; 18 | default = let 19 | ipkgs = import nixpkgs-insync-v3 { 20 | inherit (pkgs) system; 21 | inherit (config.nixpkgs) config; 22 | }; 23 | in 24 | ipkgs.insync; 25 | description = '' 26 | The insync package to use. 27 | 28 | It will get automatically added to 'allowedUnfree'. 29 | ''; 30 | }; 31 | }; 32 | 33 | config = lib.mkIf cfg.enable { 34 | nixpkgs.allowedUnfree = ["insync"]; 35 | 36 | home.packages = [cfg.package]; 37 | 38 | systemd.user.services.insync = { 39 | Unit = { 40 | Description = "Insync - Google Drive, OneDrive, and Dropbox Syncing on Linux, Windows & Mac"; 41 | After = ["graphical-session-pre.target"]; 42 | PartOf = ["graphical-session.target"]; 43 | }; 44 | 45 | Install = {WantedBy = ["graphical-session.target"];}; 46 | 47 | Service = { 48 | Type = "simple"; 49 | ExecStart = "${cfg.package}/bin/insync start --no-daemon"; 50 | ExecStop = "${cfg.package}/bin/insync stop"; 51 | Restart = "always"; 52 | RestartSec = "5"; 53 | }; 54 | }; 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /home/modules/services/rustic/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: let 7 | cfg = config.services.rustic; 8 | 9 | bin = lib.getExe cfg.package; 10 | 11 | globs = let lines = map (g: "${g}\n") cfg.globs; in lib.concatStrings lines; 12 | globsFile = pkgs.writeText "globs" globs; 13 | globFlags = lib.optionals (cfg.globs != []) ["--glob-file" globsFile]; 14 | 15 | oneFsFlags = lib.optional cfg.oneFileSystem "-x"; 16 | 17 | flagList = ["--tag" "home"] ++ globFlags ++ oneFsFlags; 18 | flags = lib.concatStringsSep " " flagList; 19 | 20 | command = "${bin} backup ${flags} %h"; 21 | 22 | profileModule = { 23 | name, 24 | config, 25 | ... 26 | }: { 27 | enable = lib.mkEnableOption name // {default = true;}; 28 | 29 | repo = lib.mkOption { 30 | type = lib.types.str; 31 | description = "Location of the repository"; 32 | }; 33 | 34 | globs = lib.mkOption { 35 | type = lib.types.listOf lib.types.str; 36 | default = []; 37 | description = "Patterns to apply to backup. Use a hardcoded prefix for the home directory"; 38 | }; 39 | 40 | oneFileSystem = lib.mkOption { 41 | type = lib.types.bool; 42 | default = false; 43 | description = "If true, exclude other file systems, don't cross filesystem boundaries and subvolumes"; 44 | }; 45 | 46 | passwordFile = lib.mkOption { 47 | type = lib.types.path; 48 | default = "${config.xdg.configHome}/rustic/password"; 49 | description = "Location of the password file"; 50 | }; 51 | 52 | source = lib.mkOption { 53 | type = lib.types.path; 54 | description = "Location of the base directory for the backup.Of "; 55 | }; 56 | 57 | settings = lib.mkOption { 58 | type = lib.types.attrsOf lib.types.any; 59 | description = "A nix representation of the profile settings which gets converted to a TOML file"; 60 | }; 61 | }; 62 | in { 63 | options.services.rustic = { 64 | enable = lib.mkEnableOption "rustic"; 65 | 66 | package = lib.mkOption { 67 | type = lib.types.package; 68 | default = pkgs.rustic-rs; 69 | description = "Rustic derivation to use"; 70 | }; 71 | 72 | globs = lib.mkOption { 73 | type = lib.types.listOf lib.types.str; 74 | default = []; 75 | description = "Patterns to apply to backup. Use `%h` instead of `~`"; 76 | }; 77 | 78 | oneFileSystem = lib.mkOption { 79 | type = lib.types.bool; 80 | default = false; 81 | description = "If true, exclude other file systems, don't cross filesystem boundaries and subvolumes"; 82 | }; 83 | 84 | repo = lib.mkOption { 85 | type = lib.types.str; 86 | description = "Location of the repository"; 87 | }; 88 | 89 | passwordFile = lib.mkOption { 90 | type = lib.types.path; 91 | default = "${config.xdg.configHome}/rustic/password"; 92 | description = "Location of the password file"; 93 | }; 94 | 95 | profile = lib.mkOption { 96 | type = lib.types.attrsOf profileModule; 97 | description = "Specifies the backup profile to use and its settings"; 98 | }; 99 | }; 100 | 101 | config = lib.mkIf cfg.enable { 102 | home.packages = [cfg.package]; 103 | 104 | systemd.user.services.rustic-backup = { 105 | Unit = { 106 | Description = "Rustic Backup Tool"; 107 | StartLimitIntervalSec = "25m"; 108 | StartLimitBurst = "4"; 109 | }; 110 | 111 | Service = { 112 | LoadCredential = [ 113 | "pass:${cfg.passwordFile}" 114 | ]; 115 | Environment = [ 116 | "RUSTIC_PASSWORD_FILE=%d/pass" 117 | "RUSTIC_REPOSITORY=${cfg.repo}" 118 | ]; 119 | Type = "oneshot"; 120 | ExecStart = command; 121 | Restart = "on-failure"; 122 | RestartSec = "2m"; 123 | }; 124 | }; 125 | 126 | systemd.user.timers.rustic-backup = { 127 | Unit.Description = "Rustic periodic backup"; 128 | Install.WantedBy = ["timers.target"]; 129 | Timer = { 130 | Unit = "rustic-backup.service"; 131 | OnCalendar = "hourly"; # TODO: Make configurable! 132 | }; 133 | }; 134 | }; 135 | } 136 | -------------------------------------------------------------------------------- /lefthook.yml: -------------------------------------------------------------------------------- 1 | pre-commit: 2 | parallel: true 3 | commands: 4 | formatting: 5 | glob: "*.nix" 6 | run: nix fmt -- --check {staged_files} 7 | 8 | linting: 9 | glob: "*.nix" 10 | run: nix run --inputs-from . nixpkgs#statix -- check 11 | 12 | statix: 13 | parallel: false 14 | commands: 15 | statix: 16 | glob: "*.nix" 17 | run: statix check -i packages/nodePackages/node-env.nix 18 | -------------------------------------------------------------------------------- /mixed/default.nix: -------------------------------------------------------------------------------- 1 | inputs: { 2 | ipAddresses = import ./ip_addresses.nix inputs; 3 | } 4 | -------------------------------------------------------------------------------- /mixed/ip_addresses.nix: -------------------------------------------------------------------------------- 1 | _: _: { 2 | lib.nobbz = { 3 | enceladeus.v4 = "172.24.199.101"; 4 | enceladeus.v6 = "fcc5:ee64:a023:8429:3ae6:0000:0000:0001"; 5 | 6 | rhea.v4 = "72.24.2.1"; 7 | rhea.v6 = "fcc5:ee64:a0b7:9bb6:2ed8:0000:0000:0001"; 8 | 9 | mimas.v4 = "172.24.152.168"; 10 | mimas.v6 = "fcc5:ee64:a0cd:9c36:c3ff:0000:0000:0001"; 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /nixos/configurations/bootloader/enceladeus.nix: -------------------------------------------------------------------------------- 1 | { 2 | # Use the GRUB 2 boot loader. 3 | boot.loader.grub.enable = true; 4 | boot.loader.grub.useOSProber = false; 5 | 6 | # boot.loader.grub.efiSupport = true; 7 | # boot.loader.grub.efiInstallAsRemovable = true; 8 | # boot.loader.efi.efiSysMountPoint = "/boot/efi"; 9 | # Define on which hard drive you want to install Grub. 10 | boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only 11 | } 12 | -------------------------------------------------------------------------------- /nixos/configurations/bootloader/hyperion.nix: -------------------------------------------------------------------------------- 1 | { 2 | boot.loader.systemd-boot.enable = true; 3 | boot.loader.efi.canTouchEfiVariables = true; 4 | boot.loader.efi.efiSysMountPoint = "/boot/efi"; 5 | } 6 | -------------------------------------------------------------------------------- /nixos/configurations/bootloader/janus.nix: -------------------------------------------------------------------------------- 1 | _: {} 2 | # TODO: Move BL relevant config here! 3 | 4 | -------------------------------------------------------------------------------- /nixos/configurations/bootloader/mimas.nix: -------------------------------------------------------------------------------- 1 | { 2 | boot.loader.systemd-boot.enable = true; 3 | boot.loader.efi.canTouchEfiVariables = true; 4 | } 5 | -------------------------------------------------------------------------------- /nixos/configurations/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | nobbz.nixosConfigurations.mimas.system = "x86_64-linux"; 3 | } 4 | -------------------------------------------------------------------------------- /nixos/configurations/hardware/enceladeus.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | {lib, ...}: { 5 | boot.initrd.availableKernelModules = ["uhci_hcd" "ehci_pci" "ahci" "firewire_ohci" "usbhid" "usb_storage" "sd_mod" "sr_mod" "sdhci_pci"]; 6 | boot.initrd.kernelModules = ["dm-snapshot"]; 7 | boot.kernelModules = ["kvm-intel" "wl"]; 8 | boot.extraModulePackages = []; 9 | boot.supportedFilesystems = ["ntfs-3g"]; 10 | 11 | fileSystems."/" = { 12 | device = "/dev/disk/by-uuid/1be71104-48ad-40c3-bf4c-086cd887969f"; 13 | fsType = "ext4"; 14 | }; 15 | 16 | # fileSystems."/nix/store" = { 17 | # device = "/dev/disk/by-uuid/1ee9d669-07e1-4f40-93af-71f9ad999f70"; 18 | # fsType = "ext4"; 19 | # }; 20 | 21 | fileSystems."/nix/store" = { 22 | device = "/dev/mapper/pool-store--old"; 23 | fsType = "ext4"; 24 | }; 25 | 26 | fileSystems."/home" = { 27 | device = "/dev/disk/by-uuid/53a36eeb-9f0e-4cb6-bdd9-53ae5a74c683"; 28 | fsType = "ext4"; 29 | }; 30 | 31 | fileSystems."/boot" = { 32 | device = "/dev/sda1"; 33 | fsType = "ext4"; 34 | }; 35 | 36 | swapDevices = [{device = "/dev/disk/by-uuid/87c5fea1-6bcb-41d4-af9d-b9342a45c9b3";}]; 37 | 38 | nix.settings.max-jobs = lib.mkDefault 1; 39 | } 40 | -------------------------------------------------------------------------------- /nixos/configurations/hardware/hyperion.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { 5 | lib, 6 | modulesPath, 7 | ... 8 | }: { 9 | imports = [ 10 | (modulesPath + "/profiles/qemu-guest.nix") 11 | ]; 12 | 13 | boot.initrd.availableKernelModules = ["xhci_pci" "virtio_pci" "usbhid" "usb_storage" "sr_mod"]; 14 | boot.initrd.kernelModules = []; 15 | boot.kernelModules = []; 16 | boot.extraModulePackages = []; 17 | 18 | fileSystems."/" = { 19 | device = "/dev/disk/by-uuid/1c2c9f5f-041a-400d-9bfb-7b25639dff4f"; 20 | fsType = "ext4"; 21 | }; 22 | 23 | fileSystems."/boot/efi" = { 24 | device = "/dev/disk/by-uuid/0A83-6143"; 25 | fsType = "vfat"; 26 | }; 27 | 28 | swapDevices = [ 29 | {device = "/dev/disk/by-uuid/d0a59a01-aa79-4ec6-aec0-b299be6c1157";} 30 | ]; 31 | 32 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 33 | # (the default) this is the recommended approach. When using systemd-networkd it's 34 | # still possible to use this option, but it's recommended to use it in conjunction 35 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`. 36 | networking.useDHCP = lib.mkDefault true; 37 | # networking.interfaces.enp0s6.useDHCP = lib.mkDefault true; 38 | 39 | nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux"; 40 | } 41 | -------------------------------------------------------------------------------- /nixos/configurations/hardware/janus.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { 5 | config, 6 | lib, 7 | pkgs, 8 | modulesPath, 9 | ... 10 | }: { 11 | imports = [ 12 | (modulesPath + "/installer/scan/not-detected.nix") 13 | ]; 14 | 15 | boot.initrd.availableKernelModules = ["xhci_pci" "thunderbolt" "nvme" "usb_storage" "sd_mod" "sdhci_pci"]; 16 | boot.initrd.kernelModules = ["dm-snapshot"]; 17 | boot.initrd.luks.devices.cryptroot.device = "/dev/disk/by-partlabel/nixoscrypt"; 18 | boot.kernelModules = ["kvm-intel"]; 19 | boot.extraModulePackages = []; 20 | 21 | fileSystems."/" = { 22 | device = "/dev/mainpool/vdo-root"; 23 | fsType = "xfs"; 24 | }; 25 | 26 | fileSystems."/boot" = { 27 | device = "/dev/nvme0n1p1"; 28 | fsType = "vfat"; 29 | }; 30 | 31 | fileSystems."/nix" = { 32 | device = "/dev/mainpool/vdo-nix"; 33 | fsType = "xfs"; 34 | }; 35 | 36 | fileSystems."/home" = { 37 | device = "/dev/mainpool/vdo-home"; 38 | fsType = "xfs"; 39 | }; 40 | 41 | swapDevices = []; 42 | 43 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 44 | # (the default) this is the recommended approach. When using systemd-networkd it's 45 | # still possible to use this option, but it's recommended to use it in conjunction 46 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`. 47 | networking.useDHCP = lib.mkDefault true; 48 | # networking.interfaces.enp0s31f6.useDHCP = lib.mkDefault true; 49 | # networking.interfaces.enp56s0u1u1.useDHCP = lib.mkDefault true; 50 | # networking.interfaces.wlp0s20f3.useDHCP = lib.mkDefault true; 51 | 52 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 53 | powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; 54 | hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 55 | } 56 | -------------------------------------------------------------------------------- /nixos/configurations/hardware/mimas.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { 5 | lib, 6 | pkgs, 7 | ... 8 | }: { 9 | imports = []; 10 | 11 | boot.initrd.availableKernelModules = ["xhci_pci" "ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "sr_mod" "rtsx_pci_sdmmc"]; 12 | boot.initrd.kernelModules = ["dm-snapshot" "i915"]; 13 | boot.kernelModules = ["kvm-intel"]; 14 | boot.kernelParams = ["intel_pstate=active"]; 15 | boot.extraModulePackages = []; 16 | boot.supportedFilesystems = ["ntfs" "exfat" "avfs" "xfs"]; 17 | 18 | hardware.cpu.intel.updateMicrocode = true; 19 | hardware.enableRedistributableFirmware = true; 20 | 21 | fileSystems."/" = { 22 | device = "/dev/disk/by-uuid/440c8ce1-1799-4239-936f-a54c879941a5"; 23 | fsType = "ext4"; 24 | }; 25 | 26 | fileSystems."/home" = { 27 | device = "/dev/disk/by-uuid/8119ca17-576f-49a2-9496-946d6759a59b"; 28 | fsType = "ext4"; 29 | }; 30 | 31 | fileSystems."/nix" = { 32 | device = "/dev/disk/by-uuid/48574e4d-3a82-4b04-ac28-d55c32fa3aff"; 33 | fsType = "ext4"; 34 | }; 35 | 36 | fileSystems."/var/lib/docker" = { 37 | device = "/dev/pool/docker"; 38 | fsType = "ext4"; 39 | options = ["nofail"]; 40 | }; 41 | 42 | fileSystems."/var/lib/gitea" = { 43 | device = "/dev/pool/gitea"; 44 | fsType = "ext4"; 45 | options = ["nofail"]; 46 | }; 47 | 48 | fileSystems."/var/lib/grafana" = { 49 | device = "/dev/pool/grafana"; 50 | fsType = "ext4"; 51 | options = ["nofail"]; 52 | }; 53 | 54 | fileSystems."/var/lib/prometheus2" = { 55 | device = "/dev/pool/prometheus"; 56 | fsType = "ext4"; 57 | options = ["nofail"]; 58 | }; 59 | 60 | fileSystems."/var/lib/paperless" = { 61 | device = "/dev/pool/paperless"; 62 | fsType = "ext4"; 63 | options = ["nofail"]; 64 | }; 65 | 66 | fileSystems."/var/lib/restic" = { 67 | device = "/dev/usbpool/restic"; 68 | fsType = "ext4"; 69 | options = ["nofail"]; 70 | }; 71 | 72 | fileSystems."/var/lib/ums" = { 73 | device = "/dev/usbpool/ums"; 74 | fsType = "ext4"; 75 | options = ["nofail"]; 76 | }; 77 | 78 | fileSystems."/var/lib/actual" = { 79 | device = "/dev/pool/actual"; 80 | fsType = "xfs"; 81 | options = ["nofail"]; 82 | }; 83 | 84 | fileSystems."/boot" = { 85 | device = "/dev/disk/by-uuid/7000-3A85"; 86 | fsType = "vfat"; 87 | }; 88 | 89 | fileSystems."/tmp" = { 90 | device = "/dev/pool/lvm-tmp"; 91 | fsType = "ext4"; 92 | }; 93 | 94 | swapDevices = []; 95 | 96 | nix.settings.max-jobs = lib.mkDefault 4; 97 | powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; 98 | 99 | hardware.graphics.extraPackages = with pkgs; [ 100 | vaapiIntel 101 | vaapiVdpau 102 | libvdpau-va-gl 103 | intel-media-driver 104 | ]; 105 | } 106 | -------------------------------------------------------------------------------- /nixos/configurations/mimas.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 | {self, ...} @ inputs: { 5 | config, 6 | pkgs, 7 | lib, 8 | ... 9 | }: let 10 | steamPackages = ["steam" "steam-run" "steam-original" "steam-runtime" "steam-unwrapped"]; 11 | in { 12 | imports = [ 13 | (import ./mimas/paperless.nix inputs) 14 | (import ./mimas/restic.nix inputs) 15 | (import ./mimas/rustic-timers.nix inputs) 16 | (import ./mimas/vaultwarden.nix inputs) 17 | ./mimas/gitea.nix 18 | ]; 19 | 20 | services.tailscale.enable = true; 21 | 22 | security.pam.services.i3lock.enable = true; 23 | security.pam.services.i3lock-color.enable = true; 24 | 25 | sops.age.sshKeyPaths = ["/etc/ssh/ssh_host_ed25519_key"]; 26 | sops.defaultSopsFile = "${self}/secrets/mimas/default.yaml"; 27 | 28 | sops.secrets.restic = {}; 29 | sops.secrets.traefik = {}; 30 | 31 | nix.allowedUnfree = ["zerotierone"] ++ steamPackages; 32 | nix.settings.experimental-features = ["ca-derivations" "impure-derivations"]; 33 | nix.distributedBuilds = true; 34 | # nix.enabledMachines = ["enceladeus"]; 35 | 36 | security.chromiumSuidSandbox.enable = true; 37 | 38 | zramSwap.enable = true; 39 | zramSwap.memoryPercent = 25; 40 | 41 | services.lvm.boot.thin.enable = true; 42 | boot.enableContainers = false; 43 | 44 | boot.binfmt.emulatedSystems = ["i686-linux" "aarch64-linux"]; 45 | nix.settings.extra-platforms = config.boot.binfmt.emulatedSystems; 46 | nix.settings.system-features = ["nixos-test" "benchmark" "big-parallel" "kvm" "gccarch-core2" "gccarch-haswell"]; 47 | 48 | # The global useDHCP flag is deprecated, therefore explicitly set to false here. 49 | # Per-interface useDHCP will be mandatory in the future, so this generated config 50 | # replicates the default behaviour. 51 | networking.useDHCP = false; 52 | networking.interfaces.enp5s0f2.useDHCP = false; 53 | networking.interfaces.wlp4s0.useDHCP = false; 54 | networking.hostId = "21025bb1"; 55 | networking.networkmanager.enable = true; 56 | networking.networkmanager.unmanaged = [ 57 | # "mac:80:fa:5b:09:15:6e" 58 | ]; 59 | 60 | # Select internationalisation properties. 61 | i18n = { 62 | # consoleFont = "Lat2-Terminus16"; 63 | # consoleKeyMap = "de"; 64 | defaultLocale = "en_US.UTF-8"; 65 | }; 66 | 67 | console.font = "Lat2-Terminus16"; 68 | console.keyMap = "de"; 69 | 70 | # Set your time zone. 71 | time.timeZone = "Europe/Berlin"; 72 | 73 | # List packages installed in system profile. To search, run: 74 | # $ nix search wget 75 | environment.systemPackages = with pkgs; [ 76 | virt-manager 77 | iptables 78 | ]; 79 | 80 | # Some programs need SUID wrappers, can be configured further or are 81 | # started in user sessions. 82 | # programs.mtr.enable = true; 83 | # programs.gnupg.agent = { enable = true; enableSSHSupport = true; }; 84 | 85 | # List services that you want to enable: 86 | 87 | # Enable the OpenSSH daemon. 88 | services.openssh.enable = true; 89 | 90 | # Add to XDG_DATA_DIRS: 91 | # * /var/lib/flatpak/exports/share 92 | # * $HOME/.local/share/flatpak/exports/share 93 | services.flatpak.enable = true; 94 | 95 | # Open ports in the firewall. 96 | networking.firewall.allowedTCPPorts = [80 443 1111 5555 8080 9002 9003 58080 4001]; 97 | # networking.firewall.allowedUDPPorts = [ ... ]; 98 | # Or disable the firewall altogether. 99 | networking.firewall.enable = true; 100 | 101 | # services.fwupd.enable = true; 102 | 103 | # Enable CUPS to print documents. 104 | services.printing.enable = true; 105 | 106 | services.avahi.enable = true; 107 | services.avahi.nssmdns4 = true; 108 | services.avahi.openFirewall = true; 109 | 110 | services.ratbagd.enable = true; 111 | 112 | programs.partition-manager.enable = true; 113 | # security.polkit.enable = true; 114 | 115 | # services.hydra = { 116 | # enable = true; 117 | # package = pkgs.hydra-unstable; 118 | 119 | # hydraURL = "https://localhost:3000"; 120 | # notificationSender = "hydra@localhost"; 121 | # buildMachinesFiles = [ ]; 122 | # useSubstitutes = true; 123 | # }; 124 | # networking.firewall.allowedTCPPorts = [ 3000 ]; 125 | 126 | # Enable pulse compat. 127 | services.pipewire.pulse.enable = true; 128 | 129 | hardware.bluetooth.enable = true; 130 | 131 | # Enable the X11 windowing system. 132 | services.xserver.enable = true; 133 | services.xserver.xkb.layout = "de"; 134 | 135 | # Enable touchpad support. 136 | # services.xserver.libinput.enable = true; 137 | 138 | # Enable the KDE Desktop Environment. 139 | services.displayManager.sddm.enable = true; 140 | services.xserver.desktopManager.plasma5.enable = true; 141 | services.xserver.windowManager.awesome.enable = true; 142 | 143 | services.dbus.packages = [pkgs.dconf]; 144 | 145 | services.udev.extraRules = '' 146 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0666" 147 | ''; 148 | 149 | services.transmission.enable = true; 150 | systemd.services.transmission.after = ["var-lib-transmission.mount"]; 151 | 152 | programs = { 153 | steam.enable = true; 154 | 155 | zsh.enable = true; 156 | zsh.enableCompletion = false; 157 | }; 158 | 159 | hardware.graphics.enable = true; 160 | hardware.graphics.extraPackages = [pkgs.vaapiIntel]; 161 | 162 | services.gitea = { 163 | enable = true; 164 | settings.server.DOMAIN = "gitea.mimas.internal.nobbz.dev"; 165 | settings.server.HTTP_ADDR = "127.0.0.1"; 166 | settings.server.ROOT_URL = lib.mkForce "https://gitea.mimas.internal.nobbz.dev/"; 167 | settings."git.timeout".DEFAULT = 3600; # 1 hour 168 | settings."git.timeout".MIGRATE = 3600; # 1 hour 169 | settings."git.timeout".MIRROR = 3600; # 1 hour 170 | settings."git.timeout".CLONE = 3600; # 1 hour 171 | settings."git.timeout".PULL = 3600; # 1 hour 172 | settings."git.timeout".GC = 3600; # 1 hour 173 | }; 174 | systemd.services.gitea.after = ["var-lib-gitea.mount"]; 175 | 176 | virtualisation = { 177 | docker = { 178 | enable = true; 179 | # storageDriver = "zfs"; 180 | # extraOptions = "--storage-opt zfs.fsname=rpool/local/docker"; 181 | package = pkgs.docker; 182 | extraOptions = "--dns 1.1.1.1"; 183 | }; 184 | 185 | containers.enable = true; 186 | 187 | libvirtd.enable = true; 188 | }; 189 | 190 | # Define a user account. Don't forget to set a password with ‘passwd’. 191 | # users.users.jane = { 192 | # isNormalUser = true; 193 | # extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user. 194 | # }; 195 | users.users = { 196 | nmelzer = { 197 | isNormalUser = true; 198 | shell = pkgs.zsh; 199 | extraGroups = [ 200 | "wheel" 201 | "audio" 202 | "networkmanager" 203 | "vboxusers" 204 | "libvirtd" 205 | "docker" 206 | "transmission" 207 | "scanner" 208 | "lp" 209 | ]; 210 | }; 211 | 212 | gamer = { 213 | isNormalUser = true; 214 | extraGroups = [ 215 | "audio" 216 | "networkmanager" 217 | ]; 218 | }; 219 | 220 | aroemer = { 221 | isNormalUser = true; 222 | extraGroups = []; 223 | }; 224 | }; 225 | 226 | security.sudo.extraConfig = "Defaults passwd_timeout=0"; 227 | 228 | # services.wakeonlan.interfaces = [ 229 | # { 230 | # interface = "enp5s0f2"; 231 | # method = "magicpacket"; 232 | # } 233 | # ]; 234 | 235 | # grafana configuration 236 | services.grafana = { 237 | enable = true; 238 | settings.server = { 239 | domain = "grafana.mimas.internal.nobbz.lan"; 240 | http_port = 2342; 241 | http_addr = "127.0.0.1"; 242 | }; 243 | }; 244 | 245 | # nginx reverse proxy 246 | services.nginx.virtualHosts.${config.services.grafana.domain} = { 247 | locations."/" = { 248 | proxyPass = "http://127.0.0.1:${toString config.services.grafana.settings.server.http_port}"; 249 | proxyWebsockets = true; 250 | }; 251 | }; 252 | 253 | hardware.keyboard.zsa.enable = true; 254 | hardware.sane.enable = true; 255 | 256 | services.traefik.enable = true; 257 | systemd.services.traefik.serviceConfig.EnvironmentFile = [config.sops.secrets.traefik.path]; 258 | services.traefik.staticConfigOptions = { 259 | log.level = "DEBUG"; 260 | 261 | api.dashboard = true; 262 | api.insecure = true; 263 | # experimental.http3 = true; 264 | 265 | certificatesResolvers.mimasWildcard.acme = { 266 | email = "acme@nobbz.dev"; 267 | storage = "/var/lib/traefik/mimas.json"; 268 | # caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"; 269 | dnsChallenge.provider = "cloudflare"; 270 | dnsChallenge.resolvers = ["1.1.1.1:53" "8.8.8.8:53"]; 271 | }; 272 | 273 | entryPoints = { 274 | http = { 275 | address = ":80"; 276 | forwardedHeaders.insecure = true; 277 | http.redirections.entryPoint = { 278 | to = "https"; 279 | scheme = "https"; 280 | }; 281 | }; 282 | 283 | https = { 284 | address = ":443"; 285 | # enableHTTP3 = true; 286 | forwardedHeaders.insecure = true; 287 | }; 288 | 289 | experimental = { 290 | address = ":1111"; 291 | forwardedHeaders.insecure = true; 292 | }; 293 | }; 294 | }; 295 | services.traefik.dynamicConfigOptions = { 296 | http.routers = { 297 | api = { 298 | entrypoints = ["traefik"]; 299 | rule = "PathPrefix(`/api/`)"; 300 | service = "api@internal"; 301 | }; 302 | fritz = { 303 | entryPoints = ["https" "http"]; 304 | rule = "Host(`fritz.mimas.internal.nobbz.dev`)"; 305 | service = "fritz"; 306 | tls.domains = [{main = "*.mimas.internal.nobbz.dev";}]; 307 | tls.certResolver = "mimasWildcard"; 308 | }; 309 | gitea = { 310 | entryPoints = ["https" "http"]; 311 | rule = "Host(`gitea.mimas.internal.nobbz.dev`)"; 312 | service = "gitea"; 313 | tls.domains = [{main = "*.mimas.internal.nobbz.dev";}]; 314 | tls.certResolver = "mimasWildcard"; 315 | }; 316 | grafana = { 317 | entryPoints = ["https" "http"]; 318 | rule = "Host(`grafana.mimas.internal.nobbz.dev`)"; 319 | service = "grafana"; 320 | tls.domains = [{main = "*.mimas.internal.nobbz.dev";}]; 321 | tls.certResolver = "mimasWildcard"; 322 | }; 323 | # minio-tls = { 324 | # entryPoints = [ "https" "experimental" ]; 325 | # rule = "HostRegexp(`{subdomain:[a-z0-9]+}.mimas.internal.nobbz.dev`) && PathPrefix(`/`)"; 326 | # service = "minio"; 327 | # tls.domains = [{ main = "*.mimas.internal.nobbz.dev"; }]; 328 | # tls.certresolver = "mimasWildcard"; 329 | # }; 330 | }; 331 | http.services = { 332 | minio.loadBalancer.passHostHeader = true; 333 | minio.loadBalancer.servers = [{url = "http://192.168.122.122/";}]; 334 | 335 | fritz.loadBalancer.passHostHeader = false; 336 | fritz.loadBalancer.servers = [{url = "http://fritz.box";}]; 337 | 338 | gitea.loadBalancer.passHostHeader = true; 339 | gitea.loadBalancer.servers = [{url = "http://localhost:${toString config.services.gitea.settings.server.HTTP_PORT}";}]; 340 | 341 | grafana.loadBalancer.passHostHeader = true; 342 | grafana.loadBalancer.servers = [{url = "http://localhost:${toString config.services.grafana.settings.server.http_port}";}]; 343 | }; 344 | }; 345 | 346 | services.prometheus = { 347 | enable = true; 348 | port = 9001; 349 | 350 | rules = [ 351 | '' 352 | groups: 353 | - name: test 354 | rules: 355 | - record: nobbz:code_cpu_percent 356 | expr: avg without (cpu) (irate(node_cpu_seconds_total[5m])) 357 | '' 358 | ]; 359 | 360 | exporters = { 361 | node = { 362 | enable = true; 363 | enabledCollectors = ["systemd"]; 364 | port = 9002; 365 | }; 366 | }; 367 | 368 | scrapeConfigs = [ 369 | { 370 | job_name = "grafana"; 371 | static_configs = [{targets = ["127.0.0.1:2342"];}]; 372 | } 373 | { 374 | job_name = "prometheus"; 375 | static_configs = [{targets = ["127.0.0.1:9001"];}]; 376 | } 377 | { 378 | job_name = "node_import"; 379 | static_configs = [ 380 | { 381 | targets = [ 382 | "127.0.0.1:${toString config.services.prometheus.exporters.node.port}" 383 | "${config.lib.nobbz.enceladeus.v4}:9002" 384 | ]; 385 | } 386 | ]; 387 | } 388 | ]; 389 | }; 390 | 391 | nix.buildMachines = let 392 | communityBuilder = name: system: { 393 | hostName = "${name}.nix-community.org"; 394 | inherit system; 395 | sshKey = "/root/.ssh/id_ed25519"; 396 | sshUser = "NobbZ"; 397 | maxJobs = 8; 398 | protocol = "ssh"; 399 | speedFactor = 4; 400 | supportedFeatures = ["nixos-test" "benchmark" "big-parallel" "kvm"]; 401 | }; 402 | in [ 403 | (communityBuilder "build-box" "x86_64-linux") 404 | (communityBuilder "aarch64-build.box" "aarch64-linux") 405 | ]; 406 | 407 | # This value determines the NixOS release with which your system is to be 408 | # compatible, in order to avoid breaking some software such as database 409 | # servers. You should change this only after NixOS release notes say you 410 | # should. 411 | system.stateVersion = "20.09"; # Did you read the comment? 412 | } 413 | -------------------------------------------------------------------------------- /nixos/configurations/mimas/gitea.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | lib, 4 | config, 5 | ... 6 | }: let 7 | writeNuBin = pkgs.writers.writeNuBin.override {makeBinaryWrapper = pkgs.makeShellWrapper;}; 8 | 9 | find = lib.getExe pkgs.findutils; 10 | git = lib.getExe pkgs.git; 11 | systemd-notify = lib.getExe' pkgs.systemd "systemd-notify"; 12 | 13 | gitea-gc-script = 14 | writeNuBin "gitea-gc" 15 | # nu 16 | '' 17 | use std log 18 | 19 | def main [ 20 | repositories_base_folder: string, 21 | ] { 22 | log info $"Performing garbage collection for all repos in ($repositories_base_folder)" 23 | 24 | let repo_paths = run-external ${find} $repositories_base_folder "-maxdepth" 2 "-name" '*.git' | lines 25 | let repo_count = $repo_paths | length 26 | 27 | run-external ${systemd-notify} "--ready" 28 | 29 | $repo_paths | enumerate | each {|itm| 30 | let repo = $itm.item 31 | let idx = $itm.index 32 | 33 | let short_name = $repo | str substring --grapheme-clusters ($repositories_base_folder + "/" | str length)..-1 34 | 35 | log info $"Starting garbage collection for ($short_name)" 36 | run-external ${systemd-notify} $"--status=($idx + 1)/($repo_count): ($short_name)" 37 | run-external ${git} "-C" $repo gc "--aggressive" "--no-quiet" 38 | log info $"Finished garbage collection for ($short_name)" 39 | } 40 | 41 | run-external ${systemd-notify} "--stopping" 42 | 43 | log info "Overall garbage collection suceeded" 44 | } 45 | ''; 46 | in { 47 | systemd = { 48 | services.gitea-gc = { 49 | description = "Garbage Collect gitea repositories"; 50 | restartIfChanged = false; 51 | environment = { 52 | NU_LOG_LEVEL = "DEBUG"; 53 | }; 54 | serviceConfig = { 55 | CPUAccounting = true; 56 | CPUQuota = "200%"; 57 | CPUWeight = "idle"; 58 | ExecStart = "${lib.getExe gitea-gc-script} /var/lib/gitea/repositories"; 59 | NotifyAccess = "all"; 60 | Type = "notify"; 61 | User = config.services.gitea.user; 62 | }; 63 | }; 64 | 65 | timers.gitea-gc = { 66 | description = "Garbage Collection for gitea repositories - timer"; 67 | wantedBy = ["timers.target"]; 68 | timerConfig.OnCalendar = "Mon 01:00:00"; 69 | }; 70 | }; 71 | } 72 | -------------------------------------------------------------------------------- /nixos/configurations/mimas/paperless.nix: -------------------------------------------------------------------------------- 1 | _: {config, ...}: { 2 | services.paperless = { 3 | enable = true; 4 | address = "0.0.0.0"; 5 | port = 58080; 6 | settings.PAPERLESS_OCR_LANGUAGE = "deu+eng"; 7 | }; 8 | 9 | systemd.services.paperless-consumer.after = ["var-lib-paperless.mount"]; 10 | systemd.services.paperless-scheduler.after = ["var-lib-paperless.mount"]; 11 | systemd.services.paperless-task-queue.after = ["var-lib-paperless.mount"]; 12 | systemd.services.paperless-web.after = ["var-lib-paperless.mount"]; 13 | 14 | services.traefik.dynamicConfigOptions.http.routers.paperless = { 15 | entryPoints = ["https" "http"]; 16 | rule = "Host(`paperless.mimas.internal.nobbz.dev`)"; 17 | service = "paperless"; 18 | tls.domains = [{main = "*.mimas.internal.nobbz.dev";}]; 19 | tls.certResolver = "mimasWildcard"; 20 | }; 21 | 22 | services.traefik.dynamicConfigOptions.http.services.paperless.loadBalancer = { 23 | passHostHeader = true; 24 | servers = [{url = "http://localhost:${toString config.services.paperless.port}";}]; 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /nixos/configurations/mimas/restic.nix: -------------------------------------------------------------------------------- 1 | {self, ...}: { 2 | config, 3 | pkgs, 4 | lib, 5 | ... 6 | }: let 7 | resticPort = 9999; 8 | 9 | inherit (pkgs) proot mount umount restic; 10 | 11 | pools = { 12 | gitea = "/var/lib/gitea"; 13 | grafana = "/var/lib/grafana"; 14 | paperless = "/var/lib/paperless"; 15 | prometheus = "/var/lib/prometheus2"; 16 | }; 17 | 18 | extraPathes = [ 19 | "/var/lib/nixos" 20 | "/var/lib/redis-paperless" 21 | ]; 22 | 23 | basePath = "/tmp/backup"; 24 | mounts = lib.flatten ( 25 | (lib.mapAttrsToList (lv: path: ["-b" "${basePath}/${lv}:${path}"]) pools) 26 | ++ (builtins.map (path: ["-b" "${path}:${path}"]) extraPathes) 27 | ); 28 | 29 | snaps = lib.mapAttrs' (lv: _: lib.nameValuePair "${lv}_snap" "pool/${lv}") pools; 30 | lvcreates = lib.concatStringsSep "\n" (lib.mapAttrsToList (name: origin: "lvcreate -s --name ${name} ${origin}") snaps); 31 | lvactivates = lib.concatStringsSep "\n" (lib.mapAttrsToList (name: _: "lvchange -ay -Ky pool/${name}") snaps); 32 | mkdirs = lib.concatStringsSep "\n" (lib.mapAttrsToList (lv: _: "mkdir -p ${basePath}/${lv}") pools); 33 | mountCmds = lib.concatStringsSep "\n" (lib.mapAttrsToList (lv: _: "mount -o ro /dev/pool/${lv}_snap ${basePath}/${lv}") pools); 34 | 35 | unmountCmds = lib.concatStringsSep "\n" (lib.mapAttrsToList (lv: _: "umount ${basePath}/${lv}") pools); 36 | uncheckedUnmountCmds = lib.concatStringsSep "\n" (lib.mapAttrsToList (lv: _: "umount ${basePath}/${lv} || true") pools); 37 | lvdeactivates = lib.concatStringsSep "\n" (lib.mapAttrsToList (name: _: "lvs | grep -E '${name}\\s+.*a' && lvchange -an pool/${name}") snaps); 38 | lvremoves = lib.concatStringsSep "\n" (lib.mapAttrsToList (name: _: "lvs | grep -E '${name}' && lvremove pool/${name}") snaps); 39 | 40 | rest_repo = "rest:https://restic.mimas.internal.nobbz.dev/mimas"; 41 | pass = config.sops.secrets.restic.path; 42 | 43 | preStart = '' 44 | set -x 45 | 46 | ${uncheckedUnmountCmds} 47 | 48 | ${lvdeactivates} 49 | ${lvremoves} 50 | 51 | ${lvcreates} 52 | ${lvactivates} 53 | 54 | ${mkdirs} 55 | 56 | ${mountCmds} 57 | 58 | /run/wrappers/bin/sudo -u vaultwarden ${pkgs.sqlite}/bin/sqlite3 /var/lib/bitwarden_rs/db.sqlite3 .dump > /var/lib/bitwarden_rs/dump.sql 59 | ''; 60 | 61 | script = '' 62 | set -x 63 | 64 | # TODO: Make the latter from snapshots as well! 65 | proot ${lib.escapeShellArgs mounts} \ 66 | -b /var/lib/bitwarden_rs:/var/lib/bitwarden_rs \ 67 | -b /nix:/nix \ 68 | -b ''${CREDENTIALS_DIRECTORY}:''${CREDENTIALS_DIRECTORY} \ 69 | -b /etc:/etc \ 70 | -b /tmp:/tmp \ 71 | -r /var/empty \ 72 | restic --tag services -vv backup /var/lib 73 | ''; 74 | 75 | postStart = '' 76 | set -x 77 | 78 | ${unmountCmds} 79 | 80 | ${lvdeactivates} 81 | ${lvremoves} 82 | 83 | rm -rfv ${basePath} 84 | ''; 85 | in { 86 | services.restic.server = { 87 | enable = true; 88 | prometheus = true; 89 | extraFlags = ["--no-auth"]; # This is fine, as we are only reachable through VPN 90 | listenAddress = "127.0.0.1:${toString resticPort}"; 91 | }; 92 | 93 | # We have an extra mount to put restic data on, we need to make sure it is properly 94 | # mounted before writing anything to it 95 | systemd.services.restic-rest-server.after = ["var-lib-restic.mount"]; 96 | 97 | # Add an appropriate router for traefik 98 | services.traefik.dynamicConfigOptions.http.routers.restic = { 99 | entryPoints = ["https" "http"]; 100 | rule = "Host(`restic.mimas.internal.nobbz.dev`)"; 101 | service = "restic"; 102 | tls.domains = [{main = "*.mimas.internal.nobbz.dev";}]; 103 | tls.certResolver = "mimasWildcard"; 104 | }; 105 | 106 | # And the service configuration 107 | services.traefik.dynamicConfigOptions.http.services.restic.loadBalancer = { 108 | passHostHeader = false; 109 | servers = [{url = "http://127.0.0.1:${toString resticPort}";}]; 110 | }; 111 | 112 | systemd.timers.restic-system-snapshot-backup = { 113 | wantedBy = ["timers.target"]; 114 | timerConfig.OnCalendar = "hourly"; 115 | }; 116 | 117 | systemd.services.restic-system-snapshot-backup = { 118 | inherit preStart script postStart; 119 | path = [proot restic mount umount config.services.lvm.package]; 120 | serviceConfig.LoadCredential = ["pass:${pass}"]; 121 | environment = { 122 | RESTIC_REPOSITORY = rest_repo; 123 | RESTIC_PASSWORD_FILE = "%d/pass"; 124 | RESTIC_COMPRESSION = "max"; 125 | }; 126 | serviceConfig = { 127 | Type = "oneshot"; 128 | }; 129 | }; 130 | } 131 | -------------------------------------------------------------------------------- /nixos/configurations/mimas/rustic-timers.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | config, 3 | pkgs, 4 | lib, 5 | ... 6 | }: let 7 | profile_name = template: lib.removeSuffix ".toml" config.sops.templates."${template}".path; 8 | 9 | environment = { 10 | RUSTIC_NO_PROGRESS = "true"; 11 | RUSTIC_CACHE_DIR = "%T/rustic"; 12 | }; 13 | 14 | mimas_template = 15 | # toml 16 | '' 17 | [repository] 18 | repository = "rest:https://restic.mimas.internal.nobbz.dev/mimas" 19 | password-file = "${config.sops.secrets.rustic.path}" 20 | 21 | [copy] 22 | targets = ["${profile_name "mimas_hetzner.toml"}"] 23 | ''; 24 | mimas_hetzner_template = 25 | # toml 26 | '' 27 | [repository] 28 | repository = "opendal:sftp" 29 | password-file = "${config.sops.secrets.rustic.path}" 30 | 31 | [repository.options] 32 | endpoint = "ssh://${config.sops.placeholder.rustic-user}.your-storagebox.de:23" 33 | user = "${config.sops.placeholder.rustic-user}" 34 | key = "/root/.ssh/id_ed25519" 35 | root = "/home/mimas" 36 | ''; 37 | 38 | nobbz_template = 39 | # toml 40 | '' 41 | [repository] 42 | repository = "rest:https://restic.mimas.internal.nobbz.dev/nobbz" 43 | password-file = "${config.sops.secrets.rustic.path}" 44 | 45 | [copy] 46 | targets = ["${profile_name "nobbz_hetzner.toml"}"] 47 | ''; 48 | 49 | nobbz_hetzner_template = 50 | # toml 51 | '' 52 | [repository] 53 | repository = "opendal:sftp" 54 | password-file = "${config.sops.secrets.rustic.path}" 55 | 56 | [repository.options] 57 | endpoint = "ssh://${config.sops.placeholder.rustic-user}.your-storagebox.de:23" 58 | user = "${config.sops.placeholder.rustic-user}" 59 | key = "/root/.ssh/id_ed25519" 60 | root = "/home/nobbz" 61 | ''; 62 | 63 | schedule = { 64 | rustic-mimas-clean = "*-*-* 01:00:00"; 65 | rustic-nobbz-clean = "*-*-* 01:30:00"; 66 | rustic-mimas-hetzner-clean = "*-*-* 02:00:00"; 67 | rustic-nobbz-hetzner-clean = "*-*-* 03:00:00"; 68 | }; 69 | 70 | mkTimer = name: calendar: { 71 | "${name}" = { 72 | wantedBy = ["timers.target"]; 73 | timerConfig.OnCalendar = calendar; 74 | }; 75 | }; 76 | 77 | notify = lib.getExe' pkgs.systemd "systemd-notify"; 78 | in { 79 | sops.secrets.rustic = {}; 80 | sops.secrets.rustic-user = {}; 81 | 82 | sops.templates."mimas.toml".content = mimas_template; 83 | sops.templates."mimas_hetzner.toml".content = mimas_hetzner_template; 84 | sops.templates."nobbz.toml".content = nobbz_template; 85 | sops.templates."nobbz_hetzner.toml".content = nobbz_hetzner_template; 86 | 87 | systemd.timers = lib.pipe schedule [ 88 | (lib.mapAttrsToList mkTimer) 89 | lib.mkMerge 90 | ]; 91 | 92 | systemd.services = { 93 | rustic-mimas-clean = { 94 | path = [pkgs.rustic pkgs.openssh]; 95 | inherit environment; 96 | serviceConfig = { 97 | NotifyAccess = "all"; 98 | Type = "notify"; 99 | }; 100 | script = '' 101 | ${notify} --ready 102 | ${notify} --status=forget 103 | rustic forget -P ${profile_name "mimas.toml"} \ 104 | --keep-last 4 \ 105 | --keep-within-hourly 1d \ 106 | --keep-within-daily 5d \ 107 | --keep-within-weekly 35d \ 108 | --keep-within-monthly 100d \ 109 | --keep-within-yearly 2y 110 | 111 | ${notify} --status=prune 112 | rustic prune -P ${profile_name "mimas.toml"} \ 113 | --max-unused=0B \ 114 | --keep-delete=12h \ 115 | --max-repack=50GiB 116 | 117 | ${notify} --status=copy 118 | rustic copy -P ${profile_name "mimas.toml"} 119 | 120 | ${notify} --stopping --status="" 121 | ''; 122 | }; 123 | 124 | rustic-nobbz-clean = { 125 | path = [pkgs.rustic pkgs.openssh]; 126 | inherit environment; 127 | serviceConfig = { 128 | NotifyAccess = "all"; 129 | Type = "notify"; 130 | }; 131 | script = '' 132 | ${notify} --ready 133 | ${notify} --status=forget 134 | rustic forget -P ${profile_name "nobbz.toml"} \ 135 | --filter-tags home \ 136 | --keep-last 4 \ 137 | --keep-within-hourly 1d \ 138 | --keep-within-daily 5d \ 139 | --keep-within-weekly 35d \ 140 | --keep-within-monthly 100d \ 141 | --keep-within-yearly 2y 142 | 143 | ${notify} --status=prune 144 | rustic prune -P ${profile_name "nobbz.toml"} \ 145 | --max-unused=0B \ 146 | --keep-delete=12h \ 147 | --max-repack=50GiB 148 | 149 | ${notify} --status=copy 150 | rustic copy -P ${profile_name "nobbz.toml"} 151 | 152 | ${notify} --stopping --status="" 153 | ''; 154 | }; 155 | 156 | rustic-nobbz-hetzner-clean = { 157 | path = [pkgs.rustic pkgs.openssh]; 158 | inherit environment; 159 | serviceConfig = { 160 | NotifyAccess = "all"; 161 | Type = "notify"; 162 | }; 163 | script = '' 164 | ${notify} --ready 165 | ${notify} --status=forget 166 | rustic forget -P ${profile_name "nobbz_hetzner.toml"} \ 167 | --keep-last 1 \ 168 | --keep-within-hourly 2h \ 169 | --keep-within-daily 10d \ 170 | --keep-within-weekly 65d \ 171 | --keep-within-monthly 190d \ 172 | --keep-within-yearly 5y 173 | 174 | ${notify} --status=prune 175 | rustic prune -P ${profile_name "nobbz_hetzner.toml"} \ 176 | --max-unused 0B \ 177 | --max-repack 20GiB \ 178 | --keep-delete 11h 179 | 180 | ${notify} --stopping --status="" 181 | ''; 182 | }; 183 | 184 | rustic-mimas-hetzner-clean = { 185 | path = [pkgs.rustic pkgs.openssh]; 186 | inherit environment; 187 | serviceConfig = { 188 | NotifyAccess = "all"; 189 | Type = "notify"; 190 | }; 191 | script = '' 192 | ${notify} --ready 193 | ${notify} --status=forget 194 | rustic forget -P ${profile_name "mimas_hetzner.toml"} \ 195 | --keep-last 1 \ 196 | --keep-within-hourly 2h \ 197 | --keep-within-daily 10d \ 198 | --keep-within-weekly 65d \ 199 | --keep-within-monthly 190d \ 200 | --keep-within-yearly 5y 201 | 202 | ${notify} --status=prune 203 | rustic prune -P ${profile_name "mimas_hetzner.toml"} \ 204 | --max-unused 0B \ 205 | --max-repack 20GiB \ 206 | --keep-delete 11h 207 | 208 | ${notify} --stopping --status="" 209 | ''; 210 | }; 211 | }; 212 | } 213 | -------------------------------------------------------------------------------- /nixos/configurations/mimas/vaultwarden.nix: -------------------------------------------------------------------------------- 1 | _: {config, ...}: let 2 | host = "passwords.mimas.internal.nobbz.dev"; 3 | wardenPort = 10000; 4 | in { 5 | sops.secrets.warden = {}; 6 | 7 | services.vaultwarden = { 8 | enable = true; 9 | environmentFile = config.sops.secrets.warden.path; 10 | config = { 11 | DOMAIN = "https://${host}"; 12 | DATABASE_MAX_CONNS = "5"; 13 | 14 | # LOG_LEVEL = "debug"; 15 | 16 | ROCKET_ADDRESS = "127.0.0.1"; 17 | ROCKET_PORT = "${toString wardenPort}"; 18 | ROCKET_WORKERS = "5"; 19 | }; 20 | }; 21 | 22 | services.traefik.dynamicConfigOptions.http.routers.warden = { 23 | entryPoints = ["https" "http"]; 24 | rule = "Host(`${host}`)"; 25 | service = "vaultwarden"; 26 | tls.domains = [{main = "*.mimas.internal.nobbz.dev";}]; 27 | tls.certResolver = "mimasWildcard"; 28 | }; 29 | 30 | services.traefik.dynamicConfigOptions.http.services.vaultwarden.loadBalancer = { 31 | passHostHeader = false; 32 | servers = [{url = "http://127.0.0.1:${toString wardenPort}";}]; 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /nixos/modules/cachix/caches/nix-community.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: { 6 | nix = lib.mkIf (config.networking.hostName != "delly-nixos") { 7 | settings.substituters = [ 8 | "https://nix-community.cachix.org" 9 | ]; 10 | settings.trusted-public-keys = [ 11 | "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" 12 | ]; 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /nixos/modules/cachix/caches/nobbz.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: { 6 | nix = lib.mkIf (config.networking.hostName != "delly-nixos") { 7 | settings.substituters = [ 8 | "https://nobbz.cachix.org" 9 | ]; 10 | settings.trusted-public-keys = [ 11 | "nobbz.cachix.org-1:fODxpqE4ni+pFDSuj2ybYZbMUjmxNTjA7rtUNHW61Ok=" 12 | ]; 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /nixos/modules/cachix/caches/ts-helper.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: { 6 | nix = lib.mkIf (config.networking.hostName != "delly-nixos") { 7 | settings.substituters = [ 8 | "https://ts-helper.cachix.org" 9 | ]; 10 | settings.trusted-public-keys = [ 11 | "ts-helper.cachix.org-1:l9XtzxPqlR/lKsKpTS+DcCn4cCuYiUSgGzIsLF3vz9Q=" 12 | ]; 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /nixos/modules/cachix/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | config, 3 | pkgs, 4 | lib, 5 | ... 6 | }: let 7 | folder = ./caches; 8 | toImport = name: value: folder + ("/" + name); 9 | filterCaches = key: value: value == "regular" && lib.hasSuffix ".nix" key; 10 | imports = lib.mapAttrsToList toImport (lib.filterAttrs filterCaches (builtins.readDir folder)); 11 | in { 12 | inherit imports; 13 | nix.settings.substituters = ["https://cache.nixos.org/"]; 14 | 15 | environment.systemPackages = [pkgs.cachix]; 16 | } 17 | -------------------------------------------------------------------------------- /nixos/modules/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | nobbz.nixosModules = { 3 | cachix = ./cachix; 4 | distributed = ./distributed.nix; 5 | flake = ./flake.nix; 6 | hostnames = ./hostnames.nix; 7 | kernel = ./kernel.nix; 8 | moonlander = ./moonlander.nix; 9 | nix = ./nix.nix; 10 | switcher = ./switcher.nix; 11 | zerotier = ./zerotier.nix; 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /nixos/modules/distributed.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | config, 3 | lib, 4 | ... 5 | }: let 6 | machines = { 7 | # Please try to keep the definitions alphabetically sorted 8 | enceladeus = { 9 | systems = ["i686-linux" "x86_64-linux"]; 10 | supportedFeatures = []; 11 | sshUser = "root"; 12 | sshKey = "/home/nmelzer/.ssh/id_rsa"; # TODO: sopsify 13 | speedFactor = 1; 14 | protocol = "ssh-ng"; 15 | maxJobs = 2; 16 | hostName = "enceladeus"; 17 | }; 18 | 19 | mimas = { 20 | systems = ["i686-linux" "aarch64-linux" "x86_64-linux"]; 21 | supportedFeatures = ["kvm" "big-parallel"]; 22 | sshUser = "root"; 23 | sshKey = "/home/nmelzer/.ssh/id_rsa"; # TODO: sopsify 24 | speedFactor = 8; 25 | protocol = "ssh-ng"; 26 | maxJobs = 4; 27 | hostName = "mimas"; 28 | }; 29 | }; 30 | 31 | names = builtins.attrNames machines; 32 | 33 | inherit (lib.types) listOf enum; 34 | inherit (config.nix) enabledMachines distributedBuilds; 35 | inherit (config.networking) hostName; 36 | 37 | selfRemote = builtins.elem hostName enabledMachines; 38 | in { 39 | options.nix = { 40 | enabledMachines = lib.mkOption { 41 | type = listOf (enum names); 42 | default = []; 43 | description = '' 44 | A list of hosts to use for remote builds. 45 | ''; 46 | }; 47 | }; 48 | 49 | config = lib.mkIf distributedBuilds { 50 | assertions = [ 51 | { 52 | assertion = !selfRemote; 53 | message = "You are not allowed to use yourself as a distributed builder"; 54 | } 55 | ]; 56 | nix.buildMachines = builtins.map (name: builtins.getAttr name machines) enabledMachines; 57 | }; 58 | } 59 | -------------------------------------------------------------------------------- /nixos/modules/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | nix, 3 | nixpkgs, 4 | programsdb, 5 | ... 6 | }: { 7 | config, 8 | pkgs, 9 | lib, 10 | ... 11 | }: let 12 | base = "/etc/nixpkgs/channels"; 13 | nixpkgsPath = "${base}/nixpkgs"; 14 | in { 15 | options.nix.flakes.enable = lib.mkEnableOption "nix flakes"; 16 | 17 | config = lib.mkIf config.nix.flakes.enable { 18 | programs.command-not-found.dbPath = programsdb.packages.${pkgs.system}.programs-sqlite; 19 | 20 | nix = { 21 | package = lib.mkDefault nix.packages.${pkgs.system}.nix-cli; 22 | 23 | settings.experimental-features = ["nix-command" "flakes"]; 24 | 25 | registry.nixpkgs.flake = nixpkgs; 26 | 27 | nixPath = [ 28 | "nixpkgs=${nixpkgsPath}" 29 | "/nix/var/nix/profiles/per-user/root/channels" 30 | ]; 31 | }; 32 | 33 | systemd.tmpfiles.rules = [ 34 | "L+ ${nixpkgsPath} - - - - ${nixpkgs}" 35 | ]; 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /nixos/modules/hostnames.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: { 7 | networking.search = ["internal.nobbz.dev"]; 8 | networking.domain = "internal.nobbz.dev"; 9 | } 10 | -------------------------------------------------------------------------------- /nixos/modules/kernel.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | pkgs, 3 | lib, 4 | config, 5 | ... 6 | }: let 7 | supportedFilesystems = 8 | if builtins.isList config.boot.supportedFilesystems 9 | then config.boot.supportedFilesystems ++ config.boot.initrd.supportedFilesystems 10 | else builtins.attrNames (lib.filterAttrs (_name: value: value) (config.boot.supportedFilesystems // config.boot.initrd.supportedFilesystems)); 11 | zfsUsed = lib.lists.elem "zfs" supportedFilesystems; 12 | in { 13 | boot.kernelPackages = lib.mkDefault ( 14 | if zfsUsed 15 | then pkgs.zfs.latestCompatibleLinuxPackages 16 | else pkgs.linuxPackages_latest 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /nixos/modules/moonlander.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: let 7 | inherit (lib) mkIf; 8 | inherit (pkgs) wally-cli; 9 | 10 | cfg = config.hardware.keyboard.zsa; 11 | in { 12 | config = mkIf cfg.enable { 13 | users.users.nmelzer.extraGroups = ["plugdev"]; 14 | environment.systemPackages = [wally-cli]; 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /nixos/modules/nix.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | config, 3 | lib, 4 | ... 5 | }: let 6 | allowed = config.nix.allowedUnfree; 7 | kibibyte = 1024; 8 | mibibyte = 1024 * kibibyte; 9 | gibibyte = 1024 * mibibyte; 10 | in { 11 | options.nix = { 12 | allowedUnfree = lib.mkOption { 13 | type = lib.types.listOf lib.types.str; 14 | default = []; 15 | description = '' 16 | Allows for unfree packages by their name. 17 | ''; 18 | }; 19 | }; 20 | 21 | config = lib.mkMerge [ 22 | (lib.mkIf (allowed != []) {nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) allowed;}) 23 | {nix.settings.auto-optimise-store = lib.mkDefault true;} 24 | { 25 | nix.settings.trusted-users = lib.mkDefault ["root" "@wheel"]; 26 | nix.settings.min-free = lib.mkDefault (5 * gibibyte); 27 | nix.settings.max-free = lib.mkDefault (25 * gibibyte); 28 | nix.settings.allow-import-from-derivation = lib.mkDefault false; 29 | } 30 | ]; 31 | } 32 | -------------------------------------------------------------------------------- /nixos/modules/prefer-local.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/build-remote/build-remote.cc b/src/build-remote/build-remote.cc 2 | index cfc4baaca..4fbaae4fa 100644 3 | --- a/src/build-remote/build-remote.cc 4 | +++ b/src/build-remote/build-remote.cc 5 | @@ -122,6 +122,8 @@ static int main_build_remote(int argc, char * * argv) 6 | /* It's possible to build this locally right now: */ 7 | bool canBuildLocally = amWilling && couldBuildLocally; 8 | 9 | + if (canBuildLocally) continue; 10 | + 11 | /* Error ignored here, will be caught later */ 12 | mkdir(currentLoad.c_str(), 0777); 13 | 14 | -------------------------------------------------------------------------------- /nixos/modules/switcher.nix: -------------------------------------------------------------------------------- 1 | {self, ...}: { 2 | pkgs, 3 | config, 4 | ... 5 | }: { 6 | environment.systemPackages = [self.packages."${pkgs.system}".switcher]; 7 | 8 | security.sudo.extraRules = let 9 | storePrefix = "/nix/store/*"; 10 | commandPrefix = "/run/current-system/sw"; 11 | systemName = "nixos-system-${config.networking.hostName}-*"; 12 | nixEnvCmd = "${commandPrefix}/bin/nix-env"; 13 | systemdPath = "${commandPrefix}/bin/systemd-run"; 14 | systemdRunCmd = "${systemdPath} -E LOCALE_ARCHIVE -E NIXOS_INSTALL_BOOTLOADER --collect --no-ask-password --pty --quiet --same-dir --service-type=exec --unit=nixos-rebuild-switch-to-configuration"; 15 | systemdRunEqCmd = "${systemdPath} -E LOCALE_ARCHIVE -E NIXOS_INSTALL_BOOTLOADER= --collect --no-ask-password --pty --quiet --same-dir --service-type=exec --unit=nixos-rebuild-switch-to-configuration"; 16 | options = ["NOPASSWD"]; 17 | mkRule = command: { 18 | commands = [{inherit command options;}]; 19 | groups = ["wheel"]; 20 | }; 21 | in [ 22 | (mkRule "${nixEnvCmd} -p /nix/var/nix/profiles/system --set ${storePrefix}-${systemName}") 23 | (mkRule "${systemdRunCmd} --wait true") 24 | (mkRule "${systemdRunEqCmd} --wait ${storePrefix}-${systemName}/bin/switch-to-configuration switch") 25 | ]; 26 | } 27 | -------------------------------------------------------------------------------- /nixos/modules/zerotier.nix: -------------------------------------------------------------------------------- 1 | {nixpkgs-pre-rust, ...}: { 2 | config, 3 | pkgs, 4 | ... 5 | }: { 6 | services.zerotierone.enable = true; 7 | services.zerotierone.joinNetworks = ["8286ac0e4768c8ae"]; 8 | 9 | services.zerotierone.localConf = {}; 10 | 11 | services.zerotierone.package = 12 | (import nixpkgs-pre-rust { 13 | inherit (config.nixpkgs) config; 14 | inherit (pkgs) system; 15 | }) 16 | .zerotierone; 17 | } 18 | -------------------------------------------------------------------------------- /npins/default.nix: -------------------------------------------------------------------------------- 1 | # Generated by npins. Do not modify; will be overwritten regularly 2 | let 3 | data = builtins.fromJSON (builtins.readFile ./sources.json); 4 | version = data.version; 5 | 6 | mkSource = spec: 7 | assert spec ? type; let 8 | path = 9 | if spec.type == "Git" 10 | then mkGitSource spec 11 | else if spec.type == "GitRelease" 12 | then mkGitSource spec 13 | else if spec.type == "PyPi" 14 | then mkPyPiSource spec 15 | else if spec.type == "Channel" 16 | then mkChannelSource spec 17 | else builtins.throw "Unknown source type ${spec.type}"; 18 | in 19 | spec // {outPath = path;}; 20 | 21 | mkGitSource = { 22 | repository, 23 | revision, 24 | url ? null, 25 | hash, 26 | ... 27 | }: 28 | assert repository ? type; 29 | # At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository 30 | # In the latter case, there we will always be an url to the tarball 31 | if url != null 32 | then 33 | (builtins.fetchTarball { 34 | inherit url; 35 | sha256 = hash; # FIXME: check nix version & use SRI hashes 36 | }) 37 | else 38 | assert repository.type == "Git"; 39 | builtins.fetchGit { 40 | url = repository.url; 41 | rev = revision; 42 | # hash = hash; 43 | }; 44 | 45 | mkPyPiSource = { 46 | url, 47 | hash, 48 | ... 49 | }: 50 | builtins.fetchurl { 51 | inherit url; 52 | sha256 = hash; 53 | }; 54 | 55 | mkChannelSource = { 56 | url, 57 | hash, 58 | ... 59 | }: 60 | builtins.fetchTarball { 61 | inherit url; 62 | sha256 = hash; 63 | }; 64 | in 65 | if version == 3 66 | then builtins.mapAttrs (_: mkSource) data.pins 67 | else throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`" 68 | -------------------------------------------------------------------------------- /npins/sources.json: -------------------------------------------------------------------------------- 1 | { 2 | "pins": { 3 | "catppuccin-bat": { 4 | "type": "Git", 5 | "repository": { 6 | "type": "GitHub", 7 | "owner": "catppuccin", 8 | "repo": "bat" 9 | }, 10 | "branch": "main", 11 | "revision": "699f60fc8ec434574ca7451b444b880430319941", 12 | "url": "https://github.com/catppuccin/bat/archive/699f60fc8ec434574ca7451b444b880430319941.tar.gz", 13 | "hash": "1lirgwgh2hnz6j60py19bbmhvgaqs7i6wf6702k6n83lgw4aixg9" 14 | }, 15 | "catppuccin-rofi": { 16 | "type": "Git", 17 | "repository": { 18 | "type": "GitHub", 19 | "owner": "catppuccin", 20 | "repo": "rofi" 21 | }, 22 | "branch": "main", 23 | "revision": "c24a212a6b07c2d45f32d01d7f10b4d88ddc9f45", 24 | "url": "https://github.com/catppuccin/rofi/archive/c24a212a6b07c2d45f32d01d7f10b4d88ddc9f45.tar.gz", 25 | "hash": "0236bcwad4cmr1fhnywvcnzf7xdmhhwgrkrq8jdg8livhh1h8rjq" 26 | }, 27 | "fzf-tab": { 28 | "type": "Git", 29 | "repository": { 30 | "type": "GitHub", 31 | "owner": "Aloxaf", 32 | "repo": "fzf-tab" 33 | }, 34 | "branch": "master", 35 | "revision": "6aced3f35def61c5edf9d790e945e8bb4fe7b305", 36 | "url": "https://github.com/Aloxaf/fzf-tab/archive/6aced3f35def61c5edf9d790e945e8bb4fe7b305.tar.gz", 37 | "hash": "1brljd9744wg8p9v3q39kdys33jb03d27pd0apbg1cz0a2r1wqqi" 38 | }, 39 | "zsh-syntax-highlighting": { 40 | "type": "Git", 41 | "repository": { 42 | "type": "GitHub", 43 | "owner": "zsh-users", 44 | "repo": "zsh-syntax-highlighting" 45 | }, 46 | "branch": "master", 47 | "revision": "5eb677bb0fa9a3e60f0eff031dc13926e093df92", 48 | "url": "https://github.com/zsh-users/zsh-syntax-highlighting/archive/5eb677bb0fa9a3e60f0eff031dc13926e093df92.tar.gz", 49 | "hash": "1x33gk7hhp07jqq7yjvrsp2vmdbxmadlv3335ixx29bc6h8106r9" 50 | } 51 | }, 52 | "version": 3 53 | } -------------------------------------------------------------------------------- /packages/advcp/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | stdenv, 3 | fetchurl, 4 | fetchpatch, 5 | upstream ? "coreutils", 6 | }: 7 | stdenv.mkDerivation rec { 8 | name = "advcp"; 9 | version = "9.1"; 10 | strictDeps = true; 11 | 12 | src = fetchurl { 13 | name = "source-${name}-${version}.tar.xz"; 14 | url = "ftp://ftp.gnu.org/gnu/${upstream}/${upstream}-${version}.tar.xz"; 15 | hash = "sha256-YaH0ENeLp+fzelpPUObRMgrKMzdUhKMlXt3xejhYBCM="; 16 | }; 17 | 18 | patches = [ 19 | (fetchpatch { 20 | url = "https://raw.githubusercontent.com/jarun/advcpmv/ea268d870b475edd5960dcd55d5378abc9705958/advcpmv-0.9-${version}.patch"; 21 | hash = "sha256-d+SRT/R4xmfHLAdOr7m4R3WFiW64P5ZH6iqDvErYCyg="; 22 | }) 23 | ]; 24 | 25 | installPhase = '' 26 | install -D src/cp $out/bin/advcp 27 | install -D src/mv $out/bin/advmv 28 | ''; 29 | } 30 | -------------------------------------------------------------------------------- /packages/default.nix: -------------------------------------------------------------------------------- 1 | {inputs, ...}: { 2 | perSystem = { 3 | system, 4 | pkgs, 5 | lib, 6 | inputs', 7 | ... 8 | }: let 9 | upkgs = inputs'.nixpkgs.legacyPackages; 10 | 11 | chromePkgs = import inputs.nixpkgs { 12 | inherit system; 13 | config.allowUnfree = true; 14 | config.google-chrome.enableWideVine = true; 15 | }; 16 | in { 17 | packages = lib.mkMerge [ 18 | { 19 | advcp = upkgs.callPackage ./advcp {}; 20 | "rofi/unicode" = upkgs.callPackage ./rofi-unicode {}; 21 | } 22 | (lib.mkIf pkgs.stdenv.isLinux { 23 | inherit (inputs'.switcher.packages) switcher; 24 | }) 25 | (lib.mkIf (system == "x86_64-linux") { 26 | inherit (chromePkgs) google-chrome; 27 | }) 28 | ]; 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /packages/rofi-unicode/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | stdenvNoCC, 3 | xsel, 4 | fetchgit, 5 | }: let 6 | source = builtins.fromJSON (builtins.readFile ./rofi-unicode.json); 7 | in 8 | stdenvNoCC.mkDerivation (self: { 9 | pname = "rofiemoji-rofiunicode"; 10 | version = "${source.rev}"; 11 | strictDeps = true; 12 | 13 | src = fetchgit { 14 | inherit (source) rev url sha256; 15 | }; 16 | 17 | installPhase = '' 18 | mkdir -pv $out/{bin,lists} 19 | 20 | install -v lists/* $out/lists 21 | install -v *.sh $out/bin 22 | ''; 23 | 24 | postFixup = '' 25 | for f in $out/bin/*.sh; do 26 | substituteInPlace $f \ 27 | --replace 'DIR="$HOME/.config/rofiemoji-rofiunicode/lists"' \ 28 | 'DIR="${placeholder "out"}/lists"' \ 29 | --replace 'xsel' '${xsel}/bin/xsel' 30 | done; 31 | ''; 32 | }) 33 | -------------------------------------------------------------------------------- /packages/rofi-unicode/rofi-unicode.json: -------------------------------------------------------------------------------- 1 | { 2 | "date": "2020-01-05T04:06:07-08:00", 3 | "deepClone": false, 4 | "fetchSubmodules": false, 5 | "leaveDotGit": false, 6 | "path": "/nix/store/i6rnld4fhw8wjd14z45xjz1l8jh2pvrd-rofiemoji-rofiunicode", 7 | "rev": "b30ffa698f1979dae5495f04b20fec413fa085d6", 8 | "sha256": "1568m6d0g2v6cv1sbkk127n12d66z3xx09v80rfrqclgic6ihhml", 9 | "url": "https://git.teknik.io/matf/rofiemoji-rofiunicode.git", 10 | "version": "master" 11 | } 12 | -------------------------------------------------------------------------------- /parts/auxiliary.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | perSystem = { 3 | config, 4 | pkgs, 5 | inputs', 6 | self', 7 | system, 8 | ... 9 | }: { 10 | formatter = pkgs.alejandra; 11 | 12 | apps.rotate.meta.description = "rotate keys for sops"; 13 | apps.rotate.program = let 14 | sopsrotate = pkgs.writeShellScript "sops-rotate" '' 15 | file=$1 16 | 17 | printf "Rotating %s...\n" "''${file}" 18 | ${pkgs.sops}/bin/sops -r -i "''${file}" 19 | ''; 20 | rotate = pkgs.writeShellScript "rotate" '' 21 | ${pkgs.git}/bin/git switch -c rotate-$(${pkgs.coreutils}/bin/date -Idate) >/dev/null || true 22 | 23 | ${pkgs.findutils}/bin/find secrets -type f -exec ${sopsrotate} '{}' \; 24 | 25 | ${pkgs.git}/bin/git add secrets 26 | ${pkgs.git}/bin/git commit -m "chore: rotate secrets $(${pkgs.coreutils}/bin/date -Idate)" 27 | ''; 28 | in "${rotate}"; 29 | 30 | devShells.default = pkgs.mkShell { 31 | packages = builtins.attrValues { 32 | inherit (pkgs) npins sops age ssh-to-age nil alejandra; 33 | }; 34 | }; 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /parts/home_configs.nix: -------------------------------------------------------------------------------- 1 | { 2 | self, 3 | inputs, 4 | config, 5 | lib, 6 | npins, 7 | ... 8 | }: let 9 | cfg = config.nobbz.homeConfigurations; 10 | 11 | enabledCfgs = lib.filterAttrs (_: config: config.enable) cfg; 12 | 13 | configs = builtins.mapAttrs (_: config: config.finalHome) enabledCfgs; 14 | 15 | packages = builtins.attrValues (builtins.mapAttrs (_: config: config.packageModule) enabledCfgs); 16 | in { 17 | options = { 18 | nobbz.homeConfigurations = lib.mkOption { 19 | type = lib.types.attrsOf (lib.types.submodule ({ 20 | name, 21 | config, 22 | ... 23 | }: { 24 | options = { 25 | enable = lib.mkEnableOption "Enable this home configuration." // {default = true;}; 26 | 27 | nixpkgs = lib.mkOption { 28 | type = lib.types.unspecified; 29 | default = inputs.nixpkgs; 30 | }; 31 | 32 | system = lib.mkOption {type = lib.types.enum ["x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin"];}; 33 | 34 | username = lib.mkOption { 35 | type = lib.types.str; 36 | default = builtins.elemAt (lib.strings.split "@" name) 0; 37 | }; 38 | 39 | hostname = lib.mkOption { 40 | type = lib.types.str; 41 | default = builtins.elemAt (lib.strings.split "@" name) 2; 42 | }; 43 | 44 | entryPoint = lib.mkOption { 45 | type = lib.types.unspecified; 46 | readOnly = true; 47 | }; 48 | 49 | base = lib.mkOption { 50 | type = lib.types.str; 51 | readOnly = true; 52 | }; 53 | 54 | homeDirectory = lib.mkOption { 55 | type = lib.types.str; 56 | readOnly = true; 57 | }; 58 | 59 | modules = lib.mkOption { 60 | type = lib.types.listOf lib.types.unspecified; 61 | default = []; 62 | }; 63 | 64 | finalModules = lib.mkOption { 65 | type = lib.types.listOf lib.types.unspecified; 66 | readOnly = true; 67 | }; 68 | 69 | packageName = lib.mkOption { 70 | type = lib.types.str; 71 | readOnly = true; 72 | }; 73 | 74 | finalPackage = lib.mkOption { 75 | type = lib.types.package; 76 | readOnly = true; 77 | }; 78 | 79 | finalHome = lib.mkOption { 80 | type = lib.types.unspecified; 81 | readOnly = true; 82 | }; 83 | 84 | packageModule = lib.mkOption { 85 | type = lib.types.unspecified; 86 | readOnly = true; 87 | }; 88 | }; 89 | 90 | config = lib.mkIf config.enable { 91 | entryPoint = import "${self}/home/configurations/${config.username}_at_${config.hostname}.nix" (inputs // {inherit self;}); 92 | base = 93 | if lib.strings.hasSuffix "-darwin" config.system 94 | then "Users" 95 | else "home"; 96 | homeDirectory = "/${config.base}/${config.username}"; 97 | 98 | finalModules = 99 | [ 100 | config.entryPoint 101 | {home = {inherit (config) username homeDirectory;};} 102 | {systemd.user.startServices = "sd-switch";} 103 | {news.display = "silent";} 104 | inputs.nixos-vscode-server.nixosModules.home 105 | inputs.sops-nix.homeManagerModules.sops 106 | ] 107 | ++ config.modules 108 | ++ builtins.attrValues self.homeManagerModules 109 | ++ builtins.attrValues self.mixedModules; 110 | 111 | packageName = "home/config/${name}"; 112 | finalPackage = config.finalHome.activationPackage; 113 | 114 | packageModule = {${config.system}.${config.packageName} = config.finalPackage;}; 115 | 116 | finalHome = inputs.home-manager.lib.homeManagerConfiguration { 117 | pkgs = config.nixpkgs.legacyPackages.${config.system}; 118 | extraSpecialArgs.npins = npins; 119 | modules = config.finalModules; 120 | }; 121 | }; 122 | })); 123 | }; 124 | }; 125 | 126 | config.flake.homeConfigurations = configs; 127 | config.flake.packages = lib.mkMerge packages; 128 | } 129 | -------------------------------------------------------------------------------- /parts/home_modules.nix: -------------------------------------------------------------------------------- 1 | { 2 | self, 3 | inputs, 4 | config, 5 | lib, 6 | ... 7 | }: let 8 | cfg = config.nobbz.homeManagerModules; 9 | 10 | inherit (import ./module_helpers.nix lib inputs) submodule; 11 | 12 | modules = builtins.mapAttrs (_: config: config.wrappedModule) cfg; 13 | in { 14 | options = { 15 | nobbz.homeManagerModules = lib.mkOption { 16 | type = lib.types.attrsOf submodule; 17 | }; 18 | }; 19 | 20 | config.flake.homeManagerModules = modules; 21 | } 22 | -------------------------------------------------------------------------------- /parts/module_helpers.nix: -------------------------------------------------------------------------------- 1 | lib: inputs: let 2 | inherit (builtins) isString isPath; 3 | 4 | callModule = module: args: let 5 | moduleToImport = 6 | if args == null 7 | then module 8 | else import module args; 9 | in 10 | {imports = [moduleToImport];} 11 | // lib.optionalAttrs (builtins.any (p: p module) [isPath isString]) {_file = module;}; 12 | 13 | from = lib.types.oneOf [lib.types.str lib.types.path]; 14 | 15 | submodule = lib.types.coercedTo from (m: {module = m;}) (lib.types.submodule ({ 16 | name, 17 | config, 18 | ... 19 | }: { 20 | options = { 21 | name = lib.mkOption { 22 | type = lib.types.str; 23 | default = name; 24 | }; 25 | 26 | module = lib.mkOption { 27 | type = lib.types.oneOf [ 28 | lib.types.str 29 | lib.types.path 30 | # TODO: add sets and functions 31 | ]; 32 | }; 33 | 34 | extraArgs = lib.mkOption { 35 | type = lib.types.nullOr (lib.types.attrsOf lib.types.unspecified); 36 | default = inputs; 37 | }; 38 | 39 | wrappedModule = lib.mkOption { 40 | type = lib.types.unspecified; 41 | readOnly = true; 42 | }; 43 | }; 44 | 45 | config = { 46 | wrappedModule = callModule config.module config.extraArgs; 47 | }; 48 | })); 49 | in { 50 | inherit callModule submodule; 51 | } 52 | -------------------------------------------------------------------------------- /parts/nixos_modules.nix: -------------------------------------------------------------------------------- 1 | { 2 | self, 3 | inputs, 4 | config, 5 | lib, 6 | ... 7 | }: let 8 | cfg = config.nobbz.nixosModules; 9 | 10 | inherit (import ./module_helpers.nix lib inputs) submodule; 11 | 12 | modules = builtins.mapAttrs (_: config: config.wrappedModule) cfg; 13 | in { 14 | options = { 15 | nobbz.nixosModules = lib.mkOption { 16 | type = lib.types.attrsOf submodule; 17 | }; 18 | }; 19 | 20 | config.flake.nixosModules = modules; 21 | } 22 | -------------------------------------------------------------------------------- /parts/system_configs.nix: -------------------------------------------------------------------------------- 1 | { 2 | self, 3 | inputs, 4 | config, 5 | lib, 6 | ... 7 | }: let 8 | cfg = config.nobbz.nixosConfigurations; 9 | 10 | configs = builtins.mapAttrs (_: config: config.finalSystem) cfg; 11 | 12 | packages = builtins.attrValues (builtins.mapAttrs (_: config: config.packageModule) cfg); 13 | in { 14 | options = { 15 | nobbz.nixosConfigurations = lib.mkOption { 16 | type = lib.types.attrsOf (lib.types.submodule ({ 17 | name, 18 | config, 19 | ... 20 | }: { 21 | options = { 22 | nixpkgs = lib.mkOption { 23 | type = lib.types.unspecified; 24 | default = inputs.nixpkgs; 25 | }; 26 | system = lib.mkOption {type = lib.types.enum ["x86_64-linux" "aarch64-linux"];}; 27 | 28 | modules = lib.mkOption { 29 | type = lib.types.listOf lib.types.unspecified; 30 | default = []; 31 | }; 32 | 33 | entryPoint = lib.mkOption { 34 | type = lib.types.unspecified; 35 | readOnly = true; 36 | }; 37 | 38 | finalModules = lib.mkOption { 39 | type = lib.types.listOf lib.types.unspecified; 40 | readOnly = true; 41 | }; 42 | 43 | configFolder = lib.mkOption { 44 | type = lib.types.str; 45 | readOnly = true; 46 | }; 47 | 48 | bootloader = lib.mkOption { 49 | type = lib.types.str; 50 | readOnly = true; 51 | }; 52 | 53 | hardware = lib.mkOption { 54 | type = lib.types.str; 55 | readOnly = true; 56 | }; 57 | 58 | finalSystem = lib.mkOption { 59 | type = lib.types.unspecified; 60 | readOnly = true; 61 | }; 62 | 63 | packageName = lib.mkOption { 64 | type = lib.types.str; 65 | readOnly = true; 66 | }; 67 | 68 | finalPackage = lib.mkOption { 69 | type = lib.types.package; 70 | readOnly = true; 71 | }; 72 | 73 | packageModule = lib.mkOption { 74 | type = lib.types.unspecified; 75 | readOnly = true; 76 | }; 77 | }; 78 | 79 | config = { 80 | configFolder = "${self}/nixos/configurations"; 81 | entryPoint = import "${config.configFolder}/${name}.nix" (inputs // {inherit self;}); 82 | bootloader = "${config.configFolder}/bootloader/${name}.nix"; 83 | hardware = "${config.configFolder}/hardware/${name}.nix"; 84 | 85 | finalModules = 86 | [ 87 | {boot.tmp.cleanOnBoot = true;} 88 | {networking.hostName = name;} 89 | {nix.flakes.enable = true;} 90 | {system.configurationRevision = self.rev or "${self.dirtyRev or "unknown"}-dirty";} 91 | {documentation.man.enable = true;} 92 | {documentation.man.generateCaches = true;} 93 | {nixpkgs.hostPlatform.system = config.system;} 94 | inputs.sops-nix.nixosModules.sops 95 | ] 96 | ++ config.modules 97 | ++ builtins.attrValues { 98 | inherit (config) entryPoint bootloader hardware; 99 | } 100 | ++ builtins.attrValues self.nixosModules 101 | ++ builtins.attrValues self.mixedModules; 102 | 103 | packageName = "nixos/config/${name}"; 104 | finalPackage = config.finalSystem.config.system.build.toplevel; 105 | 106 | packageModule = {${config.system}.${config.packageName} = config.finalPackage;}; 107 | 108 | finalSystem = config.nixpkgs.lib.nixosSystem { 109 | modules = config.finalModules; 110 | }; 111 | }; 112 | })); 113 | }; 114 | }; 115 | 116 | config.flake.nixosConfigurations = configs; 117 | config.flake.packages = lib.mkMerge packages; 118 | } 119 | -------------------------------------------------------------------------------- /secrets/mimas/default.yaml: -------------------------------------------------------------------------------- 1 | restic: ENC[AES256_GCM,data:XMkh9jvehbD3Zg==,iv:9NdaTuhLR57mv8OaCSyso9cfr8V1iQNuQuWInKyi3bI=,tag:Kz08EadPaIWcytF6ASJssw==,type:str] 2 | rustic: ENC[AES256_GCM,data:ETWxyvBz3AlXNp0=,iv:MXlQuvTJa2mZuXeiCX/YYpbqKpT1+RE5TNahBrUMM3Y=,tag:Vl7n0JF5M9Q+xZD32G1njQ==,type:str] 3 | rustic-user: ENC[AES256_GCM,data:2hwYQS4nAA==,iv:y0pbF5axrPRdYRGAmx+kp7jkmSl77R8LQMUKQaiDWak=,tag:8kgcxNtvjmyT9PPc/WjrOg==,type:str] 4 | traefik: ENC[AES256_GCM,data:kMnWaxpt0fLxJeX3oYLQrnZPS+pq/xjqVINleaCfaiXeMlJ8qno0eHBkx82gjldeObvTO1ENFz5k5EJ0ICbnS0ny6qHxeBAMaNVF3dZ+XmKx7w==,iv:ZL90s3YuBmwafBz7VEwCTr2flnkguUxJgPp9OrnyfGA=,tag:UeyiUtdQwOlyQoHObL+80w==,type:str] 5 | warden: ENC[AES256_GCM,data:H3So3oZfZ6MBKsjxJNnxk/6UZi6J5D6H5bCMsb1E7rk/r51qYDe+1z2Gq1o0qqwX0k/O4Dxq7wJPaelLO4kE9bxQHvoT1NJQIZolnYF5G/PMqMKWIE4bxq6uLmxNKBmjOkJLo3hBiOHT8MjD/S6rOkUAB6Mn4YRKqcG+EG1Wz0sw1a+6KcNFMqO9xdcwD44MZYrreexOiwVx6UMPSJc/67fvzJ4ms/E3gQEOq6VvCHpxmk4bujo9ucqajfPGK4ewHqkdn4r0vQvrYxXMBkX7AXcL6CHSZ+ht0Hcw0A+m12GuTSHC0g38Avz5klP3FIruzj7oWcjv6XPBYfk=,iv:OauSp63ywmrkENIqBVGVQ99Ozyom0o+DfSqYaL46Ujg=,tag:ZcYkapCUZZE9DDh0PSfZEg==,type:str] 6 | sops: 7 | kms: [] 8 | gcp_kms: [] 9 | azure_kv: [] 10 | hc_vault: [] 11 | age: 12 | - recipient: age1wpwkf2g475umw3wwns57r8ucykvy6lflpc7uphs0mx9exsj04quqpy7t6r 13 | enc: | 14 | -----BEGIN AGE ENCRYPTED FILE----- 15 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVRkRBcWlnM25ablJBdit2 16 | b0Y1Zy9PM2FjRmg5ajN0YWpsaitJUStTTXlBCnpuL2wvU0hxZFpDREhiTmhnaFFi 17 | LzkxMmVHYWo4TkZOaStJeHZsK3pIZG8KLS0tIC9DSjUyUVk0SG9mNHd0aGdXN1ow 18 | N2Q4QWk3RU83dUxuSG85V1N5TzFkSVEK58cE6fE6mxjRCgtHRMqqahqMkwYeUnhx 19 | F2Bdg5oPPQxoqIf769fZD9L1y/+LZ6Vi4YhJkjfMVFXk6YtEjKJSmQ== 20 | -----END AGE ENCRYPTED FILE----- 21 | - recipient: age10jl78vwyqk622dpn2890l9jl4et3p7lsr8wh8vusem3j8jdxle8qg000qa 22 | enc: | 23 | -----BEGIN AGE ENCRYPTED FILE----- 24 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkY3EzZyt1YXFTTlVhK3Rk 25 | djUvWmVjeDBSajlENCtNc0RZMVRVWUVuRWtBCnFpa0NnVjBvb0J2NCtpYitoMngv 26 | WkxNaDNIQnRSSm0vSXF4a1RYcmNsK2MKLS0tIE5zSkExNVVJYkZsV244eElwMTd0 27 | N3ZuTHhVdFo0aGZVMXFlaTdsRi9lRUUK+K5CUVCdjtMVegVydoKRIb6kpPnfBiy1 28 | FxkXAp3a1qU2WqNvXCSO3gtUwYaMG+MPSCWI1gA3oBjGGtTasHyHsQ== 29 | -----END AGE ENCRYPTED FILE----- 30 | lastmodified: "2025-03-08T10:44:25Z" 31 | mac: ENC[AES256_GCM,data:iKKmalnJnmm8EkDupTPKmKJydLLYkbAabLy5KJdQfKGvRj6vbJAQHZ3u0Pu2TI0oi5Xv3dtPh7ww04kT0Whe1E97p4t3RPyNCCGNqA8OqQiCPDUn6uqTQwOo1//3xIGFnnRC0VSYrQT0rjebbL96RnWE9XF67TefycxIMHusUXU=,iv:FU6VTW2zkEIlH5P/rr58gmuMnz16TCLP+UtEVkiLueg=,tag:uf7I1GwWxXOT190y8Hddow==,type:str] 32 | pgp: [] 33 | unencrypted_suffix: _unencrypted 34 | version: 3.9.4 35 | -------------------------------------------------------------------------------- /secrets/mimas/nmelzer/default.yaml: -------------------------------------------------------------------------------- 1 | rustic: ENC[AES256_GCM,data:aYi1wQgLgRL3n40=,iv:NHuqnSibmY/RkJrSUWm0TbgG45iSdjso9ABI8SGqUTg=,tag:k13fNK3kDcylC53d/haqog==,type:str] 2 | sops: 3 | kms: [] 4 | gcp_kms: [] 5 | azure_kv: [] 6 | hc_vault: [] 7 | age: 8 | - recipient: age1wpwkf2g475umw3wwns57r8ucykvy6lflpc7uphs0mx9exsj04quqpy7t6r 9 | enc: | 10 | -----BEGIN AGE ENCRYPTED FILE----- 11 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3U1ExOVN2aWVRVnB2M3RR 12 | QmxQNDZnSWVWMW1IZWh5YmFmNTZYbGRzSFVRCjdvSGp1WThzc29aNUZQMHJDMThJ 13 | MXNURHJUVVpDQ1hmUDBFamJ3TnRUSzQKLS0tIExXdWNoRm9aL29nUldQemwxOXdV 14 | aktSY1lQZmxkTThpcU82Q0dwSUUzUmcKm2VCJHEUzjz2vXAJH1wOovNqzK6Hkk2z 15 | hoIQzqgfQL3a4WA1q0Oj+R8wBChuRMUAYW4+TWCIAckKKwLqRyzBcQ== 16 | -----END AGE ENCRYPTED FILE----- 17 | - recipient: age1w6xjgskpxnlpleswumdhtt7x8zx35qn329yz3x7ftqdcmcxrrvnqnuf9d6 18 | enc: | 19 | -----BEGIN AGE ENCRYPTED FILE----- 20 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSamQ1R0tHZGIxUlN3NWtV 21 | Q1htSVdJMG5rUEN6Rm1QTStONys3YjNiVEdzCmE0bDJCa1VaVTIyK1IvTDBFbVhs 22 | ZWVGSzdwUWpVZTNSYUkvNjNtTERnZHMKLS0tIHRLSnBxTm8rVVo5ME4vS0dKZXF5 23 | MjdaWk9mZEczVGVxZEpnN3pCQTdMOFEKO4oemn8P9PYZVTsJ81oDy17PRAaeu3pn 24 | zxZ5a8/IrS/lZfMJ1vYwlZf0AEgOMTSyjVMNyOkWAgWIq8z1UkrpUA== 25 | -----END AGE ENCRYPTED FILE----- 26 | lastmodified: "2025-03-08T10:28:45Z" 27 | mac: ENC[AES256_GCM,data:k+Ui8hxJM/W4vHxZtSkTO86L81ZnzXHcX+VEzef438dfoB6rhIUhz6OaVfLnF6v3RSzRPsYCoDP8L2p1vHAY42ljl4jzZvMqrIYU2N7ATTNFc+m2FO1lcfmKbsOqjkrVQxnux8lwBdD9e2H4/xOB+nAivuCEDd3rihYR0yRYiMI=,iv:yMu0MA0VTdwUsKkZUZAVo91iI9qaT+qOVVI3hlmZC0c=,tag:bbKM/vE0lEpvPHIKWk9llQ==,type:str] 28 | pgp: [] 29 | unencrypted_suffix: _unencrypted 30 | version: 3.8.1 31 | -------------------------------------------------------------------------------- /secrets/phoebe/nmelzer/default.yaml: -------------------------------------------------------------------------------- 1 | ssh: ENC[AES256_GCM,data:Ti7PvRp+ooyu/MHGv90zlACZVzE5EseJUFk5KvxwYbE+bLcEKnTWW8yV+BBa3xoOe50P4X0GeNFHLsaCcCtrjNshNJSxZ3QHt1TQjLABvKrQvpU8BgN3qT3RMo019NMj0+UxWL4/5icaR4XAax+JWCTBXhncqFzyXqcB/IbLLJKKqqFTWe4zYhvQitBDF+oU6nTv/qTtj/6B7XN6byTbGPjTJrEXLotmbvl8ll/LiEkTPmuu,iv:poHvd4U4dJha27Bqf4hA1pFhna29kO/RnFNjJsflpaA=,tag:uUfl6tjzVQQ5oaKOcmUYQA==,type:str] 2 | sops: 3 | kms: [] 4 | gcp_kms: [] 5 | azure_kv: [] 6 | hc_vault: [] 7 | age: 8 | - recipient: age1wpwkf2g475umw3wwns57r8ucykvy6lflpc7uphs0mx9exsj04quqpy7t6r 9 | enc: | 10 | -----BEGIN AGE ENCRYPTED FILE----- 11 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwMnNzT2dFWWVPRjh2QUdF 12 | VUZkUzdsQXRISG9kaHVqSGp2UWhCNlN3cVFJCmtQbE9LelRkbW4yU3ZyWG9MdnZB 13 | b1k1QUwrOXBZQTVoRTArNGFtTEJSU0kKLS0tIG5KS3ZFd0hKMEhsSkV4ck5za2VQ 14 | YzFLSjNUVXNRaklnczVKdGQ4V0JYUE0KGVHj8sWKKvVGwMrYmx0Js1uI1DmD028V 15 | R+Y+p8H766496hBt6Eza6r7JhKtLXR5CrcoItq8m+fWU6lu+ElsnAw== 16 | -----END AGE ENCRYPTED FILE----- 17 | - recipient: age1vr0uq6mwv844yvm8pe7qxjxpqrekgel3lqfzuuqtfzj0ehz3hphqzsxjna 18 | enc: | 19 | -----BEGIN AGE ENCRYPTED FILE----- 20 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRSTB0dGxWOFhTK0FHcGxI 21 | VkFKV2NkZTlJRVNSZ1dnWVBKQk02YmZ3aERnClZaeTFSYzRJZ3ZWQjNPc1BnanhU 22 | ak1RZ0w0MDExZVlJWVNrYjZxMHZsNEkKLS0tIE9tWHlVMEFpek1VTFdROE8zUFZa 23 | VU9yempBMGVXenkxdkpHZC9YdlFZYm8KsdOmOI4ah0pEjqPt9XnJNxMyFSY4eYsI 24 | UOgJZqRhlG8Y4NL6J1DyJPfeKeIroTAbNoCb65lxWHHWfoPvt3gU3A== 25 | -----END AGE ENCRYPTED FILE----- 26 | lastmodified: "2025-03-08T10:28:45Z" 27 | mac: ENC[AES256_GCM,data:ycmOZIduc6cbx9daCGmLOL6eNSroAkGJw9dSnR79feaplXi6hmvycijcSJkys2vA3m81K2E7MW465GfodkpW1YWT1xW8RPp+WOOlqZvu3qoSu3F2T/VJxx4wCzTaXwvkcY9APAqb+WydN5KQDzakWaJfw+gTP3OS8LTRkYCDtcc=,iv:soCcQcGoi41g+g5X1SVDNH7iH28BCSImZqY1OE/H1Bo=,tag:RGY47osA22GETBuOynX1Dg==,type:str] 28 | pgp: [] 29 | unencrypted_suffix: _unencrypted 30 | version: 3.9.1 31 | -------------------------------------------------------------------------------- /secrets/users/nmelzer/default.yaml: -------------------------------------------------------------------------------- 1 | access-tokens: ENC[AES256_GCM,data:sLkIWAyispOwNUZJqXfTFVl8NbUcLhWhgLIVI2rahROYHMO3aU/0x8BOtmm0QkPYHA3C7GwzyvatMoASJWrqn6ife48=,iv:BPI8HwuKwfzOMT2gs7U0cpbpP77f+X/HvCcfvIJh9Q4=,tag:Kf2wZ+3xtKhaSY5S1QjTuw==,type:str] 2 | sops: 3 | kms: [] 4 | gcp_kms: [] 5 | azure_kv: [] 6 | hc_vault: [] 7 | age: 8 | - recipient: age1wpwkf2g475umw3wwns57r8ucykvy6lflpc7uphs0mx9exsj04quqpy7t6r 9 | enc: | 10 | -----BEGIN AGE ENCRYPTED FILE----- 11 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwcVV6MWRlWjhSQUt6V2E4 12 | R3h5ZTlTei9QaTBnSm0zQXU4Q2dkVFdkL0JRCjVnbHFpQ0VaVis1TENCbVQ0Tm9F 13 | bmxZakNpMmIyTmZTdy9aRDJKNGU0dWMKLS0tIHYwMGJxV3VhNTd3b1gwRUREMWVW 14 | MUVzclBGZmV5d2lZcFJyMzViZGxXbFkKpgyVR4xv8NA6J7keZwVvJX0QSjoTAaW7 15 | 9fu5UR/d/pYIoJswd7jPNdhnClRLnTpJB62RZf+HHzGU2uq6aND1AA== 16 | -----END AGE ENCRYPTED FILE----- 17 | - recipient: age18p8x2cxam2l0trtpyhj4x9amcppp9ruzkqxzgapy9wnfpzl9hgaqlkht86 18 | enc: | 19 | -----BEGIN AGE ENCRYPTED FILE----- 20 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXeGFqL0NVaFYxaWVNdVFa 21 | Y3JKdFE3dnh0cFhQRVFqZjdXWHJ6VjV4eVdZCmZQUmJXNDZUbmVvWjRaMk5VSkxL 22 | dFpVTDRqR05xcm5OMDYxc2NjNXNJYTAKLS0tIFNmZ0JsR2MwSzhWeWhwUEx0WlUy 23 | ZlM1NXhPSjdQaGZlVDN1UGZLNDJRNVEKLmyd5dcZhNPKltxgVgHjJR1KQEcYOJ1V 24 | 6jY2Pq1dw8n8CswcThH4GmWBTqttEirFV8tB8CkYvHGk7oJCpX8gIg== 25 | -----END AGE ENCRYPTED FILE----- 26 | - recipient: age1w6xjgskpxnlpleswumdhtt7x8zx35qn329yz3x7ftqdcmcxrrvnqnuf9d6 27 | enc: | 28 | -----BEGIN AGE ENCRYPTED FILE----- 29 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwTEZRbk42bk9UdWh5bUFY 30 | MlBoVUFScE0yUlJNeUlDOFNkZTNmZ2ZYZXg4CnV0a3JTOEZmZXdJYmxUOUlQR2pm 31 | QzRmcGhWZW5RcGpLYURTWGoxcEtZVVUKLS0tIHVieWVteHcyMFRUOEZFVVYxN1oz 32 | SklxWSs3RDhtNHdjZ2tZb0ZSRG4ydlkKvjxtjpOtaNmzeGnVqVLbkI8cEh0wKsLH 33 | k5J7At247/4BFnQApfnw2cbeve2aQVsDjO6a6aZwcVrYQrErq/Ltog== 34 | -----END AGE ENCRYPTED FILE----- 35 | - recipient: age1tf0zelmw4lh9gvkl0qycdk83fut9t4q3tfcdzk8cvlyhjp7z0g2q7hklgq 36 | enc: | 37 | -----BEGIN AGE ENCRYPTED FILE----- 38 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvemdIMXNVSFNibjBmc3cz 39 | YXR3dHNGVGpUZDhtWGtSZVMwWHdKcU9zQ0VjCnNpdmMzNldvYi91ZWdGTkJyaWlF 40 | R2tBcHg5aXpFR2x3M2Q0RU0vVWU0OUEKLS0tIEZYRWVpc2JLWGEvVExpSktDcFNQ 41 | ZDFySCtOdk1Kdm1yRnlaTzFZRkpvQVUKGZoNU9KJgFOJau7Gxge47txwpAlMh2rQ 42 | 6Hfjf8E1igzLnbjvxQcGa2xVvI95KqhKZZclzPX9Vagl1z3XnoCvSw== 43 | -----END AGE ENCRYPTED FILE----- 44 | - recipient: age1vr0uq6mwv844yvm8pe7qxjxpqrekgel3lqfzuuqtfzj0ehz3hphqzsxjna 45 | enc: | 46 | -----BEGIN AGE ENCRYPTED FILE----- 47 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1ci9GbWNmMWU4S1lGelFi 48 | TVAvUUE0TmtxNE9nSURqQjVSb244bnBjdlJBCkY5eHhaRUxiOXA2OFhSTkthR0d4 49 | dDhMUGhNeXA3aHcvemNZczU2bVpsQkkKLS0tIFZEMFFyTGJwWkR6QXFvYnZHVnNs 50 | OUR3N2IyMkxJc3RqcmorUFBOYjRpa2cKPQT3cmtP7I2C38OPaRqxudCXv6CEObnp 51 | DOVPG5JpeQGEu74kK5WTqbWlQU8AToOXmJdc+ru7ea1wAiXZiKEG4Q== 52 | -----END AGE ENCRYPTED FILE----- 53 | lastmodified: "2025-03-08T10:28:45Z" 54 | mac: ENC[AES256_GCM,data:VktkGG1xk+tFtgdmLrM7rLQ+NEqDMATyu0kdm4iRe61mcMppNVR7ZxjP7Ryfz6kkiwAfqrv5g8pzaoHHCJoLAOShgCDdHB49USDVR7OZHp/BiNJkSwSYgSWsWQf4Wxve2lADcGJNrOD/l8jmO9DcUDldLdGEGJeZ6waej3g7z7Q=,iv:FhfHa/LN9UVC8fnilYv2NxlNT+xRRXdsKIejOqug4cc=,tag:mTBuhaR2AxulRrfPSB6F+Q==,type:str] 55 | pgp: [] 56 | unencrypted_suffix: _unencrypted 57 | version: 3.9.1 58 | -------------------------------------------------------------------------------- /secrets/users/nmelzer/github: -------------------------------------------------------------------------------- 1 | { 2 | "data": "ENC[AES256_GCM,data:WaE9ywj9g4TvMdjrRmKjwxwTuak4gsPENMaP37qdxQTSvp+dhklwaIh+LIAIMhPHYtrhBMNj1viHnaIETwMIB7uUsblKIYa6AOxpi9CU9xPkpBhKGw7vMEfCjlj9rHPjB41W9EN/EDVgY0phYFRF7DSoOa1wpHouKwKbbaO3r8L+ZbN4BOiizquzMOVOxp1b71xsc34WvrAIQc7+0H5f145I+KPAKGkUSMrV7t0RJTC24ENa9Zz7n0NduoLokK/IGXt6tsQNnzdS/DTmLw2W6fVkb5b4uzEvkqgnQOuQilH4CMX+xsuEkUkWqe3E8sUlzvdUszAjfruQUvJDuC//Vvx0vE1Kx70h+8BCqDGPLIs/4aEtW7xfu5B09WOQKByyd86NArZsC6R+sbmTCPD7WLFV9NI7Sg+E1wkPSmtYUYeMTmvPwfNISLKC4KHNm0cp5rb0EhmZTxKu1qId59vNdpjTnTEz0AZAGoVB1pGi45Bb0pUE/n54WsNhuscOVHk2XdYH/BTcEU8VYpLvcNAWFX/a1MWc0Bx21e8Qk/KNZGuATrWLiXIhGxT33bmlm2/Lb+5LS7xwMxomu1g0xGzSzD3z2B9CExekUw7q9VWfAinVecHA8NbMLrajkqGQb7fbcTqXOQqXL6BrQDbaOb/hC/AffYq4SEurvP4BI30E1hArLIlHabLwxBOaNLB/Ii7i51BKWqQGaof01ziAWChptvSic/oN6xnF6CbpXLr1r/z5WoLm4MqEQJ4Qvp+vsAChan/1kG3S93xpgYof3PZsrSpxxfGSJq2qBZq5Xd//6CfHdwhdulaciKi32F0GV+DTkDAWTwOOy5fo8IC3bLnWr8rFo3iS0DhETR2V7s1/w6MU/0iuPz95TrBffNvaI9uSehJaQwI4a3Y2M79nxB9xfgHIsbh4+fef8OFa53snckCCzY74Rsv3Th7HliBLVcpAUNvaw5xFnECFkjq/uJVd3cJ3GnYO01InxRqkHm7Bl4RqA0tctpzM98p6RtidTAZ1RHZD3rwgU/oPoV8a32gcmhdRbm8m1/nBXDg2aoSXYJ9NhGtJ2hK+ufsW+szAv240SVX/JH5vk7w7T6H7n6UcZqxYozjAqawP7hUSB/eYfY3uKJIxUdJmGfnDq+L8/d15Pnbqb6zD9qSHi38OfKUTAe8WONWSiziK9EEO5R1EPAdsZod3CFBx0K/TfrBC2mpCZIUUY1HqIDICsDUoFdzj377tLQqcF6K/b0r0sL5rw8L0I6pZiYCCz4LfaBg+oCJwupTqnm1Lusstw1EZP0Psqt+pabj30wA5JPPbo+EB7X5oK6P9N7b/Hw9MpQNNddTvZk0bHI9l5hUZF/rv6TY/qVVCKcAH06bCbQfPvzV9Q6fc+e6/k401zVplq73+WjiqxUWm9iNhrWodXpLWH7Zj3Tcn/mmWNRYUvJE9IccTd+mQ+rvfAM8om66NH68zISbPlDeBuEUIhUlCihpUOerE5j/SasBuTqnrXNz1Z+aR3LT40r4QH2OMEeBR93pPbsZ2l/2zoqL8t685U8B3nimYAE6bwpdn6tErT3MnO2+R6VKIISaUm29Kang6jfDPgPaOZPVXCN05O35Of555TjbSn2XXsh7jqnnp7qW6zUXCcM2Q470yAlQXF9VAXLTI0zKkTVK5b4g0jNs9IFHXelw4vZNM26L5wsTVsvvjW8TpJm8Hkf/Flv3hjLQql21YyAejxRe/vu4ku80Gglwrqyu6wVdZtL28lqZwt0k06z19JuxbTwyck7cSQpMiHg5Ou/0ThqHJdEbCv10d61Be6bZ/kGaqG7mjzX16BjGJamzrRsW+dB96WGipFfLswFka4slB0Bsn5uA9awhNTR9JJyAk+6LvXDg/YigSYiwpXqcOoSPY8KrfBapNussU9oYPqIumdocMGvIzg9MOqpR4Kl9E/ZOyf0gzomIYqdP7elFNnmcxDmuGBwexqO188w2pRIQ7C/GrCwmarMJfe2ZKozmVAbMPaze9B3lLs2gb059tj6WF2xTJd/3HYxbdmUtMeGIrQkxKhFxBY/+bU8M4rhbR5HZiOJIfqko/lAPPQIB9UMGC0yBfGofaZYndHtJAjf9LKLtj3crHAPd1vsS7zyy8rhGkNGFHJNnYgyvYZT1A3eM36W7MlCnVImgENg50uV6xFFKzruiVLTLhF68bfKRKnncxw2sb0dKBGvVcOFm6At7ZgtM8bX2HIlM+7A==,iv:+pnvwKJLNUD+0tpxurFocDgK0qOGzVsYkcV6b6KYock=,tag:oVCamxWlyuQU7McVwxZUKw==,type:str]", 3 | "sops": { 4 | "kms": null, 5 | "gcp_kms": null, 6 | "azure_kv": null, 7 | "hc_vault": null, 8 | "age": [ 9 | { 10 | "recipient": "age1wpwkf2g475umw3wwns57r8ucykvy6lflpc7uphs0mx9exsj04quqpy7t6r", 11 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOSEw0c0dWY0JhdGpMVFo1\nc2kzQm1FdHZIaEtuRG4zYUIyU0Z0QmVOdVZFCkpNTFJpTi9ha1VFb2l5czJONnl4\na3lYU1VmNmpBNzNBdVZEMjNRVjF0RG8KLS0tIFRhTEs1RFF0cTRnNTJqbDVJajh5\naG5UWExpVVl5YjZKUUQrT3gxR09CbVkKc64s7ROfryegUfEr+lS1KkbUDJo7+hso\nBvdJ4EJqS1Uu6H2XugpwBco640PKknJABrkL68LdUGlsUsITqK/MFQ==\n-----END AGE ENCRYPTED FILE-----\n" 12 | }, 13 | { 14 | "recipient": "age18p8x2cxam2l0trtpyhj4x9amcppp9ruzkqxzgapy9wnfpzl9hgaqlkht86", 15 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGOFBxeFNVU1RTSUNCOG1B\nZGhZQm1WSjR1NmsrYkpBd3A0M3liNlNEYXdZCkJKUkp3TGRsMzMrZ2RvU1YxVU0y\nMDJGT0dwQzM3T2pHZFplcFozYi9Pek0KLS0tIFlEb3VuaVJ1QlJPRWlVVDJaMnV4\nQzNhNzBuL1JZeFljb1hwMkp6NE9hY0EKtSZY/B+DbKkDW6cof3sjud77Qz+S6qO4\n81N0I13ywjMmLKLE/eXKEwRXvZkTV8o4AfkZIZo+JPvMgXcujrTFzA==\n-----END AGE ENCRYPTED FILE-----\n" 16 | }, 17 | { 18 | "recipient": "age1w6xjgskpxnlpleswumdhtt7x8zx35qn329yz3x7ftqdcmcxrrvnqnuf9d6", 19 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKMHA0ZHRjU2tYSEZna2ZV\nUjFTRDdMV1B1Ny9YbGlXVmEyRUNuMlRWSDFjClR6cjhHaHVKRFFGWEJHdERZZDRw\nQU9sVC9SNGZUUGxrVUdJWlVwbGpBa1EKLS0tIHYyeWZtS2ZjWTVJZWExTkJWdzFJ\na3NDMUNhSEtiamhIVUV6T2luNjI0S1UKIVHr+P3jpJY/k44EEE1RYB/PQxI4E3lw\n1DdyulRw0CvhuxVoZsINckTjgNIfRSeJlqS2OYEYfHPvqg2xcBNlGg==\n-----END AGE ENCRYPTED FILE-----\n" 20 | }, 21 | { 22 | "recipient": "age1tf0zelmw4lh9gvkl0qycdk83fut9t4q3tfcdzk8cvlyhjp7z0g2q7hklgq", 23 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArRWhuWVNScC9IK0Vya2oz\nZ1JSRERnSmpJVEVNY3VlWnZLcUFESUxVM2dBCjFSdUtEbTVDZ3V1eERja1hnb09I\nWGNLcmNKcW5wOHFIMjJUWTJrTXh4M2MKLS0tIGI2OFh2ak5PTEV4MFZKWjhIVSsv\nZXA1dFFRY2FjVnI1MnE0TUtJemoxTEkKcCGDk5Mj16JL4/fevQCXYuTdY5ZVE2rb\n7nP+oqXXRTQAMVYsWwWIftNjd2XCM43UkTUKetMktGlcBMd/vNh/Xg==\n-----END AGE ENCRYPTED FILE-----\n" 24 | }, 25 | { 26 | "recipient": "age1vr0uq6mwv844yvm8pe7qxjxpqrekgel3lqfzuuqtfzj0ehz3hphqzsxjna", 27 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1RE0rOU1pYWVQOFU0N3da\nd2NmNjlZVWtEdisvcTVJa2ExRzVsK2lFcDNvCnkzb0dTQ1ZkM085VFpLQ09NZXBR\nd2VKNWtmWVp4YVViV2dpeUJyblBoNHcKLS0tIGUybXNsQ2tsaU81MURmKzJ5YThY\nS280YUMyL2JyK2pHMWlRTnNpSjRqNmsKg80xYn2ZE2zjt/t6pSUpXm0umg1+OM3h\niWJzu2RPayXglUc22hIiC08kahueHA+iJ+OPvMkl+NEM0FBMHotGLA==\n-----END AGE ENCRYPTED FILE-----\n" 28 | } 29 | ], 30 | "lastmodified": "2025-03-08T10:28:45Z", 31 | "mac": "ENC[AES256_GCM,data:xbFr0rhkcvO/+fTrGrOLCcmE52QVVxvwEu2Zg2vQ8DIt9aa+8p/aXI5ndY8TDoHsrl27IqZUetTYReXgyNBWuYhCbh6pLlJ/9GBipq+HTtyTuorj/hAREnaWDI049awM9yR6S6jELBSvPfUSKDi8JfBYelO04D9a2VinuAyP8/A=,iv:HzqLaMQbsNhwgBCX2YZj4pNbnLf73hc/IpJ8Hm5+pDQ=,tag:3rBwAgrscRB7hSKKj8ps6Q==,type:str]", 32 | "pgp": null, 33 | "unencrypted_suffix": "_unencrypted", 34 | "version": "3.8.1" 35 | } 36 | } -------------------------------------------------------------------------------- /secrets/users/nmelzer/gitlab: -------------------------------------------------------------------------------- 1 | { 2 | "data": "ENC[AES256_GCM,data:Ogl6BZFz2S1TTDdGDckoF2Mb8KD6G+tD1gIKsiiGBJBQFkC62fT/bEPKNEQ1kndIsLQAcsU26tBEn9YhCLyWkeIIcFDSnq58u9La4HVtydpNo8f+jrvWeDqp3lfXPgIMKRUywC499Oa0HtIyUGs5Xf3DuwoaECS/hhNBNUG9gSb2X6iLb0C7mV+Gd66kJf31DX0cm0JFChiwdQyLlxgnxRMeeBeUhXETMQBVPlRtEs1WxUnvn8D8WkHRcZBs+/TRIRaJ3rY7oG62iBAum/UmVBgs3kt5ZfsK9wBkIFuujwd1wVlTZjWkUYnte87G2p2My2khEQX0A9AXatAxRowRUMI/BS7nq51iv4RLGuHEWK/2IOwmfKPShPvUOZsRx+b16GT2/Xeaq5WnIdW2PaBcfYJV4GaLUwFSlsFHq8D1E/DnlD1s3msmoy0IppNwvk4zkK9zdZxoWIhldq1Baa+GpFHhqPjRIgpN9Gd/hulcygvDKr/rrekOiz/xdjBREXvwW2siwnMIr2SfnKLlGYyb+P8KmYXdPgHh2+X8k767b6fzQ6WmoqzeXVlsLtjPHK32nOz0T5eilQYrL5oC1Mi0u+4wmD8QiIS7KvMC/pU6B5lCb0yjpsdLET5gbQ5Xqo0vn4inftGMwHl7HoQbB9bokHhCmZSoI7DQCUjIYlKCHR5we46IZv55RzLCkmMpBlHCjhqn6nK08+Kj34jl65BBx1BjUR/digio29VhCgL8NwYgwk1k2YABVuFJFnCERBPiDLpL9v0zTQzB1Z8qfFpwxmLw/e/4UbqhPl7z2uhlFMkMjF01kgqBpZNzXTEwUm+kWegURdGdo+XJhHs634QuCZKsKExODCw4Lgl5jUCBgSxHYdnqzyN1MH9ws6xrvywAMmzTwMX19gb3q/NGijlX/Ipt5hrOGlmteNuhepW4KVuTanxhdtRfU9CeSBsHxabZkglkl2tQhfaXoW1OwE/Sp/NF4pYfxy09kOqH/c+Yp2j9WGyxrLTnNlS5XNPY+NCVDk31/zQno2hV77EbXK7pW10TThlu0iNOa2X0OhkJEZV9nWhN8QeKwN/Xao8F29JZ0WDYmcXMWrTPAmSsDob2SnQwgEvRpmxxtuum53IYnTxdGZGpL7DBWLdKZBMsJ9bP5vgeHClSHPyjpro1zK4VhxW/U6Yzpi3PCEyx+KpV/v8sG1DnvSReYd5RHga+p2ekYE8zWD0BzeNfvucroKMFcX2erZHYBKliMuAM85jXLXEohMhoOVdLm/1gAPt49LJnz2QFaU91G89QRxSjXaIqNjZdCDM/jE4Oa3qx3P7QtBzKzS9q6EYjvKzoFlo8I33X7CpAZ0PZuJttD3jDLHmmoOaVnIiquq0I7ESBjIbCtzjuerhDEhkaQDlHPUlFthK5Dg21/cPUbKL1xrZLYoOC6UfWa0lkayz8m7+o6NQAEJYJmvGd4pWVPoHPuYKCtmXWHeNNH8GIcGLvwUe87F5LeC/QFe+oPix8FHOfjZS3vzQRTDdEp057UewWMvodChFnZV+73rl1WOHhqGWghi58ghIY7pkhzj76lrMBhRq8ryyefrDq00uVYntoIbetxwH/GducP7JBvNPbFVvRn4/n3u6/3/0ZrdzyuXKtgwW17YP6UOexvQmkzgyBnTVs+JW1hnS/BToIliMtBg6KlUXcQR+0X+6hLF5mms1oPmX7wH1sC01iMKpt/jpnfIhq5tjySaebCahjqDJ7XC3HuvBjCvGmVpLYFWBjJoUX8fnPcaVI50zUtwqofF0BPcsSCg5U8S9vjVB61A9mTqOcH/6p5lThL/8yAii76XRn+tLA8UoabuQs+Z1bPb6DowkMnmT93Ye22NRX6fxFrXyJCr0puRkh2Qn9xbPmcIwx3CxRhO4DmBivtVtZtmYhoxYvcs3dNV/ergk6O7FKwM+q8c6Ia363GAhATHJkNyjxmDZRvaSY7v9CeqMyFmGobp0ZohWyfgXRuMO20CU9Ub7VdIct1mgMslhYSOfW4UStc66tGvozsMdyvnCo5lzjQUBHxOq93HxkSTedP9FB03WFyVWZEH2++nYyc3IsExGnq7ce6YQwL5rPThMNw5Ur09zrf4aX9Rl4mQJaMQyQWES9BfO0fDRIMciZXwWW0FDSlMCeBwesQwlnBpVIjPixsy8r09LMd3LxxPw1pt7vtfJh1R+6y4ye8/1VdVsGBp6AFLTvpaYW/aZUFAr8SP/mVYhlfms=,iv:wutx8cOVSjjC69NzlIrojwRLhs28QvNXRnRJSC6MMb0=,tag:cPf78d+51Op/58UiaM8IqQ==,type:str]", 3 | "sops": { 4 | "kms": null, 5 | "gcp_kms": null, 6 | "azure_kv": null, 7 | "hc_vault": null, 8 | "age": [ 9 | { 10 | "recipient": "age1wpwkf2g475umw3wwns57r8ucykvy6lflpc7uphs0mx9exsj04quqpy7t6r", 11 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJc1N0MUNwVFNlTEdjUElq\nUWlsTG8vc2xQYitYNWlUTlRGRTVLVzRyY1dBCmlMVG9OcUU5bjhzNDhpWStDaWVn\nRTcxZ1QySFhabklhQzJKL3BqSVVydncKLS0tIGhIamdINjdJZERnbXowZTlNRGtY\nOVVJSEZ1Q2NNNXNXV3UrbldUTy8yTlUKeLwquuhjLHDwzzL8JERFELXD9b6HWlKD\n6YXv+mHaeKtcN0y61uzH2O51U13e79ipex9AeYj8YSIZx1DRiJAg5Q==\n-----END AGE ENCRYPTED FILE-----\n" 12 | }, 13 | { 14 | "recipient": "age18p8x2cxam2l0trtpyhj4x9amcppp9ruzkqxzgapy9wnfpzl9hgaqlkht86", 15 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlU2tFSTgwSXFyVEo4YVdO\naUx5R2F3UGxhY0RBbStMNDdpMWZCdkVzMEc4CmcwOVVFbDBGRlZDS3dhdGZNNUtI\nWWNCRDRUelhvVzA2ZFIwZ09QYUhZWk0KLS0tIDRORmpMZk5CcDdOL2pvMW51clA2\naFpFS1k2dW9rY1dQR2hwb2FlMWVrREUKL3F0eiR8lKlDfQMYekRvxUo/c/qDVgKJ\nl5+yOsCMh6iu2u696gRcrnzrZ/aX23TJE98ttYS97DeUjUCc0Dpo1w==\n-----END AGE ENCRYPTED FILE-----\n" 16 | }, 17 | { 18 | "recipient": "age1w6xjgskpxnlpleswumdhtt7x8zx35qn329yz3x7ftqdcmcxrrvnqnuf9d6", 19 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHcUhZOU9kQ1FkMWY4TkdS\neStwOThKdkpWa04xYUU4MENrbjZRQ29ya3pZCkpqaHRGeVUyeGdDemZUeXNkMlo5\nTkg3dFNlL3c1NWJNS1FzWUJ3b3FSYkkKLS0tIG9aUkxYTTVDRitCWTh1TmRFMXoy\nU3p6RHk4cUVOOTlDamNSZFdIVmc3STQKdvB/aVmyKhVAA+JKT8aQo1VmDa2WhGl7\nzGIGX77gsjDiy9Jb15Z3KWGu4AP+bonUTmTkUWA5Oiqe1rhOe9MDMA==\n-----END AGE ENCRYPTED FILE-----\n" 20 | }, 21 | { 22 | "recipient": "age1tf0zelmw4lh9gvkl0qycdk83fut9t4q3tfcdzk8cvlyhjp7z0g2q7hklgq", 23 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaNWhBaWQycm1EZ0JwKzIv\nSit2UjFhNUsrd00wSzhua2xONXZwZlA1WjMwCk80WG5acXNGTkFEdmxyYlRCNlIv\nc05CY0RQM3Z0ZXZNTkswOXVsaVcwS0EKLS0tIHBrNnpZbFRpY1BuMm5ocnlYWXNZ\nTXdBMkhROGxBM0R1MDdPNHhKM1NYYVUKjZaHwqh/0OKB+ybatAfxEF4OmskYW2E9\nYEjuhy9jdcqi2a3hm2bI6rdSCsemAADJPW2PWsqjNc2TB9QeAK9ZgQ==\n-----END AGE ENCRYPTED FILE-----\n" 24 | }, 25 | { 26 | "recipient": "age1vr0uq6mwv844yvm8pe7qxjxpqrekgel3lqfzuuqtfzj0ehz3hphqzsxjna", 27 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTUEJ4ZjV5aUhLNUVxNlZp\nY1N1WUEwNE5odUQ2ZkdqdFV5cjB6WW1LWkRNCndObExzUDB4ZFdsYVVNbUtBbFE2\nSU5kZy9iK3RlY3FLWXFrR1pzZmhYOU0KLS0tIG04dm85SGtMQmZmT2RqTGYyRWlS\nTVhCRVUwWGhUaGdpUExPVjIxUVl1ZzQKkcnzuMCngr9oWFDynRENTlJQEFIbRJV/\nY8THko3rajg5QrIcoDTHeQ85WM6ucapUakAUTbis+Sa9xBoQ2coqDg==\n-----END AGE ENCRYPTED FILE-----\n" 28 | } 29 | ], 30 | "lastmodified": "2025-03-08T10:28:45Z", 31 | "mac": "ENC[AES256_GCM,data:1Y93EdZwSxZ3u+F0umtNc0jxzHHR7CdF2OUDb+DhxhmJrt9dEBoK1pRAN2qkdTMRMu5SDZVh0oilbQQC8HSC0iegpvlJo7lkG/qXyo1ixqEdp/P+mjqZTRqyxt2F/fFTPU9ggXhpQKyJcDgV6fjGm1pyYcTSMsvm0hOyrFq2+fE=,iv:rBYnAsB8PFoK2y0rb3G8YgX7e0yACTSE/AO1fYoRV8Q=,tag:TR6ZqCdPll7zPVSL/qUTzg==,type:str]", 32 | "pgp": null, 33 | "unencrypted_suffix": "_unencrypted", 34 | "version": "3.8.1" 35 | } 36 | } -------------------------------------------------------------------------------- /secrets/users/nmelzer/nix-community: -------------------------------------------------------------------------------- 1 | { 2 | "data": "ENC[AES256_GCM,data:beYSt9kq8a7NhS+FQcWQFFz0AjJP+Ybz1o5tYhAXkFo88OlxooLKCEpFgSDmN8jKgoE/IItxuLNVJJmPmo7+QUbQZgZq2Gs5xE5Am40ckfWc5vdGshxa5cPFqt1v+Sq/D6+oMj+8wxRC8zbUXGAH7Pah9Zaht/O/8gYcdnuypokYz6iKn9J713JbKAUHNNK358UUQhkEuVHWIgsWjbe6FylP+GlNtziYm2d4FwhAebuoOmZx3prQidP2qAcuul/FWjvRa5tJX3mEEa/oA1z44Q54jkPyWHvaMbsXMwdmq/3iFL26pMMZJl7FrM5OjfcxsTPNFHZFe9zonVWzffvdgu3KDpNcGTDK2OZRbOszr6kXy3BZYkzt/EMHoqH75mJ+WNCaGIZ41c3MMWBjEr0AkDLrLWA59EcVAJdH0WQ0TaVUErncLG6kR9UfGTMNm6dFs50IJy0PfGISHAKrnNL+2NkAdEVKlhHouP/0nlCqgB9Zg33nWzHniP7e4j2yDz6jfIkoIUjBHuwYPh44MEFE,iv:liL/qeyXe5Wbm3WtMCR8iIUk0O7gdIqYTOS9sBJSyqo=,tag:pkKFZEKNNBvl3/SfjH2nwQ==,type:str]", 3 | "sops": { 4 | "kms": null, 5 | "gcp_kms": null, 6 | "azure_kv": null, 7 | "hc_vault": null, 8 | "age": [ 9 | { 10 | "recipient": "age1wpwkf2g475umw3wwns57r8ucykvy6lflpc7uphs0mx9exsj04quqpy7t6r", 11 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtZ2c0aUJiRENZM1FNamJX\ndElNRmNsdlRBMFZNeG5vRHdVcjFyWEhYTnhBClJEbWF4ZFkxM3NoS0hXS2tnaTJY\nM29oY2xzQldidzdBcE54c2pTdkhCNncKLS0tIEFLNC94aUZmUkdLc09oSEkrb0VS\nM29wT2h4SEdjUE9CMWtFMmYwSHVSaUEKN9MEDf76Wa5JNjk0DSy8MExMDjyxhpSu\nBCPeuJpyYqac2vpwc09ttV4vqbzRzrGHlMGPpgFkgkYvvzX5lqehkQ==\n-----END AGE ENCRYPTED FILE-----\n" 12 | }, 13 | { 14 | "recipient": "age18p8x2cxam2l0trtpyhj4x9amcppp9ruzkqxzgapy9wnfpzl9hgaqlkht86", 15 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXeGZtQ2xERDlxd3l1TzFW\nTFhmRDJnOUJxUW0vemtZM1FORCsyMHFyTkJFCmtvR3I4eWhuSjFrNTJDdkd4Z29k\nRkt4eHM0aWVtNTZuc2txVGNKc2N1SDQKLS0tIEZ4bE5qU3hSSGpXb3lGWHp6MGti\nb2QzWDRYRmluWDllTVNJNmJaMlMxZDAKB0LOonMk7ypELophUHLnR2eEOclM5CgD\nrbgkmmKZPXMSvXLXDoQDICxleDNoFD2mWi4JvwZWZuRpaNs/1KPraw==\n-----END AGE ENCRYPTED FILE-----\n" 16 | }, 17 | { 18 | "recipient": "age1w6xjgskpxnlpleswumdhtt7x8zx35qn329yz3x7ftqdcmcxrrvnqnuf9d6", 19 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGdTVoVUI4UzM1VmlTZWVy\nblZxZE04TmIxaU1zOGhrREh6NnJaaTIwSjBBClFHejZwdHlFRTQyMC9YOFFsczhI\nMjh6cjJzcklFUGlHV1p6TnJUdzNPVGsKLS0tIFVQTDI1K0Jydno1ZVgrN2p2aDdi\nQ01mR3lNVzRmSEptQklBR0tIbWR0WE0KKND3aAMOLmMLjQV4iexO+XnjZIgZSSOj\nbK3qtICJ7E9lcRgoXtHDJm6+e5BzpBOUVkfX7cKAEWWtbfwrHbYnyA==\n-----END AGE ENCRYPTED FILE-----\n" 20 | }, 21 | { 22 | "recipient": "age1tf0zelmw4lh9gvkl0qycdk83fut9t4q3tfcdzk8cvlyhjp7z0g2q7hklgq", 23 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYZTVyRU9DQmNIRm1HWDQy\nUmhQUGVPM21ldGhCSzMydGpMK2JBdUNZU1JrCkpTa1krT1haWGo3OEdnLzFQZzh5\nTkFYb21JZjhGdmZxTjU1U1hRU0hkaGMKLS0tIDl0M3NaeE0vOTlTU0psSnVpYUw1\nYUE3ZGxXUmk0WUZmWUlQdjJNMTRBclEKPCZVzELeRe9jUC+dY/LTFrk0yrk4uWn0\nhNCROYc6jQPAHLhYRnCbWkENCQHfhBrxVLeyzLmELoU5ZdM0KgtPyA==\n-----END AGE ENCRYPTED FILE-----\n" 24 | }, 25 | { 26 | "recipient": "age1vr0uq6mwv844yvm8pe7qxjxpqrekgel3lqfzuuqtfzj0ehz3hphqzsxjna", 27 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3aU02ZFlIcDFpUXU5ZUg3\nUFZTR0Uya2JDUkw5L29tK3d2cmg2N05XVFRJClZnWVpwVHo3cFp2b0h3QVh0Wk15\nWGFOclBuQVMvcVdMcklGOUVST2JGYVkKLS0tIHFrRUl1aW1OZ1Z2SkF5K3FMRmFu\nQXlDZjdlWVFVZWEzaXN5NnNFc25iRkUKk6/f0mFEON/gplXSDCviVm4+e+duQJlw\nBT1oJflU2VHXK9RJBiUl9sV3tGHF41MeXpt3WoEO1AKMsk8Q3Q++1w==\n-----END AGE ENCRYPTED FILE-----\n" 28 | } 29 | ], 30 | "lastmodified": "2025-03-08T10:28:45Z", 31 | "mac": "ENC[AES256_GCM,data:yenOYHB/Eax95Z8YqLd2kWq6bHUIbDXHj/qQntzLgLmBTUpnWW4DKuyligR3iBH91WD4evWBc+bDU5sMfGuozDQpgynsoIjPiOsNXPlLOURZLQf4tnqPzd4VzSkWsH2Q+b5bQvEteqYwYt9EI0XUxOfIF0X10yrjCM6axV6bsu8=,iv:du8kmJ2P/33SsLOih+5oCMrdvIEgWsFEC4ys51ASLJ4=,tag:4jsUew+WAfIj6pAUTGymLg==,type:str]", 32 | "pgp": null, 33 | "unencrypted_suffix": "_unencrypted", 34 | "version": "3.9.2" 35 | } 36 | } -------------------------------------------------------------------------------- /secrets/users/nmelzer/nobbz_dev: -------------------------------------------------------------------------------- 1 | { 2 | "data": "ENC[AES256_GCM,data:JbATH1rQff0rUhJUxXAKwqq+KO8hjLXnwp6uwBwCpQXK1OAD88l/4StWTZ94oSqUwcwjT8DtI2M0DLFdGFQTmmQrrt/Or8XKHnZc1zu5axgJ8H/Ey3m+CFDgz6Wg9rOuc1nz0EBTBk6XIGvyeXc4AMMfUuVDo14ijarTL34JqPy4sB0ayzCGCWZTyxy0VKQoQnYQBK5D2JTqG4P2IjFY4yh/2R+IRmK+MghErz3gKg5ORKPfIqH4rFAszGbUjYZt9TKpVGiidW2lYVn0nqVHHzMgZGokst+jkrcriKQS4CLLLk/zh0Dx0fHo1QrJyRYzry5cFFQVCQZKyTe3nbkuExPbxfm13hROCC7jK+XYgn6T+MowJ4u6/B6F//UgjTLQ9by58lhbG7N1IUbXcgGYpWYib9bavF1ELk2PXdazP+WQJTQXMYT/f++eT80m6PdPbmHVbm1cjVD22SjnMa8g695eTUcvx8jwFbTKVEkE9kMEMOlAG6hVvf6/+8G+xvoCYXu/C35/mf9k6n62ii5QkoPiqT5yKKiGv/GXht+24d9NQGX4f1CF4p/6s3yRfKaOnnOF2MLseY8eYGrlLdGqdr3QWet0cAcraTXP62OH3gBBPhTW0U4N0EciBsX3/9atVxoiq4y9C/SQOYla6MIRRK6NTrWlWLCRif/MOBja+Ya7BG3s51umZgS8v3uPL9OyjpWutRpYvBPkherfHpKKzUUNJx+o/2De0yFtQx659bVddBQ1dBmJPjYkUbSzQBJE767pEyZf1oac88SC0wizxPFLDcI7ZzFvQlO9XYs5pgoO9aZKqYDx97rT6BJeOyUmLE4XhURliQtpL18fRqIqHu6SoAQoLZpjLx9A5JUHyI2iem7FyZJKFVeA/bL1hdXL1hby/VpnuP3PmbGP90Y4FOHPozUsLgBLObqbgf6SMKZBEs7JWWEK4i9A1uYbv7LIvxslqYvB+qwdCDEa+tFfz8TG9pBerJ2oqCpaNbO0UGruvpwJ7HXSpn4VdAXgG5zy4glupIqkGUNoERpYEVJMRZxx4K8ST9OZ+0qwpAOOTXTwYuqkcEw5TNwcoNswUNzu9Ck2/An0307fhOYXjO0D8IDvTDIF5CSESILjASB5H7qhbR4hbUE4G09fIChKi6DLyTP/zMAwWpgUBwxByZGMrttH+EzntFNbgL2EGbbdCfr8Vf7XWHhXT/bNYhlGJp2dkdOOBnV3XdPMIkyl4zJqzzAFySx4cpFTfCQ/zwWOEQN7H58sEsqcUxeYOtnSwccWkuP0+9Z4nrdJrAjq32RLeLSzTJ8cMStB85E3h/Gqx+O0Jw9fA+H4sE49JGkIobiuioz0wC/6uMQvyMBs5cyDvpiWFQ3dj2bKgpCtBVrAlcNG1Q8Hljc55WblkFiQRxVix1xB13yCpFMeNuIdCifGXUbTWuA64H4QjG5/P5KgH5IkT6Ry0wDPGw7CSqMXCXhCiRLsyzByGfy+LMkjL4LZk8GP21+6NlUkc+5j+cNZkjZ22J5LhxIdz4eE7MXSMKTno0iMrvUKYPJe0+NgIrXtprsacHLDyDSXowS3FUPWqPfPLG6vOBfz+99DMumFY1UU6eHSdFHVovBdp50kHnu3LbsiNh4iNvl8rtctgVl7PGRMvU+tF4GtiIrxHt0MRZzQ6WemRVvRIvZBYMXEEjn5p6Xn9Lg5p9HjsnvpjdmJOZCp4CCwYrkm9kzk+f2qwPVy/J6DQBwgr41k0Pd8fbCQjdICkGSU8yJxwCsWvP5I2T5NWrPiUdav0doc2i5fEi02NnDcL1ncChBooqrVjD0mLIbQ9ra9F+f+51RGZO+Y7XjfFH8E2uUb8GS3u/bZbhmoCvouVKHLurOCcmFfs14ZGek0bZT7Q+PHChWzv890MkA1S5A3x9orY6WmhR4Zy86Bsi9PA3YNL59jUQTl0nWknbrxuhPdPcsmCL+DgdSV7E5zesUaeRJi7QuL/GCZ2E8PKKSuh9Kq56pYk8HsYMsrqNqyU80QM8aRc1o++YSq6SLwEmY1Pm8fsssZTjP9PT2RZIXt5LjskQbkA4Q4rECm4JQepx9jHZeFAgo0tDOfAmj7q1QQq3bxEfvRO1dxJ212tvcFpR5ehDO8d4CLyTMqprBvG9/0r2qO8xp7ifJQKHx4CDpiiZaNS9Fyl1QdfqADvrT9z15ucRsmoQuL5zjVdbC05lAie4wswlcOUUvu3qoj6RikDC+xFG6AXd+e33un1v9rT2XmVzz+47WKPCQLfRqCDkNgwpjxUkrgCsiFun3+EhzWxLxzXLIEkVfE8c7eJnQSDu3IEShZ2vF2sT5FFJScN8tf888J7mCgLsHpnWbSplXxa4RMjO1rHD1S04tLC80EPGl/rdaraHmnEtt4mc9boo7IyusR19gotEjRRnZDZJaplDt72IdgC6hBCQM=,iv:iwfQiWkkxmB52x5mVXlhS3pbzKL3/ctoJMctdhHGQuk=,tag:VQ0GWz0xyQiCx/WpYq1itA==,type:str]", 3 | "sops": { 4 | "kms": null, 5 | "gcp_kms": null, 6 | "azure_kv": null, 7 | "hc_vault": null, 8 | "age": [ 9 | { 10 | "recipient": "age1wpwkf2g475umw3wwns57r8ucykvy6lflpc7uphs0mx9exsj04quqpy7t6r", 11 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtQUpwZ2JXYTUybXc5Tm9T\na1p6azYvbno0NzY0UGNrWnNjQUd3SnJMakV3CjVMemhwQ3NmOWFJSGEzQ2ZsL1pF\najgrM2g2THQ2dkxTUUM0QlpnODRjbUkKLS0tIDZKaFYydnZRYWdxZFIzYnNZbjZ3\nWkxPcWdHbm9ZZnZNNVpIQmZ5djVHTGcKAiKFm4r93FBNXxt/jgofvKS3pn0NbdWW\njDacQ7VUubSqpmHax/s/FNV75g5ynIm8ldOJVoW6lgNxPWxcfucTLA==\n-----END AGE ENCRYPTED FILE-----\n" 12 | }, 13 | { 14 | "recipient": "age18p8x2cxam2l0trtpyhj4x9amcppp9ruzkqxzgapy9wnfpzl9hgaqlkht86", 15 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLMU5ycnhZSlJyQ0UrRXVo\naVIra1o2TkRmbTFFMHFzeTN2d1NGQUluTVRzCk4wRm41Sy8rNWh4OXI0eUdKdDhH\nRjZwcE80K1NUbGxubGp1akh1WVFTWU0KLS0tIFZraWFpdmU3dlRCMnVtMHN3RnFD\nYmN5dmIwRUlJQktKTmUzZllTb1lOUTQKkJLBrTeUlPaZ1C/pGWu9WQNFCBgsJVqS\nYnPpsvYJiOE/6WmCzB34OVpO8vdrv1mE5jR/Ila3YQVjBt8JHo7Zqw==\n-----END AGE ENCRYPTED FILE-----\n" 16 | }, 17 | { 18 | "recipient": "age1w6xjgskpxnlpleswumdhtt7x8zx35qn329yz3x7ftqdcmcxrrvnqnuf9d6", 19 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVUEx6UkEveUI1UVRqQm1n\ncE9OcFNnZFM4eU5iM2NpQjQ5R0NteFZOMlhZCk1Kd3JxVy9tTk5oTU1GSUgyTjNO\nY1hmaTZjYmZkZHVnazl3Q1ViT1R6RVUKLS0tIE9udElPWU9vNWpYYWtmMmluTWQ2\nK0hWL25OemxpVStNMFZJUGI4UUc4MmsKs7DTAfnY74yp33cmdyYiF6fPiNgheehm\nRO9PDQ/Yh6wIq/6j/brPsMJLyYrC7+Mjgx/oX5lNmMwTVLBrCe/qdg==\n-----END AGE ENCRYPTED FILE-----\n" 20 | }, 21 | { 22 | "recipient": "age1tf0zelmw4lh9gvkl0qycdk83fut9t4q3tfcdzk8cvlyhjp7z0g2q7hklgq", 23 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqVW5aVUVpZk14U1pYK2NJ\nRVpGbGdXVzlLQ25PSWYyWjR6bGRCWkIxM3dVCnlGd1h3Z2pJNmNweTgwRmUyL1Bo\nNVBoaFprQWVUK1pQbi9YOTgreFBpcDgKLS0tIFhCUE5WQ2w4R3J1eXVhSFJEOGRp\nMlZpSnovWnpvc3lGemE3WmJkK2xQWVkKkNZaVbq8X99+MXfei0BzbXBwzibERWvR\nV26mOEEYcfv/3/KqCLOjBVCLEE3RSuB9AtniAAFC6Fj0/jHnMzaghQ==\n-----END AGE ENCRYPTED FILE-----\n" 24 | }, 25 | { 26 | "recipient": "age1vr0uq6mwv844yvm8pe7qxjxpqrekgel3lqfzuuqtfzj0ehz3hphqzsxjna", 27 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQdlIzc3NQM2JkdW1TQzVX\nYVRjR2hEY3NrME9GeHJhbitpQURVbUdoTWlrCm81Wmt5dWpWWlVtaHJKcnNnMVJm\nekZnM0gycDdlZi9ZdUhYMTRpTFhjK28KLS0tIHcrcFQ3SEphOW1oeEsvcDdBUFRI\nU1psVWVldkZ0TXp3QnBmMUxHdm1ocmsKn/oYX+0hYRZvC32KGQ9hNRDMdlxclv5x\nekDM5wPeI9wT/j62bxmykEtNnI40WEpEopz7MSZvRnj6B8zF9boFPw==\n-----END AGE ENCRYPTED FILE-----\n" 28 | } 29 | ], 30 | "lastmodified": "2025-03-08T10:28:45Z", 31 | "mac": "ENC[AES256_GCM,data:7XBQhTfVn9Uq4ZjjpLdMyvw+kDhIJ+dUEjI1j7Lq8QzoxLN7kqWyrotavl4T7x3kbhGseqA/RtuldK5cvw90OK7FVvWD0H5WSsxDCG2zuNRCELmiOEM8O4Iw47J6ye3wY9F+05F7ggG/GrZGJK09YojuZyek4G+/slHfp/Zgxy0=,iv:vAqJx7GT28f4wC0iH0w+K/HRywJlMb6/N/5Lb1/4q80=,tag:L3odjAh/IWuddrzg7vP/Sg==,type:str]", 32 | "pgp": null, 33 | "unencrypted_suffix": "_unencrypted", 34 | "version": "3.8.1" 35 | } 36 | } -------------------------------------------------------------------------------- /statix.toml: -------------------------------------------------------------------------------- 1 | disabled = ["repeated_keys"] 2 | nix_version = '2.4' 3 | ignore = ['.direnv', "packages/nodePackages/node-env.nix", "npins/default.nix"] 4 | --------------------------------------------------------------------------------