├── .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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------