This commit is contained in:
Shelvacu
2025-05-23 17:56:46 -07:00
committed by Shelvacu on fw
parent bd4d27d948
commit 91a27769ba
54 changed files with 1278 additions and 1148 deletions

View File

@@ -25,18 +25,17 @@ let
storeContents = pkgs.linkFarmFromDrvs "store-contents" pxeConfig.netboot.storeContents; storeContents = pkgs.linkFarmFromDrvs "store-contents" pxeConfig.netboot.storeContents;
}; };
extraBuilds = { inherit isoContents pxeContents; }; extraBuilds = { inherit isoContents pxeContents; };
buildListWithout = builtins.filter (v: !builtins.elem v ignoreList) (builtins.attrNames self.buildList); buildListWithout = builtins.filter (v: !builtins.elem v ignoreList) (
builtins.attrNames self.buildList
);
allBuilds = self.buildList // extraBuilds; allBuilds = self.buildList // extraBuilds;
in in
rec { rec {
archiveList = map ( archiveList = map (name: {
name: inherit name;
{ broken = builtins.elem name self.brokenBuilds;
inherit name; impure = builtins.elem name self.impureBuilds;
broken = builtins.elem name self.brokenBuilds; }) (buildListWithout ++ builtins.attrNames extraBuilds);
impure = builtins.elem name self.impureBuilds;
}
) (buildListWithout ++ builtins.attrNames extraBuilds);
drvs = allBuilds; drvs = allBuilds;
buildDepsDrvs = builtins.mapAttrs (_: v: pkgs.closureInfo { rootPaths = [ v.drvPath ]; }) drvs; buildDepsDrvs = builtins.mapAttrs (_: v: pkgs.closureInfo { rootPaths = [ v.drvPath ]; }) drvs;

View File

@@ -7,88 +7,88 @@
}: }:
let let
enableFfmpeg = !config.vacu.isMinimal; enableFfmpeg = !config.vacu.isMinimal;
enableFfmpegFull = enableFfmpeg && config.vacu.isGui; enableFfmpegFull = enableFfmpeg && config.vacu.isGui;
enableFfmpegHeadless = enableFfmpeg && !config.vacu.isGui; enableFfmpegHeadless = enableFfmpeg && !config.vacu.isGui;
in in
{ vacu.packages = lib.mkMerge [ {
{ vacu.packages = lib.mkMerge [
borgbackup.enable = config.vacu.isDev && (pkgs.system != "aarch64-linux"); #borgbackup build is borken on aarch64 {
ffmpeg-vacu-full = { borgbackup.enable = config.vacu.isDev && (pkgs.system != "aarch64-linux"); # borgbackup build is borken on aarch64
enable = enableFfmpegFull; ffmpeg-vacu-full = {
package = pkgs.ffmpeg-full; enable = enableFfmpegFull;
overrides.libbluray = config.vacu.packages.libbluray-all.finalPackage; package = pkgs.ffmpeg-full;
}; overrides.libbluray = config.vacu.packages.libbluray-all.finalPackage;
ffmpeg-vacu-headless = {
enable = enableFfmpegHeadless;
package = pkgs.ffmpeg-headless;
overrides.libbluray = config.vacu.packages.libbluray-all.finalPackage;
};
libbluray-all = {
package = pkgs.libbluray;
overrides = {
withJava = true;
withAACS = true;
withBDplus = true;
}; };
}; ffmpeg-vacu-headless = {
inkscape-all = { enable = enableFfmpegHeadless;
package = pkgs.inkscape-with-extensions; package = pkgs.ffmpeg-headless;
# null actually means everything https://github.com/NixOS/nixpkgs/commit/5efd65b2d94b0ac0cf155e013b6747fa22bc04c3 overrides.libbluray = config.vacu.packages.libbluray-all.finalPackage;
overrides.inkscapeExtensions = null; };
}; libbluray-all = {
p7zip-unfree = { package = pkgs.libbluray;
package = pkgs.p7zip; overrides = {
overrides.enableUnfree = true; withJava = true;
}; withAACS = true;
vacu-units.package = config.vacu.units.finalPackage; withBDplus = true;
} };
(lib.mkIf config.vacu.isGui };
# pkgs for systems with a desktop GUI inkscape-all = {
'' package = pkgs.inkscape-with-extensions;
acpi # null actually means everything https://github.com/NixOS/nixpkgs/commit/5efd65b2d94b0ac0cf155e013b6747fa22bc04c3
anki overrides.inkscapeExtensions = null;
audacity };
arduino-ide p7zip-unfree = {
bitwarden-desktop package = pkgs.p7zip;
brave overrides.enableUnfree = true;
dino };
filezilla vacu-units.package = config.vacu.units.finalPackage;
ghidra }
gimp (lib.mkIf config.vacu.isGui
haruna # pkgs for systems with a desktop GUI
iio-sensor-proxy ''
inkscape-all acpi
jellyfin-media-player anki
josm audacity
kdePackages.elisa arduino-ide
kdePackages.kdenlive bitwarden-desktop
libreoffice-qt6-fresh brave
# librewolf dino
linphone filezilla
merkaartor ghidra
nextcloud-client gimp
nheko haruna
obsidian iio-sensor-proxy
openscad inkscape-all
openshot-qt jellyfin-media-player
orca-slicer josm
OSCAR kdePackages.elisa
prismlauncher kdePackages.kdenlive
shotcut libreoffice-qt6-fresh
signal-desktop # librewolf
svp linphone
thunderbird merkaartor
tremotesf nextcloud-client
ungoogled-chromium nheko
vlc obsidian
wayland-utils openscad
wev openshot-qt
wireshark orca-slicer
wl-clipboard OSCAR
'' prismlauncher
) shotcut
(lib.mkIf config.vacu.isDev signal-desktop
'' svp
thunderbird
tremotesf
ungoogled-chromium
vlc
wayland-utils
wev
wireshark
wl-clipboard
''
)
(lib.mkIf config.vacu.isDev ''
cargo cargo
gnumake gnumake
patchelf patchelf
@@ -96,97 +96,96 @@ in
ruby ruby
rustc rustc
rust-script rust-script
shellcheck
stdenv.cc stdenv.cc
'')
(lib.mkIf (!config.vacu.isMinimal)
# big pkgs for non-minimal systems
''
aircrack-ng
android-tools
bitwarden-cli
dmidecode
fido2-manage
flac
hdparm
home-manager
imagemagickBig
kanidm_1_5
libsmi
man
megatools
mercurial
minicom
mkvtoolnix-cli
# neovim => see common/nixvim.nix
net-snmp
nix-index
nix-inspect
nix-search-cli
nix-tree
nmap
nvme-cli
proxmark3
rclone
ripgrep-all
smartmontools
tcpdump
termscp
tshark
yt-dlp
''
)
# pkgs included everywhere
'' ''
) ddrescue
(lib.mkIf (!config.vacu.isMinimal) dig
# big pkgs for non-minimal systems dnsutils
'' ethtool
aircrack-ng file
android-tools gnutls
bitwarden-cli hostname
dmidecode htop
fido2-manage inetutils
flac iperf3
hdparm iputils
home-manager jq
imagemagickBig killall
kanidm_1_5 libossp_uuid # provides `uuid` binary
libsmi lsof
man mosh
megatools nano
mercurial ncdu
minicom netcat-openbsd
mkvtoolnix-cli nixos-rebuild
# neovim => see common/nixvim.nix p7zip-unfree
net-snmp pciutils
nix-index progress
nix-inspect psutils
nix-search-cli pv
nix-tree ripgrep
nmap rsync
nvme-cli screen
proxmark3 # sed => gnused
rclone shellvaculib
ripgrep-all # sops => should use `nr vacu#sops` instead
smartmontools sshfs
tcpdump ssh-to-age
termscp # tar => gnutar
tshark tmux
yt-dlp tree
'' tzdata
) # units => vacu-units
# pkgs included everywhere unzip
'' usbutils
ddrescue vacu-units
dig vim
dnsutils wget
ethtool zip
file
gnutls
hostname
htop
inetutils
iperf3
iputils
jq
killall
libossp_uuid # provides `uuid` binary
lsof
mosh
nano
ncdu
netcat-openbsd
nixos-rebuild
p7zip-unfree
pciutils
progress
psutils
pv
ripgrep
rsync
screen
# sed => gnused
shellvaculib
# sops => should use `nr vacu#sops` instead
sshfs
ssh-to-age
# tar => gnutar
tmux
tree
tzdata
# units => vacu-units
unzip
usbutils
vacu-units
vim
wget
zip
''
# packages that are in [`requiredPackages`][1] in nixos, but maybe not included in nix-on-droid
# [1]: https://github.com/NixOS/nixpkgs/blob/26d499fc9f1d567283d5d56fcf367edd815dba1d/nixos/modules/config/system-path.nix#L11
(lib.optionalAttrs (vacuModuleType == "nix-on-droid")
'' ''
# packages that are in [`requiredPackages`][1] in nixos, but maybe not included in nix-on-droid
# [1]: https://github.com/NixOS/nixpkgs/blob/26d499fc9f1d567283d5d56fcf367edd815dba1d/nixos/modules/config/system-path.nix#L11
(lib.optionalAttrs (vacuModuleType == "nix-on-droid") ''
acl acl
attr attr
bashInteractive bashInteractive
@@ -217,6 +216,6 @@ in
which which
xz xz
zstd zstd
'' '')
) ];
]; } }

View File

@@ -1,8 +1,4 @@
{ { lib, vacuModules, ... }:
lib,
vacuModules,
...
}:
{ {
imports = [ imports = [
vacuModules.knownHosts vacuModules.knownHosts
@@ -33,7 +29,10 @@
#colin's stuff #colin's stuff
"servo" = { "servo" = {
altNames = [ "git.uninsane.org" "uninsane.org" ]; altNames = [
"git.uninsane.org"
"uninsane.org"
];
isLan = true; isLan = true;
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfdSmFkrVT6DhpgvFeQKm3Fh9VKZ9DbLYOPOJWYQ0E8"; sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfdSmFkrVT6DhpgvFeQKm3Fh9VKZ9DbLYOPOJWYQ0E8";
}; };
@@ -135,9 +134,7 @@
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA6lX25mCy35tf1NpcHMAdeRgvT7l0Dw0FWBH3eX4TE2"; sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA6lX25mCy35tf1NpcHMAdeRgvT7l0Dw0FWBH3eX4TE2";
}; };
legtop = { legtop = {
altNames = [ altNames = [ "lt" ];
"lt"
];
isLan = true; isLan = true;
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKvunOGsmHg8igMGo0FpoXaegYI20wZylG8nsMFY4+JL"; sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKvunOGsmHg8igMGo0FpoXaegYI20wZylG8nsMFY4+JL";
}; };

View File

@@ -6,9 +6,7 @@
... ...
}: }:
lib.optionalAttrs (vacuModuleType == "nixos") { lib.optionalAttrs (vacuModuleType == "nixos") {
imports = [ imports = [ ../nixos-modules ];
../nixos-modules
];
options.vacu.underTest = lib.mkOption { options.vacu.underTest = lib.mkOption {
default = false; default = false;
type = lib.types.bool; type = lib.types.bool;

View File

@@ -22,12 +22,10 @@ in
}; };
config = { config = {
vacu.nixvimPkg = inputs.self.packages.${pkgs.system}.${nixvim-name}; vacu.nixvimPkg = inputs.self.packages.${pkgs.system}.${nixvim-name};
vacu.shell.functions = vacu.shell.functions = lib.mkIf (!config.vacu.isMinimal) {
lib.mkIf (!config.vacu.isMinimal) nvim-plain = ''${pkgs.neovim}/bin/nvim "$@"'';
{ nvim-nixvim = ''${config.vacu.nixvimPkg}/bin/nvim "$@"'';
nvim-plain = ''${pkgs.neovim}/bin/nvim "$@"''; nvim = ''nvim-nixvim "$@"'';
nvim-nixvim = ''${config.vacu.nixvimPkg}/bin/nvim "$@"''; };
nvim = ''nvim-nixvim "$@"'';
};
}; };
} }

View File

