Merge pull request 'feature/mydia' (#1) from feature/mydia into main
Some checks failed
Test action / kaas (push) Failing after 0s

Reviewed-on: #1
This commit is contained in:
Chris Kruining 2025-12-06 16:42:23 +00:00
commit 3ff7ddc54a
28 changed files with 921 additions and 538 deletions

View file

@ -12,4 +12,4 @@ jobs:
steps:
- name: Echo
run: |
nix --version
nix --version

1
.gitattributes vendored Normal file
View file

@ -0,0 +1 @@
* text=auto

View file

@ -2,10 +2,10 @@
[doc('List machines')]
@list:
ls -1 ../systems/x86_64-linux/
ls -1 ../systems/x86_64-linux/
[no-exit-message]
[doc('Update the target machine')]
[no-exit-message]
@update machine:
just assert '-d "../systems/x86_64-linux/{{ machine }}"' "Machine {{ machine }} does not exist, must be one of: $(ls ../systems/x86_64-linux/ | tr '\n' ' ')"
nixos-rebuild switch --use-remote-sudo --target-host {{ machine }} --flake ..#{{ machine }}
just assert '-d "../systems/x86_64-linux/{{ machine }}"' "Machine {{ machine }} does not exist, must be one of: $(ls ../systems/x86_64-linux/ | sed ':a;N;$!ba;s/\n/, /g')"
nixos-rebuild switch -L --use-remote-sudo --target-host {{ machine }} --flake ..#{{ machine }}

View file

@ -1,36 +1,38 @@
set unstable
set unstable := true
base_path := invocation_directory() / "systems/x86_64-linux"
# sops := "nix shell nixpkgs#sops --command sops"
# yq := "nix shell nixpkgs#yq --command yq"
sops := "sops"
yq := "yq"
@_default:
just --list
just --list
[doc('list all vars of the target machine')]
list machine:
sops decrypt {{ base_path }}/{{ machine }}/secrets.yml
sops decrypt {{ base_path }}/{{ machine }}/secrets.yml
@edit machine:
sops edit {{ base_path }}/{{ machine }}/secrets.yml
sops edit {{ base_path }}/{{ machine }}/secrets.yml
@set machine key value:
sops set {{ base_path }}/{{ machine }}/secrets.yml "$(printf '%s\n' '["{{ key }}"]' | sed -E 's#/#"]["#g; s/\["([0-9]+)"\]/[\1]/g')" "\"$(echo '{{ value }}' | sed 's/\"/\\\"/g')\""
sops set {{ base_path }}/{{ machine }}/secrets.yml "$(printf '%s\n' '["{{ key }}"]' | sed -E 's#/#"]["#g; s/\["([0-9]+)"\]/[\1]/g')" "\"$(echo '{{ value }}' | sed 's/\"/\\\"/g')\""
git add {{ base_path }}/{{ machine }}/secrets.yml
git commit -m 'chore(secrets): set secret "{{ key }}" for machine "{{ machine}}"' -- {{ base_path }}/{{ machine }}/secrets.yml > /dev/null
git add {{ base_path }}/{{ machine }}/secrets.yml
git commit -m 'chore(secrets): set secret "{{ key }}" for machine "{{ machine }}"' -- {{ base_path }}/{{ machine }}/secrets.yml > /dev/null
echo "Done"
echo "Done"
@get machine key:
sops decrypt {{ base_path }}/{{ machine }}/secrets.yml | yq ".$(echo "{{ key }}" | sed -E 's/\//./g')"
sops decrypt {{ base_path }}/{{ machine }}/secrets.yml | yq ".$(echo "{{ key }}" | sed -E 's/\//./g')"
@remove machine key:
sops unset {{ base_path }}/{{ machine }}/secrets.yml "$(printf '%s\n' '["{{ key }}"]' | sed -E 's#/#"]["#g; s/\["([0-9]+)"\]/[\1]/g')"
sops unset {{ base_path }}/{{ machine }}/secrets.yml "$(printf '%s\n' '["{{ key }}"]' | sed -E 's#/#"]["#g; s/\["([0-9]+)"\]/[\1]/g')"
git add {{ base_path }}/{{ machine }}/secrets.yml
git commit -m 'chore(secrets): removed secret "{{ key }}" from machine "{{ machine}}"' -- {{ base_path }}/{{ machine }}/secrets.yml > /dev/null
git add {{ base_path }}/{{ machine }}/secrets.yml
git commit -m 'chore(secrets): removed secret "{{ key }}" from machine "{{ machine }}"' -- {{ base_path }}/{{ machine }}/secrets.yml > /dev/null
echo "Done"
echo "Done"

View file

@ -19,7 +19,7 @@ mod machine '.just/machine.just'
[doc('Introspection on flake output')]
@select key:
nix eval --json .#{{ key }} | jq .
nix eval --show-trace --json .#{{ key }} | jq .
@ -30,4 +30,4 @@ mod machine '.just/machine.just'
[no-cd]
[private]
@assert condition message:
[ {{ condition }} ] || { echo -e 1>&2 "\n\x1b[1;41m Error \x1b[0m {{ message }}\n"; exit 1; }
[ {{ condition }} ] || { echo -e 1>&2 "\n\x1b[1;41m Error \x1b[0m {{ message }}\n"; exit 1; }

251
flake.lock generated
View file

@ -38,11 +38,11 @@
"base16-helix": {
"flake": false,
"locked": {
"lastModified": 1752979451,
"narHash": "sha256-0CQM+FkYy0fOO/sMGhOoNL80ftsAzYCg9VhIrodqusM=",
"lastModified": 1760703920,
"narHash": "sha256-m82fGUYns4uHd+ZTdoLX2vlHikzwzdu2s2rYM2bNwzw=",
"owner": "tinted-theming",
"repo": "base16-helix",
"rev": "27cf1e66e50abc622fb76a3019012dc07c678fac",
"rev": "d646af9b7d14bff08824538164af99d0c521b185",
"type": "github"
},
"original": {
@ -206,11 +206,11 @@
"firefox-gnome-theme": {
"flake": false,
"locked": {
"lastModified": 1758112371,
"narHash": "sha256-lizRM2pj6PHrR25yimjyFn04OS4wcdbc38DCdBVa2rk=",
"lastModified": 1764724327,
"narHash": "sha256-OkFLrD3pFR952TrjQi1+Vdj604KLcMnkpa7lkW7XskI=",
"owner": "rafaelmardojai",
"repo": "firefox-gnome-theme",
"rev": "0909cfe4a2af8d358ad13b20246a350e14c2473d",
"rev": "66b7c635763d8e6eb86bd766de5a1e1fbfcc1047",
"type": "github"
},
"original": {
@ -320,6 +320,27 @@
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": [
"mydia",
"nixpkgs"
]
},
"locked": {
"lastModified": 1763759067,
"narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_3": {
"inputs": {
"nixpkgs-lib": [
"nvf",
@ -340,7 +361,7 @@
"type": "github"
}
},
"flake-parts_3": {
"flake-parts_4": {
"inputs": {
"nixpkgs-lib": [
"stylix",
@ -348,11 +369,11 @@
]
},
"locked": {
"lastModified": 1756770412,
"narHash": "sha256-+uWLQZccFHwqpGqr2Yt5VsW/PbeJVTn9Dk6SHWhNRPw=",
"lastModified": 1763759067,
"narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "4524271976b625a4a605beefd893f270620fd751",
"rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0",
"type": "github"
},
"original": {
@ -361,7 +382,7 @@
"type": "github"
}
},
"flake-parts_4": {
"flake-parts_5": {
"inputs": {
"nixpkgs-lib": [
"terranix",
@ -511,11 +532,11 @@
"flake": false,
"locked": {
"host": "gitlab.gnome.org",
"lastModified": 1762869044,
"narHash": "sha256-nwm/GJ2Syigf7VccLAZ66mFC8mZJFqpJmIxSGKl7+Ds=",
"lastModified": 1764524476,
"narHash": "sha256-bTmNn3Q4tMQ0J/P0O5BfTQwqEnCiQIzOGef9/aqAZvk=",
"owner": "GNOME",
"repo": "gnome-shell",
"rev": "680e3d195a92203f28d4bf8c6e8bb537cc3ed4ad",
"rev": "c0e1ad9f0f703fd0519033b8f46c3267aab51a22",
"type": "gitlab"
},
"original": {
@ -553,11 +574,19 @@
"rust-overlay": "rust-overlay"
},
"locked": {
<<<<<<< HEAD
"lastModified": 1764617621,
"narHash": "sha256-Eq0TvWs6xhKZs5HXH1hlrNasrHD7AOEdeLkTis//X7w=",
"owner": "himmelblau-idm",
"repo": "himmelblau",
"rev": "c19494250d8c15e7c75e9301bdc271579a6dc77a",
=======
"lastModified": 1764787446,
"narHash": "sha256-RUfGGM8kiXSQA3ct1BZXN5Sm8hxr3XF0P/eR/WGLaGU=",
"owner": "himmelblau-idm",
"repo": "himmelblau",
"rev": "8ab33affe6db4cf5e9c17c2abcd7f3b2cedcfbd8",
>>>>>>> ba1d4e1 (chore: update deps)
"type": "github"
},
"original": {
@ -573,11 +602,19 @@
]
},
"locked": {
<<<<<<< HEAD
"lastModified": 1764603455,
"narHash": "sha256-Q70rxlbrxPcTtqWIb9+71rkJESxIOou5isZBvyOieXw=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "effe4c007d6243d9e69ce2242d76a2471c1b8d5c",
=======
"lastModified": 1764839789,
"narHash": "sha256-QCgaXEj8036JlfyVM2e5fgKIxoF7IgGRcAi8LkehKvo=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "d441981b200305ebb8e2e2921395f51d207fded6",
>>>>>>> ba1d4e1 (chore: update deps)
"type": "github"
},
"original": {
@ -615,11 +652,19 @@
]
},
"locked": {
<<<<<<< HEAD
"lastModified": 1764612577,
"narHash": "sha256-sHI+7m/ryVYf7agWkutYbvzUS07aAd8g2NVWgUqhxLg=",
"owner": "Jovian-Experiments",
"repo": "Jovian-NixOS",
"rev": "bcb22e208cf8883004fcec3a33f2500e7dc319a5",
=======
"lastModified": 1764746434,
"narHash": "sha256-6ymFuw+Z1C90ezf8H0BP3c2JFZhJYwMq31px2StwWHU=",
"owner": "Jovian-Experiments",
"repo": "Jovian-NixOS",
"rev": "b4c0b604148adacf119b89824ed26df8926ce42c",
>>>>>>> ba1d4e1 (chore: update deps)
"type": "github"
},
"original": {
@ -662,6 +707,25 @@
"type": "github"
}
},
"mydia": {
"inputs": {
"flake-parts": "flake-parts_2",
"nixpkgs": "nixpkgs_5"
},
"locked": {
"lastModified": 1764866402,
"narHash": "sha256-0NOWsPks+/vV5ZM9ti71hUPMLy3FzbEIlFI6vxARvuY=",
"owner": "chris-kruining",
"repo": "mydia",
"rev": "458fc9a21c6987d994bc7932efb6c49df25ba806",
"type": "github"
},
"original": {
"owner": "chris-kruining",
"repo": "mydia",
"type": "github"
}
},
"nix-darwin": {
"inputs": {
"nixpkgs": [
@ -709,14 +773,22 @@
"inputs": {
"flake-compat": "flake-compat_3",
"flake-utils": "flake-utils_3",
"nixpkgs": "nixpkgs_5"
"nixpkgs": "nixpkgs_6"
},
"locked": {
<<<<<<< HEAD
"lastModified": 1764556167,
"narHash": "sha256-/b+oEls56HDRzsSp60tsRfPFRjFebBPHq6k1I+hfPqw=",
"owner": "Infinidoge",
"repo": "nix-minecraft",
"rev": "849d1b2b1adddfc7bddbd3be6bffd218a3f5a6fe",
=======
"lastModified": 1764813963,
"narHash": "sha256-Vs7Mamto+T8r1evk9myHepgHGNJkS2Kr0BF64NIei94=",
"owner": "Infinidoge",
"repo": "nix-minecraft",
"rev": "491200d6848402bbab1421cccbc15a46f08c7f78",
>>>>>>> ba1d4e1 (chore: update deps)
"type": "github"
},
"original": {
@ -812,11 +884,19 @@
]
},
"locked": {
<<<<<<< HEAD
"lastModified": 1764591717,
"narHash": "sha256-T/HMA0Bb/O6UnlGQ0Xt+wGe1j8m7eyyQ5+vVcCJslsM=",
"owner": "nix-community",
"repo": "nixos-wsl",
"rev": "84d1dab290feb4865d0cfcffc7aa0cf9bc65c3b7",
=======
"lastModified": 1764730608,
"narHash": "sha256-FxKIa3OCSRVC23qrk7VT68vExUcmSruJ8OobVlSWOxc=",
"owner": "nix-community",
"repo": "nixos-wsl",
"rev": "10124c58674360765adcb38c9a8b081fb72904e4",
>>>>>>> ba1d4e1 (chore: update deps)
"type": "github"
},
"original": {
@ -856,13 +936,37 @@
"type": "github"
}
},
"nixpkgs_10": {
"locked": {
"lastModified": 1764517877,
"narHash": "sha256-pp3uT4hHijIC8JUK5MEqeAWmParJrgBVzHLNfJDZxg4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2d293cbfa5a793b4c50d17c05ef9e385b90edf6c",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
<<<<<<< HEAD
"lastModified": 1764547213,
"narHash": "sha256-pGXM6frMKLRJmeMcQ228O1QQBuNEUjzmWx9uBd+CbXM=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "64de27c1c985895c1a9f92aaeaab4e6a4c0960f5",
=======
"lastModified": 1764811743,
"narHash": "sha256-Ypfd8oBuG3HWtzcY7VtYiI6Pawznag7YHWy8RoOfiBs=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "4a6ebaabd716d6479b39fa234a8f895f0ec1cb88",
>>>>>>> ba1d4e1 (chore: update deps)
"type": "github"
},
"original": {
@ -890,11 +994,19 @@
},
"nixpkgs_4": {
"locked": {
<<<<<<< HEAD
"lastModified": 1764618760,
"narHash": "sha256-QTUgygkdUq4sq7mXoO2Q2IPpvkKOZtTAJkbTaTjMi0A=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "29a7d6eec7e1177020f62f7599e5021317219c37",
=======
"lastModified": 1764856222,
"narHash": "sha256-yEJmtoFu4cJre1NuU4fb8q57Oux+NTbocnALtJ64aEI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "ece6e266caf1effab32eceef0403b797b4330373",
>>>>>>> ba1d4e1 (chore: update deps)
"type": "github"
},
"original": {
@ -905,6 +1017,22 @@
}
},
"nixpkgs_5": {
"locked": {
"lastModified": 1764242076,
"narHash": "sha256-sKoIWfnijJ0+9e4wRvIgm/HgE27bzwQxcEmo2J/gNpI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2fad6eac6077f03fe109c4d4eb171cf96791faa4",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_6": {
"locked": {
"lastModified": 1748929857,
"narHash": "sha256-lcZQ8RhsmhsK8u7LIFsJhsLh/pzR9yZ8yqpTzyGdj+Q=",
@ -920,13 +1048,21 @@
"type": "github"
}
},
"nixpkgs_6": {
"nixpkgs_7": {
"locked": {
<<<<<<< HEAD
"lastModified": 1764517877,
"narHash": "sha256-pp3uT4hHijIC8JUK5MEqeAWmParJrgBVzHLNfJDZxg4=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "2d293cbfa5a793b4c50d17c05ef9e385b90edf6c",
=======
"lastModified": 1764667669,
"narHash": "sha256-7WUCZfmqLAssbDqwg9cUDAXrSoXN79eEEq17qhTNM/Y=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "418468ac9527e799809c900eda37cbff999199b6",
>>>>>>> ba1d4e1 (chore: update deps)
"type": "github"
},
"original": {
@ -936,7 +1072,7 @@
"type": "github"
}
},
"nixpkgs_7": {
"nixpkgs_8": {
"locked": {
"lastModified": 1761880412,
"narHash": "sha256-QoJjGd4NstnyOG4mm4KXF+weBzA2AH/7gn1Pmpfcb0A=",
@ -952,7 +1088,7 @@
"type": "github"
}
},
"nixpkgs_8": {
"nixpkgs_9": {
"locked": {
"lastModified": 1764445028,
"narHash": "sha256-ik6H/0Zl+qHYDKTXFPpzuVHSZE+uvVz2XQuQd1IVXzo=",
@ -968,22 +1104,6 @@
"type": "github"
}
},
"nixpkgs_9": {
"locked": {
"lastModified": 1762977756,
"narHash": "sha256-4PqRErxfe+2toFJFgcRKZ0UI9NSIOJa+7RXVtBhy4KE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c5ae371f1a6a7fd27823bc500d9390b38c05fa55",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nur": {
"inputs": {
"flake-parts": [
@ -996,11 +1116,11 @@
]
},
"locked": {
"lastModified": 1758998580,
"narHash": "sha256-VLx0z396gDCGSiowLMFz5XRO/XuNV+4EnDYjdJhHvUk=",
"lastModified": 1764773531,
"narHash": "sha256-mCBl7MD1WZ7yCG6bR9MmpPO2VydpNkWFgnslJRIT1YU=",
"owner": "nix-community",
"repo": "NUR",
"rev": "ba8d9c98f5f4630bcb0e815ab456afd90c930728",
"rev": "1d9616689e98beded059ad0384b9951e967a17fa",
"type": "github"
},
"original": {
@ -1012,9 +1132,9 @@
"nvf": {
"inputs": {
"flake-compat": "flake-compat_4",
"flake-parts": "flake-parts_2",
"flake-parts": "flake-parts_3",
"mnw": "mnw",
"nixpkgs": "nixpkgs_7",
"nixpkgs": "nixpkgs_8",
"systems": "systems_5"
},
"locked": {
@ -1065,11 +1185,12 @@
"himmelblau": "himmelblau",
"home-manager": "home-manager",
"jovian": "jovian",
"mydia": "mydia",
"nix-minecraft": "nix-minecraft",
"nixos-boot": "nixos-boot",
"nixos-generators": "nixos-generators",
"nixos-wsl": "nixos-wsl",
"nixpkgs": "nixpkgs_6",
"nixpkgs": "nixpkgs_7",
"nvf": "nvf",
"plasma-manager": "plasma-manager",
"snowfall-lib": "snowfall-lib",
@ -1082,11 +1203,19 @@
"rust-analyzer-src": {
"flake": false,
"locked": {
<<<<<<< HEAD
"lastModified": 1764525349,
"narHash": "sha256-vR3vU9AwzMsBvjNeeG2inA5W/2MwseFk5NIIrLFEMHk=",
"owner": "rust-lang",
"repo": "rust-analyzer",
"rev": "d646b23f000d099d845f999c2c1e05b15d9cdc78",
=======
"lastModified": 1764778537,
"narHash": "sha256-SNL+Fj1ZWiBqCrHJT1S9vMZujrWxCOmf3zkT66XSnhE=",
"owner": "rust-lang",
"repo": "rust-analyzer",
"rev": "633cff25206d5108043d87617a43c9d04aa42c88",
>>>>>>> ba1d4e1 (chore: update deps)
"type": "github"
},
"original": {
@ -1162,7 +1291,7 @@
},
"sops-nix_2": {
"inputs": {
"nixpkgs": "nixpkgs_8"
"nixpkgs": "nixpkgs_9"
},
"locked": {
"lastModified": 1764483358,
@ -1185,9 +1314,9 @@
"base16-helix": "base16-helix",
"base16-vim": "base16-vim",
"firefox-gnome-theme": "firefox-gnome-theme",
"flake-parts": "flake-parts_3",
"flake-parts": "flake-parts_4",
"gnome-shell": "gnome-shell",
"nixpkgs": "nixpkgs_9",
"nixpkgs": "nixpkgs_10",
"nur": "nur",
"systems": "systems_7",
"tinted-foot": "tinted-foot",
@ -1197,11 +1326,19 @@
"tinted-zed": "tinted-zed"
},
"locked": {
<<<<<<< HEAD
"lastModified": 1764550443,
"narHash": "sha256-ArO2V1YEHmEILilTj4KPtqF4gqc1q2HBrrrmygQ/UyU=",
"owner": "nix-community",
"repo": "stylix",
"rev": "794b6e1fa75177ebfeb32967f135858a1ab1ba15",
=======
"lastModified": 1764798099,
"narHash": "sha256-IIwR5ZWo7tjxjRpkz0tViF9KFbQ1YXs9Wkan46WQbfk=",
"owner": "nix-community",
"repo": "stylix",
"rev": "4b9e0e7ba3cccb86fe2bf0f4a2dd18256bef1cc6",
>>>>>>> ba1d4e1 (chore: update deps)
"type": "github"
},
"original": {
@ -1332,7 +1469,7 @@
},
"terranix": {
"inputs": {
"flake-parts": "flake-parts_4",
"flake-parts": "flake-parts_5",
"nixpkgs": [
"nixpkgs"
],
@ -1388,11 +1525,11 @@
"tinted-schemes": {
"flake": false,
"locked": {
"lastModified": 1757716333,
"narHash": "sha256-d4km8W7w2zCUEmPAPUoLk1NlYrGODuVa3P7St+UrqkM=",
"lastModified": 1763914658,
"narHash": "sha256-Hju0WtMf3iForxtOwXqGp3Ynipo0EYx1AqMKLPp9BJw=",
"owner": "tinted-theming",
"repo": "schemes",
"rev": "317a5e10c35825a6c905d912e480dfe8e71c7559",
"rev": "0f6be815d258e435c9b137befe5ef4ff24bea32c",
"type": "github"
},
"original": {
@ -1404,11 +1541,11 @@
"tinted-tmux": {
"flake": false,
"locked": {
"lastModified": 1757811970,
"narHash": "sha256-n5ZJgmzGZXOD9pZdAl1OnBu3PIqD+X3vEBUGbTi4JiI=",
"lastModified": 1764465359,
"narHash": "sha256-lbSVPqLEk2SqMrnpvWuKYGCaAlfWFMA6MVmcOFJjdjE=",
"owner": "tinted-theming",
"repo": "tinted-tmux",
"rev": "d217ba31c846006e9e0ae70775b0ee0f00aa6b1e",
"rev": "edf89a780e239263cc691a987721f786ddc4f6aa",
"type": "github"
},
"original": {
@ -1420,11 +1557,11 @@
"tinted-zed": {
"flake": false,
"locked": {
"lastModified": 1757811247,
"narHash": "sha256-4EFOUyLj85NRL3OacHoLGEo0wjiRJzfsXtR4CZWAn6w=",
"lastModified": 1764464512,
"narHash": "sha256-rCD/pAhkMdCx6blsFwxIyvBJbPZZ1oL2sVFrH07lmqg=",
"owner": "tinted-theming",
"repo": "base16-zed",
"rev": "824fe0aacf82b3c26690d14e8d2cedd56e18404e",
"rev": "907dbba5fb8cf69ebfd90b00813418a412d0a29a",
"type": "github"
},
"original": {
@ -1462,11 +1599,19 @@
]
},
"locked": {
<<<<<<< HEAD
"lastModified": 1764598958,
"narHash": "sha256-sJQHRL8trBoG/ArR+mUlyp5cyKU0pgQY+qDQzZGnVgM=",
"owner": "0xc000022070",
"repo": "zen-browser-flake",
"rev": "8cded25e10b13e2999241f1c73a7d4e5e5d6f69e",
=======
"lastModified": 1764825646,
"narHash": "sha256-QkKEkj3GXpkPxJz9S1RgaMlxstkyaj5IKVWvxIbtC8w=",
"owner": "0xc000022070",
"repo": "zen-browser-flake",
"rev": "8c9284cc227a5c7cd8f1e1fa7a6882b0907187c8",
>>>>>>> ba1d4e1 (chore: update deps)
"type": "github"
},
"original": {

View file

@ -88,49 +88,55 @@
url = "https://git.clan.lol/clan/clan-core/archive/main.tar.gz";
inputs.nixpkgs.follows = "nixpkgs";
};
mydia = {
url = "github:chris-kruining/mydia";
# url = "github:getmydia/mydia";
};
};
outputs = inputs: inputs.snowfall-lib.mkFlake {
inherit inputs;
src = ./.;
outputs = inputs:
inputs.snowfall-lib.mkFlake {
inherit inputs;
src = ./.;
snowfall = {
namespace = "sneeuwvlok";
snowfall = {
namespace = "sneeuwvlok";
meta = {
name = "sneeuwvlok";
title = "Sneeuwvlok";
meta = {
name = "sneeuwvlok";
title = "Sneeuwvlok";
};
};
};
channels-config = {
allowUnfree = true;
permittedInsecurePackages = [
# Due to *arr stack
"dotnet-sdk-6.0.428"
"aspnetcore-runtime-6.0.36"
channels-config = {
allowUnfree = true;
permittedInsecurePackages = [
# Due to *arr stack
"dotnet-sdk-6.0.428"
"aspnetcore-runtime-6.0.36"
# I think this is because of zen
"qtwebengine-5.15.19"
# I think this is because of zen
"qtwebengine-5.15.19"
# For Nheko, the matrix client
"olm-3.2.16"
# For Nheko, the matrix client
"olm-3.2.16"
];
};
overlays = with inputs; [
fenix.overlays.default
nix-minecraft.overlay
flux.overlays.default
];
systems.modules = with inputs; [
clan-core.nixosModules.default
];
homes.modules = with inputs; [
stylix.homeModules.stylix
plasma-manager.homeModules.plasma-manager
];
};
overlays = with inputs; [
fenix.overlays.default
nix-minecraft.overlay
flux.overlays.default
];
systems.modules = with inputs; [
clan-core.nixosModules.default
];
homes.modules = with inputs; [
stylix.homeModules.stylix
plasma-manager.homeModules.plasma-manager
];
};
}

View file

@ -1,10 +1,11 @@
{ osConfig, ... }:
{
{osConfig, ...}: {
home.stateVersion = osConfig.system.stateVersion;
programs.git = {
userName = "Chris Kruining";
userEmail = "chris@kruining.eu";
settings.user = {
name = "Chris Kruining";
email = "chris@kruining.eu";
};
};
sneeuwvlok = {

View file

@ -1,10 +1,11 @@
{ osConfig, ... }:
{
{osConfig, ...}: {
home.stateVersion = osConfig.system.stateVersion;
programs.git = {
userName = "Chris Kruining";
userEmail = "chris@kruining.eu";
settings.user = {
name = "Chris Kruining";
email = "chris@kruining.eu";
};
};
sneeuwvlok = {

View file

@ -1,10 +1,11 @@
{ osConfig, ... }:
{
{osConfig, ...}: {
home.stateVersion = osConfig.system.stateVersion;
programs.git = {
userName = "Chris Kruining";
userEmail = "chris@kruining.eu";
settings.user = {
name = "Chris Kruining";
email = "chris@kruining.eu";
};
};
sneeuwvlok = {

View file

@ -1,10 +1,11 @@
{ osConfig, ... }:
{
{osConfig, ...}: {
home.stateVersion = osConfig.system.stateVersion;
programs.git = {
userName = "Chris Kruining";
userEmail = "chris@kruining.eu";
settings.user = {
name = "Chris Kruining";
email = "chris@kruining.eu";
};
};
sneeuwvlok = {

View file

@ -1,16 +1,20 @@
{ inputs, config, lib, pkgs, namespace, ... }:
let
{
inputs,
config,
lib,
pkgs,
namespace,
...
}: let
inherit (lib) mkIf mkEnableOption;
cfg = config.${namespace}.application.onlyoffice;
in
{
in {
options.${namespace}.application.onlyoffice = {
enable = mkEnableOption "enable onlyoffice";
};
config = mkIf cfg.enable {
home.packages = with pkgs; [ onlyoffice-bin ];
# fonts.packages = with pkgs; [ corefonts ];
home.packages = with pkgs; [onlyoffice-desktopeditors];
};
}

View file

@ -10,7 +10,7 @@ in
};
config = mkIf cfg.enable {
home.packages = with pkgs; [ protonup ];
home.packages = with pkgs; [ protonup-ng ];
home.sessionVariables = {
STEAM_EXTRA_COMPAT_TOOLS_PATHS = "\${HOME}/.steam/root/compatibilitytools.d";

View file

@ -10,6 +10,6 @@ in
};
config = mkIf cfg.enable {
home.packages = with pkgs; [ teamspeak_client ];
home.packages = with pkgs; [ teamspeak3 teamspeak6-client ];
};
}

View file

@ -1,10 +1,14 @@
{ config, lib, pkgs, namespace, ... }:
let
{
config,
lib,
pkgs,
namespace,
...
}: let
inherit (lib) mkEnableOption mkIf;
cfg = config.${namespace}.shell.toolset.git;
in
{
in {
options.${namespace}.shell.toolset.git = {
enable = mkEnableOption "version-control system";
};
@ -12,7 +16,7 @@ in
config = mkIf cfg.enable {
home.sessionVariables.GITHUB_TOKEN = "$(cat /run/agenix/tokenGH)";
home.packages = with pkgs; [ lazygit lazyjj jujutsu ];
home.packages = with pkgs; [lazygit lazyjj jujutsu];
programs = {
zsh.initContent = ''
@ -29,14 +33,6 @@ in
git = {
enable = true;
package = pkgs.gitFull;
difftastic = {
enable = true;
options = {
background = "dark";
color = "always";
display = "inline";
};
};
ignores = [
# General:
@ -69,7 +65,7 @@ in
"*.elc"
];
extraConfig = {
settings = {
init.defaultBranch = "main";
core = {
editor = "nvim";
@ -106,6 +102,16 @@ in
};
};
};
difftastic = {
enable = true;
git.enable = true;
options = {
background = "dark";
color = "always";
display = "inline";
};
};
};
};
}

View file

@ -1,10 +1,15 @@
{ inputs, config, lib, pkgs, namespace, ... }:
let
{
inputs,
config,
lib,
pkgs,
namespace,
...
}: let
inherit (lib) mkIf mkEnableOption;
cfg = config.${namespace}.application.steam;
in
{
in {
options.${namespace}.application.steam = {
enable = mkEnableOption "enable steam";
};
@ -13,7 +18,7 @@ in
programs = {
steam = {
enable = true;
package = pkgs.steam-small.override {
package = pkgs.steam.override {
extraEnv = {
DXVK_HUD = "compiler";
MANGOHUD = true;

View file

@ -1,10 +1,15 @@
{ inputs, lib, config, namespace, ... }: let
{
inputs,
lib,
config,
namespace,
...
}: let
inherit (lib) mkEnableOption mkIf;
cfg = config.${namespace}.services.authentication.himmelblau;
in
{
imports = [ inputs.himmelblau.nixosModules.himmelblau ];
in {
imports = [inputs.himmelblau.nixosModules.himmelblau];
options.${namespace}.services.authentication.himmelblau = {
enable = mkEnableOption "enable azure entra ID authentication";
@ -14,7 +19,7 @@ in
services.himmelblau = {
enable = true;
settings = {
domains = [];
domain = "";
pam_allow_groups = [];
local_groups = [];
};

View file

@ -13,7 +13,7 @@ in
organization = mkOption {
type = types.attrsOf (types.submodule ({ name, ... }: {
options =
options =
let
org = name;
in
@ -23,11 +23,11 @@ in
default = false;
example = "true";
description = ''
True sets the org as default org for the instance. Only one org can be default org.
True sets the '${org}' org as default org for the instance. Only one org can be default org.
Nothing happens if you set it to false until you set another org as default org.
'';
};
project = mkOption {
default = {};
type = types.attrsOf (types.submodule {
@ -46,7 +46,7 @@ in
default = null;
example = "enforceProjectResourceOwnerPolicy";
description = ''
Defines from where the private labeling should be triggered,
Defines from where the private labeling should be triggered,
supported values:
- unspecified
@ -54,7 +54,7 @@ in
- allowLoginUserResourceOwnerPolicy
'';
};
projectRoleAssertion = mkOption {
type = types.bool;
default = false;
@ -63,7 +63,7 @@ in
Describes if roles of user should be added in token.
'';
};
projectRoleCheck = mkOption {
type = types.bool;
default = false;
@ -72,11 +72,11 @@ in
ZITADEL checks if the user has at least one on this project.
'';
};
role = mkOption {
default = {};
type = types.attrsOf (types.submodule ({ name, ... }: {
options =
options =
let
roleName = name;
in
@ -101,12 +101,12 @@ in
};
}));
};
assign = mkOption {
default = {};
type = types.attrsOf (types.listOf types.str);
};
application = mkOption {
default = {};
type = types.attrsOf (types.submodule {
@ -141,8 +141,8 @@ in
'';
};
exportMap =
let
exportMap =
let
strOpt = mkOption { type = types.nullOr types.str; default = null; };
in
mkOption {
@ -164,11 +164,11 @@ in
};
});
};
user = mkOption {
default = {};
type = types.attrsOf (types.submodule ({ name, ... }: {
options =
options =
let
username = name;
in
@ -226,7 +226,7 @@ in
};
}));
};
action = mkOption {
default = {};
type = types.attrsOf (types.submodule ({ name, ... }: {
@ -263,7 +263,7 @@ in
};
}));
};
triggers = mkOption {
default = [];
type = types.listOf (types.submodule {
@ -321,28 +321,20 @@ in
accessTokenType = mapEnum "OIDC_TOKEN_TYPE" value;
}."${type}" or value);
toResource = name: value: nameValuePair
toResource = name: value: nameValuePair
(toSnakeCase name)
(lib.mapAttrs' (k: v: nameValuePair (toSnakeCase k) (mapValue k v)) value);
withRef = type: name: attrs: attrs // (mapRef type name);
select = keys: callback: set:
if (length keys) == 0 then
if (length keys) == 0 then
mapAttrs' callback set
else let key = head keys; in
concatMapAttrs (k: v: select (drop 1 keys) (callback k) (v.${key} or {})) set
;
append = attrList: set: set // (listToAttrs attrList);
forEach = src: key: set:
let
_key = concatMapStringsSep "_" (k: "\${item.${k}}") key;
in
{
forEach = "{ for item in ${src} : \"${_key}\" => item }";
}
// set;
config' = config;
@ -352,7 +344,21 @@ in
modules = [
({ config, lib, ... }: {
config = {
config =
let
forEach = src: key: set:
let
_key = concatMapStringsSep "_" (k: "\${item.${k}}") key;
in
{
forEach = lib.tfRef ''{
for item in ${src} :
"''${item.org}_''${item.name}" => item
}'';
}
// set;
in
{
terraform.required_providers.zitadel = {
source = "zitadel/zitadel";
version = "2.2.0";
@ -376,18 +382,18 @@ in
}
] ])
";
orgs = cfg.organization |> mapAttrs (org: _: lib.tfRef "resource.zitadel_org.${org}.id");
orgs = cfg.organization |> mapAttrs (org: _: lib.tfRef "resource.zitadel_org.${org}.id");
};
resource = {
# Organizations
zitadel_org = cfg.organization |> select [] (name: { isDefault, ... }:
zitadel_org = cfg.organization |> select [] (name: { isDefault, ... }:
{ inherit name isDefault; }
|> toResource name
);
# Projects per organization
zitadel_project = cfg.organization |> select [ "project" ] (org: name: { hasProjectCheck, privateLabelingSetting, projectRoleAssertion, projectRoleCheck, ... }:
zitadel_project = cfg.organization |> select [ "project" ] (org: name: { hasProjectCheck, privateLabelingSetting, projectRoleAssertion, projectRoleCheck, ... }:
{
inherit name hasProjectCheck privateLabelingSetting projectRoleAssertion projectRoleCheck;
}
@ -396,7 +402,7 @@ in
);
# Each OIDC app per project
zitadel_application_oidc = cfg.organization |> select [ "project" "application" ] (org: project: name: { redirectUris, grantTypes, responseTypes, ...}:
zitadel_application_oidc = cfg.organization |> select [ "project" "application" ] (org: project: name: { redirectUris, grantTypes, responseTypes, ...}:
{
inherit name redirectUris grantTypes responseTypes;
@ -404,41 +410,41 @@ in
idTokenRoleAssertion = true;
accessTokenType = "JWT";
}
|> withRef "org" org
|> withRef "project" "${org}_${project}"
|> withRef "org" org
|> withRef "project" "${org}_${project}"
|> toResource "${org}_${project}_${name}"
);
# Each project role
zitadel_project_role = cfg.organization |> select [ "project" "role" ] (org: project: name: value:
zitadel_project_role = cfg.organization |> select [ "project" "role" ] (org: project: name: value:
{ inherit (value) displayName group; roleKey = name; }
|> withRef "org" org
|> withRef "project" "${org}_${project}"
|> withRef "org" org
|> withRef "project" "${org}_${project}"
|> toResource "${org}_${project}_${name}"
);
# Each project role assignment
zitadel_user_grant = cfg.organization |> select [ "project" "assign" ] (org: project: user: roles:
{ roleKeys = roles; }
|> withRef "org" org
|> withRef "project" "${org}_${project}"
|> withRef "user" "${org}_${user}"
|> withRef "org" org
|> withRef "project" "${org}_${project}"
|> withRef "user" "${org}_${user}"
|> toResource "${org}_${project}_${user}"
);
# Users
zitadel_human_user =
cfg.organization
|> select [ "user" ] (org: name: { email, userName, firstName, lastName, ... }:
zitadel_human_user =
cfg.organization
|> select [ "user" ] (org: name: { email, userName, firstName, lastName, ... }:
{
inherit email userName firstName lastName;
isEmailVerified = true;
}
}
|> withRef "org" org
|> toResource "${org}_${name}"
)
|> append
|> append
[
(forEach "local.extra_users" [ "org" "name" ] {
orgId = lib.tfRef "local.orgs[each.value.org]";
@ -446,7 +452,7 @@ in
email = lib.tfRef "each.value.email";
firstName = lib.tfRef "each.value.firstName";
lastName = lib.tfRef "each.value.lastName";
isEmailVerified = true;
}
|> toResource "extraUsers")
@ -454,20 +460,20 @@ in
;
# Global user roles
zitadel_instance_member =
cfg.organization
zitadel_instance_member =
cfg.organization
|> filterAttrsRecursive (n: v: !(v ? "instanceRoles" && (length v.instanceRoles) == 0))
|> select [ "user" ] (org: name: { instanceRoles, ... }:
{ roles = instanceRoles; }
|> select [ "user" ] (org: name: { instanceRoles, ... }:
{ roles = instanceRoles; }
|> withRef "user" "${org}_${name}"
|> toResource "${org}_${name}"
);
# Organazation specific roles
zitadel_org_member =
zitadel_org_member =
cfg.organization
|> filterAttrsRecursive (n: v: !(v ? "roles" && (length v.roles) == 0))
|> select [ "user" ] (org: name: { roles, ... }:
|> select [ "user" ] (org: name: { roles, ... }:
{ inherit roles; }
|> withRef "org" org
|> withRef "user" "${org}_${name}"
@ -475,9 +481,9 @@ in
);
# Organazation's actions
zitadel_action = cfg.organization |> select [ "action" ] (org: name: { timeout, allowedToFail, script, ...}:
{
inherit allowedToFail name;
zitadel_action = cfg.organization |> select [ "action" ] (org: name: { timeout, allowedToFail, script, ...}:
{
inherit allowedToFail name;
timeout = "${toString timeout}s";
script = "const ${name} = ${script}";
}
@ -486,20 +492,20 @@ in
);
# Organazation's action assignments
zitadel_trigger_actions =
zitadel_trigger_actions =
cfg.organization
|> concatMapAttrs (org: { triggers, ... }:
triggers
|> imap0 (i: { flowType, triggerType, actions, ... }: (let name = "trigger_${toString i}"; in
{
inherit flowType triggerType;
inherit flowType triggerType;
actionIds =
actions
actionIds =
actions
|> map (action: (lib.tfRef "zitadel_action.${org}_${toSnakeCase action}.id"));
}
|> withRef "org" org
|> toResource "${org}_${name}"
}
|> withRef "org" org
|> toResource "${org}_${name}"
))
|> listToAttrs
);
@ -516,7 +522,7 @@ in
};
# Client credentials per app
local_sensitive_file = cfg.organization |> select [ "project" "application" ] (org: project: name: { exportMap, ... }:
local_sensitive_file = cfg.organization |> select [ "project" "application" ] (org: project: name: { exportMap, ... }:
nameValuePair "${org}_${project}_${name}" {
content = ''
${if exportMap.client_id != null then exportMap.client_id else "CLIENT_ID"}=${lib.tfRef "resource.zitadel_application_oidc.${org}_${project}_${name}.client_id"}
@ -530,7 +536,7 @@ in
})
];
};
in
in
mkIf cfg.enable {
${namespace}.services.persistance.postgresql.enable = true;
@ -548,10 +554,12 @@ in
wantedBy = [ "multi-user.target" ];
wants = [ "zitadel.service" ];
script = ''
#!/usr/bin/env bash
script =
let
tofu = lib.getExe pkgs.opentofu;
in
''
if [ "$(systemctl is-active zitadel)" != "active" ]; then
echo "Zitadel is not running"
exit 1
@ -564,11 +572,11 @@ in
cp -f ${terraformConfiguration} config.tf.json
# Initialize OpenTofu
${lib.getExe pkgs.opentofu} init
${tofu} init
# Run the infrastructure code
# ${lib.getExe pkgs.opentofu} plan
${lib.getExe pkgs.opentofu} apply -auto-approve
${tofu} plan -refresh=false -out=tfplan
${tofu} apply -auto-approve tfplan
'';
serviceConfig = {
@ -628,7 +636,7 @@ in
Org = {
Name = "kruining";
Human = {
UserName = "chris";
FirstName = "Chris";
@ -639,7 +647,7 @@ in
};
Password = "KaasIsAwesome1!";
};
Machine = {
Machine = {
Username = "terraform-service-user";
@ -648,7 +656,7 @@ in
MachineKey = { ExpirationDate = "2026-01-01T00:00:00Z"; Type = 1; };
# Pat = { ExpirationDate = "2026-01-01T00:00:00Z"; };
};
# LoginClient.Machine = {
# Username = "terraform-service-user";
# Name = "Terraform";
@ -689,7 +697,7 @@ in
'';
};
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
# Secrets

View file

@ -1,5 +1,10 @@
{ config, lib, pkgs, namespace, ... }:
let
{
config,
lib,
pkgs,
namespace,
...
}: let
inherit (builtins) toString toJSON;
inherit (lib) mkIf mkEnableOption;
@ -10,8 +15,7 @@ let
port = 4001;
database = "synapse";
in
{
in {
options.${namespace}.services.communication.matrix = {
enable = mkEnableOption "Matrix server (Synapse)";
};
@ -22,13 +26,13 @@ in
# virtualisation.podman.enable = true;
};
networking.firewall.allowedTCPPorts = [ 4001 ];
networking.firewall.allowedTCPPorts = [4001];
services = {
matrix-synapse = {
enable = true;
extras = [ "oidc" ];
extras = ["oidc"];
extraConfigFiles = [
config.sops.templates."synapse-oidc.yaml".path
@ -52,7 +56,7 @@ in
backchannel_logout_enabled = true;
sso = {
client_whitelist = [ "http://[::1]:9092" ];
client_whitelist = ["http://[::1]:9092"];
update_profile_information = true;
};
@ -75,7 +79,7 @@ in
resources = [
{
names = [ "client" "federation" "openid" "metrics" "media" "health" ];
names = ["client" "federation" "openid" "metrics" "media" "health"];
compress = true;
}
];
@ -132,7 +136,7 @@ in
postgresql = {
enable = true;
ensureDatabases = [ database ];
ensureDatabases = [database];
ensureUsers = [
{
name = database;
@ -192,7 +196,7 @@ in
localpart_template: "{{ user.preferred_username }}"
display_name_template: "{{ user.name }}"
'';
restartUnits = [ "matrix-synapse.service" ];
restartUnits = ["matrix-synapse.service"];
};
};
};

View file

@ -1,12 +1,16 @@
{ config, lib, pkgs, namespace, ... }:
let
{
config,
lib,
pkgs,
namespace,
...
}: let
inherit (builtins) toString;
inherit (lib) mkIf mkEnableOption mkOption;
cfg = config.${namespace}.services.development.forgejo;
domain = "git.amarth.cloud";
in
{
in {
options.${namespace}.services.development.forgejo = {
enable = mkEnableOption "Forgejo";
@ -26,7 +30,7 @@ in
virtualisation.podman.enable = true;
};
environment.systemPackages = with pkgs; [ forgejo ];
environment.systemPackages = with pkgs; [forgejo];
services = {
forgejo = {
@ -141,7 +145,7 @@ in
};
};
openssh.settings.AllowUsers = [ "forgejo" ];
openssh.settings.AllowUsers = ["forgejo"];
gitea-actions-runner = {
package = pkgs.forgejo-runner;
@ -180,18 +184,26 @@ in
};
};
users = {
users."gitea-runner" = {
isSystemUser = true;
group = "gitea-runner";
};
groups."gitea-runner" = {};
};
sops.secrets = {
"forgejo/action_runner_token" = {
owner = "gitea-runner";
group = "gitea-runner";
restartUnits = [ "gitea-runner-default.service" ];
restartUnits = ["gitea-runner-default.service"];
};
"forgejo/email" = {
owner = "forgejo";
group = "forgejo";
key = "email/chris_kruining_eu";
restartUnits = [ "forgejo.service" ];
restartUnits = ["forgejo.service"];
};
};
};

View file

@ -1,13 +1,19 @@
{ pkgs, lib, namespace, config, inputs, system, ... }:
let
{
pkgs,
lib,
namespace,
config,
inputs,
system,
...
}: let
inherit (lib) mkIf mkEnableOption mkOption;
inherit (lib.types) str;
cfg = config.${namespace}.services.media;
arr = ["radarr" ];
in
{
arr = ["radarr"];
in {
options.${namespace}.services.media = {
enable = mkEnableOption "Enable media services";
@ -69,117 +75,132 @@ in
# Services
#=========================================================================
services = let
arr-services =
arr-services =
arr
|> lib.imap (i: service: {
name = service;
value = {
enable = true;
openFirewall = true;
value =
{
enable = true;
openFirewall = true;
environmentFiles = [
config.sops.templates."${service}/config.env".path
];
environmentFiles = [
config.sops.templates."${service}/config.env".path
];
settings = {
auth.authenticationMethod = "External";
settings = {
auth.authenticationMethod = "External";
server = {
bindaddress = "0.0.0.0";
port = 2000 + i;
server = {
bindaddress = "0.0.0.0";
port = 2000 + i;
};
postgres = {
host = "localhost";
port = "5432";
user = service;
maindb = service;
logdb = service;
};
};
postgres = {
host = "localhost";
port = "5432";
user = service;
maindb = service;
logdb = service;
};
};
}
// (if service != "prowlarr" then { user = cfg.user; group = cfg.group; } else {});
}
// (
if service != "prowlarr"
then {
user = cfg.user;
group = cfg.group;
}
else {}
);
})
|> lib.listToAttrs
;
in
arr-services // {
bazarr = {
enable = true;
openFirewall = true;
user = cfg.user;
group = cfg.group;
listenPort = 2005;
};
# port is harcoded in nixpkgs module
jellyfin = {
enable = true;
openFirewall = true;
user = cfg.user;
group = cfg.group;
};
flaresolverr = {
enable = true;
openFirewall = true;
port = 2007;
};
qbittorrent = {
enable = true;
openFirewall = true;
webuiPort = 2008;
serverConfig = {
LegalNotice.Accepted = true;
|> lib.listToAttrs;
in
arr-services
// {
bazarr = {
enable = true;
openFirewall = true;
user = cfg.user;
group = cfg.group;
listenPort = 2005;
};
user = cfg.user;
group = cfg.group;
};
# port is harcoded in nixpkgs module
jellyfin = {
enable = true;
openFirewall = true;
user = cfg.user;
group = cfg.group;
};
# port is harcoded in nixpkgs module
sabnzbd = {
enable = true;
openFirewall = true;
configFile = "${cfg.path}/sabnzbd/config.ini";
flaresolverr = {
enable = true;
openFirewall = true;
port = 2007;
};
user = cfg.user;
group = cfg.group;
};
qbittorrent = {
enable = true;
openFirewall = true;
webuiPort = 2008;
postgresql =
let
databases = arr |> lib.concatMap (s: [ s "${s}-log" ]);
in
{
enable = true;
ensureDatabases = arr;
ensureUsers = arr |> lib.map (service: {
name = service;
ensureDBOwnership = true;
});
};
serverConfig = {
LegalNotice.Accepted = true;
caddy = {
enable = true;
virtualHosts = {
"jellyfin.kruining.eu".extraConfig = ''
reverse_proxy http://[::1]:8096
'';
Prefecences.WebUI = {
Username = "admin";
};
};
user = cfg.user;
group = cfg.group;
};
# port is harcoded in nixpkgs module
sabnzbd = {
enable = true;
openFirewall = true;
configFile = "${cfg.path}/sabnzbd/config.ini";
user = cfg.user;
group = cfg.group;
};
postgresql = let
databases = arr |> lib.concatMap (s: [s "${s}-log"]);
in {
enable = true;
ensureDatabases = arr;
ensureUsers =
arr
|> lib.map (service: {
name = service;
ensureDBOwnership = true;
});
};
caddy = {
enable = true;
virtualHosts = {
"jellyfin.kruining.eu".extraConfig = ''
reverse_proxy http://[::1]:8096
'';
};
};
};
};
systemd.services.radarrApplyTerraform =
let
systemd.services.radarrApplyTerraform = let
# this is a nix package, the generated json file to be exact
terraformConfiguration = inputs.terranix.lib.terranixConfiguration {
inherit system;
modules = [
({ config, lib, ... }: {
({
config,
lib,
...
}: {
config = {
variable = {
api_key = {
@ -207,13 +228,12 @@ in
})
];
};
in
{
in {
description = "Radarr terraform apply";
wantedBy = [ "multi-user.target" ];
wants = [ "radarr.service" ];
wantedBy = ["multi-user.target"];
wants = ["radarr.service"];
script = ''
#!/usr/bin/env bash
@ -255,53 +275,70 @@ in
systemd.services.jellyfin.serviceConfig.killSignal = lib.mkForce "SIGKILL";
sops = {
secrets =
arr
|> lib.map (service: {
name = "${service}/apikey";
value = {
secrets = let
arrSecrets =
arr
|> lib.map (service: {
name = "${service}/apikey";
value = {
owner = cfg.user;
group = cfg.group;
restartUnits = ["${service}.service"];
};
})
|> lib.listToAttrs;
in
arrSecrets
// {
# "qbittorrent/password" = {};
"qbittorrent/password_hash" = {};
};
templates = let
apikeys =
arr
|> lib.map (service: {
name = "${service}/config.env";
value = {
owner = cfg.user;
group = cfg.group;
restartUnits = ["${service}.service"];
content = ''
${lib.toUpper service}__AUTH__APIKEY="${config.sops.placeholder."${service}/apikey"}"
'';
};
})
|> lib.listToAttrs;
tfvars =
arr
|> lib.map (service: {
name = "${service}/config.tfvars";
value = {
owner = cfg.user;
group = cfg.group;
restartUnits = ["${service}ApplyTerraform.service"];
content = ''
api_key = "${config.sops.placeholder."${service}/apikey"}"
'';
};
})
|> lib.listToAttrs;
qbittorrent = {
"qbittorrent/password.conf" = {
owner = cfg.user;
group = cfg.group;
restartUnits = [ "${service}.service" ];
restartUnits = ["qbittorrent.service"];
path = "${config.services.qbittorrent.profileDir}/qBittorrent/config/password.conf";
content = ''
[Preferences]
WebUI\Password_PBKDF2="${config.sops.placeholder."qbittorrent/password_hash"}"
'';
};
})
|> lib.listToAttrs
;
templates =
let
apikeys =
arr
|> lib.map (service: {
name = "${service}/config.env";
value = {
owner = cfg.user;
group = cfg.group;
restartUnits = [ "${service}.service" ];
content = ''
${lib.toUpper service}__AUTH__APIKEY="${config.sops.placeholder."${service}/apikey"}"
'';
};
})
|> lib.listToAttrs;
tfvars =
arr
|> lib.map(service: {
name = "${service}/config.tfvars";
value = {
owner = cfg.user;
group = cfg.group;
restartUnits = [ "${service}ApplyTerraform.service" ];
content = ''
api_key = "${config.sops.placeholder."${service}/apikey"}"
'';
};
})
|> lib.listToAttrs;
in
apikeys // tfvars
;
};
in
apikeys // tfvars // qbittorrent;
};
};
}

View file

@ -0,0 +1,86 @@
{
config,
lib,
namespace,
inputs,
system,
...
}: let
inherit (lib) mkIf mkEnableOption;
cfg = config.${namespace}.services.media.mydia;
in {
imports = [
inputs.mydia.nixosModules.default
];
options.${namespace}.services.media.mydia = {
enable = mkEnableOption "Enable Mydia";
};
config = mkIf cfg.enable {
services.mydia = {
enable = true;
port = 2010;
listenAddress = "0.0.0.0";
openFirewall = true;
mediaLibraries = [
"/var/mydia/movies"
"/var/mydia/series"
];
database = {
# type = "sqlite";
# uri = "file:///var/lib/mydia/mydia.db";
type = "postgres";
uri = "postgres://mydia@localhost:5432/mydia?sslmode=disable";
passwordFile = config.sops.secrets."mydia/qbittorrent_password".path;
};
secretKeyBaseFile = config.sops.secrets."mydia/secret_key_base".path;
guardianSecretKeyFile = config.sops.secrets."mydia/guardian_secret".path;
oidc = {
enable = true;
issuer = "https://auth.kruining.eu";
clientIdFile = config.sops.secrets."mydia/oidc_id".path;
clientSecretFile = config.sops.secrets."mydia/oidc_secret".path;
scopes = ["openid" "profile" "email"];
};
downloadClients = {
qbittorrent = {
type = "qbittorrent";
host = "localhost";
port = 2008;
username = "admin";
passwordFile = config.sops.secrets."mydia/qbittorrent_password".path;
useSsl = false;
};
};
};
sops.secrets = let
base =
["secret_key_base" "guardian_secret" "oidc_id" "oidc_secret"]
|> lib.map (name:
lib.nameValuePair "mydia/${name}" {
owner = config.services.mydia.user;
group = config.services.mydia.group;
restartUnits = ["mydia.service"];
})
|> lib.listToAttrs;
in
base
// {
"mydia/qbittorrent_password" = {
owner = config.services.mydia.user;
group = config.services.mydia.group;
restartUnits = ["mydia.service"];
key = "qbittorrent/password";
};
};
};
}

View file

@ -1,14 +1,20 @@
{ pkgs, config, lib, namespace, inputs, system, ... }:
let
{
pkgs,
config,
lib,
namespace,
inputs,
system,
...
}: let
inherit (builtins) toString;
inherit (lib) mkIf mkEnableOption mkOption types;
cfg = config.${namespace}.services.media.servarr;
in
{
in {
options.${namespace}.services.media = {
servarr = mkOption {
type = types.attrsOf (types.submodule ({ name, ... }: {
type = types.attrsOf (types.submodule ({name, ...}: {
options = {
enable = mkEnableOption "Enable ${name}";
debug = mkEnableOption "Use tofu plan instead of tofu apply for ${name} ";
@ -28,9 +34,13 @@ in
};
config = {
services =
services =
cfg
|> lib.mapAttrsToList (service: { enable, port, ... }: (mkIf enable {
|> lib.mapAttrsToList (service: {
enable,
port,
...
}: (mkIf enable {
"${service}" = {
enable = true;
openFirewall = true;
@ -58,31 +68,44 @@ in
};
}))
|> lib.mergeAttrsList
|> (set: set // {
postgres = {
ensureDatabases = cfg |> lib.attrNames;
ensureUsers = cfg |> lib.attrNames |> lib.map (service: {
name = service;
ensureDBOwnership = true;
});
};
})
;
|> (set:
set
// {
postgresql = {
ensureDatabases = cfg |> lib.attrNames;
ensureUsers =
cfg
|> lib.attrNames
|> lib.map (service: {
name = service;
ensureDBOwnership = true;
});
};
});
systemd =
systemd =
cfg
|> lib.mapAttrsToList (service: { enable, debug, port, rootFolders, ... }: (mkIf enable {
|> lib.mapAttrsToList (service: {
enable,
debug,
port,
rootFolders,
...
}: (mkIf enable {
tmpfiles.rules = [
"d /var/lib/${service}ApplyTerraform 0755 ${service} ${service} -"
];
services."${service}ApplyTerraform" =
let
services."${service}ApplyTerraform" = let
terraformConfiguration = inputs.terranix.lib.terranixConfiguration {
inherit system;
modules = [
({ config, lib, ... }: {
({
config,
lib,
...
}: {
config = {
variable = {
api_key = {
@ -102,23 +125,21 @@ in
};
resource = {
"${service}_root_folder" =
"${service}_root_folder" =
rootFolders
|> lib.imap (i: f: lib.nameValuePair "local${toString i}" { path = f; })
|> lib.listToAttrs
;
|> lib.imap (i: f: lib.nameValuePair "local${toString i}" {path = f;})
|> lib.listToAttrs;
};
};
})
];
};
in
{
in {
description = "${service} terraform apply";
wantedBy = [ "multi-user.target" ];
wants = [ "${service}.service" ];
wantedBy = ["multi-user.target"];
wants = ["${service}.service"];
script = ''
#!/usr/bin/env bash
@ -141,7 +162,11 @@ in
# Run the infrastructure code
${lib.getExe pkgs.opentofu} \
${if debug then "plan" else "apply -auto-approve"} \
${
if debug
then "plan"
else "apply -auto-approve"
} \
-var-file='${config.sops.templates."${service}/config.tfvars".path}'
'';
@ -158,31 +183,29 @@ in
};
};
}))
|> lib.mergeAttrsList
;
|> lib.mergeAttrsList;
users.users =
users.users =
cfg
|> lib.mapAttrsToList (service: { enable, ... }: (mkIf enable {
"${service}".extraGroups = [ "media" ];
|> lib.mapAttrsToList (service: {enable, ...}: (mkIf enable {
"${service}".extraGroups = ["media"];
}))
|> lib.mergeAttrsList
;
|> lib.mergeAttrsList;
sops =
sops =
cfg
|> lib.mapAttrsToList (service: { enable, ... }: (mkIf enable {
|> lib.mapAttrsToList (service: {enable, ...}: (mkIf enable {
secrets."${service}/apikey" = {
owner = service;
group = service;
restartUnits = [ "${service}.service" ];
restartUnits = ["${service}.service"];
};
templates = {
"${service}/config.env" = {
owner = service;
group = service;
restartUnits = [ "${service}.service" ];
restartUnits = ["${service}.service"];
content = ''
${lib.toUpper service}__AUTH__APIKEY="${config.sops.placeholder."${service}/apikey"}"
'';
@ -191,18 +214,16 @@ in
"${service}/config.tfvars" = {
owner = service;
group = service;
restartUnits = [ "${service}.service" ];
restartUnits = ["${service}.service"];
content = ''
api_key = "${config.sops.placeholder."${service}/apikey"}"
'';
};
};
}))
|> lib.mergeAttrsList
;
|> lib.mergeAttrsList;
};
# cfg
# |> lib.mapAttrsToList (service: { enable, debug, port, rootFolders, ... }: (mkIf enable {

View file

@ -1,25 +1,31 @@
{ pkgs, config, lib, namespace, ... }:
let
{
pkgs,
config,
lib,
namespace,
...
}: let
inherit (builtins) toString;
inherit (lib) mkIf mkEnableOption mkOption types getAttrs toUpper concatMapAttrsStringSep;
cfg = config.${namespace}.services.security.vaultwarden;
databaseProviderSqlite = types.submodule ({ ... }: {
databaseProviderSqlite = types.submodule ({...}: {
options = {
type = mkOption {
type = types.enum [ "sqlite" ];
type = types.enum ["sqlite"];
};
file = mkOption {
type = types.str;
description = '''';
type = types.path;
description = ''
Path to sqlite database file.
'';
};
};
});
databaseProviderPostgresql = types.submodule ({ ... }:
let
databaseProviderPostgresql = types.submodule ({...}: let
urlOptions = lib.${namespace}.options.mkUrlOptions {
host = {
description = ''
@ -40,36 +46,36 @@ let
example = "postgres";
};
};
in
{
options = {
type = mkOption {
type = types.enum [ "postgresql" ];
};
in {
options =
{
type = mkOption {
type = types.enum ["postgresql"];
};
sslMode = mkOption {
type = types.enum [ "verify-ca" "verify-full" "require" "prefer" "allow" "disabled" ];
default = "verify-full";
example = "verify-ca";
description = ''
How to verify the server's ssl
sslMode = mkOption {
type = types.enum ["verify-ca" "verify-full" "require" "prefer" "allow" "disabled"];
default = "verify-full";
example = "verify-ca";
description = ''
How to verify the server's ssl
| mode | eavesdropping protection | MITM protection | Statement |
|-------------|--------------------------|----------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
| disable | No | No | I don't care about security, and I don't want to pay the overhead of encryption. |
| allow | Maybe | No | I don't care about security, but I will pay the overhead of encryption if the server insists on it. |
| prefer | Maybe | No | I don't care about encryption, but I wish to pay the overhead of encryption if the server supports it. |
| require | Yes | No | I want my data to be encrypted, and I accept the overhead. I trust that the network will make sure I always connect to the server I want. |
| verify-ca | Yes | Depends on CA policy | I want my data encrypted, and I accept the overhead. I want to be sure that I connect to a server that I trust. |
| verify-full | Yes | Yes | I want my data encrypted, and I accept the overhead. I want to be sure that I connect to a server I trust, and that it's the one I specify. |
[Source](https://www.postgresql.org/docs/current/libpq-ssl.html#LIBPQ-SSL-SSLMODE-STATEMENTS)
'';
};
} // (urlOptions |> getAttrs [ "protocol" "host" "port" ]);
| mode | eavesdropping protection | MITM protection | Statement |
|-------------|--------------------------|----------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
| disable | No | No | I don't care about security, and I don't want to pay the overhead of encryption. |
| allow | Maybe | No | I don't care about security, but I will pay the overhead of encryption if the server insists on it. |
| prefer | Maybe | No | I don't care about encryption, but I wish to pay the overhead of encryption if the server supports it. |
| require | Yes | No | I want my data to be encrypted, and I accept the overhead. I trust that the network will make sure I always connect to the server I want. |
| verify-ca | Yes | Depends on CA policy | I want my data encrypted, and I accept the overhead. I want to be sure that I connect to a server that I trust. |
| verify-full | Yes | Yes | I want my data encrypted, and I accept the overhead. I want to be sure that I connect to a server I trust, and that it's the one I specify. |
[Source](https://www.postgresql.org/docs/current/libpq-ssl.html#LIBPQ-SSL-SSLMODE-STATEMENTS)
'';
};
}
// (urlOptions |> getAttrs ["protocol" "host" "port"]);
});
in
{
in {
options.${namespace}.services.security.vaultwarden = {
enable = mkEnableOption "enable vaultwarden";
@ -136,7 +142,7 @@ in
postgresql = {
enable = true;
ensureDatabases = [ "vaultwarden" ];
ensureDatabases = ["vaultwarden"];
ensureUsers = [
{
name = "vaultwarden";
@ -171,7 +177,7 @@ in
owner = config.users.users.vaultwarden.name;
group = config.users.users.vaultwarden.name;
key = "email/chris_kruining_eu";
restartUnits = [ "vaultwarden.service" ];
restartUnits = ["vaultwarden.service"];
};
};
@ -183,34 +189,31 @@ in
owner = config.users.users.vaultwarden.name;
group = config.users.groups.vaultwarden.name;
};
temp-db-output.content =
let
config =
cfg.database
|> ({ type, ... }@db:
if type == "sqlite" then
{ inherit (db) type file; }
else if type == "postgresql" then
{
inherit (db) type;
url = lib.${namespace}.strings.toUrl {
inherit (db) protocol host port;
path = "vaultwarden";
query = {
sslmode = db.sslMode;
};
temp-db-output.content = let
config =
cfg.database
|> (
{type, ...} @ db:
if type == "sqlite"
then {inherit (db) type file;}
else if type == "postgresql"
then {
inherit (db) type;
url = lib.${namespace}.strings.toUrl {
inherit (db) protocol host port;
path = "vaultwarden";
query = {
sslmode = db.sslMode;
};
}
else
{}
)
|> concatMapAttrsStringSep "\n" (n: v: "${toUpper n}=${v}")
;
in
''
# GENERATED VALUES
${config}
'';
};
}
else {}
)
|> concatMapAttrsStringSep "\n" (n: v: "${toUpper n}=${v}");
in ''
# GENERATED VALUES
${config}
'';
};
};
};

View file

@ -1,2 +1,2 @@
{ ... }:
{}
{...}: {
}

View file

@ -1,5 +1,10 @@
{ mkShell, inputs, pkgs, ... }:
{
mkShell,
inputs,
pkgs,
stdenv,
...
}:
mkShell {
packages = with pkgs; [
bash
@ -7,6 +12,10 @@ mkShell {
just
yq
pwgen
inputs.clan-core.packages.x86_64-linux.clan-cli
alejandra
nil
nixd
openssl
inputs.clan-core.packages.${stdenv.hostPlatform.system}.clan-cli
];
}
}

View file

@ -1,5 +1,4 @@
{ ... }:
{
{...}: {
imports = [
./disks.nix
./hardware.nix
@ -8,7 +7,10 @@
networking = {
interfaces.enp2s0 = {
ipv6.addresses = [
{ address = "2a0d:6e00:1dc9:0::dead:beef"; prefixLength = 64; }
{
address = "2a0d:6e00:1dc9:0::dead:beef";
prefixLength = 64;
}
];
useDHCP = true;
@ -39,7 +41,7 @@
sneeuwvlok = {
services = {
backup.borg.enable = true;
authentication.zitadel = {
enable = true;
@ -51,8 +53,8 @@
firstName = "Chris";
lastName = "Kruining";
roles = [ "ORG_OWNER" ];
instanceRoles = [ "IAM_OWNER" ];
roles = ["ORG_OWNER"];
instanceRoles = ["IAM_OWNER"];
};
kaas = {
@ -78,27 +80,27 @@
};
assign = {
chris = [ "jellyfin" "jellyfin_admin" ];
kaas = [ "jellyfin" ];
chris = ["jellyfin" "jellyfin_admin"];
kaas = ["jellyfin"];
};
application = {
jellyfin = {
redirectUris = [ "https://jellyfin.kruining.eu/sso/OID/redirect/zitadel" ];
grantTypes = [ "authorizationCode" ];
responseTypes = [ "code" ];
redirectUris = ["https://jellyfin.kruining.eu/sso/OID/redirect/zitadel"];
grantTypes = ["authorizationCode"];
responseTypes = ["code"];
};
forgejo = {
redirectUris = [ "https://git.amarth.cloud/user/oauth2/zitadel/callback" ];
grantTypes = [ "authorizationCode" ];
responseTypes = [ "code" ];
redirectUris = ["https://git.amarth.cloud/user/oauth2/zitadel/callback"];
grantTypes = ["authorizationCode"];
responseTypes = ["code"];
};
vaultwarden = {
redirectUris = [ "https://vault.kruining.eu/identity/connect/oidc-signin" ];
grantTypes = [ "authorizationCode" ];
responseTypes = [ "code" ];
redirectUris = ["https://vault.kruining.eu/identity/connect/oidc-signin"];
grantTypes = ["authorizationCode"];
responseTypes = ["code"];
exportMap = {
client_id = "SSO_CLIENT_ID";
client_secret = "SSO_CLIENT_SECRET";
@ -106,9 +108,15 @@
};
matrix = {
redirectUris = [ "https://matrix.kruining.eu/_synapse/client/oidc/callback" ];
grantTypes = [ "authorizationCode" ];
responseTypes = [ "code" ];
redirectUris = ["https://matrix.kruining.eu/_synapse/client/oidc/callback"];
grantTypes = ["authorizationCode"];
responseTypes = ["code"];
};
mydia = {
redirectUris = ["http://localhost:2010/auth/oidc/callback"];
grantTypes = ["authorizationCode"];
responseTypes = ["code"];
};
};
};
@ -121,9 +129,9 @@
if (ctx.v1.user.grants == undefined || ctx.v1.user.grants.count == 0) {
return;
}
const roles = ctx.v1.user.grants.grants.flatMap(({ roles, projectId }) => roles.map(role => projectId + ':' + role));
api.v1.claims.setClaim('nix:zitadel:custom', JSON.stringify({ roles }));
};
'';
@ -131,8 +139,16 @@
};
triggers = [
{ flowType = "customiseToken"; triggerType = "preUserinfoCreation"; actions = [ "flattenRoles" ]; }
{ flowType = "customiseToken"; triggerType = "preAccessTokenCreation"; actions = [ "flattenRoles" ]; }
{
flowType = "customiseToken";
triggerType = "preUserinfoCreation";
actions = ["flattenRoles"];
}
{
flowType = "customiseToken";
triggerType = "preAccessTokenCreation";
actions = ["flattenRoles"];
}
];
};
};
@ -146,6 +162,7 @@
media.enable = true;
media.homer.enable = true;
media.mydia.enable = true;
media.nfs.enable = true;
media.servarr = {
# radarr = {
@ -190,7 +207,7 @@
database = {
# type = "sqlite";
# file = "/var/lib/vaultwarden/state.db";
type = "postgresql";
host = "localhost";
port = 5432;

View file

@ -19,6 +19,14 @@ lidarr:
apikey: ENC[AES256_GCM,data:I2eKaxidmxem7C7ukmyIfwASNqrkS4vEOiCcU5kSNY6DR0pXsYg0PBdgu8vzK6llbXODLdG5t55BordIWvVRJGAauo0FMvtp59NSNpza7cK68tdKGvNefD6bqhUIR06BY11niQ==,iv:48AD7cd17TlWY5yAagepLOIVwgxhD/d13Pnup6GsWDA=,tag:teOVtW8opE99hqAXQwvlrA==,type:str]
prowlarr:
apikey: ENC[AES256_GCM,data:pyZ2WGEs/PlIdhDsQq2TPGJbplkd5fLF0ZkBjITqIJlnAzYHb+rl+KOM4rHqQcI6yAJM8X1Y3ymGrD7vG7GiRxB7yoEG13SKhZIWOddTnxIhbkz81RfrL2fUJIydOaP6sS//9Q==,iv:Tr6MWoC6nC7rdVTOjT1T2itT+lVL4GnUiAr5/+IHAs0=,tag:keIJNuGeVht8+xSN3FnBGA==,type:str]
mydia:
oidc_id: ENC[AES256_GCM,data:LfYWh9EC0aio3w1Xsj/jtU6z,iv:+dX9KkNtfQMYSX4yr83KyXalWMD/aWby7fC8aL4ZT3I=,tag:CvdbMoMTuC9FohTMIE5pmg==,type:str]
oidc_secret: ENC[AES256_GCM,data:PgI4hmP/3wt9uj+1QvCYcT8Wav0hgCRADouzWM3V695SSfXfbwDgez8tA/tm1/1jymAU2F2sZH8G2hZ1cdHyHQ==,iv:h3o3jsTmnoNE3+mGX12J3ZU0/6PlQNjdndEvaj/czj0=,tag:p3+p4E8fBtR7a8UpM8cUsg==,type:str]
secret_key_base: ENC[AES256_GCM,data:yG7HJ5r74Qtxbeyf8F6dA0uHv2pQ8YAJKlKiKjS+m24JRvJWQaTThJ+c5HbuUa6R3e9XtVHchhlVPkF0Is/b+g==,iv:v65xdRr4JdKZmBtjZ08/J3LLqnphSGt9QfVPNQ2x/xg=,tag:n7tD2dhr4IJn1LWM9WW8UA==,type:str]
guardian_secret: ENC[AES256_GCM,data:OjnNFSHlecL+qXwlhTm++itRM6ga5E5KrSJxbgIUpbMEkIWgu3xhRtnPdipXbedgall0XdO/s+jnWCagZX94BA==,iv:DukdKvm9vey8BWUiml20tgA/Vji1XVX4+sUPge9nTk0=,tag:q3HdvgUYqR0APiaFz0ul5Q==,type:str]
qbittorrent:
password_hash: ENC[AES256_GCM,data:QWuQYmfBn9eLDYztH7TmQvw74MvmzCQ98OlBtyjm1Icr2c63epRuHWzQbm+Q+1jrCSiQreOB3ZyjLzkeV6SlLonryUSD71uBWVwctgPXO0XDrxE1Vi6dkiwC3TF65JTMDhyjDLEj1YkiMP25Fz5NidJTP/r9GlXTfM7gjWo=,iv:bpgL5IoAv+1PUtgNIjLcbzN8C9z55ndypz4LEELAhLc=,tag:VB+XTCwLeIEYKnOr/0f7zA==,type:str]
password: ENC[AES256_GCM,data:UepYY6UjJV/jo2aXTOEnKRtsjSqOSYPQlKlrAa7rf9rdnt2UXGjCkvN+A72pICuIBCAmhXZBAUMvmWTV9trk6NREHe0cY1xTC7pNv3x9TM/ZQmH498pbT/95pYAKwouHp9heJQ==,iv:FzjF+xPoaOp+gplxpz940V2dkWSTWe8dWUxexCoxxHc=,tag:TDZsboq9fEmmBrwJN/HTpQ==,type:str]
sops:
age:
- recipient: age19qfpf980tadguqq44zf6xwvjvl428dyrj46ha3n6aeqddwhtnuqqml7etq
@ -39,7 +47,7 @@ sops:
TTRWaHhpNWlkVDFmMFN4ZTNHMUxyNVkKV693pzTKRkZboQCMPr9IyMGSgxfuHXcb
Y6BNcp6Qg6PWtX5QI7wRkPNINAK1TEbRBba+b8h6gMmVU4DliQyFiQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-11-19T09:51:26Z"
mac: ENC[AES256_GCM,data:pMMkxHPochpI8si/oHhU7MHqC1JjNhMP7HCRNQQEkwBQI489xiC02t+qUwpmG4oIheqi8lEcZPpL4t9HzRN9sZImaI2LrJn3cHFojHzXzo7FPfvfUilZe1+JXLfm+wn+bflAEutIcfDiZc/MjiKOxRHwZy5Pr41Mj6uPIUr62zk=,iv:GwvMVgJ6m1DQcRZMVzshbuMK/Kx8vE8Ym83KbxuvYRg=,tag:wVSol9LDRzoFjQppB8J9gA==,type:str]
lastmodified: "2025-12-04T11:24:52Z"
mac: ENC[AES256_GCM,data:jIgkl1lcVDSlKqJs9fjaHUAZsGL+22T86/qqKyDziHl0+VU763Ezwm8P+la+55jIIT2zLhFcUjhn2BabBi90OeEPztAC4rGpZj6+ZZ0GDCj/JhjPAAo3LgAKOCG0Xgf8MZWr/rXd6bLhW7Qj36PMJnap26rjEiUZeSvpWS2dz8g=,iv:CDx8fBI9Dl1uwrbMD1fa7/h3C7haK3xZxJI59mtL1LA=,tag:2UDRFJoevGEBKZA/9eUiOw==,type:str]
unencrypted_suffix: _unencrypted
version: 3.11.0