├── .gitignore ├── .gitattributes ├── mixed ├── default.nix └── ip_addresses.nix ├── nixos ├── configurations │ ├── bootloader │ │ ├── janus.nix │ │ ├── mimas.nix │ │ ├── hyperion.nix │ │ └── enceladeus.nix │ ├── default.nix │ ├── mimas │ │ ├── paperless.nix │ │ ├── vaultwarden.nix │ │ ├── gitea.nix │ │ ├── restic.nix │ │ └── rustic-timers.nix │ ├── hardware │ │ ├── enceladeus.nix │ │ ├── hyperion.nix │ │ ├── janus.nix │ │ └── mimas.nix │ └── mimas.nix └── modules │ ├── hostnames.nix │ ├── moonlander.nix │ ├── default.nix │ ├── cachix │ ├── caches │ │ ├── nobbz.nix │ │ ├── ts-helper.nix │ │ └── nix-community.nix │ └── default.nix │ ├── zerotier.nix │ ├── prefer-local.patch │ ├── kernel.nix │ ├── flake.nix │ ├── nix.nix │ ├── switcher.nix │ └── distributed.nix ├── .coderabbit.yaml ├── packages ├── installer │ ├── nix-glow-black.png │ ├── lvm.nix │ ├── sddm.nix │ ├── network.nix │ ├── base.nix │ ├── default.nix │ ├── xterm.nix │ ├── motd.nix │ ├── awesome.nix │ └── nix-flake.svg ├── rofi-unicode │ ├── rofi-unicode.json │ └── default.nix ├── advcp │ └── default.nix └── default.nix ├── statix.toml ├── home ├── configurations │ ├── default.nix │ ├── nmelzer_at_phoebe.nix │ └── nmelzer_at_mimas.nix └── modules │ ├── programs │ ├── rbw │ │ └── default.nix │ ├── eza │ │ └── default.nix │ ├── ghostty │ │ └── default.nix │ ├── advcp │ │ └── default.nix │ ├── nixpkgs │ │ └── default.nix │ ├── p10k │ │ └── default.nix │ └── wezterm │ │ └── default.nix │ ├── profiles │ ├── default.nix │ ├── base │ │ ├── colums-fix.patch │ │ ├── nix-completions.sh │ │ └── default.nix │ ├── browsing │ │ └── default.nix │ └── development │ │ └── default.nix │ ├── misc │ ├── rofi │ │ ├── common.rasi │ │ └── default.nix │ └── home │ │ └── default.nix │ ├── default.nix │ └── services │ ├── insync │ └── default.nix │ └── rustic │ └── default.nix ├── checks ├── statix.nix ├── alejandra.nix └── default.nix ├── cicd ├── coderabbit.cue ├── check-generated.cue ├── pull-check.cue ├── flake-update.cue └── workflows.cue ├── cue.mod └── module.cue ├── .github ├── dependabot.yml └── workflows │ ├── check-generated.yml │ ├── pull-check.yml │ └── flake-update.yml ├── .envrc ├── lefthook.yml ├── parts ├── nixos_modules.nix ├── home_modules.nix ├── auxiliary.nix ├── module_helpers.nix ├── system_configs.nix └── home_configs.nix ├── LICENSE ├── .sops.yaml ├── README.md ├── Makefile ├── secrets ├── mimas │ ├── nmelzer │ │ └── default.yaml │ └── default.yaml ├── phoebe │ └── nmelzer │ │ └── default.yaml └── users │ └── nmelzer │ ├── default.yaml │ ├── nix-community │ ├── github │ ├── gitlab │ └── nobbz_dev ├── npins ├── sources.json └── default.nix ├── flake.nix └── flake.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /result* 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.yaml diff=sopsdiffer 2 | -------------------------------------------------------------------------------- /mixed/default.nix: -------------------------------------------------------------------------------- 1 | inputs: { 2 | ipAddresses = import ./ip_addresses.nix inputs; 3 | } 4 | -------------------------------------------------------------------------------- /nixos/configurations/bootloader/janus.nix: -------------------------------------------------------------------------------- 1 | _: {} 2 | # TODO: Move BL relevant config here! 3 | 4 | -------------------------------------------------------------------------------- /nixos/configurations/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | nobbz.nixosConfigurations.mimas.system = "x86_64-linux"; 3 | } 4 | -------------------------------------------------------------------------------- /.coderabbit.yaml: -------------------------------------------------------------------------------- 1 | reviews: 2 | tools: 3 | github-checks: 4 | enabled: true 5 | timeout_ms: 900000 6 | -------------------------------------------------------------------------------- /packages/installer/nix-glow-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NobbZ/nixos-config/HEAD/packages/installer/nix-glow-black.png -------------------------------------------------------------------------------- /nixos/configurations/bootloader/mimas.nix: -------------------------------------------------------------------------------- 1 | { 2 | boot.loader.systemd-boot.enable = true; 3 | boot.loader.efi.canTouchEfiVariables = true; 4 | } 5 | -------------------------------------------------------------------------------- /statix.toml: -------------------------------------------------------------------------------- 1 | disabled = ["repeated_keys"] 2 | nix_version = '2.4' 3 | ignore = ['.direnv', "packages/nodePackages/node-env.nix", "npins/default.nix"] 4 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /packages/installer/lvm.nix: -------------------------------------------------------------------------------- 1 | { 2 | _file = ./lvm.nix; 3 | 4 | services.lvm = { 5 | boot.thin.enable = true; 6 | boot.vdo.enable = true; 7 | dmeventd.enable = true; 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /packages/installer/sddm.nix: -------------------------------------------------------------------------------- 1 | { 2 | _file = ./sddm.nix; 3 | 4 | services.xserver = { 5 | displayManager.sddm.enable = true; 6 | displayManager.autoLogin.enable = true; 7 | displayManager.autoLogin.user = "nixos"; 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /packages/installer/network.nix: -------------------------------------------------------------------------------- 1 | {pkgs, ...}: { 2 | networking.networkmanager.enable = true; 3 | 4 | systemd.user.services.nmapplet = { 5 | wantedBy = ["graphical-session.target"]; 6 | script = "${pkgs.networkmanagerapplet}/bin/nm-applet"; 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /cicd/coderabbit.cue: -------------------------------------------------------------------------------- 1 | package cicd 2 | 3 | import "github.com/nobbz/coderabbit-cue@v0:coderabbit" 4 | 5 | coderabbit_yml: coderabbit.#Config & { 6 | reviews: tools: "github-checks": { 7 | enabled: true 8 | timeout_ms: 15 * 60 * 1000 // 15 minutes 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /cue.mod/module.cue: -------------------------------------------------------------------------------- 1 | module: "github.com/nobbz/nixos-config" 2 | language: { 3 | version: "v0.14.2" 4 | } 5 | deps: { 6 | "cue.dev/x/githubactions@v0": { 7 | v: "v0.2.0" 8 | default: true 9 | } 10 | "github.com/nobbz/coderabbit-cue@v0": { 11 | v: "v0.0.1" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /packages/installer/base.nix: -------------------------------------------------------------------------------- 1 | {modulesPath, ...}: { 2 | _file = ./base.nix; 3 | 4 | imports = [ 5 | "${modulesPath}/installer/cd-dvd/installation-cd-graphical-base.nix" 6 | ]; 7 | 8 | isoImage = { 9 | edition = "nobbz"; 10 | squashfsCompression = "zstd -Xcompression-level 10"; 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /cicd/check-generated.cue: -------------------------------------------------------------------------------- 1 | package cicd 2 | 3 | import "cue.dev/x/githubactions" 4 | 5 | workflows: checker: githubactions.#Workflow & { 6 | name: "Check generated files" 7 | "on": pull_request: {} 8 | jobs: check_generated: { 9 | steps: [ 10 | _cloneRepo, 11 | _installCue, 12 | {run: "make check"}, 13 | ] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /packages/installer/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | nixosSystem, 3 | system, 4 | npins, 5 | nvim, 6 | self', 7 | }: 8 | nixosSystem { 9 | inherit system; 10 | 11 | specialArgs = {inherit npins nvim self';}; 12 | 13 | modules = [ 14 | ./awesome.nix 15 | ./base.nix 16 | ./lvm.nix 17 | ./motd.nix 18 | ./network.nix 19 | ./sddm.nix 20 | ./xterm.nix 21 | ]; 22 | } 23 | -------------------------------------------------------------------------------- /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 | pinentry = pkgs.pinentry-curses; 12 | 13 | email = "timmelzer@gmail.com"; 14 | base_url = "https://passwords.mimas.internal.nobbz.dev"; 15 | }; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /packages/installer/xterm.nix: -------------------------------------------------------------------------------- 1 | {pkgs, ...}: let 2 | inherit (pkgs) writeText; 3 | in { 4 | systemd.user.tmpfiles.rules = let 5 | xresources = writeText "xresources" '' 6 | XTerm.vt100.foreground: rgb:d3/d3/d3 7 | XTerm.vt100.background: rgb:00/00/00 8 | XTerm.vt100.faceName: FreeMono 9 | XTerm.vt100.faceSize: 12 10 | ''; 11 | in [ 12 | "L+ %h/.Xresources - - - - ${xresources}" 13 | ]; 14 | } 15 | -------------------------------------------------------------------------------- /cicd/pull-check.cue: -------------------------------------------------------------------------------- 1 | package cicd 2 | 3 | import "cue.dev/x/githubactions" 4 | 5 | workflows: pull_request: githubactions.#Workflow & { 6 | name: "Pull Request Checker" 7 | "on": pull_request: {} 8 | jobs: { 9 | generate_matrix: workflows.updater.jobs.generate_matrix 10 | build_flake: _buildFlake & {_flakeLock: false} 11 | build_checks: _buildChecks & {_flakeLock: false} 12 | check_flake: _checkFlake & {_flakeLock: false} 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.github/workflows/check-generated.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | check_generated: 3 | runs-on: ubuntu-24.04 4 | steps: 5 | - name: Clone Repository 6 | uses: actions/checkout@v6 7 | with: 8 | token: ${{ secrets.TEST_TOKEN }} 9 | - name: Install Cue 10 | uses: cue-lang/setup-cue@v1.0.1 11 | with: 12 | version: v0.14.2 13 | - run: make check 14 | name: Check generated files 15 | "on": 16 | pull_request: {} 17 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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.stdenv.hostPlatform) system; 15 | }) 16 | .zerotierone; 17 | } 18 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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.stdenv.hostPlatform.system}.advcp]; 15 | 16 | programs.zsh.shellAliases = { 17 | cp = "advcp -g"; 18 | mv = "advmv -g"; 19 | }; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /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/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/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.stdenv.hostPlatform.system}.google-chrome lynx]; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /packages/installer/motd.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | lib, 4 | ... 5 | }: { 6 | _file = ./motd.nix; 7 | 8 | users.motd = "This is a test message."; 9 | 10 | systemd.user.services.motd = { 11 | description = "Prints a test message"; 12 | wantedBy = ["graphical-session.target"]; 13 | script = '' 14 | motd=$(cat /etc/gui-motd) 15 | ${lib.getExe pkgs.zenity} --info --text="$motd" --no-wrap --title="Short usage notes" 16 | ''; 17 | serviceConfig = { 18 | Type = "simple"; 19 | Restart = "on-failure"; 20 | }; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /packages/installer/awesome.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | self', 4 | ... 5 | }: let 6 | rc_lua = pkgs.runCommand "awesomerc.lua" {} '' 7 | substitute ${./awesomerc.lua} $out \ 8 | --subst-var-by FILE_PATH_WALLPAPER ${./nix-glow-black.png} \ 9 | --subst-var-by NIX_FLAKE_SVG ${./nix-flake.svg} 10 | ''; 11 | in { 12 | _file = ./awesome.nix; 13 | 14 | services.xserver.windowManager.awesome = { 15 | enable = true; 16 | package = self'.packages.awesome; 17 | }; 18 | 19 | systemd.user.tmpfiles.rules = [ 20 | "L+ %h/.config/awesome/rc.lua - - - - ${rc_lua}" 21 | ]; 22 | } 23 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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/installer/nix-flake.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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.stdenv.hostPlatform.system}.programs-sqlite; 19 | 20 | nix = { 21 | package = lib.mkDefault nix.packages.${pkgs.stdenv.hostPlatform.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/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/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/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 | -------------------------------------------------------------------------------- /home/modules/misc/home/default.nix: -------------------------------------------------------------------------------- 1 | {self, ...}: { 2 | config, 3 | pkgs, 4 | lib, 5 | ... 6 | }: let 7 | self' = self.packages.${pkgs.stdenv.hostPlatform.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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 lua-language-server cue; 33 | }; 34 | }; 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: workflows check fmt 2 | 3 | workflows: .github/workflows/flake-update.yml .github/workflows/pull-check.yml .github/workflows/check-generated.yml .coderabbit.yaml 4 | 5 | check: 6 | cue vet -c ./cicd/ .github/workflows/flake-update.yml -d 'workflows.updater' 7 | cue vet -c ./cicd/ .github/workflows/pull-check.yml -d 'workflows.pull_request' 8 | cue vet -c ./cicd/ .github/workflows/check-generated.yml -d 'workflows.checker' 9 | cue vet -c ./cicd/ .coderabbit.yaml -d 'coderabbit_yml' 10 | 11 | .github/workflows/flake-update.yml: cicd/*.cue cue.mod/module.cue 12 | CUE_DEBUG=sortfields cue export ./cicd/ -f -e workflows.updater -o .github/workflows/flake-update.yml 13 | 14 | .github/workflows/pull-check.yml: cicd/*.cue cue.mod/module.cue 15 | CUE_DEBUG=sortfields cue export ./cicd/ -f -e workflows.pull_request -o .github/workflows/pull-check.yml 16 | 17 | .github/workflows/check-generated.yml: cicd/*.cue cue.mod/module.cue 18 | CUE_DEBUG=sortfields cue export ./cicd/ -f -e workflows.checker -o .github/workflows/check-generated.yml 19 | 20 | .coderabbit.yaml: cicd/*.cue cue.mod/module.cue 21 | CUE_DEBUG=sortfields cue export ./cicd/ -f -e coderabbit_yml -o .coderabbit.yaml 22 | 23 | fmt: 24 | cue fmt cicd/*.cue 25 | alejandra . 26 | -------------------------------------------------------------------------------- /nixos/modules/switcher.nix: -------------------------------------------------------------------------------- 1 | {self, ...}: { 2 | pkgs, 3 | config, 4 | ... 5 | }: { 6 | environment.systemPackages = [self.packages."${pkgs.stdenv.hostPlatform.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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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.stdenv.hostPlatform) 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 | -------------------------------------------------------------------------------- /packages/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs, 3 | npins, 4 | ... 5 | }: { 6 | perSystem = { 7 | system, 8 | pkgs, 9 | lib, 10 | inputs', 11 | self', 12 | ... 13 | }: let 14 | upkgs = inputs'.nixpkgs.legacyPackages; 15 | 16 | chromePkgs = import inputs.nixpkgs { 17 | inherit system; 18 | config.allowUnfree = true; 19 | config.google-chrome.enableWideVine = true; 20 | }; 21 | 22 | awesome = pkgs.awesome.overrideAttrs (oa: { 23 | version = npins.awesome.revision; 24 | src = npins.awesome; 25 | 26 | patches = []; 27 | 28 | cmakeFlags = (oa.cmakeFlags or []) ++ ["-DCMAKE_POLICY_VERSION_MINIMUM=3.5"]; 29 | 30 | postPatch = '' 31 | patchShebangs tests/examples/_postprocess.lua 32 | ''; 33 | }); 34 | in { 35 | packages = lib.mkMerge [ 36 | { 37 | installer-iso = 38 | (upkgs.callPackage ./installer { 39 | inherit (inputs.nixpkgs.lib) nixosSystem; 40 | inherit npins; 41 | inherit (inputs) nvim; 42 | inherit self'; 43 | }) 44 | .config 45 | .system 46 | .build 47 | .isoImage; 48 | 49 | advcp = upkgs.callPackage ./advcp {}; 50 | "rofi/unicode" = upkgs.callPackage ./rofi-unicode {}; 51 | } 52 | (lib.mkIf pkgs.stdenv.isLinux { 53 | inherit (inputs'.switcher.packages) switcher; 54 | inherit awesome; 55 | }) 56 | (lib.mkIf (system == "x86_64-linux") { 57 | inherit (chromePkgs) google-chrome; 58 | }) 59 | ]; 60 | }; 61 | } 62 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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.runCommand "common.rasi" {preferLocalBuild = true;} '' 10 | substitute ${./common.rasi} $out \ 11 | --subst-var-by TERMINAL ${lib.getExe pkgs.wezterm} 12 | ''; 13 | 14 | catppuccin = pkgs.runCommand "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 | runCommand, 41 | makeWrapper, 42 | }: 43 | runCommand "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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /cicd/flake-update.cue: -------------------------------------------------------------------------------- 1 | package cicd 2 | 3 | import "cue.dev/x/githubactions" 4 | 5 | workflows: updater: githubactions.#Workflow & { 6 | name: "Updater" 7 | "on": { 8 | schedule: [{cron: "0 2 * * *"}] 9 | workflow_dispatch: {} 10 | } 11 | jobs: { 12 | generate_matrix: { 13 | outputs: { 14 | packages: "${{ steps.gen_packages.outputs.packages }}" 15 | checks: "${{ steps.gen_checks.outputs.checks }}" 16 | } 17 | steps: [ 18 | _cloneRepo, 19 | _installNix, 20 | { 21 | name: "Generate flake.json" 22 | run: "nix flake show --json > flake.json" 23 | }, 24 | { 25 | id: "gen_packages" 26 | run: """ 27 | packages=$(jq -c '.packages."x86_64-linux" | keys' < flake.json) 28 | printf "packages=%s" "$packages" >> "${GITHUB_OUTPUT}" 29 | """ 30 | }, 31 | { 32 | id: "gen_checks" 33 | run: """ 34 | checks=$(jq -c '.checks."x86_64-linux" | keys' < flake.json) 35 | printf "checks=%s" "$checks" >> "${GITHUB_OUTPUT}" 36 | """ 37 | }, 38 | ] 39 | } 40 | update_flake: steps: [ 41 | _cloneRepo, 42 | _installNix, 43 | _setupGit, 44 | { 45 | name: "Update the flake" 46 | run: "nix flake update" 47 | }, 48 | { 49 | name: "Store flake.lock" 50 | uses: "actions/upload-artifact@v6" 51 | with: { 52 | name: "flake_lock" 53 | path: "flake.lock" 54 | } 55 | }, 56 | ] 57 | build_flake: _buildFlake & {_flakeLock: true} 58 | build_checks: _buildChecks & {_flakeLock: true} 59 | check_flake: _checkFlake & {_flakeLock: true} 60 | 61 | push_update: { 62 | permissions: "write-all" 63 | needs: ["update_flake", "build_flake", "build_checks", "check_flake"] 64 | steps: [ 65 | _cloneRepo, 66 | _restoreFlakeLock, 67 | _setupGit, 68 | { 69 | name: "Create and merge PR" 70 | run: """ 71 | git switch -c updates-${{ github.run_id }} 72 | git commit -am "flake.lock: Update" 73 | git push -u origin updates-${{ github.run_id }} 74 | PR="$(gh pr create \\ 75 | --assignee NobbZ \\ 76 | --base main \\ 77 | --body "Automatic flake update on $(date -Idate)" \\ 78 | --fill \\ 79 | --label bot \\ 80 | --title "Auto update $(date -Idate)")" 81 | gh pr merge "$PR" --merge --delete-branch 82 | """ 83 | env: "GITHUB_TOKEN": "${{ secrets.TEST_TOKEN }}" 84 | }, 85 | ] 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /npins/sources.json: -------------------------------------------------------------------------------- 1 | { 2 | "pins": { 3 | "awesome": { 4 | "type": "Git", 5 | "repository": { 6 | "type": "GitHub", 7 | "owner": "awesomewm", 8 | "repo": "awesome" 9 | }, 10 | "branch": "master", 11 | "submodules": false, 12 | "revision": "4f2bc5c10acaec4a1229db40f690e66284c109b9", 13 | "url": "https://github.com/awesomewm/awesome/archive/4f2bc5c10acaec4a1229db40f690e66284c109b9.tar.gz", 14 | "hash": "0x308h0spkcfwvcr4s0gj7j11dw5w00qky6xyf227fkidcgc6lc1" 15 | }, 16 | "catppuccin-bat": { 17 | "type": "Git", 18 | "repository": { 19 | "type": "GitHub", 20 | "owner": "catppuccin", 21 | "repo": "bat" 22 | }, 23 | "branch": "main", 24 | "submodules": false, 25 | "revision": "699f60fc8ec434574ca7451b444b880430319941", 26 | "url": "https://github.com/catppuccin/bat/archive/699f60fc8ec434574ca7451b444b880430319941.tar.gz", 27 | "hash": "1lirgwgh2hnz6j60py19bbmhvgaqs7i6wf6702k6n83lgw4aixg9" 28 | }, 29 | "catppuccin-rofi": { 30 | "type": "Git", 31 | "repository": { 32 | "type": "GitHub", 33 | "owner": "catppuccin", 34 | "repo": "rofi" 35 | }, 36 | "branch": "main", 37 | "submodules": false, 38 | "revision": "c24a212a6b07c2d45f32d01d7f10b4d88ddc9f45", 39 | "url": "https://github.com/catppuccin/rofi/archive/c24a212a6b07c2d45f32d01d7f10b4d88ddc9f45.tar.gz", 40 | "hash": "0236bcwad4cmr1fhnywvcnzf7xdmhhwgrkrq8jdg8livhh1h8rjq" 41 | }, 42 | "fzf-tab": { 43 | "type": "Git", 44 | "repository": { 45 | "type": "GitHub", 46 | "owner": "Aloxaf", 47 | "repo": "fzf-tab" 48 | }, 49 | "branch": "master", 50 | "submodules": false, 51 | "revision": "6aced3f35def61c5edf9d790e945e8bb4fe7b305", 52 | "url": "https://github.com/Aloxaf/fzf-tab/archive/6aced3f35def61c5edf9d790e945e8bb4fe7b305.tar.gz", 53 | "hash": "1brljd9744wg8p9v3q39kdys33jb03d27pd0apbg1cz0a2r1wqqi" 54 | }, 55 | "zsh-syntax-highlighting": { 56 | "type": "Git", 57 | "repository": { 58 | "type": "GitHub", 59 | "owner": "zsh-users", 60 | "repo": "zsh-syntax-highlighting" 61 | }, 62 | "branch": "master", 63 | "submodules": false, 64 | "revision": "5eb677bb0fa9a3e60f0eff031dc13926e093df92", 65 | "url": "https://github.com/zsh-users/zsh-syntax-highlighting/archive/5eb677bb0fa9a3e60f0eff031dc13926e093df92.tar.gz", 66 | "hash": "1x33gk7hhp07jqq7yjvrsp2vmdbxmadlv3335ixx29bc6h8106r9" 67 | } 68 | }, 69 | "version": 5 70 | } 71 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | intel-vaapi-driver 101 | libva-vdpau-driver 102 | libvdpau-va-gl 103 | intel-media-driver 104 | ]; 105 | } 106 | -------------------------------------------------------------------------------- /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.stdenv.hostPlatform.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.stdenv.hostPlatform.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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /cicd/workflows.cue: -------------------------------------------------------------------------------- 1 | package cicd 2 | 3 | import "cue.dev/x/githubactions" 4 | 5 | _nixVersion: "2.32.1" 6 | 7 | workflows: [_]: githubactions.#Workflow & { 8 | jobs: [_]: "runs-on": *"ubuntu-24.04" | _ 9 | } 10 | 11 | _cloneRepo: githubactions.#Step & { 12 | name: "Clone Repository" 13 | uses: "actions/checkout@v6" 14 | with: token: "${{ secrets.TEST_TOKEN }}" 15 | } 16 | 17 | _installCue: githubactions.#Step & { 18 | name: "Install Cue" 19 | uses: "cue-lang/setup-cue@v1.0.1" 20 | with: version: "v0.14.2" 21 | } 22 | 23 | _installNix: githubactions.#Step & { 24 | name: "Install nix" 25 | uses: "cachix/install-nix-action@v31" 26 | with: { 27 | extra_nix_config: """ 28 | auto-optimise-store = true 29 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 30 | experimental-features = nix-command flakes 31 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org 32 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= 33 | """ 34 | install_url: "https://releases.nixos.org/nix/nix-\(_nixVersion)/install" 35 | } 36 | } 37 | 38 | _freeSpace: githubactions.#Step & { 39 | name: "Free diskspace" 40 | uses: "wimpysworld/nothing-but-nix@main" 41 | } 42 | 43 | _cachixBase: githubactions.#Step & { 44 | name: "Set up cachix" 45 | uses: "cachix/cachix-action@v16" 46 | with: { 47 | name: "nobbz" 48 | signingKey: "${{ secrets.CACHIX_SIGNING_KEY }}" 49 | } 50 | } 51 | 52 | _cachixNoPush: _cachixBase & { 53 | with: { 54 | skipPush: true 55 | } 56 | } 57 | 58 | _cachix: _cachixBase & { 59 | with: { 60 | pathsToPush: "result" 61 | } 62 | } 63 | 64 | _restoreFlakeLock: githubactions.#Step & { 65 | name: "Restore flake.lock" 66 | uses: "actions/download-artifact@v7" 67 | with: name: "flake_lock" 68 | } 69 | 70 | _setupGit: githubactions.#Step & { 71 | name: "Setup git" 72 | run: """ 73 | git config user.email gitbot@nobbz.dev 74 | git config user.name "Git Bot" 75 | """ 76 | } 77 | 78 | _buildFlake: githubactions.#Job & { 79 | _flakeLock!: bool 80 | needs: [ 81 | "generate_matrix", 82 | if _flakeLock {"update_flake"}, 83 | ] 84 | strategy: { 85 | "fail-fast": false 86 | "max-parallel": 5 87 | matrix: { 88 | package: "${{fromJson(needs.generate_matrix.outputs.packages)}}" 89 | exclude: [{package: "installer-iso"}] 90 | } 91 | } 92 | steps: [ 93 | _freeSpace, 94 | _cloneRepo, 95 | _installNix, 96 | _cachix, 97 | if _flakeLock {_restoreFlakeLock}, 98 | { 99 | name: "Build everything" 100 | run: "nix build .#${{ matrix.package }}" 101 | }, 102 | ] 103 | } 104 | 105 | _buildChecks: githubactions.#Job & { 106 | _flakeLock!: bool 107 | needs: [ 108 | "generate_matrix", 109 | if _flakeLock {"update_flake"}, 110 | ] 111 | strategy: { 112 | "fail-fast": false 113 | "max-parallel": 5 114 | matrix: { 115 | check: "${{fromJson(needs.generate_matrix.outputs.checks)}}" 116 | } 117 | } 118 | steps: [ 119 | _cloneRepo, 120 | _installNix, 121 | _cachixNoPush, 122 | if _flakeLock {_restoreFlakeLock}, 123 | { 124 | name: "Build the check" 125 | run: "nix build .#checks.x86_64-linux.${{ matrix.check }} --no-link" 126 | }, 127 | ] 128 | } 129 | 130 | _checkFlake: githubactions.#Job & { 131 | _flakeLock!: bool 132 | needs: [ 133 | "generate_matrix", 134 | if _flakeLock {"update_flake"}, 135 | ] 136 | "continue-on-error": true 137 | steps: [ 138 | _cloneRepo, 139 | _installNix, 140 | if _flakeLock {_restoreFlakeLock}, 141 | { 142 | name: "Run generic check" 143 | run: "nix flake check --keep-going" 144 | }, 145 | ] 146 | } 147 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /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 | {programs.command-not-found.enable = true;} 95 | inputs.sops-nix.nixosModules.sops 96 | ] 97 | ++ config.modules 98 | ++ builtins.attrValues { 99 | inherit (config) entryPoint bootloader hardware; 100 | } 101 | ++ builtins.attrValues self.nixosModules 102 | ++ builtins.attrValues self.mixedModules; 103 | 104 | packageName = "nixos/config/${name}"; 105 | finalPackage = config.finalSystem.config.system.build.toplevel; 106 | 107 | packageModule = {${config.system}.${config.packageName} = config.finalPackage;}; 108 | 109 | finalSystem = config.nixpkgs.lib.nixosSystem { 110 | modules = config.finalModules; 111 | }; 112 | }; 113 | })); 114 | }; 115 | }; 116 | 117 | config.flake.nixosConfigurations = configs; 118 | config.flake.packages = lib.mkMerge packages; 119 | } 120 | -------------------------------------------------------------------------------- /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; 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 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | outputs = {parts, ...} @ inputs: 3 | parts.lib.mkFlake {inherit inputs;} { 4 | systems = ["x86_64-linux" "aarch64-linux" "aarch64-darwin"]; 5 | 6 | debug = true; 7 | 8 | _module.args.npins = import ./npins; 9 | 10 | imports = [ 11 | ./parts/auxiliary.nix 12 | ./parts/home_configs.nix 13 | ./parts/home_modules.nix 14 | ./parts/nixos_modules.nix 15 | ./parts/system_configs.nix 16 | 17 | ./nixos/configurations 18 | ./home/configurations 19 | 20 | ./home/modules 21 | ./nixos/modules 22 | 23 | ./packages 24 | ]; 25 | 26 | perSystem = { 27 | pkgs, 28 | self', 29 | ... 30 | }: { 31 | apps.installer.program = let 32 | isoPath = "iso/${self'.packages.installer-iso.isoName}"; 33 | in 34 | pkgs.writeShellScriptBin "installer" '' 35 | image=disk.qcow2 36 | isoPath=$(mktemp -d)/result 37 | isoFull=$isoPath/${isoPath} 38 | 39 | test -f $image || ${pkgs.qemu}/bin/qemu-img create -f qcow2 $image 50G 40 | 41 | nom build .#installer-iso -o $isoPath 42 | 43 | ${pkgs.qemu}/bin/qemu-system-x86_64 \ 44 | -drive file=$image,if=virtio \ 45 | -cdrom $isoPath/${isoPath} \ 46 | -m 8G \ 47 | -smp 2 \ 48 | -enable-kvm \ 49 | -netdev user,id=net0 \ 50 | -device virtio-net,netdev=net0 \ 51 | -device virtio-vga \ 52 | -bios ${pkgs.OVMF.fd}/FV/OVMF.fd 53 | 54 | du -h $isoFull 55 | rm -f $isoPath 56 | ''; 57 | 58 | apps.awesome-preview.program = let 59 | rc_lua = pkgs.runCommand "awesomerc.lua" {} '' 60 | substitute ${./packages/installer/awesomerc.lua} $out \ 61 | --subst-var-by FILE_PATH_WALLPAPER ${./packages/installer/nix-glow-black.png} \ 62 | --subst-var-by NIX_FLAKE_SVG ${./packages/installer/nix-flake.svg} 63 | ''; 64 | in 65 | pkgs.writeShellScriptBin "awesome-preview" '' 66 | ${pkgs.xorg.xorgserver}/bin/Xephyr :5 & sleep 1 ; DISPLAY=:5 ${self'.packages.awesome}/bin/awesome --config ${rc_lua} 67 | ''; 68 | }; 69 | 70 | flake = { 71 | mixedModules = import ./mixed inputs; 72 | 73 | checks.x86_64-linux = import ./checks inputs; 74 | }; 75 | }; 76 | 77 | inputs = { 78 | nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; 79 | # nixpkgs-insync-v3.url = "github:nixos/nixpkgs?ref=32fdc268e921994e3f38088486ddfe765d11df93"; 80 | nixpkgs-insync-v3.follows = "nixpkgs"; 81 | nixpkgs-pre-rust.url = "github:nixos/nixpkgs?ref=57d0d4a8f302"; 82 | 83 | nvim.url = "github:nobbz/nobbz-vim"; 84 | nvim.inputs.parts.follows = "parts"; 85 | nvim.inputs.nixpkgs.follows = "nixpkgs"; 86 | 87 | switcher.url = "github:nobbz/nix-switcher?ref=main"; 88 | # switcher.inputs.nixpkgs.follows = "nixpkgs"; 89 | switcher.inputs.flake-parts.follows = "parts"; 90 | 91 | parts.url = "github:hercules-ci/flake-parts"; 92 | parts.inputs.nixpkgs-lib.follows = "nixpkgs"; 93 | 94 | programsdb.url = "github:wamserma/flake-programs-sqlite"; 95 | programsdb.inputs.nixpkgs.follows = "nixpkgs"; 96 | 97 | nix.url = "github:nixos/nix"; 98 | nix.inputs.flake-parts.follows = "parts"; 99 | # a libgit2 in the current version fails to build with the nix provided patches. 100 | # therefore using upstreams pin for now. 101 | # nix.inputs.nixpkgs.follows = "nixpkgs"; 102 | 103 | nix-gl.url = "github:nix-community/nixgl"; 104 | nix-gl.inputs.nixpkgs.follows = "nixpkgs"; 105 | 106 | home-manager.url = "github:nix-community/home-manager"; 107 | home-manager.inputs.nixpkgs.follows = "nixpkgs"; 108 | 109 | emacs.url = "github:nix-community/emacs-overlay"; 110 | emacs.inputs.nixpkgs.follows = "nixpkgs"; 111 | emacs.inputs.nixpkgs-stable.follows = "nixpkgs"; 112 | 113 | nixos-vscode-server.url = "github:msteen/nixos-vscode-server"; 114 | nixos-vscode-server.inputs.nixpkgs.follows = "nixpkgs"; 115 | 116 | sops-nix.url = "github:Mic92/sops-nix"; 117 | }; 118 | } 119 | -------------------------------------------------------------------------------- /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 | gtk.gtk2.force = true; 19 | 20 | home.packages = builtins.attrValues { 21 | inherit (pkgs) keybase-gui freerdp keepassxc nix-output-monitor discord; 22 | inherit (pkgs) obsidian; 23 | inherit (pkgs) gnome-tweaks; 24 | inherit (pkgs) vscode wezterm; 25 | }; 26 | 27 | programs.obs-studio.enable = true; 28 | programs.obs-studio.plugins = builtins.attrValues { 29 | inherit (pkgs.obs-studio-plugins) obs-backgroundremoval; 30 | }; 31 | programs.htop = { 32 | settings = { 33 | detailed_cpu_time = true; 34 | }; 35 | # meters.right = [ 36 | # { kind = "Battery"; mode = 1; } 37 | # "Tasks" 38 | # "LoadAverage" 39 | # "Uptime" 40 | # ]; 41 | }; 42 | 43 | programs.yazi.enable = true; 44 | 45 | xsession.windowManager.awesome.autostart = [ 46 | "${pkgs.blueman}/bin/blueman-applet" 47 | "${pkgs.networkmanagerapplet}/bin/nm-applet" 48 | ]; 49 | 50 | systemd.user.tmpfiles.rules = [ 51 | "d ${config.home.homeDirectory}/tmp 700 ${config.home.username} users 14d" 52 | ]; 53 | 54 | services = { 55 | keybase.enable = true; 56 | kbfs.enable = true; 57 | insync.enable = true; 58 | playerctld.enable = true; 59 | flameshot.enable = true; 60 | 61 | rustic = { 62 | enable = true; 63 | passwordFile = config.sops.secrets.rustic.path; 64 | globs = let 65 | mkHome = e: "${config.home.homeDirectory}/${e}"; 66 | mkIgnore = e: "!${e}"; 67 | 68 | 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"]; 69 | patterns = ["_build" "Cache" "deps" "result" "target" ".elixir_ls" "ccls-cache" ".direnv" "direnv" "node_modules"]; 70 | in 71 | map mkIgnore (home ++ patterns); 72 | oneFileSystem = true; 73 | repo = "rest:https://restic.mimas.internal.nobbz.dev/nobbz"; 74 | }; 75 | }; 76 | 77 | systemd.user.services = { 78 | rustic.Unit.After = ["sops-nix.service"]; 79 | keybase-gui = { 80 | Unit = { 81 | Description = "Keybase GUI"; 82 | Requires = ["keybase.service" "kbfs.service"]; 83 | After = ["keybase.service" "kbfs.service"]; 84 | }; 85 | Service = { 86 | ExecStart = "${pkgs.keybase-gui}/share/keybase/Keybase"; 87 | PrivateTmp = true; 88 | # Slice = "keybase.slice"; 89 | }; 90 | }; 91 | }; 92 | 93 | xdg.configFile = { 94 | "rustic/mimas-hetzner.toml".text = 95 | # toml 96 | '' 97 | [repository] 98 | repository = "rclone:hetzner-restic:mimas" 99 | password-file = "${config.sops.secrets.rustic.path}" 100 | ''; 101 | "rustic/mimas.toml".text = 102 | # toml 103 | '' 104 | [repository] 105 | repository = "rest:https://restic.mimas.internal.nobbz.dev/mimas" 106 | password-file = "${config.sops.secrets.rustic.path}" 107 | 108 | [copy] 109 | targets = ["mimas-hetzner"] 110 | ''; 111 | 112 | "rustic/nobbz-hetzner.toml".text = 113 | # toml 114 | '' 115 | [repository] 116 | repository = "rclone:hetzner-restic:nobbz" 117 | password-file = "${config.sops.secrets.rustic.path}" 118 | ''; 119 | "rustic/nobbz.toml".text = 120 | # toml 121 | '' 122 | [repository] 123 | repository = "rest:https://restic.mimas.internal.nobbz.dev/nobbz" 124 | password-file = "${config.sops.secrets.rustic.path}" 125 | 126 | [copy] 127 | targets = ["nobbz-hetzner"] 128 | ''; 129 | }; 130 | 131 | home.stateVersion = "20.09"; 132 | } 133 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /.github/workflows/pull-check.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | build_checks: 3 | needs: 4 | - generate_matrix 5 | runs-on: ubuntu-24.04 6 | steps: 7 | - name: Clone Repository 8 | uses: actions/checkout@v6 9 | with: 10 | token: ${{ secrets.TEST_TOKEN }} 11 | - name: Install nix 12 | uses: cachix/install-nix-action@v31 13 | with: 14 | extra_nix_config: |- 15 | auto-optimise-store = true 16 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 17 | experimental-features = nix-command flakes 18 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org 19 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= 20 | install_url: https://releases.nixos.org/nix/nix-2.32.1/install 21 | - name: Set up cachix 22 | uses: cachix/cachix-action@v16 23 | with: 24 | name: nobbz 25 | signingKey: ${{ secrets.CACHIX_SIGNING_KEY }} 26 | skipPush: true 27 | - name: Build the check 28 | run: nix build .#checks.x86_64-linux.${{ matrix.check }} --no-link 29 | strategy: 30 | fail-fast: false 31 | matrix: 32 | check: ${{fromJson(needs.generate_matrix.outputs.checks)}} 33 | max-parallel: 5 34 | build_flake: 35 | needs: 36 | - generate_matrix 37 | runs-on: ubuntu-24.04 38 | steps: 39 | - name: Free diskspace 40 | uses: wimpysworld/nothing-but-nix@main 41 | - name: Clone Repository 42 | uses: actions/checkout@v6 43 | with: 44 | token: ${{ secrets.TEST_TOKEN }} 45 | - name: Install nix 46 | uses: cachix/install-nix-action@v31 47 | with: 48 | extra_nix_config: |- 49 | auto-optimise-store = true 50 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 51 | experimental-features = nix-command flakes 52 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org 53 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= 54 | install_url: https://releases.nixos.org/nix/nix-2.32.1/install 55 | - name: Set up cachix 56 | uses: cachix/cachix-action@v16 57 | with: 58 | name: nobbz 59 | pathsToPush: result 60 | signingKey: ${{ secrets.CACHIX_SIGNING_KEY }} 61 | - name: Build everything 62 | run: nix build .#${{ matrix.package }} 63 | strategy: 64 | fail-fast: false 65 | matrix: 66 | exclude: 67 | - package: installer-iso 68 | package: ${{fromJson(needs.generate_matrix.outputs.packages)}} 69 | max-parallel: 5 70 | check_flake: 71 | continue-on-error: true 72 | needs: 73 | - generate_matrix 74 | runs-on: ubuntu-24.04 75 | steps: 76 | - name: Clone Repository 77 | uses: actions/checkout@v6 78 | with: 79 | token: ${{ secrets.TEST_TOKEN }} 80 | - name: Install nix 81 | uses: cachix/install-nix-action@v31 82 | with: 83 | extra_nix_config: |- 84 | auto-optimise-store = true 85 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 86 | experimental-features = nix-command flakes 87 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org 88 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= 89 | install_url: https://releases.nixos.org/nix/nix-2.32.1/install 90 | - name: Run generic check 91 | run: nix flake check --keep-going 92 | generate_matrix: 93 | outputs: 94 | checks: ${{ steps.gen_checks.outputs.checks }} 95 | packages: ${{ steps.gen_packages.outputs.packages }} 96 | runs-on: ubuntu-24.04 97 | steps: 98 | - name: Clone Repository 99 | uses: actions/checkout@v6 100 | with: 101 | token: ${{ secrets.TEST_TOKEN }} 102 | - name: Install nix 103 | uses: cachix/install-nix-action@v31 104 | with: 105 | extra_nix_config: |- 106 | auto-optimise-store = true 107 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 108 | experimental-features = nix-command flakes 109 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org 110 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= 111 | install_url: https://releases.nixos.org/nix/nix-2.32.1/install 112 | - name: Generate flake.json 113 | run: nix flake show --json > flake.json 114 | - id: gen_packages 115 | run: |- 116 | packages=$(jq -c '.packages."x86_64-linux" | keys' < flake.json) 117 | printf "packages=%s" "$packages" >> "${GITHUB_OUTPUT}" 118 | - id: gen_checks 119 | run: |- 120 | checks=$(jq -c '.checks."x86_64-linux" | keys' < flake.json) 121 | printf "checks=%s" "$checks" >> "${GITHUB_OUTPUT}" 122 | name: Pull Request Checker 123 | "on": 124 | pull_request: {} 125 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /npins/default.nix: -------------------------------------------------------------------------------- 1 | /* 2 | This file is provided under the MIT licence: 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | # Generated by npins. Do not modify; will be overwritten regularly 11 | let 12 | data = builtins.fromJSON (builtins.readFile ./sources.json); 13 | version = data.version; 14 | 15 | # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295 16 | range = first: last: 17 | if first > last 18 | then [] 19 | else builtins.genList (n: first + n) (last - first + 1); 20 | 21 | # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257 22 | stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1)); 23 | 24 | # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269 25 | stringAsChars = f: s: concatStrings (map f (stringToCharacters s)); 26 | concatMapStrings = f: list: concatStrings (map f list); 27 | concatStrings = builtins.concatStringsSep ""; 28 | 29 | # If the environment variable NPINS_OVERRIDE_${name} is set, then use 30 | # the path directly as opposed to the fetched source. 31 | # (Taken from Niv for compatibility) 32 | mayOverride = name: path: let 33 | envVarName = "NPINS_OVERRIDE_${saneName}"; 34 | saneName = stringAsChars (c: 35 | if (builtins.match "[a-zA-Z0-9]" c) == null 36 | then "_" 37 | else c) 38 | name; 39 | ersatz = builtins.getEnv envVarName; 40 | in 41 | if ersatz == "" 42 | then path 43 | else 44 | # this turns the string into an actual Nix path (for both absolute and 45 | # relative paths) 46 | builtins.trace "Overriding path of \"${name}\" with \"${ersatz}\" due to set \"${envVarName}\"" ( 47 | if builtins.substring 0 1 ersatz == "/" 48 | then /. + ersatz 49 | else /. + builtins.getEnv "PWD" + "/${ersatz}" 50 | ); 51 | 52 | mkSource = name: spec: 53 | assert spec ? type; let 54 | path = 55 | if spec.type == "Git" 56 | then mkGitSource spec 57 | else if spec.type == "GitRelease" 58 | then mkGitSource spec 59 | else if spec.type == "PyPi" 60 | then mkPyPiSource spec 61 | else if spec.type == "Channel" 62 | then mkChannelSource spec 63 | else if spec.type == "Tarball" 64 | then mkTarballSource spec 65 | else builtins.throw "Unknown source type ${spec.type}"; 66 | in 67 | spec // {outPath = mayOverride name path;}; 68 | 69 | mkGitSource = { 70 | repository, 71 | revision, 72 | url ? null, 73 | submodules, 74 | hash, 75 | branch ? null, 76 | ... 77 | }: 78 | assert repository ? type; 79 | # At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository 80 | # In the latter case, there we will always be an url to the tarball 81 | if url != null && !submodules 82 | then 83 | builtins.fetchTarball { 84 | inherit url; 85 | sha256 = hash; # FIXME: check nix version & use SRI hashes 86 | } 87 | else let 88 | url = 89 | if repository.type == "Git" 90 | then repository.url 91 | else if repository.type == "GitHub" 92 | then "https://github.com/${repository.owner}/${repository.repo}.git" 93 | else if repository.type == "GitLab" 94 | then "${repository.server}/${repository.repo_path}.git" 95 | else throw "Unrecognized repository type ${repository.type}"; 96 | urlToName = url: rev: let 97 | matched = builtins.match "^.*/([^/]*)(\\.git)?$" url; 98 | 99 | short = builtins.substring 0 7 rev; 100 | 101 | appendShort = 102 | if (builtins.match "[a-f0-9]*" rev) != null 103 | then "-${short}" 104 | else ""; 105 | in "${ 106 | if matched == null 107 | then "source" 108 | else builtins.head matched 109 | }${appendShort}"; 110 | name = urlToName url revision; 111 | in 112 | builtins.fetchGit { 113 | rev = revision; 114 | inherit name; 115 | # hash = hash; 116 | inherit url submodules; 117 | }; 118 | 119 | mkPyPiSource = { 120 | url, 121 | hash, 122 | ... 123 | }: 124 | builtins.fetchurl { 125 | inherit url; 126 | sha256 = hash; 127 | }; 128 | 129 | mkChannelSource = { 130 | url, 131 | hash, 132 | ... 133 | }: 134 | builtins.fetchTarball { 135 | inherit url; 136 | sha256 = hash; 137 | }; 138 | 139 | mkTarballSource = { 140 | url, 141 | locked_url ? url, 142 | hash, 143 | ... 144 | }: 145 | builtins.fetchTarball { 146 | url = locked_url; 147 | sha256 = hash; 148 | }; 149 | in 150 | if version == 5 151 | then builtins.mapAttrs mkSource data.pins 152 | else throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`" 153 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | inherit (config.programs.git.settings.user) name email; 21 | }; 22 | 23 | ui.diff-formatter = [config.programs.git.settings.diff.external "--color=always" "$left" "$right"]; 24 | ui.paginate = "never"; 25 | }; 26 | }; 27 | 28 | programs.gh.enable = true; 29 | programs.git = { 30 | enable = true; 31 | 32 | settings.user.name = "Norbert Melzer"; 33 | settings.user.email = "timmelzer@gmail.com"; 34 | 35 | settings.alias = 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 | settings = { 143 | init.defaultBranch = "main"; 144 | diff.external = lib.getExe pkgs.difftastic; 145 | pull.rebase = false; 146 | merge.conflictStyle = "diff3"; 147 | merge.mergiraf.name = "mergiraf"; 148 | merge.mergiraf.driver = ''${lib.getExe pkgs.mergiraf} merge --git "%O" "%A" "%B" -s "%S" -x "%X" -y "%Y" -p "%P" -l "%L"''; 149 | rerere.enabled = true; 150 | }; 151 | 152 | attributes = [ 153 | "* merge=mergiraf" 154 | ]; 155 | 156 | ignores = [ 157 | # IntelliJ files and folders 158 | ".idea/" 159 | "*.iml" 160 | # backupfiles and shadow copies done by editors 161 | "*~" 162 | "\\#*\\#" 163 | ".#*" 164 | # Elixir language server 165 | "/.elixir_ls" 166 | # MyPy Cache 167 | ".mypy_cache" 168 | # Visual Studio Code project configuration 169 | "/.vscode" 170 | # Result folder for nix builds 171 | "result" 172 | "result-*" 173 | # direnv caches 174 | ".direnv/" 175 | # emacs/python stuff 176 | "flycheck_*.py" 177 | ]; 178 | 179 | includes = [ 180 | { 181 | condition = "gitdir:~/cloudseeds/**"; 182 | contents = { 183 | init.defaultBranch = "master"; 184 | user.email = "norbert.melzer@cloudseeds.de"; 185 | }; 186 | } 187 | { 188 | condition = "gitdir:~/Projects/BravoBike/**"; 189 | contents = { 190 | user.email = "norbert.melzer@bravobike.de"; 191 | }; 192 | } 193 | ]; 194 | }; 195 | 196 | home.packages = [pkgs.ripgrep pkgs.difftastic]; 197 | }; 198 | } 199 | -------------------------------------------------------------------------------- /.github/workflows/flake-update.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | build_checks: 3 | needs: 4 | - generate_matrix 5 | - update_flake 6 | runs-on: ubuntu-24.04 7 | steps: 8 | - name: Clone Repository 9 | uses: actions/checkout@v6 10 | with: 11 | token: ${{ secrets.TEST_TOKEN }} 12 | - name: Install nix 13 | uses: cachix/install-nix-action@v31 14 | with: 15 | extra_nix_config: |- 16 | auto-optimise-store = true 17 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 18 | experimental-features = nix-command flakes 19 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org 20 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= 21 | install_url: https://releases.nixos.org/nix/nix-2.32.1/install 22 | - name: Set up cachix 23 | uses: cachix/cachix-action@v16 24 | with: 25 | name: nobbz 26 | signingKey: ${{ secrets.CACHIX_SIGNING_KEY }} 27 | skipPush: true 28 | - name: Restore flake.lock 29 | uses: actions/download-artifact@v7 30 | with: 31 | name: flake_lock 32 | - name: Build the check 33 | run: nix build .#checks.x86_64-linux.${{ matrix.check }} --no-link 34 | strategy: 35 | fail-fast: false 36 | matrix: 37 | check: ${{fromJson(needs.generate_matrix.outputs.checks)}} 38 | max-parallel: 5 39 | build_flake: 40 | needs: 41 | - generate_matrix 42 | - update_flake 43 | runs-on: ubuntu-24.04 44 | steps: 45 | - name: Free diskspace 46 | uses: wimpysworld/nothing-but-nix@main 47 | - name: Clone Repository 48 | uses: actions/checkout@v6 49 | with: 50 | token: ${{ secrets.TEST_TOKEN }} 51 | - name: Install nix 52 | uses: cachix/install-nix-action@v31 53 | with: 54 | extra_nix_config: |- 55 | auto-optimise-store = true 56 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 57 | experimental-features = nix-command flakes 58 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org 59 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= 60 | install_url: https://releases.nixos.org/nix/nix-2.32.1/install 61 | - name: Set up cachix 62 | uses: cachix/cachix-action@v16 63 | with: 64 | name: nobbz 65 | pathsToPush: result 66 | signingKey: ${{ secrets.CACHIX_SIGNING_KEY }} 67 | - name: Restore flake.lock 68 | uses: actions/download-artifact@v7 69 | with: 70 | name: flake_lock 71 | - name: Build everything 72 | run: nix build .#${{ matrix.package }} 73 | strategy: 74 | fail-fast: false 75 | matrix: 76 | exclude: 77 | - package: installer-iso 78 | package: ${{fromJson(needs.generate_matrix.outputs.packages)}} 79 | max-parallel: 5 80 | check_flake: 81 | continue-on-error: true 82 | needs: 83 | - generate_matrix 84 | - update_flake 85 | runs-on: ubuntu-24.04 86 | steps: 87 | - name: Clone Repository 88 | uses: actions/checkout@v6 89 | with: 90 | token: ${{ secrets.TEST_TOKEN }} 91 | - name: Install nix 92 | uses: cachix/install-nix-action@v31 93 | with: 94 | extra_nix_config: |- 95 | auto-optimise-store = true 96 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 97 | experimental-features = nix-command flakes 98 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org 99 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= 100 | install_url: https://releases.nixos.org/nix/nix-2.32.1/install 101 | - name: Restore flake.lock 102 | uses: actions/download-artifact@v7 103 | with: 104 | name: flake_lock 105 | - name: Run generic check 106 | run: nix flake check --keep-going 107 | generate_matrix: 108 | outputs: 109 | checks: ${{ steps.gen_checks.outputs.checks }} 110 | packages: ${{ steps.gen_packages.outputs.packages }} 111 | runs-on: ubuntu-24.04 112 | steps: 113 | - name: Clone Repository 114 | uses: actions/checkout@v6 115 | with: 116 | token: ${{ secrets.TEST_TOKEN }} 117 | - name: Install nix 118 | uses: cachix/install-nix-action@v31 119 | with: 120 | extra_nix_config: |- 121 | auto-optimise-store = true 122 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 123 | experimental-features = nix-command flakes 124 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org 125 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= 126 | install_url: https://releases.nixos.org/nix/nix-2.32.1/install 127 | - name: Generate flake.json 128 | run: nix flake show --json > flake.json 129 | - id: gen_packages 130 | run: |- 131 | packages=$(jq -c '.packages."x86_64-linux" | keys' < flake.json) 132 | printf "packages=%s" "$packages" >> "${GITHUB_OUTPUT}" 133 | - id: gen_checks 134 | run: |- 135 | checks=$(jq -c '.checks."x86_64-linux" | keys' < flake.json) 136 | printf "checks=%s" "$checks" >> "${GITHUB_OUTPUT}" 137 | push_update: 138 | needs: 139 | - update_flake 140 | - build_flake 141 | - build_checks 142 | - check_flake 143 | permissions: write-all 144 | runs-on: ubuntu-24.04 145 | steps: 146 | - name: Clone Repository 147 | uses: actions/checkout@v6 148 | with: 149 | token: ${{ secrets.TEST_TOKEN }} 150 | - name: Restore flake.lock 151 | uses: actions/download-artifact@v7 152 | with: 153 | name: flake_lock 154 | - name: Setup git 155 | run: |- 156 | git config user.email gitbot@nobbz.dev 157 | git config user.name "Git Bot" 158 | - env: 159 | GITHUB_TOKEN: ${{ secrets.TEST_TOKEN }} 160 | name: Create and merge PR 161 | run: |- 162 | git switch -c updates-${{ github.run_id }} 163 | git commit -am "flake.lock: Update" 164 | git push -u origin updates-${{ github.run_id }} 165 | PR="$(gh pr create \ 166 | --assignee NobbZ \ 167 | --base main \ 168 | --body "Automatic flake update on $(date -Idate)" \ 169 | --fill \ 170 | --label bot \ 171 | --title "Auto update $(date -Idate)")" 172 | gh pr merge "$PR" --merge --delete-branch 173 | update_flake: 174 | runs-on: ubuntu-24.04 175 | steps: 176 | - name: Clone Repository 177 | uses: actions/checkout@v6 178 | with: 179 | token: ${{ secrets.TEST_TOKEN }} 180 | - name: Install nix 181 | uses: cachix/install-nix-action@v31 182 | with: 183 | extra_nix_config: |- 184 | auto-optimise-store = true 185 | access-tokens = github.com=${{ secrets.TEST_TOKEN }} 186 | experimental-features = nix-command flakes 187 | substituters = https://cache.nixos.org/ https://nix-community.cachix.org 188 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= 189 | install_url: https://releases.nixos.org/nix/nix-2.32.1/install 190 | - name: Setup git 191 | run: |- 192 | git config user.email gitbot@nobbz.dev 193 | git config user.name "Git Bot" 194 | - name: Update the flake 195 | run: nix flake update 196 | - name: Store flake.lock 197 | uses: actions/upload-artifact@v6 198 | with: 199 | name: flake_lock 200 | path: flake.lock 201 | name: Updater 202 | "on": 203 | schedule: 204 | - cron: 0 2 * * * 205 | workflow_dispatch: {} 206 | -------------------------------------------------------------------------------- /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 | "cannot:${pkgs.pv}/bin/pv" 91 | ]; 92 | } '' 93 | count=$(fd . /nix/store/.links/ | pv -l | wc -l) 94 | 95 | # TODO: make resholve understant the call to `stat` 96 | saved=$(fd . /nix/store/.links/ -X ${pkgs.coreutils}/bin/stat --format='%h %s' {} \ 97 | | pv -altrpe -s $count \ 98 | | awk '{sum += ($1 - 2) * $2} END {print sum}') 99 | 100 | printf "Currently hardlinking saves %sB (%s B)\n" \ 101 | "$(numfmt --to=iec-i --format='%.2f' ''${saved} \ 102 | | sed -E 's/([0-9])([A-Za-z])/\1 \2/')" \ 103 | "$(numfmt --to=none --format="%'f" ''${saved})" 104 | ''; 105 | neovide = 106 | if cfg.needsGL 107 | then 108 | pkgs.writeShellScriptBin nvim.packages.x86_64-linux.neovide.meta.mainProgram '' 109 | exec ${lib.getExe nix-gl.packages.x86_64-linux.nixGLIntel} ${lib.getExe nvim.packages.x86_64-linux.neovide} "$@" 110 | '' 111 | else nvim.packages.x86_64-linux.neovide; 112 | in 113 | lib.mkMerge [ 114 | [optisave pkgs.departure-mono pkgs.hydra-check nvim.packages.x86_64-linux.neovim neovide] 115 | (lib.mkIf pkgs.stdenv.isLinux [pkgs.dconf]) 116 | ]; 117 | 118 | # dconf.enable = lib.mkMerge [ 119 | # (lib.mkIf pkgs.stdenv.isLinux true) 120 | # (lib.mkIf pkgs.stdenv.isDarwin false) 121 | # ]; 122 | 123 | xsession = { 124 | enable = true; 125 | numlock.enable = true; 126 | profileExtra = '' 127 | setxkbmap de 128 | ''; 129 | }; 130 | 131 | programs = { 132 | advancedCopy.enable = true; 133 | direnv.enable = true; 134 | direnv.nix-direnv.enable = true; 135 | direnv.nix-direnv.package = pkgs.nix-direnv.override {nix = nix.packages.${pkgs.stdenv.hostPlatform.system}.default;}; 136 | eza.enable = true; 137 | fzf.enable = true; 138 | home-manager.enable = true; 139 | htop.enable = true; 140 | jq.enable = true; 141 | p10k.enable = true; 142 | zoxide.enable = true; 143 | 144 | bat = { 145 | enable = true; 146 | 147 | config.theme = "mocha"; 148 | 149 | themes.mocha = { 150 | src = npins.catppuccin-bat; 151 | file = "themes/Catppuccin Mocha.tmTheme"; 152 | }; 153 | }; 154 | 155 | ssh = { 156 | enable = true; 157 | enableDefaultConfig = false; 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 | compression = true; 204 | forwardAgent = false; 205 | addKeysToAgent = "no"; 206 | serverAliveInterval = 0; 207 | serverAliveCountMax = 3; 208 | hashKnownHosts = false; 209 | userKnownHostsFile = "${config.home.homeDirectory}/.ssh/known_hosts"; 210 | }; 211 | }; 212 | }; 213 | 214 | tmux = { 215 | enable = true; 216 | 217 | clock24 = true; 218 | historyLimit = 10000; 219 | terminal = "tmux-256color"; 220 | 221 | plugins = [ 222 | { 223 | plugin = pkgs.tmuxPlugins.catppuccin; 224 | extraConfig = '' 225 | set -g @catppuccin_flavor "mocha" 226 | set -g @catppuccin_window_status_style "rounded" 227 | ''; 228 | } 229 | ]; 230 | 231 | extraConfig = '' 232 | set -ag terminal-overrides ",xterm-256color:RGB" 233 | ''; 234 | }; 235 | 236 | zsh = { 237 | enable = true; 238 | 239 | enableCompletion = true; 240 | autosuggestion.enable = true; 241 | 242 | autocd = true; 243 | 244 | dotDir = "${config.home.homeDirectory}/.config/zsh"; 245 | 246 | defaultKeymap = "emacs"; 247 | 248 | plugins = [ 249 | { 250 | name = "fzf-tab"; 251 | src = fzf-tab; 252 | } 253 | { 254 | name = "nix-zsh-complete.zsh"; 255 | src = zsh-complete; 256 | file = "_nix"; 257 | } 258 | { 259 | name = "zsh-syntax-highlighting"; 260 | src = npins.zsh-syntax-highlighting; 261 | } 262 | ]; 263 | 264 | initContent = '' 265 | bindkey "^[[1;5D" backward-word 266 | bindkey "^[[1;5C" forward-word 267 | 268 | ZSH_AUTOSUGGEST_STRATEGY=(completion history) 269 | ''; 270 | 271 | sessionVariables = { 272 | PROMPT_EOL_MARK = "%F{243}¶%f"; 273 | }; 274 | 275 | shellAliases.fixstore = "sudo nix-store --verify --check-contents --repair"; 276 | shellAliases.pq = "pueue"; 277 | }; 278 | }; 279 | }; 280 | } 281 | -------------------------------------------------------------------------------- /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 | programs.mosh.enable = true; 22 | 23 | security.pam.services.i3lock.enable = true; 24 | security.pam.services.i3lock-color.enable = true; 25 | 26 | sops.age.sshKeyPaths = ["/etc/ssh/ssh_host_ed25519_key"]; 27 | sops.defaultSopsFile = "${self}/secrets/mimas/default.yaml"; 28 | 29 | sops.secrets.restic = {}; 30 | sops.secrets.traefik = {}; 31 | 32 | nix.allowedUnfree = ["zerotierone"] ++ steamPackages; 33 | nix.settings.experimental-features = ["ca-derivations" "impure-derivations"]; 34 | nix.distributedBuilds = true; 35 | # nix.enabledMachines = ["enceladeus"]; 36 | 37 | security.chromiumSuidSandbox.enable = true; 38 | 39 | zramSwap.enable = true; 40 | zramSwap.memoryPercent = 25; 41 | 42 | services.lvm.boot.thin.enable = true; 43 | boot.enableContainers = false; 44 | 45 | boot.binfmt.emulatedSystems = ["i686-linux" "aarch64-linux"]; 46 | nix.settings.extra-platforms = config.boot.binfmt.emulatedSystems; 47 | nix.settings.system-features = ["nixos-test" "benchmark" "big-parallel" "kvm" "gccarch-core2" "gccarch-haswell"]; 48 | 49 | # The global useDHCP flag is deprecated, therefore explicitly set to false here. 50 | # Per-interface useDHCP will be mandatory in the future, so this generated config 51 | # replicates the default behaviour. 52 | networking.useDHCP = false; 53 | networking.interfaces.enp5s0f2.useDHCP = false; 54 | networking.interfaces.wlp4s0.useDHCP = false; 55 | networking.hostId = "21025bb1"; 56 | networking.networkmanager.enable = true; 57 | networking.networkmanager.unmanaged = [ 58 | # "mac:80:fa:5b:09:15:6e" 59 | ]; 60 | 61 | # Select internationalisation properties. 62 | i18n = { 63 | # consoleFont = "Lat2-Terminus16"; 64 | # consoleKeyMap = "de"; 65 | defaultLocale = "en_US.UTF-8"; 66 | }; 67 | 68 | console.font = "Lat2-Terminus16"; 69 | console.keyMap = "de"; 70 | 71 | # Set your time zone. 72 | time.timeZone = "Europe/Berlin"; 73 | 74 | # List packages installed in system profile. To search, run: 75 | # $ nix search wget 76 | environment.systemPackages = with pkgs; [ 77 | virt-manager 78 | iptables 79 | ]; 80 | 81 | # Some programs need SUID wrappers, can be configured further or are 82 | # started in user sessions. 83 | # programs.mtr.enable = true; 84 | # programs.gnupg.agent = { enable = true; enableSSHSupport = true; }; 85 | 86 | # List services that you want to enable: 87 | 88 | # Enable the OpenSSH daemon. 89 | services.openssh.enable = true; 90 | 91 | # Add to XDG_DATA_DIRS: 92 | # * /var/lib/flatpak/exports/share 93 | # * $HOME/.local/share/flatpak/exports/share 94 | services.flatpak.enable = true; 95 | 96 | # Open ports in the firewall. 97 | networking.firewall.allowedTCPPorts = [80 443 1111 5555 8080 9002 9003 58080 4001]; 98 | # networking.firewall.allowedUDPPorts = [ ... ]; 99 | # Or disable the firewall altogether. 100 | networking.firewall.enable = true; 101 | 102 | # services.fwupd.enable = true; 103 | 104 | # Enable CUPS to print documents. 105 | services.printing.enable = true; 106 | 107 | services.avahi.enable = true; 108 | services.avahi.nssmdns4 = true; 109 | services.avahi.openFirewall = true; 110 | 111 | services.ratbagd.enable = true; 112 | 113 | programs.partition-manager.enable = true; 114 | 115 | programs.kdeconnect.enable = true; 116 | 117 | # security.polkit.enable = true; 118 | 119 | # services.hydra = { 120 | # enable = true; 121 | # package = pkgs.hydra-unstable; 122 | 123 | # hydraURL = "https://localhost:3000"; 124 | # notificationSender = "hydra@localhost"; 125 | # buildMachinesFiles = [ ]; 126 | # useSubstitutes = true; 127 | # }; 128 | # networking.firewall.allowedTCPPorts = [ 3000 ]; 129 | 130 | # Enable pulse compat. 131 | services.pipewire.pulse.enable = true; 132 | 133 | hardware.bluetooth.enable = true; 134 | 135 | # Enable the X11 windowing system. 136 | services.xserver.enable = true; 137 | services.xserver.xkb.layout = "de"; 138 | 139 | # Enable touchpad support. 140 | # services.xserver.libinput.enable = true; 141 | 142 | # Enable the KDE Desktop Environment. 143 | services.displayManager.sddm.enable = true; 144 | services.desktopManager.plasma6.enable = true; 145 | services.xserver.windowManager.awesome.enable = true; 146 | xdg.portal.enable = true; 147 | 148 | services.dbus.packages = [pkgs.dconf]; 149 | 150 | services.udev.extraRules = '' 151 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0666" 152 | ''; 153 | 154 | # services.transmission.enable = true; 155 | systemd.services.transmission.after = ["var-lib-transmission.mount"]; 156 | 157 | programs = { 158 | steam.enable = true; 159 | 160 | zsh.enable = true; 161 | zsh.enableCompletion = false; 162 | }; 163 | 164 | hardware.graphics.enable = true; 165 | hardware.graphics.extraPackages = [pkgs.intel-vaapi-driver]; 166 | 167 | services.gitea = { 168 | enable = true; 169 | settings.server.DOMAIN = "gitea.mimas.internal.nobbz.dev"; 170 | settings.server.HTTP_ADDR = "127.0.0.1"; 171 | settings.server.ROOT_URL = lib.mkForce "https://gitea.mimas.internal.nobbz.dev/"; 172 | settings."git.timeout".DEFAULT = 3600; # 1 hour 173 | settings."git.timeout".MIGRATE = 3600; # 1 hour 174 | settings."git.timeout".MIRROR = 3600; # 1 hour 175 | settings."git.timeout".CLONE = 3600; # 1 hour 176 | settings."git.timeout".PULL = 3600; # 1 hour 177 | settings."git.timeout".GC = 3600; # 1 hour 178 | }; 179 | systemd.services.gitea.after = ["var-lib-gitea.mount"]; 180 | 181 | virtualisation = { 182 | docker = { 183 | enable = true; 184 | # storageDriver = "zfs"; 185 | # extraOptions = "--storage-opt zfs.fsname=rpool/local/docker"; 186 | package = pkgs.docker; 187 | extraOptions = "--dns 1.1.1.1"; 188 | }; 189 | 190 | containers.enable = true; 191 | 192 | libvirtd.enable = true; 193 | }; 194 | 195 | # Define a user account. Don't forget to set a password with ‘passwd’. 196 | # users.users.jane = { 197 | # isNormalUser = true; 198 | # extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user. 199 | # }; 200 | users.users = { 201 | nmelzer = { 202 | isNormalUser = true; 203 | shell = pkgs.zsh; 204 | extraGroups = [ 205 | "wheel" 206 | "audio" 207 | "networkmanager" 208 | "vboxusers" 209 | "libvirtd" 210 | "docker" 211 | "transmission" 212 | "scanner" 213 | "lp" 214 | ]; 215 | }; 216 | 217 | gamer = { 218 | isNormalUser = true; 219 | extraGroups = [ 220 | "audio" 221 | "networkmanager" 222 | ]; 223 | }; 224 | 225 | aroemer = { 226 | isNormalUser = true; 227 | extraGroups = []; 228 | }; 229 | }; 230 | 231 | security.sudo.extraConfig = "Defaults passwd_timeout=0"; 232 | 233 | # services.wakeonlan.interfaces = [ 234 | # { 235 | # interface = "enp5s0f2"; 236 | # method = "magicpacket"; 237 | # } 238 | # ]; 239 | 240 | # grafana configuration 241 | services.grafana = { 242 | enable = true; 243 | settings.server = { 244 | domain = "grafana.mimas.internal.nobbz.lan"; 245 | http_port = 2342; 246 | http_addr = "127.0.0.1"; 247 | }; 248 | }; 249 | 250 | # nginx reverse proxy 251 | services.nginx.virtualHosts.${config.services.grafana.domain} = { 252 | locations."/" = { 253 | proxyPass = "http://127.0.0.1:${toString config.services.grafana.settings.server.http_port}"; 254 | proxyWebsockets = true; 255 | }; 256 | }; 257 | 258 | hardware.keyboard.zsa.enable = true; 259 | hardware.sane.enable = true; 260 | 261 | services.traefik.enable = true; 262 | systemd.services.traefik.serviceConfig.EnvironmentFile = [config.sops.secrets.traefik.path]; 263 | services.traefik.staticConfigOptions = { 264 | log.level = "DEBUG"; 265 | 266 | api.dashboard = true; 267 | api.insecure = true; 268 | # experimental.http3 = true; 269 | 270 | certificatesResolvers.mimasWildcard.acme = { 271 | email = "acme@nobbz.dev"; 272 | storage = "/var/lib/traefik/mimas.json"; 273 | # caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"; 274 | dnsChallenge.provider = "cloudflare"; 275 | dnsChallenge.resolvers = ["1.1.1.1:53" "8.8.8.8:53"]; 276 | }; 277 | 278 | entryPoints = { 279 | http = { 280 | address = ":80"; 281 | forwardedHeaders.insecure = true; 282 | http.redirections.entryPoint = { 283 | to = "https"; 284 | scheme = "https"; 285 | }; 286 | }; 287 | 288 | https = { 289 | address = ":443"; 290 | # enableHTTP3 = true; 291 | forwardedHeaders.insecure = true; 292 | }; 293 | 294 | experimental = { 295 | address = ":1111"; 296 | forwardedHeaders.insecure = true; 297 | }; 298 | }; 299 | }; 300 | services.traefik.dynamicConfigOptions = { 301 | http.routers = { 302 | api = { 303 | entrypoints = ["traefik"]; 304 | rule = "PathPrefix(`/api/`)"; 305 | service = "api@internal"; 306 | }; 307 | fritz = { 308 | entryPoints = ["https" "http"]; 309 | rule = "Host(`fritz.mimas.internal.nobbz.dev`)"; 310 | service = "fritz"; 311 | tls.domains = [{main = "*.mimas.internal.nobbz.dev";}]; 312 | tls.certResolver = "mimasWildcard"; 313 | }; 314 | gitea = { 315 | entryPoints = ["https" "http"]; 316 | rule = "Host(`gitea.mimas.internal.nobbz.dev`)"; 317 | service = "gitea"; 318 | tls.domains = [{main = "*.mimas.internal.nobbz.dev";}]; 319 | tls.certResolver = "mimasWildcard"; 320 | }; 321 | grafana = { 322 | entryPoints = ["https" "http"]; 323 | rule = "Host(`grafana.mimas.internal.nobbz.dev`)"; 324 | service = "grafana"; 325 | tls.domains = [{main = "*.mimas.internal.nobbz.dev";}]; 326 | tls.certResolver = "mimasWildcard"; 327 | }; 328 | # minio-tls = { 329 | # entryPoints = [ "https" "experimental" ]; 330 | # rule = "HostRegexp(`{subdomain:[a-z0-9]+}.mimas.internal.nobbz.dev`) && PathPrefix(`/`)"; 331 | # service = "minio"; 332 | # tls.domains = [{ main = "*.mimas.internal.nobbz.dev"; }]; 333 | # tls.certresolver = "mimasWildcard"; 334 | # }; 335 | }; 336 | http.services = { 337 | minio.loadBalancer.passHostHeader = true; 338 | minio.loadBalancer.servers = [{url = "http://192.168.122.122/";}]; 339 | 340 | fritz.loadBalancer.passHostHeader = false; 341 | fritz.loadBalancer.servers = [{url = "http://fritz.box";}]; 342 | 343 | gitea.loadBalancer.passHostHeader = true; 344 | gitea.loadBalancer.servers = [{url = "http://localhost:${toString config.services.gitea.settings.server.HTTP_PORT}";}]; 345 | 346 | grafana.loadBalancer.passHostHeader = true; 347 | grafana.loadBalancer.servers = [{url = "http://localhost:${toString config.services.grafana.settings.server.http_port}";}]; 348 | }; 349 | }; 350 | 351 | services.prometheus = { 352 | enable = true; 353 | port = 9001; 354 | 355 | rules = [ 356 | '' 357 | groups: 358 | - name: test 359 | rules: 360 | - record: nobbz:code_cpu_percent 361 | expr: avg without (cpu) (irate(node_cpu_seconds_total[5m])) 362 | '' 363 | ]; 364 | 365 | exporters = { 366 | node = { 367 | enable = true; 368 | enabledCollectors = ["systemd"]; 369 | port = 9002; 370 | }; 371 | }; 372 | 373 | scrapeConfigs = [ 374 | { 375 | job_name = "grafana"; 376 | static_configs = [{targets = ["127.0.0.1:2342"];}]; 377 | } 378 | { 379 | job_name = "prometheus"; 380 | static_configs = [{targets = ["127.0.0.1:9001"];}]; 381 | } 382 | { 383 | job_name = "node_import"; 384 | static_configs = [ 385 | { 386 | targets = [ 387 | "127.0.0.1:${toString config.services.prometheus.exporters.node.port}" 388 | "${config.lib.nobbz.enceladeus.v4}:9002" 389 | ]; 390 | } 391 | ]; 392 | } 393 | ]; 394 | }; 395 | 396 | nix.buildMachines = let 397 | communityBuilder = name: system: { 398 | hostName = "${name}.nix-community.org"; 399 | inherit system; 400 | sshKey = "/root/.ssh/id_ed25519"; 401 | sshUser = "NobbZ"; 402 | maxJobs = 8; 403 | protocol = "ssh"; 404 | speedFactor = 4; 405 | supportedFeatures = ["nixos-test" "benchmark" "big-parallel" "kvm"]; 406 | }; 407 | in [ 408 | (communityBuilder "build-box" "x86_64-linux") 409 | (communityBuilder "aarch64-build.box" "aarch64-linux") 410 | ]; 411 | 412 | # This value determines the NixOS release with which your system is to be 413 | # compatible, in order to avoid breaking some software such as database 414 | # servers. You should change this only after NixOS release notes say you 415 | # should. 416 | system.stateVersion = "20.09"; # Did you read the comment? 417 | } 418 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "emacs": { 4 | "inputs": { 5 | "nixpkgs": [ 6 | "nixpkgs" 7 | ], 8 | "nixpkgs-stable": [ 9 | "nixpkgs" 10 | ] 11 | }, 12 | "locked": { 13 | "lastModified": 1766370686, 14 | "narHash": "sha256-HZ1uIvsj/NTcvg6qzlHoZYKweQr0AT92puSnmeB6tuY=", 15 | "owner": "nix-community", 16 | "repo": "emacs-overlay", 17 | "rev": "db25d925f0d299cb32c38eb0d0e30cfb285245ca", 18 | "type": "github" 19 | }, 20 | "original": { 21 | "owner": "nix-community", 22 | "repo": "emacs-overlay", 23 | "type": "github" 24 | } 25 | }, 26 | "flake-compat": { 27 | "flake": false, 28 | "locked": { 29 | "lastModified": 1733328505, 30 | "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", 31 | "owner": "edolstra", 32 | "repo": "flake-compat", 33 | "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", 34 | "type": "github" 35 | }, 36 | "original": { 37 | "owner": "edolstra", 38 | "repo": "flake-compat", 39 | "type": "github" 40 | } 41 | }, 42 | "flake-compat_2": { 43 | "flake": false, 44 | "locked": { 45 | "lastModified": 1696426674, 46 | "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", 47 | "owner": "edolstra", 48 | "repo": "flake-compat", 49 | "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", 50 | "type": "github" 51 | }, 52 | "original": { 53 | "owner": "edolstra", 54 | "repo": "flake-compat", 55 | "type": "github" 56 | } 57 | }, 58 | "flake-utils": { 59 | "inputs": { 60 | "systems": "systems" 61 | }, 62 | "locked": { 63 | "lastModified": 1731533236, 64 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 65 | "owner": "numtide", 66 | "repo": "flake-utils", 67 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 68 | "type": "github" 69 | }, 70 | "original": { 71 | "owner": "numtide", 72 | "repo": "flake-utils", 73 | "type": "github" 74 | } 75 | }, 76 | "flake-utils_2": { 77 | "inputs": { 78 | "systems": "systems_2" 79 | }, 80 | "locked": { 81 | "lastModified": 1681202837, 82 | "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", 83 | "owner": "numtide", 84 | "repo": "flake-utils", 85 | "rev": "cfacdce06f30d2b68473a46042957675eebb3401", 86 | "type": "github" 87 | }, 88 | "original": { 89 | "owner": "numtide", 90 | "repo": "flake-utils", 91 | "type": "github" 92 | } 93 | }, 94 | "gen-luarc": { 95 | "inputs": { 96 | "flake-parts": [ 97 | "nvim", 98 | "parts" 99 | ], 100 | "git-hooks": "git-hooks", 101 | "luvit-meta": "luvit-meta", 102 | "nixpkgs": [ 103 | "nvim", 104 | "nixpkgs" 105 | ] 106 | }, 107 | "locked": { 108 | "lastModified": 1755304025, 109 | "narHash": "sha256-xVKfjFwc0zMbLMjLTiHz+0llggkjs93SmHkhaa9S3M4=", 110 | "owner": "mrcjkb", 111 | "repo": "nix-gen-luarc-json", 112 | "rev": "1865b0ebb753ae5324d7381b1fa8c98c04ec7509", 113 | "type": "github" 114 | }, 115 | "original": { 116 | "owner": "mrcjkb", 117 | "repo": "nix-gen-luarc-json", 118 | "type": "github" 119 | } 120 | }, 121 | "git-hooks": { 122 | "inputs": { 123 | "flake-compat": "flake-compat_2", 124 | "gitignore": "gitignore", 125 | "nixpkgs": [ 126 | "nvim", 127 | "gen-luarc", 128 | "nixpkgs" 129 | ], 130 | "nixpkgs-stable": "nixpkgs-stable" 131 | }, 132 | "locked": { 133 | "lastModified": 1723803910, 134 | "narHash": "sha256-yezvUuFiEnCFbGuwj/bQcqg7RykIEqudOy/RBrId0pc=", 135 | "owner": "cachix", 136 | "repo": "git-hooks.nix", 137 | "rev": "bfef0ada09e2c8ac55bbcd0831bd0c9d42e651ba", 138 | "type": "github" 139 | }, 140 | "original": { 141 | "owner": "cachix", 142 | "repo": "git-hooks.nix", 143 | "type": "github" 144 | } 145 | }, 146 | "git-hooks-nix": { 147 | "inputs": { 148 | "flake-compat": [ 149 | "nix" 150 | ], 151 | "gitignore": [ 152 | "nix" 153 | ], 154 | "nixpkgs": [ 155 | "nix", 156 | "nixpkgs" 157 | ], 158 | "nixpkgs-stable": [ 159 | "nix", 160 | "nixpkgs" 161 | ] 162 | }, 163 | "locked": { 164 | "lastModified": 1734279981, 165 | "narHash": "sha256-NdaCraHPp8iYMWzdXAt5Nv6sA3MUzlCiGiR586TCwo0=", 166 | "owner": "cachix", 167 | "repo": "git-hooks.nix", 168 | "rev": "aa9f40c906904ebd83da78e7f328cd8aeaeae785", 169 | "type": "github" 170 | }, 171 | "original": { 172 | "owner": "cachix", 173 | "repo": "git-hooks.nix", 174 | "type": "github" 175 | } 176 | }, 177 | "gitignore": { 178 | "inputs": { 179 | "nixpkgs": [ 180 | "nvim", 181 | "gen-luarc", 182 | "git-hooks", 183 | "nixpkgs" 184 | ] 185 | }, 186 | "locked": { 187 | "lastModified": 1709087332, 188 | "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", 189 | "owner": "hercules-ci", 190 | "repo": "gitignore.nix", 191 | "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", 192 | "type": "github" 193 | }, 194 | "original": { 195 | "owner": "hercules-ci", 196 | "repo": "gitignore.nix", 197 | "type": "github" 198 | } 199 | }, 200 | "home-manager": { 201 | "inputs": { 202 | "nixpkgs": [ 203 | "nixpkgs" 204 | ] 205 | }, 206 | "locked": { 207 | "lastModified": 1766282146, 208 | "narHash": "sha256-0V/nKU93KdYGi+5LB/MVo355obBJw/2z9b2xS3bPJxY=", 209 | "owner": "nix-community", 210 | "repo": "home-manager", 211 | "rev": "61fcc9de76b88e55578eb5d79fc80f2b236df707", 212 | "type": "github" 213 | }, 214 | "original": { 215 | "owner": "nix-community", 216 | "repo": "home-manager", 217 | "type": "github" 218 | } 219 | }, 220 | "luvit-meta": { 221 | "flake": false, 222 | "locked": { 223 | "lastModified": 1705776742, 224 | "narHash": "sha256-zAAptV/oLuLAAsa2zSB/6fxlElk4+jNZd/cPr9oxFig=", 225 | "owner": "Bilal2453", 226 | "repo": "luvit-meta", 227 | "rev": "ce76f6f6cdc9201523a5875a4471dcfe0186eb60", 228 | "type": "github" 229 | }, 230 | "original": { 231 | "owner": "Bilal2453", 232 | "repo": "luvit-meta", 233 | "type": "github" 234 | } 235 | }, 236 | "nix": { 237 | "inputs": { 238 | "flake-compat": "flake-compat", 239 | "flake-parts": [ 240 | "parts" 241 | ], 242 | "git-hooks-nix": "git-hooks-nix", 243 | "nixpkgs": "nixpkgs", 244 | "nixpkgs-23-11": "nixpkgs-23-11", 245 | "nixpkgs-regression": "nixpkgs-regression" 246 | }, 247 | "locked": { 248 | "lastModified": 1766340961, 249 | "narHash": "sha256-BPx//gPeu4nnFKdxJcLtD23gGt2GcIMGBvze6/TRWu4=", 250 | "owner": "nixos", 251 | "repo": "nix", 252 | "rev": "d85e5dfa60e7ac33b2c427f226b147982b8bd4e7", 253 | "type": "github" 254 | }, 255 | "original": { 256 | "owner": "nixos", 257 | "repo": "nix", 258 | "type": "github" 259 | } 260 | }, 261 | "nix-gl": { 262 | "inputs": { 263 | "flake-utils": "flake-utils", 264 | "nixpkgs": [ 265 | "nixpkgs" 266 | ] 267 | }, 268 | "locked": { 269 | "lastModified": 1762090880, 270 | "narHash": "sha256-fbRQzIGPkjZa83MowjbD2ALaJf9y6KMDdJBQMKFeY/8=", 271 | "owner": "nix-community", 272 | "repo": "nixgl", 273 | "rev": "b6105297e6f0cd041670c3e8628394d4ee247ed5", 274 | "type": "github" 275 | }, 276 | "original": { 277 | "owner": "nix-community", 278 | "repo": "nixgl", 279 | "type": "github" 280 | } 281 | }, 282 | "nixos-vscode-server": { 283 | "inputs": { 284 | "flake-utils": "flake-utils_2", 285 | "nixpkgs": [ 286 | "nixpkgs" 287 | ] 288 | }, 289 | "locked": { 290 | "lastModified": 1753541826, 291 | "narHash": "sha256-foGgZu8+bCNIGeuDqQ84jNbmKZpd+JvnrL2WlyU4tuU=", 292 | "owner": "msteen", 293 | "repo": "nixos-vscode-server", 294 | "rev": "6d5f074e4811d143d44169ba4af09b20ddb6937d", 295 | "type": "github" 296 | }, 297 | "original": { 298 | "owner": "msteen", 299 | "repo": "nixos-vscode-server", 300 | "type": "github" 301 | } 302 | }, 303 | "nixpkgs": { 304 | "locked": { 305 | "lastModified": 1763948260, 306 | "narHash": "sha256-zZk7fn2ARAqmLwaYTpxBJmj81KIdz11NiWt7ydHHD/M=", 307 | "rev": "1c8ba8d3f7634acac4a2094eef7c32ad9106532c", 308 | "type": "tarball", 309 | "url": "https://releases.nixos.org/nixos/25.05/nixos-25.05.813095.1c8ba8d3f763/nixexprs.tar.xz" 310 | }, 311 | "original": { 312 | "type": "tarball", 313 | "url": "https://channels.nixos.org/nixos-25.05/nixexprs.tar.xz" 314 | } 315 | }, 316 | "nixpkgs-23-11": { 317 | "locked": { 318 | "lastModified": 1717159533, 319 | "narHash": "sha256-oamiKNfr2MS6yH64rUn99mIZjc45nGJlj9eGth/3Xuw=", 320 | "owner": "NixOS", 321 | "repo": "nixpkgs", 322 | "rev": "a62e6edd6d5e1fa0329b8653c801147986f8d446", 323 | "type": "github" 324 | }, 325 | "original": { 326 | "owner": "NixOS", 327 | "repo": "nixpkgs", 328 | "rev": "a62e6edd6d5e1fa0329b8653c801147986f8d446", 329 | "type": "github" 330 | } 331 | }, 332 | "nixpkgs-emmy": { 333 | "locked": { 334 | "lastModified": 1763119271, 335 | "narHash": "sha256-DduG+5FZfDfwkO0AmatBFBhzZCf/Z30Ha5E6fSlNO10=", 336 | "owner": "NixOS", 337 | "repo": "nixpkgs", 338 | "rev": "6154b41419f3fc076ac65827d432842bc03fb66a", 339 | "type": "github" 340 | }, 341 | "original": { 342 | "owner": "NixOS", 343 | "ref": "pull/323401/head", 344 | "repo": "nixpkgs", 345 | "type": "github" 346 | } 347 | }, 348 | "nixpkgs-pre-rust": { 349 | "locked": { 350 | "lastModified": 1723634395, 351 | "narHash": "sha256-K1ohl/M/HWXqieqNtsF39FbWqtaNX/mUgulrqcOO1KU=", 352 | "owner": "nixos", 353 | "repo": "nixpkgs", 354 | "rev": "57d0d4a8f3025e2b902d2b4403bcece26ad1ea74", 355 | "type": "github" 356 | }, 357 | "original": { 358 | "owner": "nixos", 359 | "ref": "57d0d4a8f302", 360 | "repo": "nixpkgs", 361 | "type": "github" 362 | } 363 | }, 364 | "nixpkgs-regression": { 365 | "locked": { 366 | "lastModified": 1643052045, 367 | "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", 368 | "owner": "NixOS", 369 | "repo": "nixpkgs", 370 | "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", 371 | "type": "github" 372 | }, 373 | "original": { 374 | "owner": "NixOS", 375 | "repo": "nixpkgs", 376 | "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", 377 | "type": "github" 378 | } 379 | }, 380 | "nixpkgs-stable": { 381 | "locked": { 382 | "lastModified": 1720386169, 383 | "narHash": "sha256-NGKVY4PjzwAa4upkGtAMz1npHGoRzWotlSnVlqI40mo=", 384 | "owner": "NixOS", 385 | "repo": "nixpkgs", 386 | "rev": "194846768975b7ad2c4988bdb82572c00222c0d7", 387 | "type": "github" 388 | }, 389 | "original": { 390 | "owner": "NixOS", 391 | "ref": "nixos-24.05", 392 | "repo": "nixpkgs", 393 | "type": "github" 394 | } 395 | }, 396 | "nixpkgs_2": { 397 | "locked": { 398 | "lastModified": 1766070988, 399 | "narHash": "sha256-G/WVghka6c4bAzMhTwT2vjLccg/awmHkdKSd2JrycLc=", 400 | "owner": "nixos", 401 | "repo": "nixpkgs", 402 | "rev": "c6245e83d836d0433170a16eb185cefe0572f8b8", 403 | "type": "github" 404 | }, 405 | "original": { 406 | "owner": "nixos", 407 | "ref": "nixos-unstable", 408 | "repo": "nixpkgs", 409 | "type": "github" 410 | } 411 | }, 412 | "nixpkgs_3": { 413 | "locked": { 414 | "lastModified": 1766125104, 415 | "narHash": "sha256-l/YGrEpLromL4viUo5GmFH3K5M1j0Mb9O+LiaeCPWEM=", 416 | "owner": "NixOS", 417 | "repo": "nixpkgs", 418 | "rev": "7d853e518814cca2a657b72eeba67ae20ebf7059", 419 | "type": "github" 420 | }, 421 | "original": { 422 | "owner": "NixOS", 423 | "ref": "nixpkgs-unstable", 424 | "repo": "nixpkgs", 425 | "type": "github" 426 | } 427 | }, 428 | "nixpkgs_4": { 429 | "locked": { 430 | "lastModified": 1760596604, 431 | "narHash": "sha256-J/i5K6AAz/y5dBePHQOuzC7MbhyTOKsd/GLezSbEFiM=", 432 | "owner": "nixos", 433 | "repo": "nixpkgs", 434 | "rev": "3cbe716e2346710d6e1f7c559363d14e11c32a43", 435 | "type": "github" 436 | }, 437 | "original": { 438 | "owner": "nixos", 439 | "ref": "nixpkgs-unstable", 440 | "repo": "nixpkgs", 441 | "type": "github" 442 | } 443 | }, 444 | "nixpkgs_5": { 445 | "locked": { 446 | "lastModified": 1744536153, 447 | "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", 448 | "owner": "NixOS", 449 | "repo": "nixpkgs", 450 | "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", 451 | "type": "github" 452 | }, 453 | "original": { 454 | "owner": "NixOS", 455 | "ref": "nixpkgs-unstable", 456 | "repo": "nixpkgs", 457 | "type": "github" 458 | } 459 | }, 460 | "nvim": { 461 | "inputs": { 462 | "gen-luarc": "gen-luarc", 463 | "nixpkgs": [ 464 | "nixpkgs" 465 | ], 466 | "nixpkgs-emmy": "nixpkgs-emmy", 467 | "parts": [ 468 | "parts" 469 | ], 470 | "wrapper-manager": "wrapper-manager" 471 | }, 472 | "locked": { 473 | "lastModified": 1765229747, 474 | "narHash": "sha256-JslbgVLgqjgyTTTVp7wzkfJhtWEVJ3etIRROykxgRZI=", 475 | "owner": "nobbz", 476 | "repo": "nobbz-vim", 477 | "rev": "5ac81b9d8c1663c989aac4c8ae5b9871760614bc", 478 | "type": "github" 479 | }, 480 | "original": { 481 | "owner": "nobbz", 482 | "repo": "nobbz-vim", 483 | "type": "github" 484 | } 485 | }, 486 | "parts": { 487 | "inputs": { 488 | "nixpkgs-lib": [ 489 | "nixpkgs" 490 | ] 491 | }, 492 | "locked": { 493 | "lastModified": 1765835352, 494 | "narHash": "sha256-XswHlK/Qtjasvhd1nOa1e8MgZ8GS//jBoTqWtrS1Giw=", 495 | "owner": "hercules-ci", 496 | "repo": "flake-parts", 497 | "rev": "a34fae9c08a15ad73f295041fec82323541400a9", 498 | "type": "github" 499 | }, 500 | "original": { 501 | "owner": "hercules-ci", 502 | "repo": "flake-parts", 503 | "type": "github" 504 | } 505 | }, 506 | "programsdb": { 507 | "inputs": { 508 | "nixpkgs": [ 509 | "nixpkgs" 510 | ], 511 | "utils": "utils" 512 | }, 513 | "locked": { 514 | "lastModified": 1766352922, 515 | "narHash": "sha256-5JcSFkY2g4wAghIrSyjreyAP7EoS0Zp6PfJ7G/4+xEs=", 516 | "owner": "wamserma", 517 | "repo": "flake-programs-sqlite", 518 | "rev": "bf8869160d4d219d11680ee2c485aac315923e2c", 519 | "type": "github" 520 | }, 521 | "original": { 522 | "owner": "wamserma", 523 | "repo": "flake-programs-sqlite", 524 | "type": "github" 525 | } 526 | }, 527 | "root": { 528 | "inputs": { 529 | "emacs": "emacs", 530 | "home-manager": "home-manager", 531 | "nix": "nix", 532 | "nix-gl": "nix-gl", 533 | "nixos-vscode-server": "nixos-vscode-server", 534 | "nixpkgs": "nixpkgs_2", 535 | "nixpkgs-insync-v3": [ 536 | "nixpkgs" 537 | ], 538 | "nixpkgs-pre-rust": "nixpkgs-pre-rust", 539 | "nvim": "nvim", 540 | "parts": "parts", 541 | "programsdb": "programsdb", 542 | "sops-nix": "sops-nix", 543 | "switcher": "switcher" 544 | } 545 | }, 546 | "rust-overlay": { 547 | "inputs": { 548 | "nixpkgs": "nixpkgs_5" 549 | }, 550 | "locked": { 551 | "lastModified": 1760582142, 552 | "narHash": "sha256-RSLRjAoS75szOc9fFzRi9/jzPbYsiqPISSLZTloaKtM=", 553 | "owner": "oxalica", 554 | "repo": "rust-overlay", 555 | "rev": "9ea094253b9389ba7dd4f18637f66b5824276d1d", 556 | "type": "github" 557 | }, 558 | "original": { 559 | "owner": "oxalica", 560 | "repo": "rust-overlay", 561 | "type": "github" 562 | } 563 | }, 564 | "sops-nix": { 565 | "inputs": { 566 | "nixpkgs": "nixpkgs_3" 567 | }, 568 | "locked": { 569 | "lastModified": 1766289575, 570 | "narHash": "sha256-BOKCwOQQIP4p9z8DasT5r+qjri3x7sPCOq+FTjY8Z+o=", 571 | "owner": "Mic92", 572 | "repo": "sops-nix", 573 | "rev": "9836912e37aef546029e48c8749834735a6b9dad", 574 | "type": "github" 575 | }, 576 | "original": { 577 | "owner": "Mic92", 578 | "repo": "sops-nix", 579 | "type": "github" 580 | } 581 | }, 582 | "switcher": { 583 | "inputs": { 584 | "flake-parts": [ 585 | "parts" 586 | ], 587 | "nixpkgs": "nixpkgs_4", 588 | "rust-overlay": "rust-overlay" 589 | }, 590 | "locked": { 591 | "lastModified": 1763618792, 592 | "narHash": "sha256-tcQBjwGOzQhRZ7aQFY86K3GqyOWaG+ohO4hx8jO4ei4=", 593 | "owner": "nobbz", 594 | "repo": "nix-switcher", 595 | "rev": "a0ab1e1c0f10caac7418fff012d77792f1f90ff2", 596 | "type": "github" 597 | }, 598 | "original": { 599 | "owner": "nobbz", 600 | "ref": "main", 601 | "repo": "nix-switcher", 602 | "type": "github" 603 | } 604 | }, 605 | "systems": { 606 | "locked": { 607 | "lastModified": 1681028828, 608 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 609 | "owner": "nix-systems", 610 | "repo": "default", 611 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 612 | "type": "github" 613 | }, 614 | "original": { 615 | "owner": "nix-systems", 616 | "repo": "default", 617 | "type": "github" 618 | } 619 | }, 620 | "systems_2": { 621 | "locked": { 622 | "lastModified": 1681028828, 623 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 624 | "owner": "nix-systems", 625 | "repo": "default", 626 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 627 | "type": "github" 628 | }, 629 | "original": { 630 | "owner": "nix-systems", 631 | "repo": "default", 632 | "type": "github" 633 | } 634 | }, 635 | "utils": { 636 | "locked": { 637 | "lastModified": 1678901627, 638 | "narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=", 639 | "owner": "numtide", 640 | "repo": "flake-utils", 641 | "rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6", 642 | "type": "github" 643 | }, 644 | "original": { 645 | "owner": "numtide", 646 | "repo": "flake-utils", 647 | "type": "github" 648 | } 649 | }, 650 | "wrapper-manager": { 651 | "locked": { 652 | "lastModified": 1757156862, 653 | "narHash": "sha256-OGXsTE5jWhGiFfK6OwMvjksrYSobsIFUSUzKsexCDxY=", 654 | "owner": "viperml", 655 | "repo": "wrapper-manager", 656 | "rev": "801dd9c876fcada046af45543e8c7e0bbccf20ea", 657 | "type": "github" 658 | }, 659 | "original": { 660 | "owner": "viperml", 661 | "repo": "wrapper-manager", 662 | "type": "github" 663 | } 664 | } 665 | }, 666 | "root": "root", 667 | "version": 7 668 | } 669 | --------------------------------------------------------------------------------