@@ -6,29 +6,30 @@
... ...
}: }:
let let
script = script =
name: name: content:
content: pkgs.writers.makeScriptWriter
pkgs.writers.makeScriptWriter { {
interpreter = lib.getExe pkgs.bashInteractive; interpreter = lib.getExe pkgs.bashInteractive;
check = lib.escapeShellArgs [ check = lib.escapeShellArgs [
(lib.getExe pkgs.shellcheck) (lib.getExe pkgs.shellcheck)
"--norc" "--norc"
"--severity=info" "--severity=info"
pkgs.shellvaculib.file pkgs.shellvaculib.file
]; ];
} "/bin/${name}" '' }
set -euo pipefail "/bin/${name}"
source ${lib.escapeShellArg pkgs.shellvaculib.file} ''
${content} set -euo pipefail
'' source ${lib.escapeShellArg pkgs.shellvaculib.file}
; ${content}
'';
simple = simple =
name: name: args:
args:
let let
binContents = ''#!${lib.getExe pkgs.bash} binContents = ''
exec ${lib.escapeShellArgs args} "$@"''; #!${lib.getExe pkgs.bash}
exec ${lib.escapeShellArgs args} "$@"'';
funcContents = '' funcContents = ''
local aliasName=${lib.escapeShellArg name} local aliasName=${lib.escapeShellArg name}
local replacementWords=(${lib.escapeShellArgs args}) local replacementWords=(${lib.escapeShellArgs args})
@@ -40,9 +41,7 @@ let
_comp_command_offset 0 _comp_command_offset 0
''; '';
in in
pkgs.runCommandLocal name { pkgs.runCommandLocal name { meta.mainProgram = name; } ''
meta.mainProgram = name;
} ''
mkdir -p $out/bin mkdir -p $out/bin
echo ${lib.escapeShellArg binContents} > $out/bin/${name} echo ${lib.escapeShellArg binContents} > $out/bin/${name}
out_base="$(dirname "$out")" out_base="$(dirname "$out")"
@@ -117,12 +116,30 @@ in
done done
nix shell "''${new_args[@]}" nix shell "''${new_args[@]}"
'') '')
(simple "sc" [systemctl]) (simple "sc" [ systemctl ])
(simple "scs" [systemctl "status" "--lines=20" "--full"]) (simple "scs" [
(simple "scc" [systemctl "cat"]) systemctl
(simple "scr" [systemctl "restart"]) "status"
(simple "jc" [journalctl "--pager-end"]) "--lines=20"
(simple "jcu" [journalctl "--pager-end" "-u"]) "--full"
])
(simple "scc" [
systemctl
"cat"
])
(simple "scr" [
systemctl
"restart"
])
(simple "jc" [
journalctl
"--pager-end"
])
(simple "jcu" [
journalctl
"--pager-end"
"-u"
])
(script "list-auto-roots" '' (script "list-auto-roots" ''
auto_roots="/nix/var/nix/gcroots/auto" auto_roots="/nix/var/nix/gcroots/auto"
svl_exact_args $# 0 svl_exact_args $# 0

View File

@@ -1,7 +1,4 @@
{ { pkgs, ... }:
pkgs,
...
}:
{ {
config.vacu = { config.vacu = {
shell.idempotentShellLines = '' shell.idempotentShellLines = ''

View File

@@ -9,27 +9,32 @@ let
domainPartRegex = "[[:alnum:]]([[:alnum:]-]{0,61}[[:alnum:]])?"; domainPartRegex = "[[:alnum:]]([[:alnum:]-]{0,61}[[:alnum:]])?";
domainRegex = ''^${domainPartRegex}(\.${domainPartRegex})*$''; domainRegex = ''^${domainPartRegex}(\.${domainPartRegex})*$'';
domainType = types.strMatching domainRegex; domainType = types.strMatching domainRegex;
hostsLines = hostsLines = lib.pipe config.vacu.staticNames [
lib.pipe config.vacu.staticNames [ (lib.mapAttrsToList (k: v: [ k ] ++ v))
(lib.mapAttrsToList (k: v: [k] ++ v)) (lib.filter (v: (builtins.length v) > 1))
(lib.filter (v: (builtins.length v) > 1)) (map (lib.concatStringsSep " "))
(map (lib.concatStringsSep " ")) (lib.concatStringsSep "\n")
(lib.concatStringsSep "\n") ];
];
ip4Seg = ''[0-9]{1,3}''; ip4Seg = ''[0-9]{1,3}'';
ip4Regex = lib.concatStringsSep ''\.'' [ ip4Seg ip4Seg ip4Seg ip4Seg ]; ip4Regex = lib.concatStringsSep ''\.'' [
ip4Seg
ip4Seg
ip4Seg
ip4Seg
];
ip6Regex = ''[0-9a-fA-F:]+''; ip6Regex = ''[0-9a-fA-F:]+'';
ipRegex = ''(${ip4Regex})|(${ip6Regex})''; ipRegex = ''(${ip4Regex})|(${ip6Regex})'';
in in
{ {
imports = [{ imports =
vacu.assertions = map (ip: [
{ {
assertion = (builtins.match ipRegex ip) != null; vacu.assertions = map (ip: {
message = ''config.vacu.staticNames: attr name "${ip}" is invalid''; assertion = (builtins.match ipRegex ip) != null;
message = ''config.vacu.staticNames: attr name "${ip}" is invalid'';
}) (builtins.attrNames config.vacu.staticNames);
} }
) (builtins.attrNames config.vacu.staticNames); ]
}]
++ lib.optional (vacuModuleType == "nixos") { networking.hosts = config.vacu.staticNames; } ++ lib.optional (vacuModuleType == "nixos") { networking.hosts = config.vacu.staticNames; }
++ lib.optional (vacuModuleType == "nix-on-droid") { ++ lib.optional (vacuModuleType == "nix-on-droid") {
environment.etc.hosts.text = '' environment.etc.hosts.text = ''
@@ -37,23 +42,48 @@ in
::1 localhost ::1 localhost
${hostsLines} ${hostsLines}
''; '';
} };
;
options.vacu.staticNames = mkOption { options.vacu.staticNames = mkOption {
type = types.attrsOf (types.listOf domainType); type = types.attrsOf (types.listOf domainType);
default = {}; default = { };
}; };
config.vacu.staticNames = { config.vacu.staticNames = {
"205.201.63.13" = [ "prop" "prophecy" "prophecy.shelvacu-static" ]; "205.201.63.13" = [
"prop"
"prophecy"
"prophecy.shelvacu-static"
];
"10.78.79.22" = [ "prophecy.t2d.lan.shelvacu-static" ]; "10.78.79.22" = [ "prophecy.t2d.lan.shelvacu-static" ];
"178.128.79.152" = [ "liam" "liam.shelvacu-static" ]; "178.128.79.152" = [
"172.83.159.53" = [ "trip" "triple-dezert" "triple-dezert.shelvacu-static" ]; "liam"
"liam.shelvacu-static"
];
"172.83.159.53" = [
"trip"
"triple-dezert"
"triple-dezert.shelvacu-static"
];
"10.78.79.237" = [ "triple-dezert.t2d.lan.shelvacu-static" ]; "10.78.79.237" = [ "triple-dezert.t2d.lan.shelvacu-static" ];
"205.201.63.12" = [ "servo" "uninsane-servo.shelvacu-static" ]; "205.201.63.12" = [
"10.78.79.1" = [ "vnopn" "vnopn.shelvacu-static" "vnopn.t2d.lan.shelvacu-static" ]; "servo"
"10.78.79.11" = [ "mmm" "mmm.shelvacu-static" "mmm.t2d.lan.shelvacu-static" ]; "uninsane-servo.shelvacu-static"
"10.78.79.69" = [ "oeto" "oeto.shelvacu-static" "oeto.t2d.lan.shelvacu-static" ]; ];
"10.78.79.1" = [
"vnopn"
"vnopn.shelvacu-static"
"vnopn.t2d.lan.shelvacu-static"
];
"10.78.79.11" = [
"mmm"
"mmm.shelvacu-static"
"mmm.t2d.lan.shelvacu-static"
];
"10.78.79.69" = [
"oeto"
"oeto.shelvacu-static"
"oeto.t2d.lan.shelvacu-static"
];
}; };
} }

View File

@@ -13,11 +13,14 @@ in
"git".A = singleton dnsData.tripPublicV4; "git".A = singleton dnsData.tripPublicV4;
"auth".A = singleton dnsData.tripPublicV4; "auth".A = singleton dnsData.tripPublicV4;
"wisdom".A = singleton dnsData.tripPublicV4; "wisdom".A = singleton dnsData.tripPublicV4;
"chat" = { ... }: { "chat" =
imports = [ dnsData.modules.liamMail ]; { ... }:
config.A = singleton dnsData.tripPublicV4; {
config.subdomains."duo-1745490301302-14f65157._domainkey".TXT = singleton "v=DKIM1; k=rsa; s=email; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDA/94Rh5eMPsKwGGolkleY1Rhh2Q6H22bfdGVu0lXpoHP1K7JxloWu/Ice2vVN/udztmPY+BK1x+5qubcGZKpPt1bC9amsXnyTXfKIMGD2CNd0tnaO54hmMOfv+lTA9YjF0X93tcQP3yUxJgJ9yPZcalFl/bBAqv4/lUVLYFeIVQIDAQAB"; imports = [ dnsData.modules.liamMail ];
}; config.A = singleton dnsData.tripPublicV4;
config.subdomains."duo-1745490301302-14f65157._domainkey".TXT =
singleton "v=DKIM1; k=rsa; s=email; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDA/94Rh5eMPsKwGGolkleY1Rhh2Q6H22bfdGVu0lXpoHP1K7JxloWu/Ice2vVN/udztmPY+BK1x+5qubcGZKpPt1bC9amsXnyTXfKIMGD2CNd0tnaO54hmMOfv+lTA9YjF0X93tcQP3yUxJgJ9yPZcalFl/bBAqv4/lUVLYFeIVQIDAQAB";
};
"gabriel-dropout".A = singleton dnsData.tripPublicV4; "gabriel-dropout".A = singleton dnsData.tripPublicV4;
"_acme-challenge".CNAME = singleton "199b8aa4-bc9f-4f43-88bf-3f613f62b663.auwwth.dis8.net."; "_acme-challenge".CNAME = singleton "199b8aa4-bc9f-4f43-88bf-3f613f62b663.auwwth.dis8.net.";
}; };

View File

@@ -1,6 +1,11 @@
{ lib, config, dns, ... }: {
lib,
config,
dns,
...
}:
let let
s = v: [v]; s = v: [ v ];
inherit (config.vacu) dnsData; inherit (config.vacu) dnsData;
comb = dns.lib.combinators; comb = dns.lib.combinators;
trip_ips = s dnsData.tripPublicV4; trip_ips = s dnsData.tripPublicV4;
@@ -28,7 +33,7 @@ in
value = "mailto:caa-violation@shelvacu.com"; value = "mailto:caa-violation@shelvacu.com";
} }
]; ];
NS = [ "ns2.afraid.org" ]; #note: appends to NS records from modules.cloudns NS = [ "ns2.afraid.org" ]; # note: appends to NS records from modules.cloudns
subdomains = { subdomains = {
"*".A = trip_ips; "*".A = trip_ips;
# "2esrever.zt".A = s "10.244.46.71"; # "2esrever.zt".A = s "10.244.46.71";

View File

@@ -157,7 +157,10 @@
}: }:
let let
inputs = mkInputs { inherit unstable inp; }; inputs = mkInputs { inherit unstable inp; };
pkgs = mkPkgs { useUnstable = unstable; inherit system; }; pkgs = mkPkgs {
useUnstable = unstable;
inherit system;
};
in in
inputs.nixpkgs.lib.nixosSystem { inputs.nixpkgs.lib.nixosSystem {
specialArgs = { specialArgs = {
@@ -193,7 +196,10 @@
nixosConfigurations = { nixosConfigurations = {
triple-dezert = mkNixosConfig { triple-dezert = mkNixosConfig {
module = ./triple-dezert; module = ./triple-dezert;
inp = [ "most-winningest" "sops-nix" ]; inp = [
"most-winningest"
"sops-nix"
];
}; };
compute-deck = mkNixosConfig { compute-deck = mkNixosConfig {
module = ./compute-deck; module = ./compute-deck;
@@ -232,7 +238,10 @@
prophecy = mkNixosConfig { prophecy = mkNixosConfig {
module = ./prophecy; module = ./prophecy;
system = "x86_64-linux"; system = "x86_64-linux";
inp = [ "impermanence" "sops-nix" ]; inp = [
"impermanence"
"sops-nix"
];
}; };
}; };
@@ -272,9 +281,7 @@
imports = [ imports = [
commonTestModule commonTestModule
./tests/${name} ./tests/${name}
{ { node.specialArgs.inputs = self.nixosConfigurations.${name}._module.specialArgs.inputs; }
node.specialArgs.inputs = self.nixosConfigurations.${name}._module.specialArgs.inputs;
}
]; ];
}; };
checksFromConfig = plain.config.vacu.checks; checksFromConfig = plain.config.vacu.checks;
@@ -372,7 +379,14 @@
imports = [ ./nixvim ]; imports = [ ./nixvim ];
_module.args = { inherit pkgs-unstable; }; _module.args = { inherit pkgs-unstable; };
}; };
extraSpecialArgs = { inherit unstable inputs system minimal; }; extraSpecialArgs = {
inherit
unstable
inputs
system
minimal
;
};
}; };
nixpkgs-args = { nixpkgs-args = {
inherit system; inherit system;
@@ -384,11 +398,12 @@
_plain = mkPlain pkgs-unstable; _plain = mkPlain pkgs-unstable;
plain = _plain.config.vacu.withAsserts _plain; plain = _plain.config.vacu.withAsserts _plain;
treefmtEval = inputs.treefmt-nix.lib.evalModule pkgs-unstable ./treefmt.nix; treefmtEval = inputs.treefmt-nix.lib.evalModule pkgs-unstable ./treefmt.nix;
formatter = treefmtEval.config.build.wrapper;
vacuPackagePaths = import ./packages; vacuPackagePaths = import ./packages;
vacuPackages = builtins.intersectAttrs vacuPackagePaths pkgs-stable; vacuPackages = builtins.intersectAttrs vacuPackagePaths pkgs-stable;
in in
{ {
formatter = treefmtEval.config.build.wrapper; inherit formatter;
apps.sops = { apps.sops = {
type = "app"; type = "app";
program = lib.getExe self.packages.${system}.wrappedSops; program = lib.getExe self.packages.${system}.wrappedSops;
@@ -409,6 +424,7 @@
inherit pkgs lib inputs; inherit pkgs lib inputs;
inherit (plain) config; inherit (plain) config;
}; };
inherit formatter;
generated = pkgs-stable.linkFarm "generated" { generated = pkgs-stable.linkFarm "generated" {
nixpkgs = "${inputs.nixpkgs}"; nixpkgs = "${inputs.nixpkgs}";
"liam-test/hints.py" = pkgs.writeText "hints.py" ( "liam-test/hints.py" = pkgs.writeText "hints.py" (
@@ -424,12 +440,26 @@
builtins.dirOf self.checks.x86_64-linux.liam.nodes.checker.vacu.mailtest.smtp.interpreter builtins.dirOf self.checks.x86_64-linux.liam.nodes.checker.vacu.mailtest.smtp.interpreter
); );
}; };
host-pxe-installer = pkgs.callPackage ./host-pxe-installer.nix { nixosInstaller = self.nixosConfigurations.shel-installer-pxe; }; host-pxe-installer = pkgs.callPackage ./host-pxe-installer.nix {
nixosInstaller = self.nixosConfigurations.shel-installer-pxe;
};
liam-sieve-script = self.nixosConfigurations.liam.config.vacu.liam-sieve-script; liam-sieve-script = self.nixosConfigurations.liam.config.vacu.liam-sieve-script;
nixvim = mkNixvim { unstable = false; minimal = false; }; nixvim = mkNixvim {
nixvim-unstable = mkNixvim { unstable = true; minimal = false; }; unstable = false;
nixvim-minimal = mkNixvim { unstable = false; minimal = true; }; minimal = false;
nixvim-unstable-minimal = mkNixvim { unstable = true; minimal = true; }; };
nixvim-unstable = mkNixvim {
unstable = true;
minimal = false;
};
nixvim-minimal = mkNixvim {
unstable = false;
minimal = true;
};
nixvim-unstable-minimal = mkNixvim {
unstable = true;
minimal = true;
};
sopsConfig = plain.config.vacu.sopsConfigFile; sopsConfig = plain.config.vacu.sopsConfigFile;
sourceTree = plain.config.vacu.sourceTree; sourceTree = plain.config.vacu.sourceTree;
units = plain.config.vacu.units.finalPackage; units = plain.config.vacu.units.finalPackage;

View File

@@ -1,5 +1,10 @@
# everything to interact with my apex flex, pcsc stuff, fido2 stuff, etc # everything to interact with my apex flex, pcsc stuff, fido2 stuff, etc
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
# to match package used in config.services.pcscd, unfortunately not exposed like usual # to match package used in config.services.pcscd, unfortunately not exposed like usual
pcsclite-pkg = if config.security.polkit.enable then pkgs.pcscliteWithPolkit else pkgs.pcsclite; pcsclite-pkg = if config.security.polkit.enable then pkgs.pcscliteWithPolkit else pkgs.pcsclite;

View File

@@ -7,7 +7,7 @@
}: }:
let let
build = nixosInstaller.config.system.build; build = nixosInstaller.config.system.build;
script = writers.writeBashBin "host-pixie-installer" {} '' script = writers.writeBashBin "host-pixie-installer" { } ''
set -euo pipefail set -euo pipefail
exec ${lib.getExe pixiecore} boot ${build.kernel}/bzImage ${build.netbootRamdisk}/initrd "$@" exec ${lib.getExe pixiecore} boot ${build.kernel}/bzImage ${build.netbootRamdisk}/initrd "$@"
''; '';
@@ -15,8 +15,9 @@ in
(linkFarm "host-pixie-installer" { (linkFarm "host-pixie-installer" {
"bin/host-pixie-installer" = "${script}/bin/host-pixie-installer"; "bin/host-pixie-installer" = "${script}/bin/host-pixie-installer";
inherit (build) kernel netbootRamdisk; inherit (build) kernel netbootRamdisk;
}).overrideAttrs (old: { }).overrideAttrs
meta = { (old: {
mainProgram = "host-pixie-installer"; meta = {
}; mainProgram = "host-pixie-installer";
}) };
})

View File

@@ -1,8 +1,4 @@
{ { config, lib, ... }:
config,
lib,
...
}:
{ {
# this is an installer image, created anew every time. There's no state we need to worry about messing up # this is an installer image, created anew every time. There's no state we need to worry about messing up
system.stateVersion = config.system.nixos.version; system.stateVersion = config.system.nixos.version;

View File

@@ -1,7 +1,4 @@
{ { modulesPath, ... }:
modulesPath,
...
}:
{ {
imports = [ imports = [
./common ./common

View File

@@ -1,7 +1,4 @@
{ { modulesPath, ... }:
modulesPath,
...
}:
{ {
imports = [ imports = [
./common ./common

View File

@@ -487,10 +487,10 @@ let
"X-GitLab-Project" "X-GitLab-Project"
])} ])}
${pure_flags [ "git-uninsane" "git" "not-spamish" "B" ] (envelope_is "git-uninsane@shelvacu.com")} ${pure_flags [ "git-uninsane" "git" "not-spamish" "B" ] (envelope_is "git-uninsane@shelvacu.com")}
${pure_flags [ "github" "git" "not-spamish" "B" ] ( ${pure_flags [ "github" "git" "not-spamish" "B" ] (header_matches "List-Id" "*<*.github.com>")}
header_matches "List-Id" "*<*.github.com>" ${pure_flags [ "mailing-list-by-envelope" "not-spamish" "B" ] (
envelope_matches "*-ml@shelvacu.com"
)} )}
${pure_flags [ "mailing-list-by-envelope" "not-spamish" "B" ] (envelope_matches "*-ml@shelvacu.com")}
${pure_flags [ "discourse" "not-spamish" "B" ] (exists "X-Discourse-Post-Id")} ${pure_flags [ "discourse" "not-spamish" "B" ] (exists "X-Discourse-Post-Id")}
${pure_flags [ "agora" "not-spamish" ] (envelope_is "agora@shelvacu.com")} ${pure_flags [ "agora" "not-spamish" ] (envelope_is "agora@shelvacu.com")}
@@ -511,51 +511,60 @@ let
} }
${pure_flags "gmail-fwd" (envelope_is "gmailfwd-fc2e10bec8b2@shelvacu.com")} ${pure_flags "gmail-fwd" (envelope_is "gmailfwd-fc2e10bec8b2@shelvacu.com")}
${pure_flags ["aliexpress-delivered" "B"] (allof [ ${pure_flags [ "aliexpress-delivered" "B" ] (allof [
(from_is "transaction@notice.aliexpress.com") (from_is "transaction@notice.aliexpress.com")
(header_matches "Subject" "Order * has been signed for") (header_matches "Subject" "Order * has been signed for")
])} ])}
${pure_flags ["aliexpress" "C"] (allof [ ${pure_flags [ "aliexpress" "C" ] (allof [
(from_is [ (from_is [
"transaction@notice.aliexpress.com" "transaction@notice.aliexpress.com"
"aliexpress@notice.aliexpress.com" "aliexpress@notice.aliexpress.com"
]) ])
''not hasflag "aliexpress-delivered"'' ''not hasflag "aliexpress-delivered"''
])} ])}
${pure_flags ["brandcrowd" "D"] (envelope_is "brandcrowd@shelvacu.com")} ${pure_flags [ "brandcrowd" "D" ] (envelope_is "brandcrowd@shelvacu.com")}
${pure_flags ["cpapsupplies" "D"] (envelope_is "cpapsupplies@shelvacu.com")} ${pure_flags [ "cpapsupplies" "D" ] (envelope_is "cpapsupplies@shelvacu.com")}
${pure_flags ["genshin" "D"] (envelope_is "genshin@shelvacu.com")} ${pure_flags [ "genshin" "D" ] (envelope_is "genshin@shelvacu.com")}
${pure_flags ["jork" "B"] (envelope_is "jork@shelvacu.com")} ${pure_flags [ "jork" "B" ] (envelope_is "jork@shelvacu.com")}
${pure_flags ["patreon" "B" "not-spamish"] (envelope_is "patreon@shelvacu.com")} ${pure_flags [ "patreon" "B" "not-spamish" ] (envelope_is "patreon@shelvacu.com")}
${pure_flags ["rsb" "B"] (from_is "support@rapidseedbox.com")} ${pure_flags [ "rsb" "B" ] (from_is "support@rapidseedbox.com")}
${pure_flags ["fresh-avocado-dis8" "D"] (envelope_is "fresh.avocado@dis8.net")} ${pure_flags [ "fresh-avocado-dis8" "D" ] (envelope_is "fresh.avocado@dis8.net")}
${pure_flags ["discord" "A"] (envelope_matches "discord@*")} ${pure_flags [ "discord" "A" ] (envelope_matches "discord@*")}
${pure_flags ["za-sa" "D"] (from_matches ["*@*.sa.com" "*@*.za.com"])} ${pure_flags [ "za-sa" "D" ] (from_matches [
${pure_flags ["localdomain" "D"] (from_matches ["*@*.local" "*@*.localdomain"])} "*@*.sa.com"
${pure_flags ["helium" "D"] (envelope_is "creepyface@dis8.net")} "*@*.za.com"
${pure_flags ["sharkmood" "C"] (envelope_is "sharkmood@dis8.net")} ])}
${pure_flags ["im-not-district-158" "D"] (envelope_is [ ${pure_flags [ "localdomain" "D" ] (from_matches [
"*@*.local"
"*@*.localdomain"
])}
${pure_flags [ "helium" "D" ] (envelope_is "creepyface@dis8.net")}
${pure_flags [ "sharkmood" "C" ] (envelope_is "sharkmood@dis8.net")}
${pure_flags [ "im-not-district-158" "D" ] (envelope_is [
"khamar.anderson@dis8.net" "khamar.anderson@dis8.net"
"pbooth@dis8.net" "pbooth@dis8.net"
"sgaylor@dis8.net" "sgaylor@dis8.net"
])} ])}
${pure_flags ["next-level-burger" "D"] (header_matches "From" "*Next Level Burger*")} ${pure_flags [ "next-level-burger" "D" ] (header_matches "From" "*Next Level Burger*")}
${pure_flags ["lyft" "D"] (envelope_is "lyft@shelvacu.com")} ${pure_flags [ "lyft" "D" ] (envelope_is "lyft@shelvacu.com")}
${pure_flags ["coursera" "D"] (from_matches "*.*.coursera.org")} ${pure_flags [ "coursera" "D" ] (from_matches "*.*.coursera.org")}
${pure_flags ["taskrabbit" "D"] (envelope_is "taskrabbit@shelvacu.com")} ${pure_flags [ "taskrabbit" "D" ] (envelope_is "taskrabbit@shelvacu.com")}
${pure_flags ["subscribestar_code" "A"] (allof [ ${pure_flags [ "subscribestar_code" "A" ] (allof [
(envelope_is "subscribestar@shelvacu.com") (envelope_is "subscribestar@shelvacu.com")
(subject_is "Your authentication code") (subject_is "Your authentication code")
])} ])}
${pure_flags ["spamish-by-headers" "C"] [ ${pure_flags
(anyof [ [ "spamish-by-headers" "C" ]
(header_is "Precedence" "bulk") [
(exists "List-Unsubscribe") (anyof [
(exists "List-Unsubscribe-Post") (header_is "Precedence" "bulk")
]) (exists "List-Unsubscribe")
''not hasflag "not-spamish"'' (exists "List-Unsubscribe-Post")
]} ])
''not hasflag "not-spamish"''
]
}
if hasflag "agora" { if hasflag "agora" {
${fileinto "M.agora"} ${fileinto "M.agora"}

View File

@@ -27,6 +27,6 @@
restartUnits = [ "postfix.service" ]; restartUnits = [ "postfix.service" ];
owner = config.services.postfix.user; owner = config.services.postfix.user;
}; };
gnupg.sshKeyPaths = []; #explicitly empty to disable gnupg; I don't use it and it takes up space on minimal configs gnupg.sshKeyPaths = [ ]; # explicitly empty to disable gnupg; I don't use it and it takes up space on minimal configs
}; };
} }

View File

@@ -1,5 +1,9 @@
let let
directoryListing = builtins.removeAttrs (builtins.readDir ./.) [ "default.nix" ]; directoryListing = builtins.removeAttrs (builtins.readDir ./.) [ "default.nix" ];
packagePaths = builtins.mapAttrs (k: v: assert v == "directory"; ./${k}/module.nix) directoryListing; packagePaths = builtins.mapAttrs (
k: v:
assert v == "directory";
./${k}/module.nix
) directoryListing;
in in
packagePaths packagePaths

View File

@@ -10,54 +10,49 @@ let
inherit (vaculib) mkOutOption; inherit (vaculib) mkOutOption;
nameishRegex = ''[a-z0-9_\.-]+''; nameishRegex = ''[a-z0-9_\.-]+'';
nameish = types.strMatching nameishRegex; nameish = types.strMatching nameishRegex;
hostModule = { hostModule =
name, { name, config, ... }:
config, let
... fullLanNames = lib.optional (config.isLan) "${config.primaryName}.t2d.lan";
}: in
let {
fullLanNames = lib.optional (config.isLan) "${config.primaryName}.t2d.lan"; options = {
in primaryName = mkOption {
{ type = nameish;
options = { default = name;
primaryName = mkOption { };
type = nameish; altNames = mkOption {
default = name; type = types.listOf nameish;
default = [ ];
};
isLan = mkOption {
type = types.bool;
default = false;
};
finalNames = mkOption {
type = types.listOf nameish;
readOnly = true;
};
primaryIp = mkOption {
type = types.nullOr nameish;
default = null;
};
altIps = mkOption {
type = types.listOf nameish;
default = [ ];
};
finalIps = mkOption {
type = types.listOf nameish;
readOnly = true;
};
makeStaticHostsEntry = mkOption { type = types.bool; };
}; };
altNames = mkOption { config = {
type = types.listOf nameish; finalNames = lib.unique ([ config.primaryName ] ++ config.altNames ++ fullLanNames);
default = []; finalIps = lib.unique ((lib.optional (config.primaryIp != null) config.primaryIp) ++ config.altIps);
}; makeStaticHostsEntry = lib.mkDefault (config.primaryIp != null);
isLan = mkOption {
type = types.bool;
default = false;
};
finalNames = mkOption {
type = types.listOf nameish;
readOnly = true;
};
primaryIp = mkOption {
type = types.nullOr nameish;
default = null;
};
altIps = mkOption {
type = types.listOf nameish;
default = [];
};
finalIps = mkOption {
type = types.listOf nameish;
readOnly = true;
};
makeStaticHostsEntry = mkOption {
type = types.bool;
}; };
}; };
config = {
finalNames = lib.unique ([config.primaryName] ++ config.altNames ++ fullLanNames);
finalIps = lib.unique ((lib.optional (config.primaryIp != null) config.primaryIp) ++ config.altIps);
makeStaticHostsEntry = lib.mkDefault (config.primaryIp != null);
};
};
etcHostsParts = lib.concatMap ( etcHostsParts = lib.concatMap (
hostMod: hostMod:
lib.optional hostMod.makeStaticHostsEntry ( lib.optional hostMod.makeStaticHostsEntry (
@@ -71,12 +66,16 @@ in
options.vacu = { options.vacu = {
hosts = mkOption { hosts = mkOption {
type = types.attrsOf (types.submodule hostModule); type = types.attrsOf (types.submodule hostModule);
default = {}; default = { };
}; };
etcHostsText = mkOutOption etcHostsText; etcHostsText = mkOutOption etcHostsText;
}; };
config = {} config =
// lib.optionalAttrs (vacuModuleType == "nixos") { networking.extraHosts = config.vacu.etcHostsText; } { }
// lib.optionalAttrs (vacuModuleType == "nix-on-droid") { environment.etc.hosts.text = config.vacu.etcHostsText; } // lib.optionalAttrs (vacuModuleType == "nixos") {
; networking.extraHosts = config.vacu.etcHostsText;
}
// lib.optionalAttrs (vacuModuleType == "nix-on-droid") {
environment.etc.hosts.text = config.vacu.etcHostsText;
};
} }

View File

@@ -42,15 +42,16 @@ let
enable = lib.mkOverride 900 true; # more important than mkDefault, less important than setting explicitly enable = lib.mkOverride 900 true; # more important than mkDefault, less important than setting explicitly
nameToPackageSet = nameToPackageSet =
name: name:
let pieces = lib.splitString "." name; in let
pieces = lib.splitString "." name;
in
{ {
name = lib.last pieces; name = lib.last pieces;
value = { value = {
inherit enable; inherit enable;
package = lib.mkDefault (lib.attrByPath pieces (throw "Could not find package pkgs.${name}") pkgs); package = lib.mkDefault (lib.attrByPath pieces (throw "Could not find package pkgs.${name}") pkgs);
}; };
} };
;
listToPackageSet = listToPackageSet =
from: from:
lib.pipe from [ lib.pipe from [
@@ -69,40 +70,28 @@ let
} }
)) ))
builtins.listToAttrs builtins.listToAttrs
] ];
; removeComments = s: builtins.head (lib.splitString "#" s);
removeComments = nonEmpty = s: (builtins.stringLength s) > 0;
s: stringToPackageSet =
builtins.head (lib.splitString "#" s)
;
nonEmpty =
s:
(builtins.stringLength s) > 0
;
stringToPackageSet =
from: from:
lib.pipe from [ lib.pipe from [
(lib.splitString "\n") (lib.splitString "\n")
(map removeComments) (map removeComments)
(map lib.trim) (map lib.trim)
(builtins.filter nonEmpty) (builtins.filter nonEmpty)
(map nameToPackageSet) (map nameToPackageSet)
builtins.listToAttrs builtins.listToAttrs
] ];
; listOrStringToPackageSet =
listOrStringToPackageSet = from: from:
if builtins.isString from then if builtins.isString from then
stringToPackageSet from stringToPackageSet from
else if builtins.isList from then else if builtins.isList from then
listToPackageSet from listToPackageSet from
else else
throw "this should never happen; should be a list or string" throw "this should never happen; should be a list or string";
; listTy = types.listOf (types.either types.str types.package);
listTy =
types.listOf (
types.either types.str types.package
)
;
in in
{ {
options = { options = {
@@ -116,10 +105,14 @@ in
}; };
}; };
config = { config =
vacu.finalPackageList = enabledPkgs; {
} vacu.finalPackageList = enabledPkgs;
// lib.optionalAttrs (vacuModuleType == "nixos") { environment.systemPackages = config.vacu.finalPackageList; } }
// lib.optionalAttrs (vacuModuleType == "nix-on-droid") { environment.packages = config.vacu.finalPackageList; } // lib.optionalAttrs (vacuModuleType == "nixos") {
; environment.systemPackages = config.vacu.finalPackageList;
}
// lib.optionalAttrs (vacuModuleType == "nix-on-droid") {
environment.packages = config.vacu.finalPackageList;
};
} }

View File

@@ -8,55 +8,52 @@
... ...
}: }:
let let
inherit (lib) inherit (lib) mkOption types;
mkOption
types
;
inherit (vaculib) mkOutOption; inherit (vaculib) mkOutOption;
knownHostsAddonModule = { config, ... }: { knownHostsAddonModule =
options = { { config, ... }:
sshKeys = mkOption { {
type = types.coercedTo types.str lib.singleton (types.listOf types.str); options = {
default = []; sshKeys = mkOption {
type = types.coercedTo types.str lib.singleton (types.listOf types.str);
default = [ ];
};
sshUsername = mkOption {
type = types.nullOr types.str;
default = null;
};
sshPort = mkOption {
type = types.port;
default = 22;
};
sshHostname = mkOption { type = types.str; };
sshAliases = mkOption {
type = types.listOf types.str;
default = [ ];
};
}; };
sshUsername = mkOption { config = {
type = types.nullOr types.str; sshHostname = lib.mkDefault (
default = null; if (config.primaryIp != null) then config.primaryIp else config.primaryName
}; );
sshPort = mkOption { altNames = [ config.sshHostname ];
type = types.port; sshAliases = [ config.primaryName ];
default = 22;
};
sshHostname = mkOption {
type = types.str;
};
sshAliases = mkOption {
type = types.listOf types.str;
default = [];
}; };
}; };
config = {
sshHostname = lib.mkDefault (if (config.primaryIp != null) then config.primaryIp else config.primaryName);
altNames = [ config.sshHostname ];
sshAliases = [ config.primaryName ];
};
};
knownHostsParts = lib.concatMap ( knownHostsParts = lib.concatMap (
hostMod: hostMod:
let let
knownNames = map (name: if hostMod.sshPort == 22 then name else "[${name}]:${toString hostMod.sshPort}") (hostMod.finalNames ++ hostMod.finalIps); knownNames = map (
name: if hostMod.sshPort == 22 then name else "[${name}]:${toString hostMod.sshPort}"
) (hostMod.finalNames ++ hostMod.finalIps);
in in
map ( map (sshKey: lib.concatStringsSep "," knownNames + " " + sshKey) hostMod.sshKeys
sshKey:
lib.concatStringsSep "," knownNames
+ " "
+ sshKey
) hostMod.sshKeys
) (builtins.attrValues config.vacu.hosts); ) (builtins.attrValues config.vacu.hosts);
knownHostsText = lib.concatStringsSep "\n" knownHostsParts; knownHostsText = lib.concatStringsSep "\n" knownHostsParts;
hostConfigParts = builtins.concatMap ( hostConfigParts = builtins.concatMap (
hostMod: hostMod:
map (name: map (
name:
"Host ${name}\n" "Host ${name}\n"
+ lib.optionalString (hostMod.sshUsername != null) " User ${hostMod.sshUsername}\n" + lib.optionalString (hostMod.sshUsername != null) " User ${hostMod.sshUsername}\n"
+ lib.optionalString (hostMod.sshHostname != name) " HostName ${hostMod.sshHostname}\n" + lib.optionalString (hostMod.sshHostname != name) " HostName ${hostMod.sshHostname}\n"
@@ -76,17 +73,21 @@ in
}; };
vacu.ssh.config = mkOption { type = types.lines; }; vacu.ssh.config = mkOption { type = types.lines; };
}; };
config = { config =
vacu.ssh.config = lib.mkMerge [ {
(lib.mkBefore hostConfigText) vacu.ssh.config = lib.mkMerge [
(lib.mkAfter '' (lib.mkBefore hostConfigText)
Host * (lib.mkAfter ''
User shelvacu Host *
GlobalKnownHostsFile ${pkgs.writeText "known_hosts" config.vacu.ssh.knownHostsText} User shelvacu
'') GlobalKnownHostsFile ${pkgs.writeText "known_hosts" config.vacu.ssh.knownHostsText}
]; '')
} ];
// lib.optionalAttrs (vacuModuleType == "nixos") { environment.etc."ssh/ssh_config".text = lib.mkForce config.vacu.ssh.config; } }
// lib.optionalAttrs (vacuModuleType == "nix-on-droid") { environment.etc."ssh/ssh_config".text = config.vacu.ssh.config; } // lib.optionalAttrs (vacuModuleType == "nixos") {
; environment.etc."ssh/ssh_config".text = lib.mkForce config.vacu.ssh.config;
}
// lib.optionalAttrs (vacuModuleType == "nix-on-droid") {
environment.etc."ssh/ssh_config".text = config.vacu.ssh.config;
};
} }

View File

@@ -23,6 +23,8 @@ in
vacu.isContainer = mkOutOption (systemKind == "container"); vacu.isContainer = mkOutOption (systemKind == "container");
vacu.isMinimal = mkOutOption (systemKind == "minimal" || systemKind == "container"); vacu.isMinimal = mkOutOption (systemKind == "minimal" || systemKind == "container");
vacu.isGui = mkOutOption (systemKind == "desktop" || systemKind == "laptop"); vacu.isGui = mkOutOption (systemKind == "desktop" || systemKind == "laptop");
vacu.isDev = mkOutOption (systemKind == "desktop" || systemKind == "laptop" || systemKind == "server"); vacu.isDev = mkOutOption (
systemKind == "desktop" || systemKind == "laptop" || systemKind == "server"
);
}; };
} }

View File

@@ -1,5 +1 @@
{ { imports = [ ./genieacs.nix ]; }
imports = [
./genieacs.nix
];
}

View File

@@ -5,80 +5,88 @@
... ...
}: }:
let let
inherit (lib) mkEnableOption mkOption types flip; inherit (lib)
mkEnableOption
mkOption
types
flip
;
cfg = config.services.genieacs; cfg = config.services.genieacs;
enableAny = cfg.cwmp.enable || cfg.nbi.enable || cfg.fs.enable || cfg.ui.enable; enableAny = cfg.cwmp.enable || cfg.nbi.enable || cfg.fs.enable || cfg.ui.enable;
extensionsPkg = pkgs.linkFarmFromDrvs "genieacs-extensions" cfg.extensions; extensionsPkg = pkgs.linkFarmFromDrvs "genieacs-extensions" cfg.extensions;
envVarsType = types.attrsOf (types.nullOr (types.either types.str types.int)); envVarsType = types.attrsOf (types.nullOr (types.either types.str types.int));
commonOptsModule = { serviceShortName, config, ... }: commonOptsModule =
let { serviceShortName, config, ... }:
environmentVarsUnprefixed = { let
WORKER_PROCESSES = config.workerProcesses; environmentVarsUnprefixed = {
PORT = config.port; WORKER_PROCESSES = config.workerProcesses;
INTERFACE = config.interface; PORT = config.port;
SSL_CERT = config.sslCert; INTERFACE = config.interface;
SSL_KEY = config.sslKey; SSL_CERT = config.sslCert;
ACCESS_LOG_FILE = config.accessLogFile; SSL_KEY = config.sslKey;
LOG_FILE = config.eventLogFile; ACCESS_LOG_FILE = config.accessLogFile;
}; LOG_FILE = config.eventLogFile;
serviceNameCaps = lib.toUpper serviceShortName;
environmentVars = lib.concatMapAttrs (key: val: { "GENIEACS_${serviceNameCaps}_${key}" = val; }) environmentVarsUnprefixed;
in
{
options = {
enable = mkOption {
type = types.bool;
description = "Enable GenieACS ${serviceShortName} service";
default = false;
};
accessLogFile = mkOption {
type = types.nullOr types.path;
default = "/var/log/genieacs/genieacs-${serviceShortName}-access.log";
description = "File to log incoming requests for genieacs-${serviceShortName}. If `null`, logs will go to stdout. This sets `GENIEACS_${serviceNameCaps}_ACCESS_LOG_FILE`";
};
workerProcesses = mkOption {
type = types.int;
default = 0;
description = "The number of worker processes to spawn for genieacs-${serviceShortName}. A value of 0 means as many as there are CPU cores available. This sets `GENIEACS_${serviceNameCaps}_WORKER_PROCESSES`";
};
port = mkOption {
type = types.port;
description = "The TCP port that genieacs-${serviceShortName} listens on. This sets `GENIEACS_${serviceNameCaps}_PORT`";
};
interface = mkOption {
type = types.str;
default = "::";
description = "The network interface (ip address, really) that genieacs-${serviceShortName} binds to. This sets `GENIEACS_${serviceNameCaps}_INTERFACE`";
};
sslCert = mkOption {
type = types.nullOr types.path;
default = null;
description = "Path to certificate file. If `null`, non-secure HTTP will be used. This sets `GENIEACS_${serviceNameCaps}_SSL_CERT`";
};
sslKey = mkOption {
type = types.nullOr types.path;
default = null;
description = "Path to certificate key file. If `null`, non-secure HTTP will be used. This sets `GENIEACS_${serviceNameCaps}_SSL_KEY`";
};
eventLogFile = mkOption {
type = types.nullOr types.path;
default = null;
description = "File to log process related events for genieacs-${serviceShortName}. If `null`, logs will go to stderr. This sets `GENIEACS_${serviceNameCaps}_LOG_FILE`";
};
extraEnv = mkOption {
type = envVarsType;
default = { };
example = ''{ NODE_OPTIONS = "--enable-source-maps"; }'';
}; };
serviceNameCaps = lib.toUpper serviceShortName;
environmentVars = lib.concatMapAttrs (key: val: {
"GENIEACS_${serviceNameCaps}_${key}" = val;
}) environmentVarsUnprefixed;
in
{
options = {
enable = mkOption {
type = types.bool;
description = "Enable GenieACS ${serviceShortName} service";
default = false;
};
accessLogFile = mkOption {
type = types.nullOr types.path;
default = "/var/log/genieacs/genieacs-${serviceShortName}-access.log";
description = "File to log incoming requests for genieacs-${serviceShortName}. If `null`, logs will go to stdout. This sets `GENIEACS_${serviceNameCaps}_ACCESS_LOG_FILE`";
};
workerProcesses = mkOption {
type = types.int;
default = 0;
description = "The number of worker processes to spawn for genieacs-${serviceShortName}. A value of 0 means as many as there are CPU cores available. This sets `GENIEACS_${serviceNameCaps}_WORKER_PROCESSES`";
};
port = mkOption {
type = types.port;
description = "The TCP port that genieacs-${serviceShortName} listens on. This sets `GENIEACS_${serviceNameCaps}_PORT`";
};
interface = mkOption {
type = types.str;
default = "::";
description = "The network interface (ip address, really) that genieacs-${serviceShortName} binds to. This sets `GENIEACS_${serviceNameCaps}_INTERFACE`";
};
sslCert = mkOption {
type = types.nullOr types.path;
default = null;
description = "Path to certificate file. If `null`, non-secure HTTP will be used. This sets `GENIEACS_${serviceNameCaps}_SSL_CERT`";
};
sslKey = mkOption {
type = types.nullOr types.path;
default = null;
description = "Path to certificate key file. If `null`, non-secure HTTP will be used. This sets `GENIEACS_${serviceNameCaps}_SSL_KEY`";
};
eventLogFile = mkOption {
type = types.nullOr types.path;
default = null;
description = "File to log process related events for genieacs-${serviceShortName}. If `null`, logs will go to stderr. This sets `GENIEACS_${serviceNameCaps}_LOG_FILE`";
};
extraEnv = mkOption {
type = envVarsType;
default = { };
example = ''{ NODE_OPTIONS = "--enable-source-maps"; }'';
};
asEnvironmentVars = mkOption { asEnvironmentVars = mkOption {
type = envVarsType; type = envVarsType;
internal = true; internal = true;
readOnly = true; readOnly = true;
default = environmentVars // config.extraEnv; default = environmentVars // config.extraEnv;
};
}; };
}; };
};
envAllNoPrefix = { envAllNoPrefix = {
MONGODB_CONNECTION_URL = cfg.mongodbConnectionUrl; MONGODB_CONNECTION_URL = cfg.mongodbConnectionUrl;
EXT_DIR = "${extensionsPkg}"; EXT_DIR = "${extensionsPkg}";
@@ -98,7 +106,12 @@ let
fs = envAll // cfg.fs.asEnvironmentVars // { GENIEACS_FS_URL_PREFIX = cfg.urlPrefix; }; fs = envAll // cfg.fs.asEnvironmentVars // { GENIEACS_FS_URL_PREFIX = cfg.urlPrefix; };
ui = envAll // cfg.ui.asEnvironmentVars; ui = envAll // cfg.ui.asEnvironmentVars;
}; };
serviceNames = [ "cwmp" "nbi" "fs" "ui" ]; serviceNames = [
"cwmp"
"nbi"
"fs"
"ui"
];
services = map (name: { services = map (name: {
inherit name; inherit name;
config = cfg.${name}; config = cfg.${name};
@@ -118,7 +131,7 @@ in
options.services.genieacs = { options.services.genieacs = {
defaults = mkOption { defaults = mkOption {
type = types.deferredModule; type = types.deferredModule;
default = {}; default = { };
}; };
user = mkOption { user = mkOption {
type = types.str; type = types.str;
@@ -152,17 +165,26 @@ in
description = "File to dump CPE debug log. No debug log is dumped if set to `null`. This sets `GENIEACS_DEBUG_FILE`"; description = "File to dump CPE debug log. No debug log is dumped if set to `null`. This sets `GENIEACS_DEBUG_FILE`";
}; };
debugFormat = mkOption { debugFormat = mkOption {
type = types.enum [ "yaml" "json" ]; type = types.enum [
"yaml"
"json"
];
default = "yaml"; default = "yaml";
description = "Debug log format. This sets `GENIEACS_DEBUG_FORMAT`"; description = "Debug log format. This sets `GENIEACS_DEBUG_FORMAT`";
}; };
eventLogFormat = mkOption { eventLogFormat = mkOption {
type = types.enum [ "simple" "json" ]; type = types.enum [
"simple"
"json"
];
default = "simple"; default = "simple";
description = "The format used for the log entries in {option}`eventLogFile`. This sets `GENIEACS_LOG_FORMAT`"; description = "The format used for the log entries in {option}`eventLogFile`. This sets `GENIEACS_LOG_FORMAT`";
}; };
accessLogFormat = mkOption { accessLogFormat = mkOption {
type = types.enum [ "simple" "json" ]; type = types.enum [
"simple"
"json"
];
default = "simple"; default = "simple";
description = "The format used for the log entries in {option}`accessLogFile`. This sets `GENIEACS_ACCESS_LOG_FORMAT`"; description = "The format used for the log entries in {option}`accessLogFile`. This sets `GENIEACS_ACCESS_LOG_FORMAT`";
}; };
@@ -187,125 +209,140 @@ in
default = true; default = true;
}; };
cwmp = mkServiceOption "cwmp"; cwmp = mkServiceOption "cwmp";
nbi = mkServiceOption "nbi"; nbi = mkServiceOption "nbi";
fs = mkServiceOption "fs"; fs = mkServiceOption "fs";
ui = mkServiceOption "ui"; ui = mkServiceOption "ui";
}; };
config = lib.mkMerge ([ config = lib.mkMerge (
{ [
assertions = [ {
{ assertions =
assertion = [
let {
allPorts = builtins.concatMap ({config, ...}: lib.optional config.enable config.port) services; assertion =
in let
lib.allUnique allPorts; allPorts = builtins.concatMap ({ config, ... }: lib.optional config.enable config.port) services;
message = "services.genieacs: All enabled genieacs services must listen on unique ports. Current ports assignments: " + (lib.concatMapStringsSep " " ({name, config, ...}: lib.optionalString config.enable "${name}=${config.port}") services); in
} lib.allUnique allPorts;
] ++ flip lib.map services ( message =
{name, config, ...}: "services.genieacs: All enabled genieacs services must listen on unique ports. Current ports assignments: "
{ + (lib.concatMapStringsSep " " (
assertion = (config.sslCert == null) == (config.sslKey == null); { name, config, ... }: lib.optionalString config.enable "${name}=${config.port}"
message = "services.genieacs.${name}: sslCert and sslKey must either both be null or both be non-null"; ) services);
} }
); ]
services.genieacs.cwmp = cfg.defaults; ++ flip lib.map services (
services.genieacs.nbi = cfg.defaults; { name, config, ... }:
services.genieacs.fs = cfg.defaults; {
services.genieacs.ui = cfg.defaults; assertion = (config.sslCert == null) == (config.sslKey == null);
} message = "services.genieacs.${name}: sslCert and sslKey must either both be null or both be non-null";
(lib.mkIf enableAny { }
users.users.${cfg.user} = { );
isSystemUser = true; services.genieacs.cwmp = cfg.defaults;
group = cfg.group; services.genieacs.nbi = cfg.defaults;
}; services.genieacs.fs = cfg.defaults;
users.groups.${cfg.group} = { }; services.genieacs.ui = cfg.defaults;
}
systemd.targets.genieacs = { (lib.mkIf enableAny {
description = "Target for all GenieACS services"; users.users.${cfg.user} = {
wantedBy = [ "multi-user.target" ]; isSystemUser = true;
}; group = cfg.group;
})
(lib.mkIf cfg.ui.enable {
systemd.services.genieacs-ui = {
script = ''
set -euo pipefail
jwt_path=${lib.escapeShellArg cfg.jwtSecret.path}
${lib.optionalString cfg.jwtSecret.autoGenerate ''
if ! [[ -f "$jwt_path" ]]; then
umask 077
od -vN "128" -An -tx1 /dev/urandom | tr -d " \n" > "$jwt_path"
fi
''}
GENIEACS_UI_JWT_SECRET="$(cat "$jwt_path")"
export GENIEACS_UI_JWT_SECRET
${cfg.package}/bin/genieacs-ui
'';
serviceConfig.BindPaths = [ (builtins.dirOf cfg.jwtSecret.path) ];
};
})
] ++ flip map services (
{name, config, env}:
lib.mkIf config.enable {
# for those of you ripgrepping, this is what makes genieacs-cwmp.service, genieacs-nbi.service, genieacs-fs.service, and genieacs-ui.service
systemd.services."genieacs-${name}" = {
description = "GenieACS ${name} service";
wantedBy = [ "genieacs.target" ];
after = [ "network.target" ];
environment = builtins.mapAttrs (_: v: if builtins.isInt v then toString v else v) env;
serviceConfig = {
Type = "exec";
User = cfg.user;
Group = cfg.group;
#mkDefault so genieacs-ui.script can override it
ExecStart = lib.mkDefault "${cfg.package}/bin/genieacs-${name}";
BindReadOnlyPaths = [
"/nix/store"
"-/etc/resolv.conf"
"-/etc/nsswitch.conf"
"-/etc/hosts"
"-/etc/localtime"
];
BindPaths = []
++ lib.optional (config.accessLogFile != null) (builtins.dirOf config.accessLogFile)
++ lib.optional (config.eventLogFile != null) (builtins.dirOf config.eventLogFile)
;
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
DeviceAllow = "";
ProtectSystem = "strict";
LockPersonality = true;
# it's nodejs, which has a JIT, so it needs write-execute memory
# MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateTmp = true;
ProcSubset = "pid";
ProtectClock = true;
ProtectHome = true;
ProtectHostname = true;
ProtectControlGroups = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~pkey_alloc:ENOSPC"
];
}; };
}; users.groups.${cfg.group} = { };
}
)); systemd.targets.genieacs = {
description = "Target for all GenieACS services";
wantedBy = [ "multi-user.target" ];
};
})
(lib.mkIf cfg.ui.enable {
systemd.services.genieacs-ui = {
script = ''
set -euo pipefail
jwt_path=${lib.escapeShellArg cfg.jwtSecret.path}
${lib.optionalString cfg.jwtSecret.autoGenerate ''
if ! [[ -f "$jwt_path" ]]; then
umask 077
od -vN "128" -An -tx1 /dev/urandom | tr -d " \n" > "$jwt_path"
fi
''}
GENIEACS_UI_JWT_SECRET="$(cat "$jwt_path")"
export GENIEACS_UI_JWT_SECRET
${cfg.package}/bin/genieacs-ui
'';
serviceConfig.BindPaths = [ (builtins.dirOf cfg.jwtSecret.path) ];
};
})
]
++ flip map services (
{
name,
config,
env,
}:
lib.mkIf config.enable {
# for those of you ripgrepping, this is what makes genieacs-cwmp.service, genieacs-nbi.service, genieacs-fs.service, and genieacs-ui.service
systemd.services."genieacs-${name}" = {
description = "GenieACS ${name} service";
wantedBy = [ "genieacs.target" ];
after = [ "network.target" ];
environment = builtins.mapAttrs (_: v: if builtins.isInt v then toString v else v) env;
serviceConfig = {
Type = "exec";
User = cfg.user;
Group = cfg.group;
#mkDefault so genieacs-ui.script can override it
ExecStart = lib.mkDefault "${cfg.package}/bin/genieacs-${name}";
BindReadOnlyPaths = [
"/nix/store"
"-/etc/resolv.conf"
"-/etc/nsswitch.conf"
"-/etc/hosts"
"-/etc/localtime"
];
BindPaths =
[ ]
++ lib.optional (config.accessLogFile != null) (builtins.dirOf config.accessLogFile)
++ lib.optional (config.eventLogFile != null) (builtins.dirOf config.eventLogFile);
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
DeviceAllow = "";
ProtectSystem = "strict";
LockPersonality = true;
# it's nodejs, which has a JIT, so it needs write-execute memory
# MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateTmp = true;
ProcSubset = "pid";
ProtectClock = true;
ProtectHome = true;
ProtectHostname = true;
ProtectControlGroups = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~pkey_alloc:ENOSPC"
];
};
};
}
)
);
} }

View File

@@ -1,4 +1,9 @@
{ config, lib, minimal, ... }: {
config,
lib,
minimal,
...
}:
{ {
imports = [ ./lean.nix ]; imports = [ ./lean.nix ];
opts = { opts = {

View File

@@ -1,5 +1,4 @@
let let
newPackagePaths = import ../packages; newPackagePaths = import ../packages;
in in
self: _super: self: _super: builtins.mapAttrs (_: path: self.callPackage path { }) newPackagePaths
builtins.mapAttrs (_: path: self.callPackage path { }) newPackagePaths

View File

@@ -1,5 +1,9 @@
let let
directoryListing = builtins.removeAttrs (builtins.readDir ./.) [ "default.nix" ]; directoryListing = builtins.removeAttrs (builtins.readDir ./.) [ "default.nix" ];
packagePaths = builtins.mapAttrs (k: v: assert v == "directory"; ./${k}/package.nix) directoryListing; packagePaths = builtins.mapAttrs (
k: v:
assert v == "directory";
./${k}/package.nix
) directoryListing;
in in
packagePaths packagePaths

View File

@@ -34,7 +34,7 @@ buildNpmPackage (finalAttrs: {
for binFile in $out/share/genieacs/bin/*; do for binFile in $out/share/genieacs/bin/*; do
makeWrapper $binFile $out/bin/$(basename $binFile) --chdir $out/share/genieacs --prefix NODE_PATH : $out/lib/node_modules/genieacs/node_modules makeWrapper $binFile $out/bin/$(basename $binFile) --chdir $out/share/genieacs --prefix NODE_PATH : $out/lib/node_modules/genieacs/node_modules
done done
''; '';
meta = { meta = {
description = "An Automatic Configuration Server implementing the TR-069 protocol"; description = "An Automatic Configuration Server implementing the TR-069 protocol";

View File

@@ -1,4 +1,8 @@
{ lean4, fetchFromGitHub, cadical }: {
lean4,
fetchFromGitHub,
cadical,
}:
lean4 lean4
# lean4.overrideAttrs ( # lean4.overrideAttrs (
# final: prev: { # final: prev: {

View File

@@ -1,13 +1,8 @@
{ { runCommandLocal, writeText }:
runCommandLocal,
writeText,
}:
let let
filePkg = writeText "shellvaculib.bash" (builtins.readFile ./shellvaculib.bash); filePkg = writeText "shellvaculib.bash" (builtins.readFile ./shellvaculib.bash);
in in
runCommandLocal "shellvaculib" { runCommandLocal "shellvaculib" { passthru.file = filePkg; } ''
passthru.file = filePkg;
} ''
mkdir -p $out/share mkdir -p $out/share
mkdir -p $out/bin mkdir -p $out/bin
ln -s ${filePkg} $out/share/shellvaculib.bash ln -s ${filePkg} $out/share/shellvaculib.bash

View File

@@ -1,7 +1,4 @@
{ { rustPlatform, sqlite }:
rustPlatform,
sqlite,
}:
rustPlatform.buildRustPackage { rustPlatform.buildRustPackage {
pname = "vacu-history"; pname = "vacu-history";
version = "1.0.0"; version = "1.0.0";

View File

@@ -1,7 +1,4 @@
{ { pkgs, ... }:
pkgs,
...
}:
let let
btrfs-progs = pkgs.btrfs-progs; btrfs-progs = pkgs.btrfs-progs;
btrfs = "${btrfs-progs}/bin/btrfs"; btrfs = "${btrfs-progs}/bin/btrfs";
@@ -18,7 +15,10 @@ in
boot.initrd.systemd.services."vacu-impermanence-setup" = { boot.initrd.systemd.services."vacu-impermanence-setup" = {
enable = true; enable = true;
wantedBy = [ "initrd-root-device.target" ]; wantedBy = [ "initrd-root-device.target" ];
before = [ "sysroot.mount" "create-needed-for-boot-dirs.service" ]; before = [
"sysroot.mount"
"create-needed-for-boot-dirs.service"
];
serviceConfig.Type = "oneshot"; serviceConfig.Type = "oneshot";
script = '' script = ''
set -euo pipefail set -euo pipefail

View File

@@ -1,6 +1,4 @@
{ { ... }:
...
}:
{ {
imports = [ imports = [
./impermanence.nix ./impermanence.nix
@@ -10,16 +8,23 @@
./networking.nix ./networking.nix
./doof.nix ./doof.nix
./sops.nix ./sops.nix
({ config, lib, pkgs, ... }: { (
options.vacu.initramContents = lib.mkOption { {
default = config,
pkgs.runCommand "initram-contents" {} '' lib,
mkdir -p $out pkgs,
cd $out ...
${pkgs.zstd}/bin/zstdcat ${config.system.build.initialRamdisk}/initrd | ${pkgs.cpio}/bin/cpio -idmv }:
''; {
}; options.vacu.initramContents = lib.mkOption {
}) default = pkgs.runCommand "initram-contents" { } ''
mkdir -p $out
cd $out
${pkgs.zstd}/bin/zstdcat ${config.system.build.initialRamdisk}/initrd | ${pkgs.cpio}/bin/cpio -idmv
'';
};
}
)
]; ];
boot.loader.systemd-boot.enable = true; boot.loader.systemd-boot.enable = true;
boot.loader.systemd-boot.memtest86.enable = true; boot.loader.systemd-boot.memtest86.enable = true;
@@ -63,7 +68,7 @@
"jfs" "jfs"
]; ];
networking.firewall.allowedTCPPorts = [ 5201 ]; #default port for iperf3 networking.firewall.allowedTCPPorts = [ 5201 ]; # default port for iperf3
systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug"; systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug";
} }

View File

@@ -1,8 +1,4 @@
{ { lib, config, ... }:
lib,
config,
...
}:
let let
inherit (lib) mkOption types; inherit (lib) mkOption types;
cfg = config.vacu.network; cfg = config.vacu.network;
@@ -10,9 +6,7 @@ let
tunnelName = "doofTun"; tunnelName = "doofTun";
in in
{ {
options.vacu.network.doofPubKey = mkOption { options.vacu.network.doofPubKey = mkOption { type = types.str; };
type = types.str;
};
config = { config = {
vacu.network.ips = { vacu.network.ips = {
doofStatic4 = "205.201.63.13"; doofStatic4 = "205.201.63.13";
@@ -38,7 +32,10 @@ in
wireguardPeers = lib.singleton { wireguardPeers = lib.singleton {
PublicKey = cfg.doofPubKey; PublicKey = cfg.doofPubKey;
Endpoint = "tun-sea.doof.net:53263"; Endpoint = "tun-sea.doof.net:53263";
AllowedIPs = [ "0.0.0.0/0" "::/0" ]; AllowedIPs = [
"0.0.0.0/0"
"::/0"
];
PersistentKeepalive = 5; PersistentKeepalive = 5;
}; };
}; };
@@ -75,4 +72,3 @@ in
}; };
}; };
} }

View File

@@ -1,7 +1,4 @@
{ { config, ... }:
config,
...
}:
{ {
services.mongodb = { services.mongodb = {
enable = true; enable = true;

View File

@@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }: {
config,
lib,
pkgs,
...
}:
let let
wdc_sn530 = "/dev/disk/by-id/nvme-WDC_PC_SN530_SDBPNPZ-1T00-1006_214628801678"; wdc_sn530 = "/dev/disk/by-id/nvme-WDC_PC_SN530_SDBPNPZ-1T00-1006_214628801678";
seagate_ironwolf = "/dev/disk/by-id/nvme-Seagate_IronWolf510_ZP960NM30001-2S9302_7PK0052S"; seagate_ironwolf = "/dev/disk/by-id/nvme-Seagate_IronWolf510_ZP960NM30001-2S9302_7PK0052S";
@@ -10,7 +15,14 @@ let
md_dev = "/dev/disk/by-id/md-name-prophecy-root-crypt"; md_dev = "/dev/disk/by-id/md-name-prophecy-root-crypt";
in in
{ {
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" ]; boot.initrd.availableKernelModules = [
"xhci_pci"
"ahci"
"nvme"
"usbhid"
"usb_storage"
"sd_mod"
];
boot.initrd.kernelModules = [ "raid1" ]; boot.initrd.kernelModules = [ "raid1" ];
boot.kernelModules = [ "kvm-amd" ]; boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ]; boot.extraModulePackages = [ ];
@@ -37,13 +49,19 @@ in
fileSystems."/boot" = { fileSystems."/boot" = {
device = "${wdc_sn530}-part1"; device = "${wdc_sn530}-part1";
fsType = "vfat"; fsType = "vfat";
options = [ "umask=0077" "nofail" ]; options = [
"umask=0077"
"nofail"
];
}; };
fileSystems."/boot-alt" = { fileSystems."/boot-alt" = {
device = "${seagate_ironwolf}-part1"; device = "${seagate_ironwolf}-part1";
fsType = "vfat"; fsType = "vfat";
options = [ "umask=0077" "nofail" ]; options = [
"umask=0077"
"nofail"
];
}; };
swapDevices = [ ]; swapDevices = [ ];
@@ -58,4 +76,3 @@ in
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
} }

View File

@@ -1,8 +1,6 @@
{ inputs, ... }: { inputs, ... }:
{ {
imports = [ imports = [ inputs.impermanence.nixosModules.impermanence ];
inputs.impermanence.nixosModules.impermanence
];
environment.persistence."/persistent" = { environment.persistence."/persistent" = {
enable = true; enable = true;
hideMounts = true; hideMounts = true;
@@ -21,8 +19,6 @@
}; };
environment.persistence."/persistent-cache" = { environment.persistence."/persistent-cache" = {
enable = true; enable = true;
directories = [ directories = [ "/var/cache" ];
"/var/cache"
];
}; };
} }

View File

@@ -22,13 +22,17 @@ in
}; };
vacu.network.ips = lib.mkOption { vacu.network.ips = lib.mkOption {
type = lib.types.attrsOf lib.types.anything; type = lib.types.attrsOf lib.types.anything;
default = {}; default = { };
}; };
}; };
config = { config = {
vacu.network.ips = { vacu.network.ips = {
t2dLANStatic = "10.78.79.22"; t2dLANStatic = "10.78.79.22";
t2dSubnets = [ "10.78.76.0/22" "205.201.63.12/32" "172.83.159.53/32" ]; t2dSubnets = [
"10.78.76.0/22"
"205.201.63.12/32"
"172.83.159.53/32"
];
t2dRouter = "10.78.79.1"; t2dRouter = "10.78.79.1";
}; };
networking.useNetworkd = true; networking.useNetworkd = true;
@@ -49,20 +53,20 @@ in
systemd.network.networks.${cfg.lan_bridge_network} = { systemd.network.networks.${cfg.lan_bridge_network} = {
name = bridge; name = bridge;
DHCP = "no"; DHCP = "no";
address = [ address = [ "${cfg.ips.t2dLANStatic}/22" ];
"${cfg.ips.t2dLANStatic}/22" routes =
]; [ lan_route ]
routes = [lan_route] ++ (lib.concatMap (subnet: [ ++ (lib.concatMap (subnet: [
{ {
Scope = "link"; Scope = "link";
Destination = subnet; Destination = subnet;
} }
{ {
Scope = "link"; Scope = "link";
Destination = subnet; Destination = subnet;
Table = "doofTun"; Table = "doofTun";
} }
]) cfg.ips.t2dSubnets); ]) cfg.ips.t2dSubnets);
dns = [ cfg.ips.t2dRouter ]; dns = [ cfg.ips.t2dRouter ];
}; };
@@ -79,4 +83,3 @@ in
}; };
}; };
} }

View File

@@ -6,6 +6,7 @@ from typing import Any
from dataclasses import dataclass from dataclasses import dataclass
from collections.abc import Callable from collections.abc import Callable
@dataclass @dataclass
class ProcessResult[T]: class ProcessResult[T]:
stdout: T stdout: T
@@ -15,37 +16,38 @@ class ProcessResult[T]:
return self.returncode == 0 return self.returncode == 0
def map[U](self, f: Callable[[T], U]) -> ProcessResult[U]: def map[U](self, f: Callable[[T], U]) -> ProcessResult[U]:
new_stdout:U = f(self.stdout) new_stdout: U = f(self.stdout)
return ProcessResult(stdout=new_stdout, returncode=self.returncode) return ProcessResult(stdout=new_stdout, returncode=self.returncode)
def run(*cmd:str) -> ProcessResult[str]:
def run(*cmd: str) -> ProcessResult[str]:
print(f"running {cmd!r}") print(f"running {cmd!r}")
proc = subprocess.Popen( proc = subprocess.Popen(
cmd, cmd, stdout=subprocess.PIPE, stderr=None, stdin=subprocess.DEVNULL, text=True
stdout=subprocess.PIPE,
stderr=None,
stdin=subprocess.DEVNULL,
text=True
) )
(stdout_data, _) = proc.communicate() (stdout_data, _) = proc.communicate()
print(f"finished, exit code {proc.returncode}") print(f"finished, exit code {proc.returncode}")
return ProcessResult(stdout=stdout_data, returncode=proc.returncode) return ProcessResult(stdout=stdout_data, returncode=proc.returncode)
def must_succeed(*cmd:str) -> str:
def must_succeed(*cmd: str) -> str:
res = run(*cmd) res = run(*cmd)
assert res.success() assert res.success()
return res.stdout return res.stdout
def parse_maybe_json(maybe_json: str) -> Any: def parse_maybe_json(maybe_json: str) -> Any:
if maybe_json.strip() == "": if maybe_json.strip() == "":
return None return None
else: else:
return json.loads(maybe_json) return json.loads(maybe_json)
def run_json(*cmd:str) -> ProcessResult[Any]:
def run_json(*cmd: str) -> ProcessResult[Any]:
res = run(*cmd) res = run(*cmd)
return res.map(parse_maybe_json) return res.map(parse_maybe_json)
def do_build(installable: str, impure: bool) -> bool: def do_build(installable: str, impure: bool) -> bool:
eval_command = ["nix", "derivation", "show", installable] eval_command = ["nix", "derivation", "show", installable]
if impure: if impure:
@@ -56,7 +58,15 @@ def do_build(installable: str, impure: bool) -> bool:
drv_paths = list(res.stdout.keys()) drv_paths = list(res.stdout.keys())
for drv_path in drv_paths: for drv_path in drv_paths:
print(f"{installable=} {drv_path=}") print(f"{installable=} {drv_path=}")
res = run_json("nix", "build", "-j1", "--keep-going", "--no-link", "--json", drv_path + "^*") res = run_json(
"nix",
"build",
"-j1",
"--keep-going",
"--no-link",
"--json",
drv_path + "^*",
)
if not res.success(): if not res.success():
return False return False
builds = res.stdout builds = res.stdout
@@ -68,6 +78,7 @@ def do_build(installable: str, impure: bool) -> bool:
return False return False
return True return True
res = run_json("nix", "eval", ".#.", "--json", "--apply", "f: f.archival.archiveList") res = run_json("nix", "eval", ".#.", "--json", "--apply", "f: f.archival.archiveList")
assert res.success() assert res.success()
build_list = res.stdout build_list = res.stdout

View File

@@ -1,4 +1 @@
{ { writers }: writers.writePython3Bin "vacu-flake-archive" { } (builtins.readFile ./archive.py)
writers,
}:
writers.writePython3Bin "vacu-flake-archive" { } (builtins.readFile ./archive.py)

View File

@@ -4,98 +4,98 @@ dkim_key: ENC[AES256_GCM,data:CZC/1U1cJUIyNhXAWp+YFJd0pZZKvZClJxOh3uZ3YyfEQBiK9n
dkim_pub: ENC[AES256_GCM,data:XLYRTAviK+r6DnRU4+lc58elI3FJ+FPsB1A5sQOk+pb+fNu7zFCiZdz/MwTVkE9izDP1Onv+VhV8sRgmxacTv4nW5GcukCrm3FmCp2jm6QF1/40/WRv6Lkbek0tV1bMOQPy9Zj8wdO9M05XCXUVXk4x17rj+lw8ApwJS2pJMoultMFx34tx2pNEnmO3MFtuBOxzeU2yP+NhF2sJNA62to78AiH5EblkoF0a6sUYk553U+sv3Ob0lo1nSv6c8zwl7y1WSNQnLK+/3WxSVGfePHVsVM8Zze1KFTVLQQggIzWTdcr7AgcTGbk3kaYCeucfQ60pVlqOyPnkJoUJ8HR1RSajFk6Ylzw0xBpY85qAXNT2YIRiq0HTUc1s5lD0luXLQEP+g+XUwZfzFRZgt1nWBlPmpbj2Ylj1FfrA7EXsIK9nyo+rf0qRn/4HusJATr9ddYmZdxwazl1FXkOKLHPyu1NlzwoTNSQQgMHlzxzUvrrv7+mI2nQvXRx82TSRytqrMvoBTF1NFX+pRjhNg9fcq0oPJ2ORqOVQsxzhLhB+tw7Cg+UHGWlnKnkqaKH1JDmOFyJDB96aPUnSQT2J8qkyb+hMBXz9mme8rZopkHrA4WyDXv3zpEi0P5Sj0DDwdRxKMdDdZ4hw79YQIrd63cIorN8XG6Icevb25LfekLEq/C2FS8+kADagyOM0uzCw2p/qacNz37ZNGqPK6gYkjnyoAfSm14zbgoLX/5dnf7eCuMatevTm4AcE53RawQfzz0YNJuEv5uqD/WUy+UIKHIwxPYY9FWBBPmH+8eaPC1mMPh54I444b39FwpnPU8GwxEPsjRg8TSnohawNmmhEWEpmlawEKw+C+BE6A2DmVJzyeBvVRwe/W6CPgyYxgSGWUuvfZFm1GrzwZDjCOEMRn7qMwMBxh1nr2BOAiNxA38UtsymaZO5ZOknClWlKIkIFl8NJdVITNNsI48KMuSY20o1puzkxMaAUH3OrGEhtoHrEOeIq+KCFzH2gZo6L5hbv9CHM7QgCYsbtVIMwL+cRZZaSNubS3K48OmWJnHNuqkcrSI4lqfjLhz1DbnQ==,iv:/cNMmlpq9LSOk0MwVq8NaWvp47q68lKWTx4s5nkwF5c=,tag:ZNX+yZsSxdhFsavDpX380g==,type:str] dkim_pub: ENC[AES256_GCM,data:XLYRTAviK+r6DnRU4+lc58elI3FJ+FPsB1A5sQOk+pb+fNu7zFCiZdz/MwTVkE9izDP1Onv+VhV8sRgmxacTv4nW5GcukCrm3FmCp2jm6QF1/40/WRv6Lkbek0tV1bMOQPy9Zj8wdO9M05XCXUVXk4x17rj+lw8ApwJS2pJMoultMFx34tx2pNEnmO3MFtuBOxzeU2yP+NhF2sJNA62to78AiH5EblkoF0a6sUYk553U+sv3Ob0lo1nSv6c8zwl7y1WSNQnLK+/3WxSVGfePHVsVM8Zze1KFTVLQQggIzWTdcr7AgcTGbk3kaYCeucfQ60pVlqOyPnkJoUJ8HR1RSajFk6Ylzw0xBpY85qAXNT2YIRiq0HTUc1s5lD0luXLQEP+g+XUwZfzFRZgt1nWBlPmpbj2Ylj1FfrA7EXsIK9nyo+rf0qRn/4HusJATr9ddYmZdxwazl1FXkOKLHPyu1NlzwoTNSQQgMHlzxzUvrrv7+mI2nQvXRx82TSRytqrMvoBTF1NFX+pRjhNg9fcq0oPJ2ORqOVQsxzhLhB+tw7Cg+UHGWlnKnkqaKH1JDmOFyJDB96aPUnSQT2J8qkyb+hMBXz9mme8rZopkHrA4WyDXv3zpEi0P5Sj0DDwdRxKMdDdZ4hw79YQIrd63cIorN8XG6Icevb25LfekLEq/C2FS8+kADagyOM0uzCw2p/qacNz37ZNGqPK6gYkjnyoAfSm14zbgoLX/5dnf7eCuMatevTm4AcE53RawQfzz0YNJuEv5uqD/WUy+UIKHIwxPYY9FWBBPmH+8eaPC1mMPh54I444b39FwpnPU8GwxEPsjRg8TSnohawNmmhEWEpmlawEKw+C+BE6A2DmVJzyeBvVRwe/W6CPgyYxgSGWUuvfZFm1GrzwZDjCOEMRn7qMwMBxh1nr2BOAiNxA38UtsymaZO5ZOknClWlKIkIFl8NJdVITNNsI48KMuSY20o1puzkxMaAUH3OrGEhtoHrEOeIq+KCFzH2gZo6L5hbv9CHM7QgCYsbtVIMwL+cRZZaSNubS3K48OmWJnHNuqkcrSI4lqfjLhz1DbnQ==,iv:/cNMmlpq9LSOk0MwVq8NaWvp47q68lKWTx4s5nkwF5c=,tag:ZNX+yZsSxdhFsavDpX380g==,type:str]
relay_creds: ENC[AES256_GCM,data:o0FIKyqYHo1mndY+TC6TopipDlZMoyePPPRF62+WVegWjnz+dG83WTzIduJ6qdzlkBH0tgYfau7aIzYaDWZAd935efxvwTMl8lot0xTa8SqAYxQKDkTcpUhaHtu9wlpaqv31vzPdGUJbI17e9ZPdMEPRNaEYQkYqP2YoagO17WRbzIOax+XTP08pyVJChDG++aYlkuScOXQyM830hDy2xCYA9OHN4BeyU5mh6W0BiXLYIp9oOh0y1We59CUKeo0S,iv:JHgLeQO6XE5VYsoPU4YrI+LIaWSETvfnnwjrlTc1n0g=,tag:cWafuECJy2Gv5BMGKG1NOw==,type:str] relay_creds: ENC[AES256_GCM,data:o0FIKyqYHo1mndY+TC6TopipDlZMoyePPPRF62+WVegWjnz+dG83WTzIduJ6qdzlkBH0tgYfau7aIzYaDWZAd935efxvwTMl8lot0xTa8SqAYxQKDkTcpUhaHtu9wlpaqv31vzPdGUJbI17e9ZPdMEPRNaEYQkYqP2YoagO17WRbzIOax+XTP08pyVJChDG++aYlkuScOXQyM830hDy2xCYA9OHN4BeyU5mh6W0BiXLYIp9oOh0y1We59CUKeo0S,iv:JHgLeQO6XE5VYsoPU4YrI+LIaWSETvfnnwjrlTc1n0g=,tag:cWafuECJy2Gv5BMGKG1NOw==,type:str]
sops: sops:
age: age:
- recipient: age1hkve3khk7fthyrwxjqdf4r37lrqpmnkz6mke7psuphvu2ykynqaq9g6ja5 - recipient: age1hkve3khk7fthyrwxjqdf4r37lrqpmnkz6mke7psuphvu2ykynqaq9g6ja5
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvNDFQQ3lMbGtBVjdBR0t2 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvNDFQQ3lMbGtBVjdBR0t2
MjJvcmpjQmtYR1VkSVYzTzJFZDZibmFKc1dNCkZpWUsvcEM2MnA2OWdOdXVsZzJi MjJvcmpjQmtYR1VkSVYzTzJFZDZibmFKc1dNCkZpWUsvcEM2MnA2OWdOdXVsZzJi
VjFDOVNjdkVIZDgwWE5pQmpKWkxSb3MKLS0tIDlSbXZFY1R0dkl3NHdvSTlWYTZ6 VjFDOVNjdkVIZDgwWE5pQmpKWkxSb3MKLS0tIDlSbXZFY1R0dkl3NHdvSTlWYTZ6
bDV6UGVHd2RVKzVycHJUWllTMk1HU2MKkDag+K62PydC3jcvLaIxy0vOuANbA65P bDV6UGVHd2RVKzVycHJUWllTMk1HU2MKkDag+K62PydC3jcvLaIxy0vOuANbA65P
hzaTNzv8iotafjFDYLWim7PLnxv+IeywKoL+Pnn4o3+e0617omx1mA== hzaTNzv8iotafjFDYLWim7PLnxv+IeywKoL+Pnn4o3+e0617omx1mA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1dzdf4rgep3ctk3dnrmrqtdgrchaa8nszfc4dp29gqwsst3z6jyrq57vfsj - recipient: age1dzdf4rgep3ctk3dnrmrqtdgrchaa8nszfc4dp29gqwsst3z6jyrq57vfsj
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnbWUrNTN0Y2lzSjR1ckc1 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnbWUrNTN0Y2lzSjR1ckc1
cW03WXZFVzBSUzdpUzVLMWJzRjhqaWRFODFBClJGSno0QUpQaGpVSzJ0Y3h5eXFj cW03WXZFVzBSUzdpUzVLMWJzRjhqaWRFODFBClJGSno0QUpQaGpVSzJ0Y3h5eXFj
aGpoNGIycG80NkxhWEFGeU9IMk1tWFEKLS0tIDI3Q3lHNGI1VWJBcFZDRDBqNGpD aGpoNGIycG80NkxhWEFGeU9IMk1tWFEKLS0tIDI3Q3lHNGI1VWJBcFZDRDBqNGpD
RDFNajdSSWQ1ZWNNcXl0T3lLcm1YUWMKm7w5OXFeuk7Sby68ODrk9EC8SbvCTxoO RDFNajdSSWQ1ZWNNcXl0T3lLcm1YUWMKm7w5OXFeuk7Sby68ODrk9EC8SbvCTxoO
oQueOepqeeh4wip3SQpHACvtUp4s85M6ZXE96uYioRlzy3zg39tIpQ== oQueOepqeeh4wip3SQpHACvtUp4s85M6ZXE96uYioRlzy3zg39tIpQ==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1rz75dqzfd6gulwh270ukmt5amcau6j8dpxgzx8fm6u8sjkyx9usq69y4s2 - recipient: age1rz75dqzfd6gulwh270ukmt5amcau6j8dpxgzx8fm6u8sjkyx9usq69y4s2
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsMUVLVWpHaksvZkJIb0U4 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsMUVLVWpHaksvZkJIb0U4
RnVTZ0k0L0VlMjFNNFg4RVZjTmk1OHEwbGpnCkIxTXN5aWMwTlZEWERYRXV5dHEx RnVTZ0k0L0VlMjFNNFg4RVZjTmk1OHEwbGpnCkIxTXN5aWMwTlZEWERYRXV5dHEx
UVFVVEczRFhWRDJPN3g0QVh2NXlZUjAKLS0tIGNRbkk3R1RYVCs2Y2x4UmZhTXdx UVFVVEczRFhWRDJPN3g0QVh2NXlZUjAKLS0tIGNRbkk3R1RYVCs2Y2x4UmZhTXdx
UVUrQStXTU9yUWJ0SnlIbDBIRUdSb00K9oPKVn1RzK0DVtaeXnfURea9k1lNzpor UVUrQStXTU9yUWJ0SnlIbDBIRUdSb00K9oPKVn1RzK0DVtaeXnfURea9k1lNzpor
3ex6hSyrfzNazFlInCuptIFIpf5o1eeiiV2PL85w9wvpMh4MEG7peg== 3ex6hSyrfzNazFlInCuptIFIpf5o1eeiiV2PL85w9wvpMh4MEG7peg==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age13x0f3glnz4jvqty2v92cxrrnjcna6ed4qegrhulw9jjy08zuy3aqzvrfc6 - recipient: age13x0f3glnz4jvqty2v92cxrrnjcna6ed4qegrhulw9jjy08zuy3aqzvrfc6
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1MHUxcU9tR3JKSjk5TGRm YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1MHUxcU9tR3JKSjk5TGRm
c2I3S0lrV1RJZHFkN1JyNHlqc2hXbGtPVlVzCk9pMmVRdC92bld6SW0rNFVyRmJs c2I3S0lrV1RJZHFkN1JyNHlqc2hXbGtPVlVzCk9pMmVRdC92bld6SW0rNFVyRmJs
QmVOMXRrb3FvVUNUYnVuczg5MklEL1kKLS0tIEE2YkRmeWFONVpDTk02S3kwSWNI QmVOMXRrb3FvVUNUYnVuczg5MklEL1kKLS0tIEE2YkRmeWFONVpDTk02S3kwSWNI
Ty9PdGYxUnRNSUIxN21RWWJUQnVqWjAKp1KybOk5/5xHHggBwE7zyuOw17GwxPCw Ty9PdGYxUnRNSUIxN21RWWJUQnVqWjAKp1KybOk5/5xHHggBwE7zyuOw17GwxPCw
UR2R5wuc0d1Uyb/z/QvRI4lbpjAhjb749JgLE2IYTYLfPsJv59K8BA== UR2R5wuc0d1Uyb/z/QvRI4lbpjAhjb749JgLE2IYTYLfPsJv59K8BA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age13j6l33g0ghk4vezn0qwfal2qmcgqwkv89ejwezpe3n47mw8yxyuslj6y7d - recipient: age13j6l33g0ghk4vezn0qwfal2qmcgqwkv89ejwezpe3n47mw8yxyuslj6y7d
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2c2cyOWh3bEtBMUF6a3hx YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2c2cyOWh3bEtBMUF6a3hx
UjVIYkN5cE1ZcWNZM1V3Y3lhR05JYUt4Q3djCk9XNWF1dnhveVlLNWxJSVcxcVRK UjVIYkN5cE1ZcWNZM1V3Y3lhR05JYUt4Q3djCk9XNWF1dnhveVlLNWxJSVcxcVRK
V2d2aWx5ZXdrYUw0TFN3VGVZTE5RTTAKLS0tIDNnWm5nbDZUbmh3QTBCWXp6aUE0 V2d2aWx5ZXdrYUw0TFN3VGVZTE5RTTAKLS0tIDNnWm5nbDZUbmh3QTBCWXp6aUE0
ZFhoeXRTOEhDT2NpOXM2L3NCdVNEQmMKBp4e23mcqrJdlcqbf6mUjitYq7MxkeoX ZFhoeXRTOEhDT2NpOXM2L3NCdVNEQmMKBp4e23mcqrJdlcqbf6mUjitYq7MxkeoX
jX8LQTucw9dhLu/SCxymRxg9/Q2+PfhUvDR2L51tdlbr77dRhic3/A== jX8LQTucw9dhLu/SCxymRxg9/Q2+PfhUvDR2L51tdlbr77dRhic3/A==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1vla9w33lsp03s46p9p6gc2mvr844vthdqhc2hzau2ph6h60gmyqqh9sf57 - recipient: age1vla9w33lsp03s46p9p6gc2mvr844vthdqhc2hzau2ph6h60gmyqqh9sf57
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoeWltSkV6aGJ1WkJOVTBp YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoeWltSkV6aGJ1WkJOVTBp
Q24wMEFuWlVQYXMrKzRrSHN2THB3TWtYQ0VvCldHUmlpUGdNTlp4QkluZjRzK0J3 Q24wMEFuWlVQYXMrKzRrSHN2THB3TWtYQ0VvCldHUmlpUGdNTlp4QkluZjRzK0J3
U0ZGYWM2eFZyZHhuT2dWSnBJdzA0dmMKLS0tIHg0citENmY1QkpXNURzY2x4QkZM U0ZGYWM2eFZyZHhuT2dWSnBJdzA0dmMKLS0tIHg0citENmY1QkpXNURzY2x4QkZM
bG9DUTFkd2t3YXFXVElKK3JsK216Rm8KGvXixYViOUwrVarBMZeUI5HlCBtoL5bp bG9DUTFkd2t3YXFXVElKK3JsK216Rm8KGvXixYViOUwrVarBMZeUI5HlCBtoL5bp
7uZ9JFKQMh9EtiUk+Pr2xr4r9Mah0Gk3AmmVKWvaQaC/bkEIhe30Eg== 7uZ9JFKQMh9EtiUk+Pr2xr4r9Mah0Gk3AmmVKWvaQaC/bkEIhe30Eg==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1jy8mxcndkw6zd6q99tjgz3gsynn78x2lwtrff85u6ud9g9y9z5mspvhufl - recipient: age1jy8mxcndkw6zd6q99tjgz3gsynn78x2lwtrff85u6ud9g9y9z5mspvhufl
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnYmhVb0FsdUc5RjdPWnA5 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnYmhVb0FsdUc5RjdPWnA5
ZmpaMi9Rek5WM1AvSVl3Nk1maG1YanJaS0RzCjM3VEJKM3dVclZxK2FSMENKTUUz ZmpaMi9Rek5WM1AvSVl3Nk1maG1YanJaS0RzCjM3VEJKM3dVclZxK2FSMENKTUUz
d0dleUU2Rk5namdUdFl4ZjNSM05xdnMKLS0tIHRzYldRM0I4MytMcGFMUnZ3QXA0 d0dleUU2Rk5namdUdFl4ZjNSM05xdnMKLS0tIHRzYldRM0I4MytMcGFMUnZ3QXA0
MGtKcDMyejNFNktCL2I4RUI3Qkk1TWMKsxjqBw5J91f3T9TDHNAKFI2cTT4i7zJw MGtKcDMyejNFNktCL2I4RUI3Qkk1TWMKsxjqBw5J91f3T9TDHNAKFI2cTT4i7zJw
N33KbrskOaOXjCsoENnqdRl9Y7v/JbOh5YQ2/oPwZEfuwgHG9lcXqw== N33KbrskOaOXjCsoENnqdRl9Y7v/JbOh5YQ2/oPwZEfuwgHG9lcXqw==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age148huz6rc3q9xx5t873ncx75sja2sazlescwspxl7lsmxsqkz0apsy8cldp - recipient: age148huz6rc3q9xx5t873ncx75sja2sazlescwspxl7lsmxsqkz0apsy8cldp
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWdWRCdnNybjdzSFpacjNj YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWdWRCdnNybjdzSFpacjNj
eFNJNjBzYmpsRkw4czN2aWJzSnBDeFYweDM4CmZCcnZCTEJQTGtoSlo3VW45T0ZJ eFNJNjBzYmpsRkw4czN2aWJzSnBDeFYweDM4CmZCcnZCTEJQTGtoSlo3VW45T0ZJ
bmpUMHhFMy9mSUxaTWVCcFBnQlAramsKLS0tIGV3eHcxRlJZc3BxQUU3TUhsRVAr bmpUMHhFMy9mSUxaTWVCcFBnQlAramsKLS0tIGV3eHcxRlJZc3BxQUU3TUhsRVAr
VXdheGpVRFF2UFBKQTF0OFMrVzdYcjQKaEs1irVwO0OoXbBhYd1AgCCPPF3sFH3a VXdheGpVRFF2UFBKQTF0OFMrVzdYcjQKaEs1irVwO0OoXbBhYd1AgCCPPF3sFH3a
go3jAHOCnwkYQMVRd24FGZx28XuEgeXQALk7JqEEy5eCS6nKDEVqcg== go3jAHOCnwkYQMVRd24FGZx28XuEgeXQALk7JqEEy5eCS6nKDEVqcg==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age197a33mlf5294amjx59hycctu6wm4l3cu3w7n9rv3fs9340ql64rqjzpr7s - recipient: age197a33mlf5294amjx59hycctu6wm4l3cu3w7n9rv3fs9340ql64rqjzpr7s
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHcWZxa3NHR0Z4TmlNNHVU YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHcWZxa3NHR0Z4TmlNNHVU
aFNvN2tycVd2THhFMGtMckhGOXBuZXNMSkFFCm1VR1ZwUHdabFdBWmUxUXVxTVR5 aFNvN2tycVd2THhFMGtMckhGOXBuZXNMSkFFCm1VR1ZwUHdabFdBWmUxUXVxTVR5
eFVvakFDZUV2WHByU2pRU3hrWXVaMGcKLS0tIHRjbElYOU8xaW1lVFlrL0YwMDlQ eFVvakFDZUV2WHByU2pRU3hrWXVaMGcKLS0tIHRjbElYOU8xaW1lVFlrL0YwMDlQ
MEwvd1RQd1hlNVNZL3VveUkydVNjVE0KFsyjr38WdXu4R0038Dum0VeVw+LNcI6q MEwvd1RQd1hlNVNZL3VveUkydVNjVE0KFsyjr38WdXu4R0038Dum0VeVw+LNcI6q
4R0ft0KsfLLmPgoNIdK5Dq5hUxyGVe8Ej/9KaN0UrqIRsLHCHimYyQ== 4R0ft0KsfLLmPgoNIdK5Dq5hUxyGVe8Ej/9KaN0UrqIRsLHCHimYyQ==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1sqj8z3feqm2dk3gj8mxpfn5dpqnsmus862e8ayd0d4cdresqffdswcf9ru - recipient: age1sqj8z3feqm2dk3gj8mxpfn5dpqnsmus862e8ayd0d4cdresqffdswcf9ru
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4QW9yVk9zN2RrZkpTWXZU YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4QW9yVk9zN2RrZkpTWXZU
U080M1pDdzV1bDFSR2UrY0o2dnoyYlpNZXc0CmJCSE84L1ZRdUVZc21GbWc3cG9t U080M1pDdzV1bDFSR2UrY0o2dnoyYlpNZXc0CmJCSE84L1ZRdUVZc21GbWc3cG9t
NHRGQUFVS3U1TjFVYWl1Q1FyODY3UjgKLS0tIGhrY1dMa251R1hCc0F5eDhtWnc2 NHRGQUFVS3U1TjFVYWl1Q1FyODY3UjgKLS0tIGhrY1dMa251R1hCc0F5eDhtWnc2
bXpqNkVobzgwMHJIdHBFZ0xDZ2RzcmcK0m4awMUrdwYvXO14L1hvhcaGgLOW3FCq bXpqNkVobzgwMHJIdHBFZ0xDZ2RzcmcK0m4awMUrdwYvXO14L1hvhcaGgLOW3FCq
UU1Vc/vX32Lsu1BN4aXlTZ1jHD6R6CnV5TbUTcM/jxFRKoRzDwdJig== UU1Vc/vX32Lsu1BN4aXlTZ1jHD6R6CnV5TbUTcM/jxFRKoRzDwdJig==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-04-28T21:28:17Z" lastmodified: "2025-04-28T21:28:17Z"
mac: ENC[AES256_GCM,data:7xn6pRTz3IaqV3QEpOBDM9FLuvvB1Og/HL4S1Jt/PWmdQKLZTU7uQbkOwdhGmT1KEjyvaSK5HJHLrDSPhm12hi2OgedOTXVE1vtCcLyVXYIRqjwWDtpIDeOOLFpXxWAkPQOdADCpNtu9axC0yP3U3a5bE0wBfh+2lciakn4AK80=,iv:h4HJ8HKXFEegHovTPdWdwuumF2i6hxqc/sP4DB+ukcU=,tag:qoamHisqF/M9236w2gJHzQ==,type:str] mac: ENC[AES256_GCM,data:7xn6pRTz3IaqV3QEpOBDM9FLuvvB1Og/HL4S1Jt/PWmdQKLZTU7uQbkOwdhGmT1KEjyvaSK5HJHLrDSPhm12hi2OgedOTXVE1vtCcLyVXYIRqjwWDtpIDeOOLFpXxWAkPQOdADCpNtu9axC0yP3U3a5bE0wBfh+2lciakn4AK80=,iv:h4HJ8HKXFEegHovTPdWdwuumF2i6hxqc/sP4DB+ukcU=,tag:qoamHisqF/M9236w2gJHzQ==,type:str]
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.10.2 version: 3.10.2

View File

@@ -1,49 +1,49 @@
{ {
"auth_password": "ENC[AES256_GCM,data:UD8l+CrofmN9g439uTOtCyP5378VX+f856dxuFDTzfCa8B+7,iv:6hgG+py3EC4cMLkhG72O5HJfbQF5Q+APq6wBsMQVRjw=,tag:KA4AupZKFdHEBzEBnd3/1A==,type:str]", "auth_password": "ENC[AES256_GCM,data:UD8l+CrofmN9g439uTOtCyP5378VX+f856dxuFDTzfCa8B+7,iv:6hgG+py3EC4cMLkhG72O5HJfbQF5Q+APq6wBsMQVRjw=,tag:KA4AupZKFdHEBzEBnd3/1A==,type:str]",
"auth_id": "ENC[AES256_GCM,data:4cBXpVc=,iv:WPh6+xp02CMBohmxWu6UdNA3KMRSghbSQYuU0lZyUMo=,tag:+zU0EBEwLgqYC0NmW31Qtw==,type:str]", "auth_id": "ENC[AES256_GCM,data:4cBXpVc=,iv:WPh6+xp02CMBohmxWu6UdNA3KMRSghbSQYuU0lZyUMo=,tag:+zU0EBEwLgqYC0NmW31Qtw==,type:str]",
"luadns_api_key": "ENC[AES256_GCM,data:pigRaKreJMoY647T1mgZCi+eVcsM8FlBdLAe+fP2IxM=,iv:y7iTpt261eXkSF3xtCu8WuDT4LKObQpDDQRo1sorE8g=,tag:P4XBmrWWKA+scDfPTJguwQ==,type:str]", "luadns_api_key": "ENC[AES256_GCM,data:pigRaKreJMoY647T1mgZCi+eVcsM8FlBdLAe+fP2IxM=,iv:y7iTpt261eXkSF3xtCu8WuDT4LKObQpDDQRo1sorE8g=,tag:P4XBmrWWKA+scDfPTJguwQ==,type:str]",
"sops": { "sops": {
"age": [ "age": [
{ {
"recipient": "age1dzdf4rgep3ctk3dnrmrqtdgrchaa8nszfc4dp29gqwsst3z6jyrq57vfsj", "recipient": "age1dzdf4rgep3ctk3dnrmrqtdgrchaa8nszfc4dp29gqwsst3z6jyrq57vfsj",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3YW9haUtvVVRkZWVqa1Zv\nOERucllIenc3VFJkMzAvM1paTWxNaVA4MlhRCmZVNGpvdmhrUnJDYTMyWExNVVNW\nQWw2MDBPUnozTWpzTERiaExYVkJUd0kKLS0tIEFPRUhjZVdBTXZQdFFUQ0NnYU5P\nYlkvaUgzQjVORTNvTDFKYXJJYW1pTGMKW2rUNzNWsvQ9vzf+jwSBOC8OjVL30HDZ\nK8QC30Z4PUtKTk5HA7KcFfGVT8UbJc6Z4IRm6dIV6lczmctZiuAXLQ==\n-----END AGE ENCRYPTED FILE-----\n" "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3YW9haUtvVVRkZWVqa1Zv\nOERucllIenc3VFJkMzAvM1paTWxNaVA4MlhRCmZVNGpvdmhrUnJDYTMyWExNVVNW\nQWw2MDBPUnozTWpzTERiaExYVkJUd0kKLS0tIEFPRUhjZVdBTXZQdFFUQ0NnYU5P\nYlkvaUgzQjVORTNvTDFKYXJJYW1pTGMKW2rUNzNWsvQ9vzf+jwSBOC8OjVL30HDZ\nK8QC30Z4PUtKTk5HA7KcFfGVT8UbJc6Z4IRm6dIV6lczmctZiuAXLQ==\n-----END AGE ENCRYPTED FILE-----\n"
}, },
{ {
"recipient": "age1rz75dqzfd6gulwh270ukmt5amcau6j8dpxgzx8fm6u8sjkyx9usq69y4s2", "recipient": "age1rz75dqzfd6gulwh270ukmt5amcau6j8dpxgzx8fm6u8sjkyx9usq69y4s2",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMdGxOMkNFcnRWd2EzaGVV\nNGdxTDUzM1FnY21tUUtJOEhaM0RFU2ZZbXc0CkIzVXBNY0Z4dmlVRnpHZGt6dzY4\ncW80b0lCdCtJMnQ2aXJyclpiT1BlWG8KLS0tIE4vV2gwZjBVSmc0Y3ExZUdXQnJL\nMU9EOWNNRDJualAvUjNOWlZCMjdHSU0K33nP6rM7k9er+8gC2cozXF3M7WNAPb3y\ny5ecWeGnIJe1Q3BwpqXUmxWswE95VYq6g4RCJ2TbHIJWgK6HLJoamg==\n-----END AGE ENCRYPTED FILE-----\n" "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMdGxOMkNFcnRWd2EzaGVV\nNGdxTDUzM1FnY21tUUtJOEhaM0RFU2ZZbXc0CkIzVXBNY0Z4dmlVRnpHZGt6dzY4\ncW80b0lCdCtJMnQ2aXJyclpiT1BlWG8KLS0tIE4vV2gwZjBVSmc0Y3ExZUdXQnJL\nMU9EOWNNRDJualAvUjNOWlZCMjdHSU0K33nP6rM7k9er+8gC2cozXF3M7WNAPb3y\ny5ecWeGnIJe1Q3BwpqXUmxWswE95VYq6g4RCJ2TbHIJWgK6HLJoamg==\n-----END AGE ENCRYPTED FILE-----\n"
}, },
{ {
"recipient": "age13x0f3glnz4jvqty2v92cxrrnjcna6ed4qegrhulw9jjy08zuy3aqzvrfc6", "recipient": "age13x0f3glnz4jvqty2v92cxrrnjcna6ed4qegrhulw9jjy08zuy3aqzvrfc6",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzM0kyMHZ2UEpaYzMzMFRo\nV3IvYVI0RTVUM29pSnhYUFBpUlVnM3BUcEZBClpCL1c1cmFaRzZDU2tQY2hJQzNx\nb2ZvdTRBMVNTS01XdTJiYnljMzhiUFkKLS0tIGFuR05CYTZhbVdZMERCVUcrRTFO\nQWREQW9DU3pmOFRJczVBdTA0VFdwZ0UKuhijkZjfHrOrQ28WF0lsrh1YYcDjohJF\nHimoJrsMFf21bsWMPGsRXvvQWouMhhzDtp3ZzaR/jhwzqnNp6I2gWw==\n-----END AGE ENCRYPTED FILE-----\n" "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzM0kyMHZ2UEpaYzMzMFRo\nV3IvYVI0RTVUM29pSnhYUFBpUlVnM3BUcEZBClpCL1c1cmFaRzZDU2tQY2hJQzNx\nb2ZvdTRBMVNTS01XdTJiYnljMzhiUFkKLS0tIGFuR05CYTZhbVdZMERCVUcrRTFO\nQWREQW9DU3pmOFRJczVBdTA0VFdwZ0UKuhijkZjfHrOrQ28WF0lsrh1YYcDjohJF\nHimoJrsMFf21bsWMPGsRXvvQWouMhhzDtp3ZzaR/jhwzqnNp6I2gWw==\n-----END AGE ENCRYPTED FILE-----\n"
}, },
{ {
"recipient": "age13j6l33g0ghk4vezn0qwfal2qmcgqwkv89ejwezpe3n47mw8yxyuslj6y7d", "recipient": "age13j6l33g0ghk4vezn0qwfal2qmcgqwkv89ejwezpe3n47mw8yxyuslj6y7d",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHcHlmTVJ1d3ZRc09WMU5p\nbmd4TzZNVisyWm1PZFBmMXpBcmd6N3ZmL0JBCnBqZzZCNVFObHpZZzd3cXBuaEVR\nZjJCdTRLalhBTnpEN21NYzRQUnFrbjgKLS0tIDJIVDlFZzJuK1pnYklaZnRWOEgz\nNkxLNSsxbzR4cUo0TVVsajNLeXZvZEkKCqo8Hw+CoO+lpKXxI1+3Pkw6iNcaJlzU\n7HE78dhMH2C01Phn9BOFY3FATxo68wYxzLWUt90iGwtnxT1K509GGg==\n-----END AGE ENCRYPTED FILE-----\n" "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHcHlmTVJ1d3ZRc09WMU5p\nbmd4TzZNVisyWm1PZFBmMXpBcmd6N3ZmL0JBCnBqZzZCNVFObHpZZzd3cXBuaEVR\nZjJCdTRLalhBTnpEN21NYzRQUnFrbjgKLS0tIDJIVDlFZzJuK1pnYklaZnRWOEgz\nNkxLNSsxbzR4cUo0TVVsajNLeXZvZEkKCqo8Hw+CoO+lpKXxI1+3Pkw6iNcaJlzU\n7HE78dhMH2C01Phn9BOFY3FATxo68wYxzLWUt90iGwtnxT1K509GGg==\n-----END AGE ENCRYPTED FILE-----\n"
}, },
{ {
"recipient": "age1vla9w33lsp03s46p9p6gc2mvr844vthdqhc2hzau2ph6h60gmyqqh9sf57", "recipient": "age1vla9w33lsp03s46p9p6gc2mvr844vthdqhc2hzau2ph6h60gmyqqh9sf57",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRWnlkYUI3ZFIxR1dBZzNi\nNDRGT2xIZFhyWCs3SHk5Q0toWmZUc3F3RTFVCnZtZUFzNDdOMnlQWVlYVjJnYlJN\nV2xXM3F4N3RVTzVFZE5Zb1BkcjI1cUUKLS0tIHdiQTJTQlpJQlNycElCamN5MGth\nWnNKMnlEQTExbis3dktsWDliaU9IelUK/fxqRPnRbD+KCvYMI4m5K17cLI2/xEbL\nbsGdj8E0TAtzqRL4iBOQfb6xJC5AqcmHEhvFnnxEouNUXMsw5/1Ggg==\n-----END AGE ENCRYPTED FILE-----\n" "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRWnlkYUI3ZFIxR1dBZzNi\nNDRGT2xIZFhyWCs3SHk5Q0toWmZUc3F3RTFVCnZtZUFzNDdOMnlQWVlYVjJnYlJN\nV2xXM3F4N3RVTzVFZE5Zb1BkcjI1cUUKLS0tIHdiQTJTQlpJQlNycElCamN5MGth\nWnNKMnlEQTExbis3dktsWDliaU9IelUK/fxqRPnRbD+KCvYMI4m5K17cLI2/xEbL\nbsGdj8E0TAtzqRL4iBOQfb6xJC5AqcmHEhvFnnxEouNUXMsw5/1Ggg==\n-----END AGE ENCRYPTED FILE-----\n"
}, },
{ {
"recipient": "age1jy8mxcndkw6zd6q99tjgz3gsynn78x2lwtrff85u6ud9g9y9z5mspvhufl", "recipient": "age1jy8mxcndkw6zd6q99tjgz3gsynn78x2lwtrff85u6ud9g9y9z5mspvhufl",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3Zi80ZHU0WnVjMlpycVov\nWE9UNldKRmdMR2xkNVNuQ0NPWHNzTUg4cEU0CmhjdGhEdG5GWkxKUUdRUzMzN0RL\nRHo1QkdSaDNxTy9RVDd5TGtpZUpaRmMKLS0tIG1TTFdrNC9MREd2K0NIdmNscjB5\nQlpGMVdmK2wvQnVxMXJkeTdYbXJtZ0EK12lVIHRp/GxD4F0oMsiOmy4RC5iJEkle\ngvTGPFJkiJJJe36vMx34WdKq++6fwma624E75S4P5qmiVIeadDihGw==\n-----END AGE ENCRYPTED FILE-----\n" "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3Zi80ZHU0WnVjMlpycVov\nWE9UNldKRmdMR2xkNVNuQ0NPWHNzTUg4cEU0CmhjdGhEdG5GWkxKUUdRUzMzN0RL\nRHo1QkdSaDNxTy9RVDd5TGtpZUpaRmMKLS0tIG1TTFdrNC9MREd2K0NIdmNscjB5\nQlpGMVdmK2wvQnVxMXJkeTdYbXJtZ0EK12lVIHRp/GxD4F0oMsiOmy4RC5iJEkle\ngvTGPFJkiJJJe36vMx34WdKq++6fwma624E75S4P5qmiVIeadDihGw==\n-----END AGE ENCRYPTED FILE-----\n"
}, },
{ {
"recipient": "age148huz6rc3q9xx5t873ncx75sja2sazlescwspxl7lsmxsqkz0apsy8cldp", "recipient": "age148huz6rc3q9xx5t873ncx75sja2sazlescwspxl7lsmxsqkz0apsy8cldp",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUYm5Ca0NId3AyRUwxRU1q\nR0NvSUk3YmJvOVRvbTVkVjZ0ZzVxaEFtcGpFCjg3V2ZhUk9RM09ZNVRGVEhUZHZ0\nekNid3NtUVZyTTlZSFU1QkQ0amtEcUkKLS0tIDlTdTBpdDE3VHkyVHhHekZDUEdP\nRUNpdm9ENHhCWCsxbk9aOVFmeFBwUzQKJzTxCMPaYYsmjoGyEbuimDWpq5Oq8oMx\n2LXkQHYdmBi090o4ocfkHiR1SS3w6XNI8IBcQK1flobXYejI9E5yKA==\n-----END AGE ENCRYPTED FILE-----\n" "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUYm5Ca0NId3AyRUwxRU1q\nR0NvSUk3YmJvOVRvbTVkVjZ0ZzVxaEFtcGpFCjg3V2ZhUk9RM09ZNVRGVEhUZHZ0\nekNid3NtUVZyTTlZSFU1QkQ0amtEcUkKLS0tIDlTdTBpdDE3VHkyVHhHekZDUEdP\nRUNpdm9ENHhCWCsxbk9aOVFmeFBwUzQKJzTxCMPaYYsmjoGyEbuimDWpq5Oq8oMx\n2LXkQHYdmBi090o4ocfkHiR1SS3w6XNI8IBcQK1flobXYejI9E5yKA==\n-----END AGE ENCRYPTED FILE-----\n"
}, },
{ {
"recipient": "age197a33mlf5294amjx59hycctu6wm4l3cu3w7n9rv3fs9340ql64rqjzpr7s", "recipient": "age197a33mlf5294amjx59hycctu6wm4l3cu3w7n9rv3fs9340ql64rqjzpr7s",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvR21LYis4SXFxcE1PeXQ3\nelpxRTJ3Y2svRnc1ZTkvVk9lTUhFSmVneWc4CnJMT05ZQnBySDBuZ2lqcnc3eHlv\neWdKUi81aWlhY3pySzhoSjdwUlhMN0kKLS0tIDRWWFR5Q0oyZ09GdlF1a0JmeVdl\nOTV4TUhWdVBVRFhxQlB0ajFSS1FnNHcKMq1FSE3OecwHopvkShKQYSFQihzFkMrG\nFRpPqWcUzaXpib8f4YQrYmLJiihGCpfovv5+NHEQB8BMEu7UNY/emw==\n-----END AGE ENCRYPTED FILE-----\n" "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvR21LYis4SXFxcE1PeXQ3\nelpxRTJ3Y2svRnc1ZTkvVk9lTUhFSmVneWc4CnJMT05ZQnBySDBuZ2lqcnc3eHlv\neWdKUi81aWlhY3pySzhoSjdwUlhMN0kKLS0tIDRWWFR5Q0oyZ09GdlF1a0JmeVdl\nOTV4TUhWdVBVRFhxQlB0ajFSS1FnNHcKMq1FSE3OecwHopvkShKQYSFQihzFkMrG\nFRpPqWcUzaXpib8f4YQrYmLJiihGCpfovv5+NHEQB8BMEu7UNY/emw==\n-----END AGE ENCRYPTED FILE-----\n"
}, },
{ {
"recipient": "age1sqj8z3feqm2dk3gj8mxpfn5dpqnsmus862e8ayd0d4cdresqffdswcf9ru", "recipient": "age1sqj8z3feqm2dk3gj8mxpfn5dpqnsmus862e8ayd0d4cdresqffdswcf9ru",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1YnJVMmpSNDlicUh6UEJR\nL1JUZVlxeUhmTGpUeXNtUmc2NmZGc3NObldVCitHOUgyOXFibnR3WUZRdjc3TExZ\nK0lxRUJCY3ozZExlNzRack5jTTR4aFkKLS0tIGVoOTRCNW5Yb2NVd09ZU0kzSlNV\nVWxuYjVCM3lvZHhQeU05R09WNWQwU2MKNM9VU6KE/0AUzww/qdMQoXMpZ9MT5rIK\nOvltRcVvQR1lZqiox4W1zYfw3JTlficQ31C+wSMHy4aBSlnik7hzxw==\n-----END AGE ENCRYPTED FILE-----\n" "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1YnJVMmpSNDlicUh6UEJR\nL1JUZVlxeUhmTGpUeXNtUmc2NmZGc3NObldVCitHOUgyOXFibnR3WUZRdjc3TExZ\nK0lxRUJCY3ozZExlNzRack5jTTR4aFkKLS0tIGVoOTRCNW5Yb2NVd09ZU0kzSlNV\nVWxuYjVCM3lvZHhQeU05R09WNWQwU2MKNM9VU6KE/0AUzww/qdMQoXMpZ9MT5rIK\nOvltRcVvQR1lZqiox4W1zYfw3JTlficQ31C+wSMHy4aBSlnik7hzxw==\n-----END AGE ENCRYPTED FILE-----\n"
} }
], ],
"lastmodified": "2025-05-12T00:10:01Z", "lastmodified": "2025-05-12T00:10:01Z",
"mac": "ENC[AES256_GCM,data:ChVlujrAP1riogM0SbjFKVbP8M3A7frAgP2UozcWQV/jEYVJDih0wFK+Ww9+GEsgj94ni7mR3GohwdF0f5q2xdSIrw6/OkG3DXuGL8lkr9IaynBqlqwC6Xoc30G9YXDk7ufEjSkrRKO/Trrg6xYAAzxVsJfW3eEkdqS8t9v7pNc=,iv:iPoLylJ0nPWI9Hcrqy422zuZzwblLtgaQwzN/Qarp+Y=,tag:Ept3a+5BHoQlOVKgHXBNTQ==,type:str]", "mac": "ENC[AES256_GCM,data:ChVlujrAP1riogM0SbjFKVbP8M3A7frAgP2UozcWQV/jEYVJDih0wFK+Ww9+GEsgj94ni7mR3GohwdF0f5q2xdSIrw6/OkG3DXuGL8lkr9IaynBqlqwC6Xoc30G9YXDk7ufEjSkrRKO/Trrg6xYAAzxVsJfW3eEkdqS8t9v7pNc=,iv:iPoLylJ0nPWI9Hcrqy422zuZzwblLtgaQwzN/Qarp+Y=,tag:Ept3a+5BHoQlOVKgHXBNTQ==,type:str]",
"unencrypted_suffix": "_unencrypted", "unencrypted_suffix": "_unencrypted",
"version": "3.10.2" "version": "3.10.2"
} }
} }

View File

@@ -1,115 +1,115 @@
wireguardKey: ENC[AES256_GCM,data:7QSnetieVgG5oAmr7XICZxO2R5hDs4TDXDFh2Ntihurwoap91KVtGYOn5vI=,iv:Jt7P7sNrjjkv5im4JDDxaj8btLAnzCdoHOFJQpr/KTI=,tag:FTmXKSVkWftM/XWeUFvJxw==,type:str] wireguardKey: ENC[AES256_GCM,data:7QSnetieVgG5oAmr7XICZxO2R5hDs4TDXDFh2Ntihurwoap91KVtGYOn5vI=,iv:Jt7P7sNrjjkv5im4JDDxaj8btLAnzCdoHOFJQpr/KTI=,tag:FTmXKSVkWftM/XWeUFvJxw==,type:str]
sops: sops:
age: age:
- recipient: age1dzdf4rgep3ctk3dnrmrqtdgrchaa8nszfc4dp29gqwsst3z6jyrq57vfsj - recipient: age1dzdf4rgep3ctk3dnrmrqtdgrchaa8nszfc4dp29gqwsst3z6jyrq57vfsj
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwTnNyQlJWalRZUndqWWVL YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwTnNyQlJWalRZUndqWWVL
ajV6THNndTlkODVOQXdMNGhySHBOUmZLakNNCks1d1pXaFE2S1Z4UlhUN2U1a2NC ajV6THNndTlkODVOQXdMNGhySHBOUmZLakNNCks1d1pXaFE2S1Z4UlhUN2U1a2NC
MjNUZjVRU0FIcStzS012S0UwU09EdUUKLS0tIHh4Y2MyTHpNQ3VuSk0wS1hOV3Av MjNUZjVRU0FIcStzS012S0UwU09EdUUKLS0tIHh4Y2MyTHpNQ3VuSk0wS1hOV3Av
T0RsanNRU0NGZGpmejZkYVYrYUEzY2cKGx4V+4C+wBmLSvYxvq19Dgh5h6aVOYHn T0RsanNRU0NGZGpmejZkYVYrYUEzY2cKGx4V+4C+wBmLSvYxvq19Dgh5h6aVOYHn
jrSDaK4MUfT3lREb2IbiELIm8/G50nFAEmuiLt31WwA/03kiujAJVg== jrSDaK4MUfT3lREb2IbiELIm8/G50nFAEmuiLt31WwA/03kiujAJVg==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1rz75dqzfd6gulwh270ukmt5amcau6j8dpxgzx8fm6u8sjkyx9usq69y4s2 - recipient: age1rz75dqzfd6gulwh270ukmt5amcau6j8dpxgzx8fm6u8sjkyx9usq69y4s2
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHSFdndXBjYWxSUnJFbGdk YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHSFdndXBjYWxSUnJFbGdk
TEpGSzluZnMxR3MrckxUVUllSUw2M3pQN1QwCk9kRWk4N2R4NWdvS2tZbkJwRTdp TEpGSzluZnMxR3MrckxUVUllSUw2M3pQN1QwCk9kRWk4N2R4NWdvS2tZbkJwRTdp
RFdtVVREYU0rZ1Y4YVFqcnhsZnJjVUUKLS0tIGpDZkUrU2FUa04zT00vSkFTV1F6 RFdtVVREYU0rZ1Y4YVFqcnhsZnJjVUUKLS0tIGpDZkUrU2FUa04zT00vSkFTV1F6
akxxeXpRbHNGY1MwanNiSi9pRHVjQ1UKQDnGpvedudfN/XUfrCEQfauPwEoHRNnB akxxeXpRbHNGY1MwanNiSi9pRHVjQ1UKQDnGpvedudfN/XUfrCEQfauPwEoHRNnB
yVrAFd2c2LdPxUO6EChTawm0FuS/MewxNXYuFrpVYIbdtjFw1YSfUg== yVrAFd2c2LdPxUO6EChTawm0FuS/MewxNXYuFrpVYIbdtjFw1YSfUg==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age13x0f3glnz4jvqty2v92cxrrnjcna6ed4qegrhulw9jjy08zuy3aqzvrfc6 - recipient: age13x0f3glnz4jvqty2v92cxrrnjcna6ed4qegrhulw9jjy08zuy3aqzvrfc6
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrd211UmxPQUFDMDVqaTky YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrd211UmxPQUFDMDVqaTky
RTFCNWpVZ1dlbnVSSXorT2tpb1poTjBDUlVJCkM0bnZ3NUFsc0g5OWYxaWRJQU84 RTFCNWpVZ1dlbnVSSXorT2tpb1poTjBDUlVJCkM0bnZ3NUFsc0g5OWYxaWRJQU84
U0Q2dHoyUnRQZUQxN2VQSTZEL1lpVnMKLS0tIHd3U2RmU0M2R1V6cExOcGZza09X U0Q2dHoyUnRQZUQxN2VQSTZEL1lpVnMKLS0tIHd3U2RmU0M2R1V6cExOcGZza09X
WHJ2U3hoUmJjQ1dCaEJQQ2o0WkNRS0UKepPU1A2YsPCc/dbH8ebkRXWx4fQDwXSF WHJ2U3hoUmJjQ1dCaEJQQ2o0WkNRS0UKepPU1A2YsPCc/dbH8ebkRXWx4fQDwXSF
PJ//bpFMjP0vWPWg7wiIktLEJuItrbPlUiPKji4h+OrJBnF0WJw/MA== PJ//bpFMjP0vWPWg7wiIktLEJuItrbPlUiPKji4h+OrJBnF0WJw/MA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age13j6l33g0ghk4vezn0qwfal2qmcgqwkv89ejwezpe3n47mw8yxyuslj6y7d - recipient: age13j6l33g0ghk4vezn0qwfal2qmcgqwkv89ejwezpe3n47mw8yxyuslj6y7d
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsUTdaL2s1dUJpQXAyYUs3 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsUTdaL2s1dUJpQXAyYUs3
bndaNG5zK1FMRVJURFozNURlaDhEMElVSW5NCjE0Q3BTeDhQZk5iR3R0WUppWjVv bndaNG5zK1FMRVJURFozNURlaDhEMElVSW5NCjE0Q3BTeDhQZk5iR3R0WUppWjVv
Q3dRS3AwL2RJWUtoSDdXQU1DR0VnNVkKLS0tIFEvb0gxN0FoUG5hajlSTXpySk5U Q3dRS3AwL2RJWUtoSDdXQU1DR0VnNVkKLS0tIFEvb0gxN0FoUG5hajlSTXpySk5U
Nk5TbkdqNTYvRG9EdmdLUjZBNnlJVEkK779Kc0vUCXQoVVjEqo+qdh0wei11+rMD Nk5TbkdqNTYvRG9EdmdLUjZBNnlJVEkK779Kc0vUCXQoVVjEqo+qdh0wei11+rMD
4sivsMBNMLp6mxRCYv7QdOI8y9P9cVKgFNoQ+x/RBuKMRenA3jYG+A== 4sivsMBNMLp6mxRCYv7QdOI8y9P9cVKgFNoQ+x/RBuKMRenA3jYG+A==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1vla9w33lsp03s46p9p6gc2mvr844vthdqhc2hzau2ph6h60gmyqqh9sf57 - recipient: age1vla9w33lsp03s46p9p6gc2mvr844vthdqhc2hzau2ph6h60gmyqqh9sf57
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4ZzRZQVAyaGRpMnk4cWVU YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4ZzRZQVAyaGRpMnk4cWVU
N0dzajVLNy9LVlF5MHdMeGlEYVE0YmgwWkI0CnhSVzRDQzRUa09KNzVnUFlJdXBp N0dzajVLNy9LVlF5MHdMeGlEYVE0YmgwWkI0CnhSVzRDQzRUa09KNzVnUFlJdXBp
SVI0ZFVxSTUxVTlPZTJCVGd6VDhSZkUKLS0tIHA1V2NtZjRCaHR3ZFlsemxadnpq SVI0ZFVxSTUxVTlPZTJCVGd6VDhSZkUKLS0tIHA1V2NtZjRCaHR3ZFlsemxadnpq
RUI4cXJwTEdPeTluc2ZxTzV6czBndmMK911SZgZn+VIZVnH1fwGK1CFr7WhM/MXm RUI4cXJwTEdPeTluc2ZxTzV6czBndmMK911SZgZn+VIZVnH1fwGK1CFr7WhM/MXm
b98zbNtKmxr2BuP047djZFdrWljCm7ks4WdNFTOK+WdmhxvDvjwU4w== b98zbNtKmxr2BuP047djZFdrWljCm7ks4WdNFTOK+WdmhxvDvjwU4w==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1jy8mxcndkw6zd6q99tjgz3gsynn78x2lwtrff85u6ud9g9y9z5mspvhufl - recipient: age1jy8mxcndkw6zd6q99tjgz3gsynn78x2lwtrff85u6ud9g9y9z5mspvhufl
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCTjBpNUxSWFRQTXBiL055 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCTjBpNUxSWFRQTXBiL055
UldVYkZlZmdLOERTbGpRZkNSZ0ErK1ROa0ZzClJBTmFobjd2WldSdGNuSkM3NmF6 UldVYkZlZmdLOERTbGpRZkNSZ0ErK1ROa0ZzClJBTmFobjd2WldSdGNuSkM3NmF6
Y1JnTTI0MEk3dEg5SnE5MHMwTTJtSUkKLS0tIGxOcCszdHptK1p4L2p5Z01TLzBR Y1JnTTI0MEk3dEg5SnE5MHMwTTJtSUkKLS0tIGxOcCszdHptK1p4L2p5Z01TLzBR
WDd6N2g5enNZcXdDTWFsYzhqeWY2OWcKWyNSq/6OgQYSxrkeaVrQ0Yu2SXcjUT2A WDd6N2g5enNZcXdDTWFsYzhqeWY2OWcKWyNSq/6OgQYSxrkeaVrQ0Yu2SXcjUT2A
hgMTg0gwiXBZNqZ7h4+KzGtDpvwdragAsCUsa3Jxuq7hmnoS8ZBOWQ== hgMTg0gwiXBZNqZ7h4+KzGtDpvwdragAsCUsa3Jxuq7hmnoS8ZBOWQ==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age148huz6rc3q9xx5t873ncx75sja2sazlescwspxl7lsmxsqkz0apsy8cldp - recipient: age148huz6rc3q9xx5t873ncx75sja2sazlescwspxl7lsmxsqkz0apsy8cldp
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwVFVMQjZuVzNoVC9IMTVN YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwVFVMQjZuVzNoVC9IMTVN
bGgyY21CT2c5VUUvaHVDV2JNT0RPb1d2TFI4Ckl5WHplczVRcjZZS2lPVGJIWTFn bGgyY21CT2c5VUUvaHVDV2JNT0RPb1d2TFI4Ckl5WHplczVRcjZZS2lPVGJIWTFn
L214bTlESnpqalNZV3ZZRE5NSmQrU2cKLS0tICtSVTFFejljWUMyMjVrK1lvV0Vl L214bTlESnpqalNZV3ZZRE5NSmQrU2cKLS0tICtSVTFFejljWUMyMjVrK1lvV0Vl
aHdmSjlIdzhVeUdlRjFTQ21veFN5WmMKQ/FcJ/MEZtX31h2U/t5Xd6dNKoJ9aIMf aHdmSjlIdzhVeUdlRjFTQ21veFN5WmMKQ/FcJ/MEZtX31h2U/t5Xd6dNKoJ9aIMf
1fJPF/Z3yDo+P7QpKkkkpQAVbPZITcMPDZq0FrjRjpgkBWyA5TWKWw== 1fJPF/Z3yDo+P7QpKkkkpQAVbPZITcMPDZq0FrjRjpgkBWyA5TWKWw==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1hmfhmr9jv8ll33az4w2zrdu5zl2p5dx7kx97lhvc9xn68rr9049qx0hvfe - recipient: age1hmfhmr9jv8ll33az4w2zrdu5zl2p5dx7kx97lhvc9xn68rr9049qx0hvfe
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtajlGb01xclZNcytoV3BM YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtajlGb01xclZNcytoV3BM
NGVYUk9TOGhiY2RwR2krQjI0SjlhMDVKOFdrCmtxNWx3MEVTa3pHWW5IS0lZNG5C NGVYUk9TOGhiY2RwR2krQjI0SjlhMDVKOFdrCmtxNWx3MEVTa3pHWW5IS0lZNG5C
N2xaWTFXdEY0U2JsY3p6MS8rRE1Wd0kKLS0tIGpCUjRIdFBrdzA4TWw4REVTV2x5 N2xaWTFXdEY0U2JsY3p6MS8rRE1Wd0kKLS0tIGpCUjRIdFBrdzA4TWw4REVTV2x5
TUtLbDk0TEZOTTNTMWd1Vjh4a1RhQ2cKGf2//pAFtMWoGvv4HujL+uRmLYNasWQN TUtLbDk0TEZOTTNTMWd1Vjh4a1RhQ2cKGf2//pAFtMWoGvv4HujL+uRmLYNasWQN
LbvNaCZY5/FupDAuS8VDRUX84OriZ8iJb0hH1aThOJ4n86t3HkAw7Q== LbvNaCZY5/FupDAuS8VDRUX84OriZ8iJb0hH1aThOJ4n86t3HkAw7Q==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1nemhad8mc2vl3mfvzs3gax7p3u28ltmzx3mu8wx9mcu2700qjyksr8dq0g - recipient: age1nemhad8mc2vl3mfvzs3gax7p3u28ltmzx3mu8wx9mcu2700qjyksr8dq0g
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjZ2c0VTg3YkcwZFg4cG9N YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjZ2c0VTg3YkcwZFg4cG9N
QUNKWW13b0xDZDBpbis2ckM0YmI3bk9OVnk0CkpRazZvUHJFZUVwaXV0elZxbVVZ QUNKWW13b0xDZDBpbis2ckM0YmI3bk9OVnk0CkpRazZvUHJFZUVwaXV0elZxbVVZ
V0VXTWg5U2tqUEt2RVBjZEI2ZXFZazgKLS0tIENXNUlwTmNCL2k4OCtBQXlSTWtp V0VXTWg5U2tqUEt2RVBjZEI2ZXFZazgKLS0tIENXNUlwTmNCL2k4OCtBQXlSTWtp
a0ZCTTA5NFBmUTFObG1NdlExYi83MFUKO8UUPKeFwkcqhMnT6GHKQ4m9C9KUnc4b a0ZCTTA5NFBmUTFObG1NdlExYi83MFUKO8UUPKeFwkcqhMnT6GHKQ4m9C9KUnc4b
jsDJtBzLZK5TRigUaxYSTGNV7tA5HwmsqHUgaHIw4peli1olijRSPA== jsDJtBzLZK5TRigUaxYSTGNV7tA5HwmsqHUgaHIw4peli1olijRSPA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age197a33mlf5294amjx59hycctu6wm4l3cu3w7n9rv3fs9340ql64rqjzpr7s - recipient: age197a33mlf5294amjx59hycctu6wm4l3cu3w7n9rv3fs9340ql64rqjzpr7s
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBodUZ0R2grYUdTYjRsK3VW YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBodUZ0R2grYUdTYjRsK3VW
c3hISHhtekdhWmR0dzBNWFhKUm5sd081WVZnCnZaU2RZTzQ2RHVNNjZmZG1hYW9D c3hISHhtekdhWmR0dzBNWFhKUm5sd081WVZnCnZaU2RZTzQ2RHVNNjZmZG1hYW9D
Sld0cDJDbHk1OW9HRUJSY1RFVHlURXMKLS0tIDA0UXo2a3Vsa1oxOE9QNkZobHFE Sld0cDJDbHk1OW9HRUJSY1RFVHlURXMKLS0tIDA0UXo2a3Vsa1oxOE9QNkZobHFE
cEt5WVN4cmNOblNYSWl4RG5kNVpWU0kKUfSTJKdrHaOFbOU08NT6+yIFYNawCAR9 cEt5WVN4cmNOblNYSWl4RG5kNVpWU0kKUfSTJKdrHaOFbOU08NT6+yIFYNawCAR9
QYeH1hxXC6fwNsAnnaaSYnXG8/CIRG6N3IAqIX9P32dM+YQBPFguvA== QYeH1hxXC6fwNsAnnaaSYnXG8/CIRG6N3IAqIX9P32dM+YQBPFguvA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1sqj8z3feqm2dk3gj8mxpfn5dpqnsmus862e8ayd0d4cdresqffdswcf9ru - recipient: age1sqj8z3feqm2dk3gj8mxpfn5dpqnsmus862e8ayd0d4cdresqffdswcf9ru
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0VUl2UnlmS3RUemdMYkN1 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0VUl2UnlmS3RUemdMYkN1
OUpUVmFObVkzMVRKWEZ2NVpQeUdwR1dDeGxzCklDYXIvNFc4d09aazJlaEM5MDJD OUpUVmFObVkzMVRKWEZ2NVpQeUdwR1dDeGxzCklDYXIvNFc4d09aazJlaEM5MDJD
OWZnSUN6cVZmdEw2Zm9wQjZsRHFLZDgKLS0tIERBdDBSK1RBNUFPSzVtS05sVk1Y OWZnSUN6cVZmdEw2Zm9wQjZsRHFLZDgKLS0tIERBdDBSK1RBNUFPSzVtS05sVk1Y
Q3M2c3duZGhhMHpkN0hkb3VWRC9aMVEKRRos0MJWyal1fNDKKFtylNXdPAqQ9Efy Q3M2c3duZGhhMHpkN0hkb3VWRC9aMVEKRRos0MJWyal1fNDKKFtylNXdPAqQ9Efy
WdQEvKwjrFX4kDjLkxc6ILXSzGNwAl6Fl8qNvYX3bXWrJtbWcVvZog== WdQEvKwjrFX4kDjLkxc6ILXSzGNwAl6Fl8qNvYX3bXWrJtbWcVvZog==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1aj3fwaeaem7aph9f3m6tfg4dsfs3n4hdfjvgel90n8alymcn0ypsj7x9ad - recipient: age1aj3fwaeaem7aph9f3m6tfg4dsfs3n4hdfjvgel90n8alymcn0ypsj7x9ad
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4WDBzZXpTN25TUHZQSStp YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4WDBzZXpTN25TUHZQSStp
QWg5SFNMWml4aWVRS1c2dHBHcnRWK2R2SkMwCnoySjhrV1NRcmFSVHJZTTA1YmFK QWg5SFNMWml4aWVRS1c2dHBHcnRWK2R2SkMwCnoySjhrV1NRcmFSVHJZTTA1YmFK
RjNYNkRsTjd4ZjByc1owWGFibGNzd1UKLS0tIDlMNm9hdURYU2lLNjQydmdkUHgx RjNYNkRsTjd4ZjByc1owWGFibGNzd1UKLS0tIDlMNm9hdURYU2lLNjQydmdkUHgx
TnVCSTBGazlMQy9vYURIQVZrendaR3MKqJk5CF3YbOMY09CEuXVxJqsrkb6A/PLn TnVCSTBGazlMQy9vYURIQVZrendaR3MKqJk5CF3YbOMY09CEuXVxJqsrkb6A/PLn
lIWLggJpKmuqOpob8YHC9uuftW1siymHOYOzVjOIsup0uK+M3tzkcQ== lIWLggJpKmuqOpob8YHC9uuftW1siymHOYOzVjOIsup0uK+M3tzkcQ==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-05-11T08:20:24Z" lastmodified: "2025-05-11T08:20:24Z"
mac: ENC[AES256_GCM,data:O6toC5E/c3bwqC2GogMsGgS8u4DV0sr1d7Kt5JNP8cDd5mqWicgSvtzmDWb6nfs8rtWiV9rzyQaITXto3pGSSm0fPbutfwd1/zv4HVm9V8tkd90P1lal2SEmJxwmXsewMoSmnM+Dttyp8iQrhxS/Vgtl4U5gjahjNqQuMvMqOEY=,iv:aPBrbrhmU6qVgjsRXvZ7hmFb05UAxeRDkXUsPe85ryU=,tag:ulAf/h7sdPJmNGhhN6sY8A==,type:str] mac: ENC[AES256_GCM,data:O6toC5E/c3bwqC2GogMsGgS8u4DV0sr1d7Kt5JNP8cDd5mqWicgSvtzmDWb6nfs8rtWiV9rzyQaITXto3pGSSm0fPbutfwd1/zv4HVm9V8tkd90P1lal2SEmJxwmXsewMoSmnM+Dttyp8iQrhxS/Vgtl4U5gjahjNqQuMvMqOEY=,iv:aPBrbrhmU6qVgjsRXvZ7hmFb05UAxeRDkXUsPe85ryU=,tag:ulAf/h7sdPJmNGhhN6sY8A==,type:str]
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.10.2 version: 3.10.2

View File

@@ -1,97 +1,97 @@
miracult-zulip-email-password: ENC[AES256_GCM,data:GYhPa6fsoUEQdepgO8hJb2vtjBqlGtvCbWrq7SMedETPgnTt,iv:MJf2AgstKCSU30C0KsjdnSHgdXDB2xij67mwSU34sb0=,tag:yimDJ03mpfPr8qfXiT5bcQ==,type:str] miracult-zulip-email-password: ENC[AES256_GCM,data:GYhPa6fsoUEQdepgO8hJb2vtjBqlGtvCbWrq7SMedETPgnTt,iv:MJf2AgstKCSU30C0KsjdnSHgdXDB2xij67mwSU34sb0=,tag:yimDJ03mpfPr8qfXiT5bcQ==,type:str]
sops: sops:
age: age:
- recipient: age1dzdf4rgep3ctk3dnrmrqtdgrchaa8nszfc4dp29gqwsst3z6jyrq57vfsj - recipient: age1dzdf4rgep3ctk3dnrmrqtdgrchaa8nszfc4dp29gqwsst3z6jyrq57vfsj
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOWUNwRlpMWUNtN3RWM3kw YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOWUNwRlpMWUNtN3RWM3kw
TTg4cEtEYnhvSzMzMkVBVVZmVFdGZWNiZG5nCjB2dGhNZnNFMG9HWHZvdXVWNkMx TTg4cEtEYnhvSzMzMkVBVVZmVFdGZWNiZG5nCjB2dGhNZnNFMG9HWHZvdXVWNkMx
blhjNTZTMVBYY1VOMGpORDVvN2lES0EKLS0tIE1iaDByRi9HaFJSS1NiNHYxTHo2 blhjNTZTMVBYY1VOMGpORDVvN2lES0EKLS0tIE1iaDByRi9HaFJSS1NiNHYxTHo2
L1N3MkJCVE8vU3dpU1M0SzFrZThrTzQKPpKq746YP6rVlanWNc/GezFu8H1qH0xO L1N3MkJCVE8vU3dpU1M0SzFrZThrTzQKPpKq746YP6rVlanWNc/GezFu8H1qH0xO
99cvsV+5Ns03KAwjMb/gXjJOoyLzr+iK7lKzYEyP4gqL20caDxnjNw== 99cvsV+5Ns03KAwjMb/gXjJOoyLzr+iK7lKzYEyP4gqL20caDxnjNw==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1rz75dqzfd6gulwh270ukmt5amcau6j8dpxgzx8fm6u8sjkyx9usq69y4s2 - recipient: age1rz75dqzfd6gulwh270ukmt5amcau6j8dpxgzx8fm6u8sjkyx9usq69y4s2
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwRnJQRVNjQ3o5RjRzL1M1 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwRnJQRVNjQ3o5RjRzL1M1
aVJhY3BPMW40Z0ZMNk1MV3lrazJhWDRWYmtVCnIzek5vanVqWUp2ajRMSlA5VjNS aVJhY3BPMW40Z0ZMNk1MV3lrazJhWDRWYmtVCnIzek5vanVqWUp2ajRMSlA5VjNS
Z3VrM0QxWHFaM0ZkVFJ4UDcrZ0l1RVUKLS0tIDlkZUZjMERPS1lYOElOT2s0NzJ3 Z3VrM0QxWHFaM0ZkVFJ4UDcrZ0l1RVUKLS0tIDlkZUZjMERPS1lYOElOT2s0NzJ3
bWRxZHh6NlIvWmRjU0pGN0VsOGpUOWMKvjHPQLljyA3a46JeuNrjzLNe71eRA5Eq bWRxZHh6NlIvWmRjU0pGN0VsOGpUOWMKvjHPQLljyA3a46JeuNrjzLNe71eRA5Eq
EkoE4BVb5zCIzsGhigLxvOC/t1lRwY5+XVktkNTltgzuvnoV4m8czA== EkoE4BVb5zCIzsGhigLxvOC/t1lRwY5+XVktkNTltgzuvnoV4m8czA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age13x0f3glnz4jvqty2v92cxrrnjcna6ed4qegrhulw9jjy08zuy3aqzvrfc6 - recipient: age13x0f3glnz4jvqty2v92cxrrnjcna6ed4qegrhulw9jjy08zuy3aqzvrfc6
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCcG92V21xcDlZeXNvRVo4 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCcG92V21xcDlZeXNvRVo4
MGllQnlUQmQ1d1E3TVNIQUc4eWhCT1dySzJNClovMlFKS3RzSXpLMHRmSWtIRkdU MGllQnlUQmQ1d1E3TVNIQUc4eWhCT1dySzJNClovMlFKS3RzSXpLMHRmSWtIRkdU
SDluVUs0MmtZcmd4NDAzRnpPTFJ2MncKLS0tIEFJWE9WTEZEZGNYR0xaSzZ6eG5W SDluVUs0MmtZcmd4NDAzRnpPTFJ2MncKLS0tIEFJWE9WTEZEZGNYR0xaSzZ6eG5W
RWNHYzVWakMva1Z4MFcvNEVQWStnRVkKhhrGa6hBnBvqSrV3M6fk9SpgFnqSwb9i RWNHYzVWakMva1Z4MFcvNEVQWStnRVkKhhrGa6hBnBvqSrV3M6fk9SpgFnqSwb9i
bGf7SxaEiFJGLjRZk/Iw6IjYOlyVPiL5cdO0gbIcvC5ZODEYlW4G7w== bGf7SxaEiFJGLjRZk/Iw6IjYOlyVPiL5cdO0gbIcvC5ZODEYlW4G7w==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age13j6l33g0ghk4vezn0qwfal2qmcgqwkv89ejwezpe3n47mw8yxyuslj6y7d - recipient: age13j6l33g0ghk4vezn0qwfal2qmcgqwkv89ejwezpe3n47mw8yxyuslj6y7d
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRZ1pmUVBXWG9jOGpjU1hk YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRZ1pmUVBXWG9jOGpjU1hk
N0QrNW9DZFFBSW4xdC9YN05wTjlBckhxelFjCjlCMGFVcVk1d1Q3Q0FsOTRQTW05 N0QrNW9DZFFBSW4xdC9YN05wTjlBckhxelFjCjlCMGFVcVk1d1Q3Q0FsOTRQTW05
NTVYOU5ickMyZUYvck11NWNCWC9EdEkKLS0tIC90djBWbk9vVE05ZnJDWDBPbXhJ NTVYOU5ickMyZUYvck11NWNCWC9EdEkKLS0tIC90djBWbk9vVE05ZnJDWDBPbXhJ
bWpqMHpDQjZZYmhlSzJNQWZIeGp6YzgKpaWfW9ChAASEQti3WIPLCdUlkEWPe1Ad bWpqMHpDQjZZYmhlSzJNQWZIeGp6YzgKpaWfW9ChAASEQti3WIPLCdUlkEWPe1Ad
4ee5uxvsJUWDWqWHJYtH/ciBEthu0dngniPrUBOuk9+YqK+F4D0Vbg== 4ee5uxvsJUWDWqWHJYtH/ciBEthu0dngniPrUBOuk9+YqK+F4D0Vbg==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1vla9w33lsp03s46p9p6gc2mvr844vthdqhc2hzau2ph6h60gmyqqh9sf57 - recipient: age1vla9w33lsp03s46p9p6gc2mvr844vthdqhc2hzau2ph6h60gmyqqh9sf57
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGWUl6WFpqdG1aRzJVUWZy YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGWUl6WFpqdG1aRzJVUWZy
TXJmTWxQSzBvaEhHM1pQdFEvaGw2bktCSXlvCnNMaEFGdTVmTU50L1g5Tm1UbURD TXJmTWxQSzBvaEhHM1pQdFEvaGw2bktCSXlvCnNMaEFGdTVmTU50L1g5Tm1UbURD
dzJSVy9hc3U1OS9qN3lUaTFGRzNzZmcKLS0tIGU1WjhYaDRWMkdHSGVvSDd3c0Rm dzJSVy9hc3U1OS9qN3lUaTFGRzNzZmcKLS0tIGU1WjhYaDRWMkdHSGVvSDd3c0Rm
MXJ5clR6RGFFV2EreTBxYkxxYXBjS2cKSOeDOnnP5iu8OHZHDq+1F06vdrTM95XU MXJ5clR6RGFFV2EreTBxYkxxYXBjS2cKSOeDOnnP5iu8OHZHDq+1F06vdrTM95XU
nynx8fqqc3uQHaD3h2M7f+foDUE3EeTrXZjm3bKBng4DiyO4mAyfMA== nynx8fqqc3uQHaD3h2M7f+foDUE3EeTrXZjm3bKBng4DiyO4mAyfMA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1jy8mxcndkw6zd6q99tjgz3gsynn78x2lwtrff85u6ud9g9y9z5mspvhufl - recipient: age1jy8mxcndkw6zd6q99tjgz3gsynn78x2lwtrff85u6ud9g9y9z5mspvhufl
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDTUw3cjZCTytIV09Mci8z YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDTUw3cjZCTytIV09Mci8z
RHRIRFZtLzlrb0M4UFExN0k2bHcrZ3JKcHlBCkwwTXgyM0JWTHdrODl2emxMbkl4 RHRIRFZtLzlrb0M4UFExN0k2bHcrZ3JKcHlBCkwwTXgyM0JWTHdrODl2emxMbkl4
ZzhNUitGdkZLM0dqRWhUZ3FoZ040ZEEKLS0tIGR1Zi80ZzJOUWNGUGdBdlJ0Qmhm ZzhNUitGdkZLM0dqRWhUZ3FoZ040ZEEKLS0tIGR1Zi80ZzJOUWNGUGdBdlJ0Qmhm
bkxYM1NZUVVvTTY5cEF3cnFxYjk0V2MKi7aSoRN5/2oJMqjjZplKnwMHiUU71V9d bkxYM1NZUVVvTTY5cEF3cnFxYjk0V2MKi7aSoRN5/2oJMqjjZplKnwMHiUU71V9d
Lk3ZYBsJ2FSBjlVO88+LiciDxOqtm8u1TddonCCrHXVyH/ud4aDVLA== Lk3ZYBsJ2FSBjlVO88+LiciDxOqtm8u1TddonCCrHXVyH/ud4aDVLA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age148huz6rc3q9xx5t873ncx75sja2sazlescwspxl7lsmxsqkz0apsy8cldp - recipient: age148huz6rc3q9xx5t873ncx75sja2sazlescwspxl7lsmxsqkz0apsy8cldp
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlSk1RUUU0dWVsNnd1aXlM YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlSk1RUUU0dWVsNnd1aXlM
c2pRenBqZ1lGSjgrRDdGZ1BnemgyT3gzTFh3CnNFSmY2L1hHVXczUnFFcUVyWFRO c2pRenBqZ1lGSjgrRDdGZ1BnemgyT3gzTFh3CnNFSmY2L1hHVXczUnFFcUVyWFRO
dkswL0srVGErUGIwRjN4a1lacGpwOEEKLS0tIDRUOUpOVHNzdVhXY01zdHNhMlow dkswL0srVGErUGIwRjN4a1lacGpwOEEKLS0tIDRUOUpOVHNzdVhXY01zdHNhMlow
T3V2Nk1zTitNUUJORndSeElBUnR1eUkKNfYcYgMRPtJZbVjw7XSPG3gkG81RLXl6 T3V2Nk1zTitNUUJORndSeElBUnR1eUkKNfYcYgMRPtJZbVjw7XSPG3gkG81RLXl6
iCVVhiyB6Lcz9pStzYhbpxfgD21lL8TIgOJ0Sr5U6UYnt0XRmnBRYQ== iCVVhiyB6Lcz9pStzYhbpxfgD21lL8TIgOJ0Sr5U6UYnt0XRmnBRYQ==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age197a33mlf5294amjx59hycctu6wm4l3cu3w7n9rv3fs9340ql64rqjzpr7s - recipient: age197a33mlf5294amjx59hycctu6wm4l3cu3w7n9rv3fs9340ql64rqjzpr7s
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoRzdkK2NNY01hTTZkVlV0 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoRzdkK2NNY01hTTZkVlV0
bEtiYW15SWhwd1FVczZsajZWekViMUV5ZTJNCndBTnAxaW1NckZESTRVMUduSkNL bEtiYW15SWhwd1FVczZsajZWekViMUV5ZTJNCndBTnAxaW1NckZESTRVMUduSkNL
UUtLUm53RzdZajJQaHVzUG5KcDdVMDgKLS0tIDJ3YWVIUUw1QUVsVVZOb2QzRmdQ UUtLUm53RzdZajJQaHVzUG5KcDdVMDgKLS0tIDJ3YWVIUUw1QUVsVVZOb2QzRmdQ
cTl2bDlnMTNUVWR2U1BWWEwzajVTUjgKFMVRvgRwBmYBKOPxCXM4ruTjkKGmfBF5 cTl2bDlnMTNUVWR2U1BWWEwzajVTUjgKFMVRvgRwBmYBKOPxCXM4ruTjkKGmfBF5
mHeGN4KyIvd6i2l/3bOOhBqdcXcjhTpUGKjaQCHIJd00oXcXWRE5Tw== mHeGN4KyIvd6i2l/3bOOhBqdcXcjhTpUGKjaQCHIJd00oXcXWRE5Tw==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1sqj8z3feqm2dk3gj8mxpfn5dpqnsmus862e8ayd0d4cdresqffdswcf9ru - recipient: age1sqj8z3feqm2dk3gj8mxpfn5dpqnsmus862e8ayd0d4cdresqffdswcf9ru
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTMDlrZFdZNmJsZXRiRmVY YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTMDlrZFdZNmJsZXRiRmVY
NXlKWDdoV1VOblhFa3Ywd3RYMjRnVmR1dndFCktHWUdwTytienY1V29HaGNUTjF2 NXlKWDdoV1VOblhFa3Ywd3RYMjRnVmR1dndFCktHWUdwTytienY1V29HaGNUTjF2
L1BEczNTSmx4SElrNGNLVVJZTC9VT0kKLS0tIFd0MG0zY1BYNWNxT0t0bEVKUjZD L1BEczNTSmx4SElrNGNLVVJZTC9VT0kKLS0tIFd0MG0zY1BYNWNxT0t0bEVKUjZD
L3FqKzc1bEJwRStjRCtWb1BPajV2V3cKES3e5IlG+Yp4EB4XF8zTbVgMVGpKT3N7 L3FqKzc1bEJwRStjRCtWb1BPajV2V3cKES3e5IlG+Yp4EB4XF8zTbVgMVGpKT3N7
FSrmkg5xS0ApQfA/MqWAI/1UvdNsD27CEzdxTgeV/a7lfOBVAnFN3Q== FSrmkg5xS0ApQfA/MqWAI/1UvdNsD27CEzdxTgeV/a7lfOBVAnFN3Q==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age10lv32k2guszr5y69sez3z5xj92wzmdxvfejd6hm8xr0pmclw2cvq0hk6pe - recipient: age10lv32k2guszr5y69sez3z5xj92wzmdxvfejd6hm8xr0pmclw2cvq0hk6pe
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhZzlLL1RJVjE1VjRPVE1m YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhZzlLL1RJVjE1VjRPVE1m
aStJejBhcDBWRW9XSlJUQzlwYVI3Nk4yZmk4Cm5ZRnhET0xzOFVqRVc1dFlNTCsr aStJejBhcDBWRW9XSlJUQzlwYVI3Nk4yZmk4Cm5ZRnhET0xzOFVqRVc1dFlNTCsr
dEdQYnlCcXhRTlRiWm4wVjZkOStWR0EKLS0tIHAvdmFGS0pBNEUvQmhaajFwTjA4 dEdQYnlCcXhRTlRiWm4wVjZkOStWR0EKLS0tIHAvdmFGS0pBNEUvQmhaajFwTjA4
MU1oUFZVSG9WdUZUSlVCcThOV2tacWcKZJ0gOpHDyYo7c6sDo2Tr6QKb8vAeKGc5 MU1oUFZVSG9WdUZUSlVCcThOV2tacWcKZJ0gOpHDyYo7c6sDo2Tr6QKb8vAeKGc5
V+Yfme18d5chlnrgcV2KanF4ghzroAZFZnxl37cUaOpKmD1eQhfoKw== V+Yfme18d5chlnrgcV2KanF4ghzroAZFZnxl37cUaOpKmD1eQhfoKw==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-04-24T10:17:03Z" lastmodified: "2025-04-24T10:17:03Z"
mac: ENC[AES256_GCM,data:ug88LdeQowHima+G6GFfXSRbcy6yhTU55gjCZB5dGMINdrtvnW03bfOvYuI5LKNwmLDY8lh2WSvZXhuFgPLs9gDrFHg5Ys6oe7DZo5FdT6LhMcIHkhgvmK7lpXjJq7HFPrmYOitkcQjg77g0KwTrz6+SchCHm4yd+d2+TQtMggM=,iv:kEKVox/RYCnGC9xvsi+PqjNH3SVfQ+mMspN8FKND4HI=,tag:uPBBZqWj2k/bIhch/vXfug==,type:str] mac: ENC[AES256_GCM,data:ug88LdeQowHima+G6GFfXSRbcy6yhTU55gjCZB5dGMINdrtvnW03bfOvYuI5LKNwmLDY8lh2WSvZXhuFgPLs9gDrFHg5Ys6oe7DZo5FdT6LhMcIHkhgvmK7lpXjJq7HFPrmYOitkcQjg77g0KwTrz6+SchCHm4yd+d2+TQtMggM=,iv:kEKVox/RYCnGC9xvsi+PqjNH3SVfQ+mMspN8FKND4HI=,tag:uPBBZqWj2k/bIhch/vXfug==,type:str]
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.10.2 version: 3.10.2

View File

@@ -217,7 +217,7 @@ in
security.pki.certificateFiles = [ rootCA.certificatePath ]; security.pki.certificateFiles = [ rootCA.certificatePath ];
vacu.liam.backup.keyPath = pkgs.writeText "test-borg-key" testBorgKey; vacu.liam.backup.keyPath = pkgs.writeText "test-borg-key" testBorgKey;
vacu.hosts.rsn.sshKeys = lib.mkForce []; # remove known key so i can do a trust-on-first-use in the test vacu.hosts.rsn.sshKeys = lib.mkForce [ ]; # remove known key so i can do a trust-on-first-use in the test
networking.hosts."${nodes.rsyncnet.networking.primaryIPAddress}" = [ networking.hosts."${nodes.rsyncnet.networking.primaryIPAddress}" = [
config.vacu.liam.backup.rsyncHost config.vacu.liam.backup.rsyncHost
]; ];
@@ -264,10 +264,12 @@ in
}; };
}; };
environment.systemPackages = [ environment.systemPackages = [
(lib.hiPrio (pkgs.writeScriptBin "borg" '' (lib.hiPrio (
echo "bad: called plain bin/borg" >&2 pkgs.writeScriptBin "borg" ''
exit 1 echo "bad: called plain bin/borg" >&2
'')) exit 1
''
))
(pkgs.writeScriptBin "borg14" '' (pkgs.writeScriptBin "borg14" ''
exec ${lib.getExe pkgs.borgbackup} "$@" exec ${lib.getExe pkgs.borgbackup} "$@"
'') '')

View File

@@ -286,9 +286,7 @@ d = Defaults(
username="shelvacu", username="shelvacu",
) )
# test refilter # test refilter
d.make_tester().smtp_accepted().imap_move_to("MagicRefilter").imap_found_in( d.make_tester().smtp_accepted().imap_move_to("MagicRefilter").imap_found_in("B")
"B"
)
# refilter doesnt activate on other folders # refilter doesnt activate on other folders
d.make_tester().smtp_accepted().imap_move_to("testFolder").imap_found_in("testFolder") d.make_tester().smtp_accepted().imap_move_to("testFolder").imap_found_in("testFolder")
d.make_tester().smtp_accepted().imap_move_to("INBOX").imap_found_in("INBOX") d.make_tester().smtp_accepted().imap_move_to("INBOX").imap_found_in("INBOX")
@@ -309,9 +307,7 @@ d.make_tester().smtp_accepted(
mailfrom="shipment-tracking@amazon.com", mailfrom="shipment-tracking@amazon.com",
rcptto="amznbsns@shelvacu.com", rcptto="amznbsns@shelvacu.com",
subject="Your Amazon.com order has shipped (#123-1234)", subject="Your Amazon.com order has shipped (#123-1234)",
).imap_expect( ).imap_expect(mailbox="C", flags=["amazon-ignore"])
mailbox="C", flags=["amazon-ignore"]
)
TesterThing().smtp_accepted( TesterThing().smtp_accepted(
rcptto="shelvacu@shelvacu.com", username="shelvacu", smtp_starttls=True rcptto="shelvacu@shelvacu.com", username="shelvacu", smtp_starttls=True

4
tliam
View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -euo pipefail
function fail() { function fail() {
msg="$1" msg="$1"
@@ -11,7 +11,7 @@ function fail() {
git add . git add .
declare -a flake_archive_cmd=(nix flake archive --json) declare -a flake_archive_cmd=(nix flake archive --json)
declare -a prefix declare -a prefix
if [ "$HOST" != "triple-dezert" ]; then if [[ ${HOST-x} != "triple-dezert" ]]; then
flake_archive_cmd+=(--to "ssh://trip") flake_archive_cmd+=(--to "ssh://trip")
prefix+=(ssh trip -- sudo) prefix+=(ssh trip -- sudo)
fi fi

View File

@@ -1,4 +1,4 @@
{ ... }: { pkgs, ... }:
let let
shellFiles = [ shellFiles = [
"*.sh" "*.sh"
@@ -15,8 +15,17 @@ in
projectRootFile = "flake.nix"; projectRootFile = "flake.nix";
programs.nixfmt.enable = true; programs.nixfmt.enable = true;
programs.nixfmt.strict = true; programs.nixfmt.strict = true;
programs.shellcheck.enable = true; programs.shellcheck = {
programs.shellcheck.includes = shellFiles; enable = true;
includes = shellFiles;
};
settings.formatter.shellcheck.options = [
"--external-sources"
"--norc"
"--source-path=${pkgs.shellvaculib}/bin"
"--enable=all"
"--exclude=SC2250"
];
programs.shfmt.enable = true; programs.shfmt.enable = true;
programs.shfmt.includes = shellFiles; programs.shfmt.includes = shellFiles;
programs.deno.enable = true; programs.deno.enable = true;

View File

@@ -1,4 +1,9 @@
{ config, pkgs, lib, ... }: {
config,
pkgs,
lib,
...
}:
{ {
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix

View File

@@ -1,4 +1,9 @@
{ config, inputs, pkgs, ... }: {
config,
inputs,
pkgs,
...
}:
let let
name = "jl-stats"; name = "jl-stats";
contain = config.containers.${name}; contain = config.containers.${name};

View File

@@ -1,4 +1,9 @@
{ lib, pkgs, config, ... }: {
lib,
pkgs,
config,
...
}:
let let
domain = "chat.for.miras.pet"; domain = "chat.for.miras.pet";
port = 3169; port = 3169;
@@ -19,7 +24,7 @@ in
ipAddress = "127.0.0.1"; ipAddress = "127.0.0.1";
}; };
sops.secrets.miracult-zulip-email-password = {}; sops.secrets.miracult-zulip-email-password = { };
sops.templates."zulip-secrets".content = '' sops.templates."zulip-secrets".content = ''
SECRETS_email_password=${config.sops.placeholder.miracult-zulip-email-password} SECRETS_email_password=${config.sops.placeholder.miracult-zulip-email-password}
''; '';

View File

@@ -1,4 +1,9 @@
{ inputs, config, lib, ... }: {
inputs,
config,
lib,
...
}:
{ {
imports = [ inputs.sops-nix.nixosModules.sops ]; imports = [ inputs.sops-nix.nixosModules.sops ];

View File

@@ -1,33 +0,0 @@
{ lib }:
let
inherit (lib) length isString substring optional elemAt match;
in
userId:
assert isString userId;
let
splitOnColon = lib.splitString ":" userId;
# https://spec.matrix.org/v1.14/appendices/#user-identifiers
errors = []
# "The length of a user ID, including the @ sigil and the domain, MUST NOT exceed 255 bytes."
++ optional ((length userId) > 255) "must be 255 bytes or shorter"
++ optional ((substring 0 1 userId) != "@") "must start with an @ symbol"
++ optional ((length splitOnColon) < 2) "must have a : inbetween the username and the server"
++ optional ((length splitOnColon) > 3) "too many : symbols"
++ if (length splitOnColon) < 2 || (length splitOnColon) > 3 then [] else (
let
localpart_with_at = elemAt splitOnColon 0;
localpart = substring 1 -1 localpart_with_at;
domain = elemAt splitOnColon 1;
port = if (length splitOnColon) == 3 then elemAt splitOnColon 2 else null;
in
[]
++ optional ((length localpart) == 0) "username is missing"
++ optional ((match "[0-9a-z+/_=.-]+" localpart) == null) "username must only contain digits 0-9, lowercase letters a-z, and any of the symbols +/_=.-"
++ optional (
)
;
in
{
inherit errors;
valid = (length errors) == 0;
}