Compare commits

..

1 Commits

Author SHA1 Message Date
5c7f147a2e nixos: Initial netbooting installer
Some checks failed
CI / Check, build and cache Nix flake (push) Has been cancelled
Installer / Build installer (push) Failing after 4m38s
2024-06-24 00:08:55 +01:00
137 changed files with 1753 additions and 2839 deletions

View File

@@ -6,11 +6,11 @@ on:
jobs: jobs:
check: check:
name: Check, build and cache nixfiles name: Check, build and cache Nix flake
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: cachix/install-nix-action@v27 - uses: cachix/install-nix-action@v23
with: with:
# Gitea will supply a token in GITHUB_TOKEN, which this action will # Gitea will supply a token in GITHUB_TOKEN, which this action will
# try to pass to Nix when downloading from GitHub # try to pass to Nix when downloading from GitHub
@@ -18,30 +18,22 @@ jobs:
extra_nix_config: | extra_nix_config: |
# Make sure we're using sandbox # Make sure we're using sandbox
sandbox-fallback = false sandbox-fallback = false
# Big C++ projects fill up memory...
cores = 6
extra-substituters = https://nix-cache.nul.ie extra-substituters = https://nix-cache.nul.ie/main
extra-trusted-public-keys = nix-cache.nul.ie-1:BzH5yMfF4HbzY1C977XzOxoPhEc9Zbu39ftPkUbH+m4= extra-trusted-public-keys = main:mMChkG8LwXrFirVfudqjSHasK1jV31OVElYD3eImYl8=
- name: Set up attic
run: |
nix run .#nixpkgs.mine.x86_64-linux.attic-client -- \
login --set-default colony https://nix-cache.nul.ie "${{ secrets.NIX_CACHE_TOKEN }}"
- name: Check flake - name: Check flake
run: nix flake check --no-build run: nix flake check
- name: Build the world
- name: Build (and cache) the world
id: build id: build
env:
HARMONIA_SSH_KEY: ${{ secrets.HARMONIA_SSH_KEY }}
run: | run: |
nix eval --json --apply "builtins.attrNames" .#ci.x86_64-linux | jq -cr '.[]' | while read job; do path=$(nix build --no-link .#ci.x86_64-linux --json | jq -r .[0].outputs.out)
echo "::group::Build $job" echo "path=$path" >> "$GITHUB_OUTPUT"
nix build --no-link .#ci.x86_64-linux."$job" - name: Push to cache
echo "::endgroup::" run: |
nix run .#nixpkgs.mine.x86_64-linux.attic-client -- \
echo "::group::Cache $job" push main ${{ steps.build.outputs.path }}
ci/push-to-cache.sh "$(nix eval --raw .#ci.x86_64-linux."$job")"
echo "::endgroup::"
done
echo "Building and caching CI derivation"
nix build --no-link .#ciDrv.x86_64-linux
UPDATE_PROFILE=1 ci/push-to-cache.sh "$(nix eval --raw .#ciDrv.x86_64-linux)"

View File

@@ -14,20 +14,22 @@ jobs:
uses: https://github.com/actions/setup-go@v4 uses: https://github.com/actions/setup-go@v4
with: with:
go-version: '>=1.20.1' go-version: '>=1.20.1'
- uses: cachix/install-nix-action@v27 - uses: cachix/install-nix-action@v23
with: with:
github_access_token: ${{ secrets.GH_PULL_TOKEN }} github_access_token: ${{ secrets.GH_PULL_TOKEN }}
extra_nix_config: | extra_nix_config: |
# Make sure we're using sandbox # Make sure we're using sandbox
sandbox-fallback = false sandbox-fallback = false
extra-substituters = https://nix-cache.nul.ie extra-substituters = https://nix-cache.nul.ie/main
extra-trusted-public-keys = nix-cache.nul.ie-1:BzH5yMfF4HbzY1C977XzOxoPhEc9Zbu39ftPkUbH+m4= extra-trusted-public-keys = main:mMChkG8LwXrFirVfudqjSHasK1jV31OVElYD3eImYl8=
- name: Set up attic
- name: Set up vars
id: setup id: setup
run: | run: |
nix run .#nixpkgs.mine.x86_64-linux.attic-client -- \
login --set-default colony https://nix-cache.nul.ie "${{ secrets.NIX_CACHE_TOKEN }}"
echo "short_rev=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" echo "short_rev=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
- name: Build installer ISO - name: Build installer ISO
run: | run: |
nix build .#nixfiles.config.nixos.systems.installer.configuration.config.my.buildAs.iso nix build .#nixfiles.config.nixos.systems.installer.configuration.config.my.buildAs.iso
@@ -37,7 +39,7 @@ jobs:
run: | run: |
nix build .#nixfiles.config.nixos.systems.installer.configuration.config.my.buildAs.netbootArchive nix build .#nixfiles.config.nixos.systems.installer.configuration.config.my.buildAs.netbootArchive
ln -s "$(readlink result)" \ ln -s "$(readlink result)" \
jackos-installer-netboot-${{ steps.setup.outputs.short_rev }}.tar.zst jackos-installer-netboot-${{ steps.setup.outputs.short_rev }}.tar
- name: Create release - name: Create release
uses: https://gitea.com/actions/release-action@main uses: https://gitea.com/actions/release-action@main
@@ -46,4 +48,4 @@ jobs:
api_key: '${{ secrets.RELEASE_TOKEN }}' api_key: '${{ secrets.RELEASE_TOKEN }}'
files: | files: |
jackos-installer-${{ steps.setup.outputs.short_rev }}.iso jackos-installer-${{ steps.setup.outputs.short_rev }}.iso
jackos-installer-netboot-${{ steps.setup.outputs.short_rev }}.tar.zst jackos-installer-netboot-${{ steps.setup.outputs.short_rev }}.tar

View File

@@ -1 +0,0 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKXRXkYnBf2opIjN+bXE7HmhUpa4hyXJUGmBT+MRccT4 harmonia

View File

@@ -1 +0,0 @@
object-ctr.ams1.int.nul.ie ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFdHbZErWLmTPO/aEWB1Fup/aGMf31Un5Wk66FJwTz/8

View File

@@ -1,31 +0,0 @@
#!/bin/sh
set -e
REMOTE_STORE=/var/lib/harmonia
SSH_HOST="harmonia@object-ctr.ams1.int.nul.ie"
SSH_KEY=/tmp/harmonia.key
STORE_URI="ssh-ng://$SSH_HOST?ssh-key=$SSH_KEY&remote-store=$REMOTE_STORE"
remote_cmd() {
ssh -i "$SSH_KEY" "$SSH_HOST" env HOME=/run/harmonia NIX_REMOTE="$REMOTE_STORE" "$@"
}
umask_old=$(umask)
umask 0066
echo "$HARMONIA_SSH_KEY" | base64 -d > "$SSH_KEY"
umask $umask_old
mkdir -p ~/.ssh
cp ci/known_hosts ~/.ssh/
path="$1"
echo "Pushing $path to cache..."
nix copy --no-check-sigs --to "$STORE_URI" "$path"
if [ -n "$UPDATE_PROFILE" ]; then
echo "Updating profile..."
remote_cmd nix-env -p "$REMOTE_STORE"/nix/var/nix/profiles/nixfiles --set "$path"
echo "Collecting garbage..."
remote_cmd nix-collect-garbage --delete-older-than 60d
fi

View File

@@ -77,12 +77,7 @@ in
name = "build-n-switch"; name = "build-n-switch";
category = "tasks"; category = "tasks";
help = "Shortcut to nixos-rebuild for this flake"; help = "Shortcut to nixos-rebuild for this flake";
command = '' command = ''doas nixos-rebuild --flake . "$@"'';
# HACK: Upstream changes in Git + Nix makes this necessary
# https://github.com/NixOS/nix/issues/10202
doas git config --global --add safe.directory "$PWD"
doas nixos-rebuild --flake . "$@"
'';
} }
{ {
name = "run-vm"; name = "run-vm";
@@ -120,17 +115,29 @@ in
help = "Build home-manager configuration"; help = "Build home-manager configuration";
command = ''nix build "''${@:2}" ".#homeConfigurations.\"$1\".activationPackage"''; command = ''nix build "''${@:2}" ".#homeConfigurations.\"$1\".activationPackage"'';
} }
{
name = "update-inputs";
category = "tasks";
help = "Update flake inputs";
command = ''
args=()
for f in "$@"; do
args+=(--update-input "$f")
done
nix flake lock "''${args[@]}"
'';
}
{ {
name = "update-nixpkgs"; name = "update-nixpkgs";
category = "tasks"; category = "tasks";
help = "Update nixpkgs flake inputs"; help = "Update nixpkgs flake inputs";
command = ''nix flake update nixpkgs-{unstable,stable,mine,mine-stable}''; command = ''update-inputs nixpkgs-{unstable,stable,mine,mine-stable}'';
} }
{ {
name = "update-home-manager"; name = "update-home-manager";
category = "tasks"; category = "tasks";
help = "Update home-manager flake inputs"; help = "Update home-manager flake inputs";
command = ''nix flake update home-manager-{unstable,stable}''; command = ''update-inputs home-manager-{unstable,stable}'';
} }
{ {
name = "update-installer"; name = "update-installer";
@@ -138,15 +145,5 @@ in
help = "Update installer tag (to trigger new release)"; help = "Update installer tag (to trigger new release)";
command = ''git tag -f installer && git push -f origin installer''; command = ''git tag -f installer && git push -f origin installer'';
} }
{
name = "deploy-multi";
category = "tasks";
help = "Deploy multiple flakes at once";
command = ''
for f in $@; do
deploy "$O" $f
done
'';
}
]; ];
} }

View File

@@ -11,7 +11,7 @@ in
NIX_USER_CONF_FILES = toString (pkgs.writeText "nix.conf" NIX_USER_CONF_FILES = toString (pkgs.writeText "nix.conf"
'' ''
experimental-features = nix-command flakes ca-derivations experimental-features = nix-command flakes ca-derivations repl-flake
connect-timeout = 5 connect-timeout = 5
fallback = true fallback = true
${lib.my.c.nix.cache.conf} ${lib.my.c.nix.cache.conf}
@@ -24,10 +24,10 @@ in
coreutils coreutils
nixVersions.stable nixVersions.stable
rage rage
wireguard-tools
(pkgs.writeShellScriptBin "deploy" '' (pkgs.writeShellScriptBin "deploy" ''
exec ${deploy-rs.deploy-rs}/bin/deploy --skip-checks "$@" exec ${deploy-rs.deploy-rs}/bin/deploy --skip-checks "$@"
'') '')
home-manager home-manager
attic-client
]; ];
} }

380
flake.lock generated
View File

@@ -8,14 +8,14 @@
"ragenix", "ragenix",
"nixpkgs" "nixpkgs"
], ],
"systems": "systems_7" "systems": "systems_8"
}, },
"locked": { "locked": {
"lastModified": 1723293904, "lastModified": 1707830867,
"narHash": "sha256-b+uqzj+Wa6xgMS9aNbX4I+sXeb5biPDi39VgvSFqFvU=", "narHash": "sha256-PAdwm5QqdlwIqGrfzzvzZubM+FXtilekQ/FA0cI49/o=",
"owner": "ryantm", "owner": "ryantm",
"repo": "agenix", "repo": "agenix",
"rev": "f6291c5935fdc4e0bef208cfc0dcab7e3f7a1c41", "rev": "8cb01a0e717311680e0cbca06a76cbceba6f3ed6",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -24,10 +24,36 @@
"type": "github" "type": "github"
} }
}, },
"attic": {
"inputs": {
"crane": "crane",
"flake-compat": "flake-compat",
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs-unstable"
],
"nixpkgs-stable": [
"nixpkgs-stable"
]
},
"locked": {
"lastModified": 1711742460,
"narHash": "sha256-0O4v6e4a1toxXZ2gf5INhg4WPE5C5T+SVvsBt+45Mcc=",
"owner": "zhaofengli",
"repo": "attic",
"rev": "4dbdbee45728d8ce5788db6461aaaa89d98081f0",
"type": "github"
},
"original": {
"owner": "zhaofengli",
"repo": "attic",
"type": "github"
}
},
"boardie": { "boardie": {
"inputs": { "inputs": {
"devshell": "devshell", "devshell": "devshell",
"flake-utils": "flake-utils_2", "flake-utils": "flake-utils_3",
"nixpkgs": [ "nixpkgs": [
"nixpkgs-unstable" "nixpkgs-unstable"
], ],
@@ -50,17 +76,17 @@
"borgthin": { "borgthin": {
"inputs": { "inputs": {
"devshell": "devshell_2", "devshell": "devshell_2",
"flake-utils": "flake-utils_5", "flake-utils": "flake-utils_6",
"nixpkgs": [ "nixpkgs": [
"nixpkgs-mine" "nixpkgs-mine"
] ]
}, },
"locked": { "locked": {
"lastModified": 1732994213, "lastModified": 1692446555,
"narHash": "sha256-3v8cTsPB+TIdWmc1gmRNd0Mi0elpfi39CXRsA/2x/Oo=", "narHash": "sha256-Uzl8TiGKVBCjwYhkprSwbcu8xlcQwnDNIqsk9rM+P9w=",
"owner": "devplayer0", "owner": "devplayer0",
"repo": "borg", "repo": "borg",
"rev": "795f5009445987d42f32de1b49fdeb2d88326a64", "rev": "44a3dc19b014ebc8d33db0b3e145ed7bfc9a0cb7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -70,12 +96,39 @@
} }
}, },
"crane": { "crane": {
"inputs": {
"nixpkgs": [
"attic",
"nixpkgs"
]
},
"locked": { "locked": {
"lastModified": 1725409566, "lastModified": 1702918879,
"narHash": "sha256-PrtLmqhM6UtJP7v7IGyzjBFhbG4eOAHT6LPYOFmYfbk=", "narHash": "sha256-tWJqzajIvYcaRWxn+cLUB9L9Pv4dQ3Bfit/YjU5ze3g=",
"owner": "ipetkov", "owner": "ipetkov",
"repo": "crane", "repo": "crane",
"rev": "7e4586bad4e3f8f97a9271def747cf58c4b68f3c", "rev": "7195c00c272fdd92fc74e7d5a0a2844b9fadb2fb",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"crane_2": {
"inputs": {
"nixpkgs": [
"ragenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1708794349,
"narHash": "sha256-jX+B1VGHT0ruHHL5RwS8L21R6miBn4B6s9iVyUJsJJY=",
"owner": "ipetkov",
"repo": "crane",
"rev": "2c94ff9a6fbeb9f3ea0107f28688edbe9c81deaa",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -109,18 +162,18 @@
}, },
"deploy-rs": { "deploy-rs": {
"inputs": { "inputs": {
"flake-compat": "flake-compat", "flake-compat": "flake-compat_2",
"nixpkgs": [ "nixpkgs": [
"nixpkgs-unstable" "nixpkgs-unstable"
], ],
"utils": "utils" "utils": "utils"
}, },
"locked": { "locked": {
"lastModified": 1727447169, "lastModified": 1715699772,
"narHash": "sha256-3KyjMPUKHkiWhwR91J1YchF6zb6gvckCAY1jOE+ne0U=", "narHash": "sha256-sKhqIgucN5sI/7UQgBwsonzR4fONjfMr9OcHK/vPits=",
"owner": "serokell", "owner": "serokell",
"repo": "deploy-rs", "repo": "deploy-rs",
"rev": "aa07eb05537d4cd025e2310397a6adcedfe72c76", "rev": "b3ea6f333f9057b77efd9091119ba67089399ced",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -131,7 +184,7 @@
}, },
"devshell": { "devshell": {
"inputs": { "inputs": {
"flake-utils": "flake-utils", "flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
}, },
"locked": { "locked": {
@@ -150,7 +203,7 @@
}, },
"devshell-tools": { "devshell-tools": {
"inputs": { "inputs": {
"flake-utils": "flake-utils_9", "flake-utils": "flake-utils_11",
"nixpkgs": "nixpkgs_4" "nixpkgs": "nixpkgs_4"
}, },
"locked": { "locked": {
@@ -169,7 +222,7 @@
}, },
"devshell_2": { "devshell_2": {
"inputs": { "inputs": {
"flake-utils": "flake-utils_4", "flake-utils": "flake-utils_5",
"nixpkgs": "nixpkgs_3" "nixpkgs": "nixpkgs_3"
}, },
"locked": { "locked": {
@@ -188,16 +241,17 @@
}, },
"devshell_3": { "devshell_3": {
"inputs": { "inputs": {
"flake-utils": "flake-utils_7",
"nixpkgs": [ "nixpkgs": [
"nixpkgs-unstable" "nixpkgs-unstable"
] ]
}, },
"locked": { "locked": {
"lastModified": 1728330715, "lastModified": 1713532798,
"narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=", "narHash": "sha256-wtBhsdMJA3Wa32Wtm1eeo84GejtI43pMrFrmwLXrsEc=",
"owner": "numtide", "owner": "numtide",
"repo": "devshell", "repo": "devshell",
"rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef", "rev": "12e914740a25ea1891ec619bb53cf5e6ca922e40",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -207,6 +261,22 @@
} }
}, },
"flake-compat": { "flake-compat": {
"flake": false,
"locked": {
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-compat_2": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1696426674, "lastModified": 1696426674,
@@ -223,6 +293,90 @@
} }
}, },
"flake-utils": { "flake-utils": {
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_10": {
"inputs": {
"systems": "systems_9"
},
"locked": {
"lastModified": 1705309234,
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_11": {
"inputs": {
"systems": "systems_10"
},
"locked": {
"lastModified": 1709126324,
"narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "d465f4819400de7c8d874d50b982301f28a84605",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_12": {
"inputs": {
"systems": "systems_11"
},
"locked": {
"lastModified": 1705309234,
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_13": {
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"inputs": { "inputs": {
"systems": "systems" "systems": "systems"
}, },
@@ -240,40 +394,7 @@
"type": "github" "type": "github"
} }
}, },
"flake-utils_10": { "flake-utils_3": {
"inputs": {
"systems": "systems_10"
},
"locked": {
"lastModified": 1705309234,
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_11": {
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"inputs": { "inputs": {
"systems": "systems_2" "systems": "systems_2"
}, },
@@ -291,7 +412,7 @@
"type": "github" "type": "github"
} }
}, },
"flake-utils_3": { "flake-utils_4": {
"inputs": { "inputs": {
"systems": "systems_3" "systems": "systems_3"
}, },
@@ -309,7 +430,7 @@
"type": "github" "type": "github"
} }
}, },
"flake-utils_4": { "flake-utils_5": {
"locked": { "locked": {
"lastModified": 1642700792, "lastModified": 1642700792,
"narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=", "narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=",
@@ -324,7 +445,7 @@
"type": "github" "type": "github"
} }
}, },
"flake-utils_5": { "flake-utils_6": {
"locked": { "locked": {
"lastModified": 1667395993, "lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
@@ -339,31 +460,16 @@
"type": "github" "type": "github"
} }
}, },
"flake-utils_6": { "flake-utils_7": {
"inputs": { "inputs": {
"systems": "systems_6" "systems": "systems_6"
}, },
"locked": { "locked": {
"lastModified": 1731533236, "lastModified": 1701680307,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_7": {
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -374,7 +480,7 @@
}, },
"flake-utils_8": { "flake-utils_8": {
"inputs": { "inputs": {
"systems": "systems_8" "systems": "systems_7"
}, },
"locked": { "locked": {
"lastModified": 1710146030, "lastModified": 1710146030,
@@ -391,15 +497,12 @@
} }
}, },
"flake-utils_9": { "flake-utils_9": {
"inputs": {
"systems": "systems_9"
},
"locked": { "locked": {
"lastModified": 1709126324, "lastModified": 1659877975,
"narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=", "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "d465f4819400de7c8d874d50b982301f28a84605", "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -437,16 +540,16 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1732466619, "lastModified": 1716729592,
"narHash": "sha256-T1e5oceypZu3Q8vzICjv1X/sGs9XfJRMW5OuXHgpB3c=", "narHash": "sha256-Y3bOjoh2cFBqZN0Jw1zUdyr7tjygyxl2bD/QY73GZP0=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "f3111f62a23451114433888902a55cf0692b408d", "rev": "2c78a57c544dd19b07442350727ced097e1aa6e6",
"type": "github" "type": "github"
}, },
"original": { "original": {
"id": "home-manager", "id": "home-manager",
"ref": "release-24.11", "ref": "release-23.11",
"type": "indirect" "type": "indirect"
} }
}, },
@@ -457,11 +560,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1732884235, "lastModified": 1717097707,
"narHash": "sha256-r8j6R3nrvwbT1aUp4EPQ1KC7gm0pu9VcV1aNaB+XG6Q=", "narHash": "sha256-HC5vJ3oYsjwsCaSbkIPv80e4ebJpNvFKQTBOGlHvjLs=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "819f682269f4e002884702b87e445c82840c68f2", "rev": "0eb314b4f0ba337e88123e0b1e57ef58346aafd9",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -471,11 +574,11 @@
}, },
"impermanence": { "impermanence": {
"locked": { "locked": {
"lastModified": 1731242966, "lastModified": 1708968331,
"narHash": "sha256-B3C3JLbGw0FtLSWCjBxU961gLNv+BOOBC6WvstKLYMw=", "narHash": "sha256-VUXLaPusCBvwM3zhGbRIJVeYluh2uWuqtj4WirQ1L9Y=",
"owner": "nix-community", "owner": "nix-community",
"repo": "impermanence", "repo": "impermanence",
"rev": "3ed3f0eaae9fcc0a8331e77e9319c8a4abd8a71a", "rev": "a33ef102a02ce77d3e39c25197664b7a636f9c30",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -508,7 +611,7 @@
}, },
"nixGL": { "nixGL": {
"inputs": { "inputs": {
"flake-utils": "flake-utils_7", "flake-utils": "flake-utils_9",
"nixpkgs": [ "nixpkgs": [
"nixpkgs-unstable" "nixpkgs-unstable"
] ]
@@ -545,11 +648,11 @@
}, },
"nixpkgs-mine": { "nixpkgs-mine": {
"locked": { "locked": {
"lastModified": 1732985787, "lastModified": 1717628902,
"narHash": "sha256-6rSJ9L4QywpHLi/xvpOHdTuPm6/eOJcXxnYzDbP3U1k=", "narHash": "sha256-qMAW+oKis3F8jXTjX9Ng02/LzZd+7YOK05Qa33h9yqY=",
"owner": "devplayer0", "owner": "devplayer0",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "a28c46933ef5038fb7a2dd483b85152a539c7969", "rev": "3e0ee08114e1563b1a0fd6a907563b5e86258fb4",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -561,11 +664,11 @@
}, },
"nixpkgs-mine-stable": { "nixpkgs-mine-stable": {
"locked": { "locked": {
"lastModified": 1732985894, "lastModified": 1717245305,
"narHash": "sha256-YYuQQCcSF6KjgtAenZJiBmqt5jqP3UvYgC424VQ+22s=", "narHash": "sha256-LrIS3+Aa4F2VmuJPQOASRd3W+uToj878PoUKSLVw/vE=",
"owner": "devplayer0", "owner": "devplayer0",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "e0a3f4e2bbc5f7b681e344b389dcbab23f2e92a8", "rev": "17a50249712512f600eced89bebcc3252b5f630f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -577,26 +680,26 @@
}, },
"nixpkgs-stable": { "nixpkgs-stable": {
"locked": { "locked": {
"lastModified": 1732824227, "lastModified": 1716991068,
"narHash": "sha256-fYNXgpu1AEeLyd3fQt4Ym0tcVP7cdJ8wRoqJ+CtTRyY=", "narHash": "sha256-Av0UWCCiIGJxsZ6TFc+OiKCJNqwoxMNVYDBChmhjNpo=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "c71ad5c34d51dcbda4c15f44ea4e4aa6bb6ac1e9", "rev": "25cf937a30bf0801447f6bf544fc7486c6309234",
"type": "github" "type": "github"
}, },
"original": { "original": {
"id": "nixpkgs", "id": "nixpkgs",
"ref": "nixos-24.11", "ref": "nixos-23.11",
"type": "indirect" "type": "indirect"
} }
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1732758367, "lastModified": 1716948383,
"narHash": "sha256-RzaI1RO0UXqLjydtz3GAXSTzHkpb/lLD1JD8a0W4Wpo=", "narHash": "sha256-SzDKxseEcHR5KzPXLwsemyTR/kaM9whxeiJohbL04rs=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "fa42b5a5f401aab8a32bd33c9a4de0738180dc59", "rev": "ad57eef4ef0659193044870c731987a6df5cf56b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -671,7 +774,7 @@
}, },
"poetry2nix": { "poetry2nix": {
"inputs": { "inputs": {
"flake-utils": "flake-utils_3", "flake-utils": "flake-utils_4",
"nix-github-actions": "nix-github-actions", "nix-github-actions": "nix-github-actions",
"nixpkgs": "nixpkgs_2", "nixpkgs": "nixpkgs_2",
"systems": "systems_4", "systems": "systems_4",
@@ -694,35 +797,35 @@
"ragenix": { "ragenix": {
"inputs": { "inputs": {
"agenix": "agenix", "agenix": "agenix",
"crane": "crane", "crane": "crane_2",
"flake-utils": "flake-utils_8", "flake-utils": "flake-utils_10",
"nixpkgs": [ "nixpkgs": [
"nixpkgs-unstable" "nixpkgs-unstable"
], ],
"rust-overlay": "rust-overlay" "rust-overlay": "rust-overlay"
}, },
"locked": { "locked": {
"lastModified": 1731774781, "lastModified": 1709831932,
"narHash": "sha256-vwsUUYOIs8J6weeSK1n1mbZf8fgvygGUMsadx0JmG70=", "narHash": "sha256-WsP8rOFa/SqYNbVtYJ/l2mWWOgyDTJFbITMV8tv0biI=",
"owner": "devplayer0", "owner": "yaxitech",
"repo": "ragenix", "repo": "ragenix",
"rev": "ec4115da7b67c783b1091811e17dbcba50edd1c6", "rev": "06de099ef02840ec463419f12de73729d458e1eb",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "devplayer0", "owner": "yaxitech",
"ref": "add-rekey-one-flag",
"repo": "ragenix", "repo": "ragenix",
"type": "github" "type": "github"
} }
}, },
"root": { "root": {
"inputs": { "inputs": {
"attic": "attic",
"boardie": "boardie", "boardie": "boardie",
"borgthin": "borgthin", "borgthin": "borgthin",
"deploy-rs": "deploy-rs", "deploy-rs": "deploy-rs",
"devshell": "devshell_3", "devshell": "devshell_3",
"flake-utils": "flake-utils_6", "flake-utils": "flake-utils_8",
"home-manager-stable": "home-manager-stable", "home-manager-stable": "home-manager-stable",
"home-manager-unstable": "home-manager-unstable", "home-manager-unstable": "home-manager-unstable",
"impermanence": "impermanence", "impermanence": "impermanence",
@@ -737,17 +840,21 @@
}, },
"rust-overlay": { "rust-overlay": {
"inputs": { "inputs": {
"flake-utils": [
"ragenix",
"flake-utils"
],
"nixpkgs": [ "nixpkgs": [
"ragenix", "ragenix",
"nixpkgs" "nixpkgs"
] ]
}, },
"locked": { "locked": {
"lastModified": 1725675754, "lastModified": 1708740535,
"narHash": "sha256-hXW3csqePOcF2e/PYnpXj72KEYyNj2HzTrVNmS/F7Ug=", "narHash": "sha256-NCTw235XwSDbeTAtAwg/hOeNOgwYhVq7JjDdbkOgBeA=",
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "8cc45e678e914a16c8e224c3237fb07cf21e5e54", "rev": "9b24383d77f598716fa0cbb8b48c97249f5ee1af",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -758,7 +865,7 @@
}, },
"sbt": { "sbt": {
"inputs": { "inputs": {
"flake-utils": "flake-utils_11", "flake-utils": "flake-utils_13",
"nixpkgs": "nixpkgs_5" "nixpkgs": "nixpkgs_5"
}, },
"locked": { "locked": {
@@ -778,22 +885,22 @@
"sharry": { "sharry": {
"inputs": { "inputs": {
"devshell-tools": "devshell-tools", "devshell-tools": "devshell-tools",
"flake-utils": "flake-utils_10", "flake-utils": "flake-utils_12",
"nixpkgs": [ "nixpkgs": [
"nixpkgs-unstable" "nixpkgs-unstable"
], ],
"sbt": "sbt" "sbt": "sbt"
}, },
"locked": { "locked": {
"lastModified": 1720592125, "lastModified": 1710796573,
"narHash": "sha256-vR89LefkY8mBPWxDTQ8SNg6Z7/J6Yga80T4kSb6MNdk=", "narHash": "sha256-23fLZFNacZU/skc8i7JExHfD//Mpkslhga6f5ATTqBA=",
"owner": "eikek", "owner": "devplayer0",
"repo": "sharry", "repo": "sharry",
"rev": "604b20517150599cb05dbe178cd35cd10659aa4c", "rev": "4e7a87880ba0807afd5d21706ce383b8b8727990",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "eikek", "owner": "devplayer0",
"repo": "sharry", "repo": "sharry",
"type": "github" "type": "github"
} }
@@ -828,6 +935,21 @@
"type": "github" "type": "github"
} }
}, },
"systems_11": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": { "systems_2": {
"locked": { "locked": {
"lastModified": 1681028828, "lastModified": 1681028828,

View File

@@ -7,18 +7,17 @@
devshell.inputs.nixpkgs.follows = "nixpkgs-unstable"; devshell.inputs.nixpkgs.follows = "nixpkgs-unstable";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable"; nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
nixpkgs-stable.url = "nixpkgs/nixos-24.11"; nixpkgs-stable.url = "nixpkgs/nixos-23.11";
nixpkgs-mine.url = "github:devplayer0/nixpkgs/devplayer0"; nixpkgs-mine.url = "github:devplayer0/nixpkgs/devplayer0";
nixpkgs-mine-stable.url = "github:devplayer0/nixpkgs/devplayer0-stable"; nixpkgs-mine-stable.url = "github:devplayer0/nixpkgs/devplayer0-stable";
home-manager-unstable.url = "home-manager"; home-manager-unstable.url = "home-manager";
home-manager-unstable.inputs.nixpkgs.follows = "nixpkgs-unstable"; home-manager-unstable.inputs.nixpkgs.follows = "nixpkgs-unstable";
home-manager-stable.url = "home-manager/release-24.11"; home-manager-stable.url = "home-manager/release-23.11";
home-manager-stable.inputs.nixpkgs.follows = "nixpkgs-stable"; home-manager-stable.inputs.nixpkgs.follows = "nixpkgs-stable";
# Stuff used by the flake for build / deployment # Stuff used by the flake for build / deployment
# ragenix.url = "github:yaxitech/ragenix"; ragenix.url = "github:yaxitech/ragenix";
ragenix.url = "github:devplayer0/ragenix/add-rekey-one-flag";
ragenix.inputs.nixpkgs.follows = "nixpkgs-unstable"; ragenix.inputs.nixpkgs.follows = "nixpkgs-unstable";
deploy-rs.url = "github:serokell/deploy-rs"; deploy-rs.url = "github:serokell/deploy-rs";
deploy-rs.inputs.nixpkgs.follows = "nixpkgs-unstable"; deploy-rs.inputs.nixpkgs.follows = "nixpkgs-unstable";
@@ -31,10 +30,14 @@
nixGL.inputs.nixpkgs.follows = "nixpkgs-unstable"; nixGL.inputs.nixpkgs.follows = "nixpkgs-unstable";
# Packages not in nixpkgs # Packages not in nixpkgs
sharry.url = "github:eikek/sharry"; # sharry.url = "github:eikek/sharry";
sharry.url = "github:devplayer0/sharry";
sharry.inputs.nixpkgs.follows = "nixpkgs-unstable"; sharry.inputs.nixpkgs.follows = "nixpkgs-unstable";
borgthin.url = "github:devplayer0/borg"; borgthin.url = "github:devplayer0/borg";
borgthin.inputs.nixpkgs.follows = "nixpkgs-mine"; borgthin.inputs.nixpkgs.follows = "nixpkgs-mine";
attic.url = "github:zhaofengli/attic";
attic.inputs.nixpkgs.follows = "nixpkgs-unstable";
attic.inputs.nixpkgs-stable.follows = "nixpkgs-stable";
}; };
outputs = outputs =
@@ -49,7 +52,7 @@
... ...
}: }:
let let
inherit (builtins) mapAttrs replaceStrings elem; inherit (builtins) mapAttrs replaceStrings;
inherit (lib) mapAttrs' filterAttrs nameValuePair recurseIntoAttrs evalModules; inherit (lib) mapAttrs' filterAttrs nameValuePair recurseIntoAttrs evalModules;
inherit (lib.flake) flattenTree eachDefaultSystem; inherit (lib.flake) flattenTree eachDefaultSystem;
inherit (lib.my) mkDefaultSystemsPkgs flakePackageOverlay; inherit (lib.my) mkDefaultSystemsPkgs flakePackageOverlay;
@@ -93,6 +96,7 @@
inputs.ragenix.overlays.default inputs.ragenix.overlays.default
inputs.deploy-rs.overlay inputs.deploy-rs.overlay
(flakePackageOverlay inputs.home-manager-unstable system) (flakePackageOverlay inputs.home-manager-unstable system)
inputs.attic.overlays.default
]; ];
})) }))
pkgsFlakes; pkgsFlakes;
@@ -104,16 +108,6 @@
pkgsLibOverlay pkgsLibOverlay
myPkgsOverlay myPkgsOverlay
]; ];
config = {
# RMS forgive me...
# Normally this is set modularly, but sometimes we need to use other pkgs
allowUnfreePredicate = p: elem (lib.getName p) [
"widevine-cdm"
"chromium-unwrapped"
"chromium"
];
};
})) }))
pkgsFlakes; pkgsFlakes;
@@ -122,9 +116,9 @@
nixos/installer.nix nixos/installer.nix
nixos/boxes/colony nixos/boxes/colony
nixos/boxes/tower nixos/boxes/tower
nixos/boxes/castle
nixos/boxes/home/stream.nix nixos/boxes/home/stream.nix
nixos/boxes/home/palace nixos/boxes/home/palace
nixos/boxes/home/castle
nixos/boxes/britway nixos/boxes/britway
nixos/boxes/kelder nixos/boxes/kelder
@@ -204,9 +198,8 @@
systems' = mapAttrs' (n: v: nameValuePair "system-${n}" v) systems; systems' = mapAttrs' (n: v: nameValuePair "system-${n}" v) systems;
packages' = mapAttrs' (n: v: nameValuePair "package-${n}" v) packages; packages' = mapAttrs' (n: v: nameValuePair "package-${n}" v) packages;
in in
homes' // systems' // packages' // { pkgs.linkFarm "ci" (homes' // systems' // packages' // {
inherit shell; inherit shell;
}; });
ciDrv = pkgs.linkFarm "ci" ci;
})); }));
} }

View File

@@ -199,20 +199,17 @@ in
file file
tree tree
pwgen pwgen
minicom
iperf3 iperf3
mosh mosh
wget wget
hyx
whois whois
ldns ldns
minicom
mtr mtr
hyx
ncdu ncdu
jq jq
yq-go yq-go
nix-tree
]; ];
sessionVariables = { sessionVariables = {

View File

@@ -1,6 +1,6 @@
{ lib, pkgs', pkgs, config, ... }: { lib, pkgs, config, ... }:
let let
inherit (lib) genAttrs mkIf mkMerge mkForce mapAttrs mkOptionDefault; inherit (lib) genAttrs mkIf mkMerge mkForce;
inherit (lib.my) mkBoolOpt'; inherit (lib.my) mkBoolOpt';
cfg = config.my.gui; cfg = config.my.gui;
@@ -39,11 +39,10 @@ in
{ {
home = { home = {
packages = with pkgs; [ packages = with pkgs; [
xdg-utils
font.package font.package
nerd-fonts.sauce-code-pro (nerdfonts.override {
nerd-fonts.droid-sans-mono fonts = [ "DroidSansMono" "SourceCodePro" ];
})
noto-fonts-emoji noto-fonts-emoji
grim grim
@@ -63,8 +62,6 @@ in
neofetch neofetch
cmatrix cmatrix
doomsaver doomsaver
xournalpp
]; ];
}; };
@@ -79,7 +76,7 @@ in
alacritty = { alacritty = {
enable = true; enable = true;
settings = { settings = {
general.import = [ ./alacritty-xterm.toml ]; import = [ ./alacritty-xterm.toml ];
font = { font = {
size = font.size; size = font.size;
@@ -95,10 +92,9 @@ in
enable = true; enable = true;
inherit font; inherit font;
settings = { settings = {
background_opacity = "0.65"; background_opacity = "0.8";
tab_bar_edge = "top"; tab_bar_edge = "top";
shell_integration = "no-sudo"; shell_integration = "no-sudo";
font_features = "${font.name} -liga";
}; };
}; };
@@ -164,19 +160,6 @@ in
}; };
Install.RequiredBy = [ "sway-session.target" ]; Install.RequiredBy = [ "sway-session.target" ];
}; };
activate-linux = {
Unit = {
Description = "Linux activation watermark";
After = "graphical-session.target";
PartOf = "graphical-session.target";
};
Service = {
Type = "simple";
ExecStart = "${pkgs.activate-linux}/bin/activate-linux";
};
Install.RequiredBy = [ "graphical-session.target" ];
};
}; };
}; };
@@ -186,7 +169,6 @@ in
wl-clipboard wl-clipboard
wev wev
wdisplays wdisplays
swaysome
pavucontrol pavucontrol
libsecret libsecret
@@ -196,11 +178,10 @@ in
]; ];
pointerCursor = { pointerCursor = {
package = pkgs.posy-cursors; package = pkgs.vanilla-dmz;
name = "Posy_Cursor"; name = "Vanilla-DMZ";
size = 32; size = 16;
gtk.enable = true; gtk.enable = true;
x11.enable = true;
}; };
}; };
@@ -209,36 +190,9 @@ in
xsession.preferStatusNotifierItems = true; xsession.preferStatusNotifierItems = true;
wayland = { wayland = {
windowManager = { windowManager = {
sway = sway = {
let
cfg = config.wayland.windowManager.sway.config;
mod = cfg.modifier;
renameWs = pkgs.writeShellScript "sway-rename-ws" ''
focused_ws="$(swaymsg -t get_workspaces | jq ".[] | select(.focused)")"
focused_num="$(jq -r ".num" <<< "$focused_ws")"
focused_name="$(jq -r ".name" <<< "$focused_ws")"
placeholder="$(sed -E 's/[0-9]+: //' <<< "$focused_name")"
name="$(rofi -dmenu -p "rename ws $focused_num" -theme+entry+placeholder "\"$placeholder\"")"
if [ -n "$name" ]; then
swaymsg rename workspace "$focused_name" to "$focused_num: $name"
fi
'';
clearWsName = pkgs.writeShellScript "sway-clear-ws-name" ''
focused_ws="$(swaymsg -t get_workspaces | jq ".[] | select(.focused)")"
focused_num="$(jq -r ".num" <<< "$focused_ws")"
focused_name="$(jq -r ".name" <<< "$focused_ws")"
swaymsg rename workspace "$focused_name" to "$focused_num"
'';
in
{
enable = true; enable = true;
xwayland = true; xwayland = true;
extraConfigEarly = ''
set $mod ${mod}
'';
config = { config = {
input = { input = {
"type:touchpad" = { "type:touchpad" = {
@@ -253,87 +207,23 @@ in
modifier = "Mod4"; modifier = "Mod4";
terminal = "kitty"; terminal = "kitty";
keybindings = mapAttrs (k: mkOptionDefault) { keybindings =
"${mod}+Left" = "focus left"; let
"${mod}+Down" = "focus down"; cfg = config.wayland.windowManager.sway.config;
"${mod}+Up" = "focus up"; mod = cfg.modifier;
"${mod}+Right" = "focus right"; in
lib.mkOptionDefault {
"${mod}+Shift+Left" = "move left";
"${mod}+Shift+Down" = "move down";
"${mod}+Shift+Up" = "move up";
"${mod}+Shift+Right" = "move right";
"${mod}+b" = "splith";
"${mod}+v" = "splitv";
"${mod}+f" = "fullscreen toggle";
"${mod}+a" = "focus parent";
"${mod}+s" = "layout stacking";
"${mod}+w" = "layout tabbed";
"${mod}+e" = "layout toggle split";
"${mod}+Shift+space" = "floating toggle";
"${mod}+space" = "focus mode_toggle";
"${mod}+1" = "workspace number 1";
"${mod}+2" = "workspace number 2";
"${mod}+3" = "workspace number 3";
"${mod}+4" = "workspace number 4";
"${mod}+5" = "workspace number 5";
"${mod}+6" = "workspace number 6";
"${mod}+7" = "workspace number 7";
"${mod}+8" = "workspace number 8";
"${mod}+9" = "workspace number 9";
"${mod}+0" = "workspace number 10";
"${mod}+Shift+1" =
"move container to workspace number 1";
"${mod}+Shift+2" =
"move container to workspace number 2";
"${mod}+Shift+3" =
"move container to workspace number 3";
"${mod}+Shift+4" =
"move container to workspace number 4";
"${mod}+Shift+5" =
"move container to workspace number 5";
"${mod}+Shift+6" =
"move container to workspace number 6";
"${mod}+Shift+7" =
"move container to workspace number 7";
"${mod}+Shift+8" =
"move container to workspace number 8";
"${mod}+Shift+9" =
"move container to workspace number 9";
"${mod}+Shift+0" =
"move container to workspace number 10";
"${mod}+Shift+minus" = "move scratchpad";
"${mod}+minus" = "scratchpad show";
"${mod}+Return" = "exec ${cfg.terminal}";
"${mod}+r" = "mode resize";
"${mod}+d" = null; "${mod}+d" = null;
"${mod}+l" = "exec ${doomsaver}/bin/doomsaver"; "${mod}+l" = "exec ${doomsaver}/bin/doomsaver";
"${mod}+q" = "kill";
"${mod}+Shift+c" = "reload";
"${mod}+Shift+q" = "exec swaynag -t warning -m 'bruh you really wanna kill sway?' -b 'ye' 'systemctl --user stop graphical-session.target && swaymsg exit'";
# rofi
"${mod}+x" = "exec ${cfg.menu}"; "${mod}+x" = "exec ${cfg.menu}";
"${mod}+Shift+x" = "exec rofi -show drun"; "${mod}+Shift+x" = "exec rofi -show drun";
"${mod}+q" = "kill";
"${mod}+Shift+q" = "exec swaynag -t warning -m 'bruh you really wanna kill sway?' -b 'ye' 'systemctl --user stop graphical-session.target && swaymsg exit'";
"${mod}+Shift+d" = ''exec grim - | swappy -f -'';
"${mod}+Shift+s" = ''exec grim -g "$(slurp)" - | swappy -f -'';
"${mod}+Shift+e" = "exec rofi -show emoji"; "${mod}+Shift+e" = "exec rofi -show emoji";
# Config for this doesn't seem to work :/ # Config for this doesn't seem to work :/
"${mod}+c" = ''exec rofi -show calc -calc-command "echo -n '{result}' | ${pkgs.wl-clipboard}/bin/wl-copy"''; "${mod}+c" = ''exec rofi -show calc -calc-command "echo -n '{result}' | ${pkgs.wl-clipboard}/bin/wl-copy"'';
"${mod}+Shift+r" = "exec ${renameWs}";
"${mod}+Shift+n" = "exec ${clearWsName}";
# Screenshots
"${mod}+Shift+d" = ''exec grim - | swappy -f -'';
"${mod}+Shift+s" = ''exec grim -g "$(slurp)" - | swappy -f -'';
"XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set 5%-";
"XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set +5%";
"XF86AudioRaiseVolume" = "exec ${pkgs.pamixer}/bin/pamixer -i 5"; "XF86AudioRaiseVolume" = "exec ${pkgs.pamixer}/bin/pamixer -i 5";
"XF86AudioLowerVolume" = "exec ${pkgs.pamixer}/bin/pamixer -d 5"; "XF86AudioLowerVolume" = "exec ${pkgs.pamixer}/bin/pamixer -d 5";
@@ -350,9 +240,6 @@ in
menu = "rofi -show run"; menu = "rofi -show run";
bars = mkForce [ ]; bars = mkForce [ ];
}; };
extraConfig = ''
include ${./swaysome.conf}
'';
swaynag = { swaynag = {
enable = true; enable = true;
@@ -403,7 +290,6 @@ in
diff-so-fancy.enable = true; diff-so-fancy.enable = true;
userEmail = "jackos1998@gmail.com"; userEmail = "jackos1998@gmail.com";
userName = "Jack O'Sullivan"; userName = "Jack O'Sullivan";
lfs.enable = true;
extraConfig = { extraConfig = {
pull.rebase = true; pull.rebase = true;
}; };
@@ -411,13 +297,11 @@ in
waybar = import ./waybar.nix { inherit lib pkgs config font; }; waybar = import ./waybar.nix { inherit lib pkgs config font; };
rofi = { rofi = {
package = pkgs.rofi-wayland;
enable = true; enable = true;
font = "${font.name} ${toString font.size}"; font = "${font.name} ${toString font.size}";
plugins = with pkgs; (map (p: p.override { rofi-unwrapped = rofi-wayland-unwrapped; }) [ plugins = with pkgs; [
rofi-calc rofi-calc
]) ++ [ rofi-emoji
rofi-emoji-wayland
]; ];
extraConfig = { extraConfig = {
modes = "window,run,ssh,filebrowser,calc,emoji"; modes = "window,run,ssh,filebrowser,calc,emoji";
@@ -432,7 +316,7 @@ in
chromium = { chromium = {
enable = true; enable = true;
package = (pkgs'.unstable.chromium.override { enableWideVine = true; }).overrideAttrs (old: { package = (pkgs.chromium.override { enableWideVine = true; }).overrideAttrs (old: {
buildCommand = '' buildCommand = ''
${old.buildCommand} ${old.buildCommand}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 KiB

After

Width:  |  Height:  |  Size: 249 KiB

View File

@@ -1,66 +0,0 @@
# Use (un)bindcode or (un)bindsym, depending on what you used in your main sway config file.
# The `--no-warn` setting is only added to shortcuts that exist in the default config. You may want to add or remove
# that flag on some bindings depending on your config.
# Change focus between workspaces
bindsym $mod+Alt+1 exec "swaysome focus 1"
bindsym $mod+Alt+2 exec "swaysome focus 2"
bindsym $mod+Alt+3 exec "swaysome focus 3"
bindsym $mod+Alt+4 exec "swaysome focus 4"
bindsym $mod+Alt+5 exec "swaysome focus 5"
bindsym $mod+Alt+6 exec "swaysome focus 6"
bindsym $mod+Alt+7 exec "swaysome focus 7"
bindsym $mod+Alt+8 exec "swaysome focus 8"
bindsym $mod+Alt+9 exec "swaysome focus 9"
bindsym $mod+Alt+0 exec "swaysome focus 0"
# Focus workspace groups
bindsym --no-warn $mod+1 exec "swaysome focus-group 1"
bindsym --no-warn $mod+2 exec "swaysome focus-group 2"
bindsym --no-warn $mod+3 exec "swaysome focus-group 3"
bindsym --no-warn $mod+4 exec "swaysome focus-group 4"
bindsym --no-warn $mod+5 exec "swaysome focus-group 5"
bindsym --no-warn $mod+6 exec "swaysome focus-group 6"
bindsym --no-warn $mod+7 exec "swaysome focus-group 7"
bindsym --no-warn $mod+8 exec "swaysome focus-group 8"
bindsym --no-warn $mod+9 exec "swaysome focus-group 9"
bindsym --no-warn $mod+0 exec "swaysome focus-group 0"
# Move containers between workspaces
bindsym $mod+Alt+Shift+1 exec "swaysome move 1"
bindsym $mod+Alt+Shift+2 exec "swaysome move 2"
bindsym $mod+Alt+Shift+3 exec "swaysome move 3"
bindsym $mod+Alt+Shift+4 exec "swaysome move 4"
bindsym $mod+Alt+Shift+5 exec "swaysome move 5"
bindsym $mod+Alt+Shift+6 exec "swaysome move 6"
bindsym $mod+Alt+Shift+7 exec "swaysome move 7"
bindsym $mod+Alt+Shift+8 exec "swaysome move 8"
bindsym $mod+Alt+Shift+9 exec "swaysome move 9"
bindsym $mod+Alt+Shift+0 exec "swaysome move 0"
# Move containers to other workspace groups
bindsym --no-warn $mod+Shift+1 exec "swaysome move-to-group 1"
bindsym --no-warn $mod+Shift+2 exec "swaysome move-to-group 2"
bindsym --no-warn $mod+Shift+3 exec "swaysome move-to-group 3"
bindsym --no-warn $mod+Shift+4 exec "swaysome move-to-group 4"
bindsym --no-warn $mod+Shift+5 exec "swaysome move-to-group 5"
bindsym --no-warn $mod+Shift+6 exec "swaysome move-to-group 6"
bindsym --no-warn $mod+Shift+7 exec "swaysome move-to-group 7"
bindsym --no-warn $mod+Shift+8 exec "swaysome move-to-group 8"
bindsym --no-warn $mod+Shift+9 exec "swaysome move-to-group 9"
bindsym --no-warn $mod+Shift+0 exec "swaysome move-to-group 0"
# Move focused container to next output
bindsym $mod+Alt+Right exec "swaysome next-output"
# Move focused container to previous output
bindsym $mod+Alt+Left exec "swaysome prev-output"
# Move focused workspace group to next output
bindsym $mod+Shift+Alt+Right exec "swaysome workspace-group-next-output"
# Move focused workspace group to previous output
bindsym $mod+Shift+Alt+Left exec "swaysome workspace-group-prev-output"
# Init workspaces for every screen
exec "swaysome init 1"

View File

@@ -27,7 +27,7 @@ rec {
kernel = { kernel = {
lts = pkgs: pkgs.linuxKernel.packages.linux_6_6; lts = pkgs: pkgs.linuxKernel.packages.linux_6_6;
latest = pkgs: pkgs.linuxKernel.packages.linux_6_12; latest = pkgs: pkgs.linuxKernel.packages.linux_6_9;
}; };
nginx = rec { nginx = rec {
@@ -98,10 +98,10 @@ rec {
nix = { nix = {
cache = rec { cache = rec {
substituters = [ substituters = [
"https://nix-cache.${pubDomain}" "https://nix-cache.${pubDomain}/main"
]; ];
keys = [ keys = [
"nix-cache.nul.ie-1:BzH5yMfF4HbzY1C977XzOxoPhEc9Zbu39ftPkUbH+m4=" "main:mMChkG8LwXrFirVfudqjSHasK1jV31OVElYD3eImYl8="
]; ];
conf = '' conf = ''
extra-substituters = ${concatStringsSep " " substituters} extra-substituters = ${concatStringsSep " " substituters}
@@ -135,9 +135,6 @@ rec {
v4 = subnet 8 3 all.v4; v4 = subnet 8 3 all.v4;
v6 = subnet 4 3 all.v6; v6 = subnet 4 3 all.v6;
}; };
qclk = {
v4 = subnet 8 4 all.v4;
};
cust = { cust = {
v4 = subnet 8 100 all.v4; # single ip for routing only v4 = subnet 8 100 all.v4; # single ip for routing only
@@ -173,10 +170,6 @@ rec {
jam-ctr = host 3 prefixes.cust.v4; jam-ctr = host 3 prefixes.cust.v4;
}; };
qclk = {
wgPort = 51821;
};
firewallForwards = aa: [ firewallForwards = aa: [
{ {
port = "http"; port = "http";
@@ -227,23 +220,6 @@ rec {
dst = aa.simpcraft-oci.internal.ipv4.address; dst = aa.simpcraft-oci.internal.ipv4.address;
proto = "udp"; proto = "udp";
} }
{
port = 15636;
dst = aa.enshrouded-oci.internal.ipv4.address;
proto = "udp";
}
{
port = 15637;
dst = aa.enshrouded-oci.internal.ipv4.address;
proto = "udp";
}
{
port = qclk.wgPort;
dst = aa.qclk.internal.ipv4.address;
proto = "udp";
}
]; ];
fstrimConfig = { fstrimConfig = {
@@ -267,7 +243,7 @@ rec {
"stream" "stream"
]; ];
routersPubV4 = [ routersPubV4 = [
"109.255.31.155" "188.141.14.7"
"109.255.252.63" "109.255.252.63"
]; ];
@@ -317,8 +293,6 @@ rec {
v6 = host ((1*65536*65536*65536) + 65535) prefixes.as211024.v6; v6 = host ((1*65536*65536*65536) + 65535) prefixes.as211024.v6;
}; };
}; };
roceBootModules = [ "ib_core" "ib_uverbs" "mlx5_core" "mlx5_ib" ];
}; };
britway = { britway = {
@@ -383,7 +357,6 @@ rec {
deploy = ../.keys/deploy.pub; deploy = ../.keys/deploy.pub;
rsyncNet = ../.keys/zh2855.rsync.net.pub; rsyncNet = ../.keys/zh2855.rsync.net.pub;
mailcowAcme = ../.keys/mailcow-acme.pub; mailcowAcme = ../.keys/mailcow-acme.pub;
harmonia = ../.keys/harmonia.pub;
}; };
sshHostKeys = { sshHostKeys = {
mail-vm = ../.keys/mail-vm-host.pub; mail-vm = ../.keys/mail-vm-host.pub;

View File

@@ -5,7 +5,7 @@ let
genAttrs mapAttrsToList filterAttrsRecursive nameValuePair types genAttrs mapAttrsToList filterAttrsRecursive nameValuePair types
mkOption mkOverride mkForce mkIf mergeEqualOption optional mkOption mkOverride mkForce mkIf mergeEqualOption optional
showWarnings concatStringsSep flatten unique optionalAttrs showWarnings concatStringsSep flatten unique optionalAttrs
mkBefore toLower; mkBefore;
inherit (lib.flake) defaultSystems; inherit (lib.flake) defaultSystems;
in in
rec { rec {
@@ -248,37 +248,10 @@ rec {
in in
{ {
trivial = prev.trivial // { trivial = prev.trivial // {
release = "24.12:u-${prev.trivial.release}"; release = "24.06:u-${prev.trivial.release}";
codeName = "Epic"; codeName = "Carbrain";
revisionWithDefault = default: self.rev or default; revisionWithDefault = default: self.rev or default;
versionSuffix = ".${date}.${revCode self}:u-${revCode pkgsFlake}"; versionSuffix = ".${date}.${revCode self}:u-${revCode pkgsFlake}";
}; };
}; };
netbootKeaClientClasses = { tftpIP, hostname, systems }:
let
testIPXE = "substring(option[user-class].hex, 0, 4) == 'iPXE'";
in
(mapAttrsToList (name: mac: {
name = "nixos-${name}";
test = "(${testIPXE}) and (hexstring(pkt4.mac, ':') == '${toLower mac}')";
next-server = tftpIP;
server-hostname = hostname;
boot-file-name = "http://${hostname}/systems/${name}/menu.ipxe";
}) systems) ++ [
{
name = "ipxe";
test = testIPXE;
next-server = tftpIP;
server-hostname = hostname;
boot-file-name = "http://${hostname}/boot.ipxe";
}
{
name = "efi-x86_64";
test = "option[client-system].hex == 0x0007";
next-server = tftpIP;
server-hostname = hostname;
boot-file-name = "ipxe-x86_64.efi";
}
];
} }

View File

@@ -106,7 +106,7 @@ in
{ {
matchConfig.Name = "as211024"; matchConfig.Name = "as211024";
networkConfig.IPv6AcceptRA = mkForce false; networkConfig.IPv6AcceptRA = mkForce false;
routes = [ routes = map (r: { routeConfig = r; }) [
{ {
Destination = lib.my.c.colony.prefixes.all.v4; Destination = lib.my.c.colony.prefixes.all.v4;
Gateway = allAssignments.estuary.as211024.ipv4.address; Gateway = allAssignments.estuary.as211024.ipv4.address;
@@ -123,7 +123,7 @@ in
Table = "ts-extra"; Table = "ts-extra";
} }
]; ];
routingPolicyRules = [ routingPolicyRules = map (r: { routingPolicyRuleConfig = r; }) [
{ {
IncomingInterface = "tailscale0"; IncomingInterface = "tailscale0";
To = lib.my.c.colony.prefixes.all.v6; To = lib.my.c.colony.prefixes.all.v6;

View File

@@ -80,7 +80,7 @@ in
}; };
}; };
"hs.${pubDomain}" = { "ts.${pubDomain}" = {
locations."/" = { locations."/" = {
proxyPass = "http://localhost:${toString config.services.headscale.port}"; proxyPass = "http://localhost:${toString config.services.headscale.port}";
proxyWebsockets = true; proxyWebsockets = true;

View File

@@ -5,20 +5,18 @@ let
inherit (lib.my.c.britway) prefixes domain; inherit (lib.my.c.britway) prefixes domain;
# Can't use overrideAttrs because we need to override `vendorHash` within `buildGoModule` # Can't use overrideAttrs because we need to override `vendorHash` within `buildGoModule`
headscale' = (pkgs.headscale.override { headscale = pkgs.headscale.override {
buildGoModule = args: pkgs.buildGoModule (args // rec { buildGoModule = args: pkgs.buildGoModule (args // rec {
version = "0.23.0-alpha12"; version = "0.23.0-alpha2";
src = pkgs.fetchFromGitHub { src = pkgs.fetchFromGitHub {
owner = "juanfont"; owner = "juanfont";
repo = "headscale"; repo = "headscale";
rev = "v${version}"; rev = "v${version}";
hash = "sha256-kZZK0cXnFARxblSMz01TDcBbTorkHGAwGpR+a4/mYfU="; hash = "sha256-sz+uQyyq/5YYDe5I44x5x2nvd48swAhNlInB8KZYvDo=";
}; };
patches = []; vendorHash = "sha256-u9AmJguQ5dnJpfhOeLN43apvMHuraOrJhvlEIp9RoIc=";
vendorHash = "sha256-EorT2AVwA3usly/LcNor6r5UIhLCdj3L4O4ilgTIC2o=";
doCheck = false;
});
}); });
};
advRoutes = concatStringsSep "," [ advRoutes = concatStringsSep "," [
lib.my.c.home.prefixes.all.v4 lib.my.c.home.prefixes.all.v4
@@ -41,20 +39,19 @@ in
services = { services = {
headscale = { headscale = {
enable = true; enable = true;
package = headscale;
settings = { settings = {
disable_check_updates = true; disable_check_updates = true;
unix_socket_permission = "0770"; unix_socket_permission = "0770";
server_url = "https://hs.${pubDomain}"; server_url = "https://ts.${pubDomain}";
database = { db_type = "sqlite3";
type = "sqlite3"; db_path = "/var/lib/headscale/db.sqlite3";
sqlite.path = "/var/lib/headscale/db.sqlite3";
};
noise.private_key_path = "/var/lib/headscale/noise_private.key"; noise.private_key_path = "/var/lib/headscale/noise_private.key";
prefixes = with lib.my.c.tailscale.prefix; { inherit v4 v6; }; ip_prefixes = with lib.my.c.tailscale.prefix; [ v4 v6 ];
dns = { dns_config = {
# Use IPs that will route inside the VPN to prevent interception # Use IPs that will route inside the VPN to prevent interception
# (e.g. DNS rebinding filtering) # (e.g. DNS rebinding filtering)
nameservers.split = { restricted_nameservers = {
"${domain}" = pubNameservers; "${domain}" = pubNameservers;
"${lib.my.c.colony.domain}" = with allAssignments.estuary.base; [ "${lib.my.c.colony.domain}" = with allAssignments.estuary.base; [
ipv4.address ipv6.address ipv4.address ipv6.address
@@ -68,6 +65,7 @@ in
}; };
magic_dns = true; magic_dns = true;
base_domain = "ts.${pubDomain}"; base_domain = "ts.${pubDomain}";
override_local_dns = false;
}; };
oidc = { oidc = {
only_start_if_oidc_is_available = true; only_start_if_oidc_is_available = true;
@@ -87,7 +85,7 @@ in
interfaceName = "tailscale0"; interfaceName = "tailscale0";
extraUpFlags = [ extraUpFlags = [
"--operator=${config.my.user.config.name}" "--operator=${config.my.user.config.name}"
"--login-server=https://hs.nul.ie" "--login-server=https://ts.nul.ie"
"--netfilter-mode=off" "--netfilter-mode=off"
"--advertise-exit-node" "--advertise-exit-node"
"--advertise-routes=${advRoutes}" "--advertise-routes=${advRoutes}"

View File

@@ -1,8 +1,7 @@
{ lib, ... }: { lib, ... }:
let let
inherit (lib.my) net; inherit (lib.my) net;
inherit (lib.my.c) networkd; inherit (lib.my.c.home) domain vlans prefixes;
inherit (lib.my.c.home) domain vlans prefixes vips roceBootModules;
in in
{ {
nixos.systems.castle = { nixos.systems.castle = {
@@ -16,7 +15,7 @@ in
ipv4 = { ipv4 = {
address = net.cidr.host 40 prefixes.hi.v4; address = net.cidr.host 40 prefixes.hi.v4;
mask = 22; mask = 22;
gateway = vips.hi.v4; gateway = null;
}; };
ipv6 = { ipv6 = {
iid = "::3:1"; iid = "::3:1";
@@ -36,7 +35,7 @@ in
cpu = { cpu = {
amd.updateMicrocode = true; amd.updateMicrocode = true;
}; };
graphics.extraPackages = with pkgs; [ opengl.extraPackages = with pkgs; [
intel-media-driver intel-media-driver
]; ];
bluetooth.enable = true; bluetooth.enable = true;
@@ -48,7 +47,7 @@ in
timeout = 10; timeout = 10;
}; };
kernelPackages = lib.my.c.kernel.latest pkgs; kernelPackages = lib.my.c.kernel.latest pkgs;
kernelModules = [ "kvm-amd" "dm-snapshot" ]; kernelModules = [ "kvm-amd" ];
kernelParams = [ "amd_iommu=on" "amd_pstate=passive" ]; kernelParams = [ "amd_iommu=on" "amd_pstate=passive" ];
kernelPatches = [ kernelPatches = [
# { # {
@@ -58,40 +57,27 @@ in
# } # }
]; ];
initrd = { initrd = {
availableKernelModules = [ availableKernelModules = [ "thunderbolt" "xhci_pci" "nvme" "ahci" "usbhid" "usb_storage" "sd_mod" ];
"thunderbolt" "xhci_pci" "nvme" "ahci" "usbhid" "usb_storage" "sd_mod"
"8021q"
] ++ roceBootModules;
systemd.network = {
netdevs = mkVLAN "lan-hi" vlans.hi;
networks = {
"10-et100g" = {
matchConfig.Name = "et100g";
vlan = [ "lan-hi" ];
linkConfig.RequiredForOnline = "no";
networkConfig = networkd.noL3;
}; };
"20-lan-hi" = networkdAssignment "lan-hi" assignments.hi;
};
};
};
binfmt.emulatedSystems = [ "aarch64-linux" "armv7l-linux" ];
}; };
fileSystems = { fileSystems = {
"/boot" = {
device = "/dev/disk/by-partuuid/8ce4248a-3ee4-f44f-801f-064a628b4d6e";
fsType = "vfat";
};
"/nix" = { "/nix" = {
device = "/dev/nvmeof/nix"; device = "/dev/disk/by-partuuid/2da23a1d-2daf-d943-b91e-fc175f3dad07";
fsType = "ext4"; fsType = "ext4";
}; };
"/persist" = { "/persist" = {
device = "/dev/nvmeof/persist"; device = "/dev/disk/by-partuuid/f4c80d4f-a022-e941-b5d1-fe2e65e444b9";
fsType = "ext4"; fsType = "ext4";
neededForBoot = true; neededForBoot = true;
}; };
"/home" = { "/home" = {
device = "/dev/nvmeof/home"; device = "/dev/disk/by-partuuid/992a93cf-6c9c-324b-b0ce-f8eb2d1ce10d";
fsType = "ext4"; fsType = "ext4";
}; };
}; };
@@ -134,7 +120,7 @@ in
virtualisation.libvirtd.enable = true; virtualisation.libvirtd.enable = true;
networking = { networking = {
inherit domain; domain = "h.${lib.my.c.pubDomain}";
firewall.enable = false; firewall.enable = false;
}; };
@@ -154,14 +140,11 @@ in
nix = { nix = {
gc.automatic = false; gc.automatic = false;
settings = {
experimental-features = [ "recursive-nix" ];
system-features = [ "nixos-test" "benchmark" "big-parallel" "kvm" "recursive-nix" ];
};
}; };
systemd = { systemd = {
network = { network = {
wait-online.enable = false;
netdevs = mkMerge [ netdevs = mkMerge [
(mkVLAN "lan-hi" vlans.hi) (mkVLAN "lan-hi" vlans.hi)
]; ];
@@ -178,20 +161,29 @@ in
matchConfig.PermanentMACAddress = "24:8a:07:a8:fe:3a"; matchConfig.PermanentMACAddress = "24:8a:07:a8:fe:3a";
linkConfig = { linkConfig = {
Name = "et100g"; Name = "et100g";
MTUBytes = toString lib.my.c.home.hiMTU; MTUBytes = "9000";
}; };
}; };
}; };
networks = { networks = {
"30-et100g" = { "50-lan" = {
matchConfig.Name = "et2.5g";
DHCP = "no";
address = [ "10.16.7.1/16" ];
};
"50-et100g" = {
matchConfig.Name = "et100g"; matchConfig.Name = "et100g";
vlan = [ "lan-hi" ]; vlan = [ "lan-hi" ];
networkConfig.IPv6AcceptRA = false; networkConfig.IPv6AcceptRA = false;
}; };
"40-lan-hi" = mkMerge [ "60-lan-hi" = mkMerge [
(networkdAssignment "lan-hi" assignments.hi) (networkdAssignment "lan-hi" assignments.hi)
# So we don't drop the IP we use to connect to NVMe-oF! {
{ networkConfig.KeepConfiguration = "static"; } DHCP = "yes";
matchConfig.Name = "lan-hi";
linkConfig.MTUBytes = "9000";
}
]; ];
}; };
}; };
@@ -225,7 +217,6 @@ in
HDMI-A-1 = { HDMI-A-1 = {
transform = "270"; transform = "270";
position = "0 0"; position = "0 0";
bg = "${./his-team-player.jpg} fill";
}; };
DP-1 = { DP-1 = {
mode = "2560x1440@170Hz"; mode = "2560x1440@170Hz";
@@ -247,19 +238,11 @@ in
}; };
#deploy.generate.system.mode = "boot"; #deploy.generate.system.mode = "boot";
deploy.node.hostname = "castle.box.${config.networking.domain}";
secrets = { secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMlVuTzKObeaUuPocCF41IO/8X+443lzUJLuCIclt2vr"; key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMlVuTzKObeaUuPocCF41IO/8X+443lzUJLuCIclt2vr";
}; };
netboot.client = { nvme.uuid = "2230b066-a674-4f45-a1dc-f7727b3a9e7b";
enable = true;
};
nvme = {
uuid = "2230b066-a674-4f45-a1dc-f7727b3a9e7b";
boot = {
nqn = "nqn.2016-06.io.spdk:castle";
address = "192.168.68.80";
};
};
firewall = { firewall = {
enable = false; enable = false;

View File

@@ -252,10 +252,10 @@ in
}; };
ipv6Prefixes = [ ipv6Prefixes = [
{ {
Prefix = prefixes.vms.v6; ipv6PrefixConfig.Prefix = prefixes.vms.v6;
} }
]; ];
routes = [ routes = map (r: { routeConfig = r; }) [
{ {
Destination = prefixes.ctrs.v4; Destination = prefixes.ctrs.v4;
Gateway = allAssignments.shill.routing.ipv4.address; Gateway = allAssignments.shill.routing.ipv4.address;
@@ -264,12 +264,10 @@ in
Destination = prefixes.ctrs.v6; Destination = prefixes.ctrs.v6;
Gateway = allAssignments.shill.internal.ipv6.address; Gateway = allAssignments.shill.internal.ipv6.address;
} }
{ {
Destination = allAssignments.shill.internal.ipv4.address; Destination = allAssignments.shill.internal.ipv4.address;
Gateway = allAssignments.shill.routing.ipv4.address; Gateway = allAssignments.shill.routing.ipv4.address;
} }
{ {
Destination = lib.my.c.tailscale.prefix.v4; Destination = lib.my.c.tailscale.prefix.v4;
Gateway = allAssignments.shill.routing.ipv4.address; Gateway = allAssignments.shill.routing.ipv4.address;
@@ -278,11 +276,6 @@ in
Destination = lib.my.c.tailscale.prefix.v6; Destination = lib.my.c.tailscale.prefix.v6;
Gateway = allAssignments.shill.internal.ipv6.address; Gateway = allAssignments.shill.internal.ipv6.address;
} }
{
Destination = prefixes.qclk.v4;
Gateway = allAssignments.shill.routing.ipv4.address;
}
{ {
Destination = prefixes.jam.v6; Destination = prefixes.jam.v6;
Gateway = allAssignments.shill.internal.ipv6.address; Gateway = allAssignments.shill.internal.ipv6.address;
@@ -327,10 +320,10 @@ in
}; };
ipv6Prefixes = [ ipv6Prefixes = [
{ {
Prefix = prefixes.mail.v6; ipv6PrefixConfig.Prefix = prefixes.mail.v6;
} }
]; ];
routes = [ routes = map (r: { routeConfig = r; }) [
{ {
Destination = prefixes.mail.v4; Destination = prefixes.mail.v4;
Scope = "link"; Scope = "link";
@@ -350,10 +343,10 @@ in
}; };
ipv6Prefixes = [ ipv6Prefixes = [
{ {
Prefix = prefixes.darts.v6; ipv6PrefixConfig.Prefix = prefixes.darts.v6;
} }
]; ];
routes = [ routes = map (r: { routeConfig = r; }) [
{ {
Destination = prefixes.darts.v4; Destination = prefixes.darts.v4;
Scope = "link"; Scope = "link";

View File

@@ -29,9 +29,6 @@
}; };
in in
{ {
# Kernel Same-Page Merging to attempt memory usage reduction
hardware.ksm.enable = false;
systemd = { systemd = {
network = { network = {
links = { links = {
@@ -133,7 +130,7 @@
(vm.lvmDisk "media") (vm.lvmDisk "media")
(vm.lvmDisk "minio") (vm.lvmDisk "minio")
(vm.lvmDisk "nix-cache") (vm.lvmDisk "nix-atticd")
(vm.lvmDisk "jam") (vm.lvmDisk "jam")
]); ]);
}; };

View File

@@ -164,9 +164,11 @@ in
}; };
wireguardPeers = [ wireguardPeers = [
{ {
wireguardPeerConfig = {
PublicKey = "7N9YdQaCMWWIwAnW37vrthm9ZpbnG4Lx3gheHeRYz2E="; PublicKey = "7N9YdQaCMWWIwAnW37vrthm9ZpbnG4Lx3gheHeRYz2E=";
AllowedIPs = [ allAssignments.kelder.estuary.ipv4.address ]; AllowedIPs = [ allAssignments.kelder.estuary.ipv4.address ];
PersistentKeepalive = 25; PersistentKeepalive = 25;
};
} }
]; ];
}; };
@@ -276,10 +278,11 @@ in
}; };
ipv6Prefixes = [ ipv6Prefixes = [
{ {
Prefix = prefixes.base.v6; ipv6PrefixConfig.Prefix = prefixes.base.v6;
} }
]; ];
routes = flatten ([ routes = map (r: { routeConfig = r; }) (flatten
([
{ {
Destination = prefixes.vip1; Destination = prefixes.vip1;
Gateway = allAssignments.colony.routing.ipv4.address; Gateway = allAssignments.colony.routing.ipv4.address;
@@ -305,11 +308,6 @@ in
Destination = lib.my.c.tailscale.prefix.v6; Destination = lib.my.c.tailscale.prefix.v6;
Gateway = allAssignments.colony.internal.ipv6.address; Gateway = allAssignments.colony.internal.ipv6.address;
} }
{
Destination = prefixes.qclk.v4;
Gateway = allAssignments.colony.routing.ipv4.address;
}
] ++ ] ++
(map (pName: [ (map (pName: [
{ {
@@ -320,7 +318,7 @@ in
Destination = prefixes."${pName}".v6; Destination = prefixes."${pName}".v6;
Gateway = allAssignments.colony.internal.ipv6.address; Gateway = allAssignments.colony.internal.ipv6.address;
} }
]) [ "vms" "ctrs" "oci" ])); ]) [ "vms" "ctrs" "oci" ])));
} }
]; ];
@@ -329,7 +327,7 @@ in
{ {
matchConfig.Name = "as211024"; matchConfig.Name = "as211024";
networkConfig.IPv6AcceptRA = mkForce false; networkConfig.IPv6AcceptRA = mkForce false;
routes = [ routes = map (r: { routeConfig = r; }) [
{ {
Destination = lib.my.c.home.prefixes.all.v4; Destination = lib.my.c.home.prefixes.all.v4;
Gateway = lib.my.c.home.vips.as211024.v4; Gateway = lib.my.c.home.vips.as211024.v4;
@@ -341,8 +339,10 @@ in
matchConfig.Name = "kelder"; matchConfig.Name = "kelder";
routes = [ routes = [
{ {
routeConfig = {
Destination = allAssignments.kelder.estuary.ipv4.address; Destination = allAssignments.kelder.estuary.ipv4.address;
Scope = "link"; Scope = "link";
};
} }
]; ];
}; };
@@ -407,7 +407,6 @@ in
ip6 daddr ${aa.valheim-oci.internal.ipv6.address} udp dport { 2456-2457 } accept ip6 daddr ${aa.valheim-oci.internal.ipv6.address} udp dport { 2456-2457 } accept
ip6 daddr ${aa.waffletail.internal.ipv6.address} udp dport 41641 accept ip6 daddr ${aa.waffletail.internal.ipv6.address} udp dport 41641 accept
ip6 daddr ${aa.simpcraft-oci.internal.ipv6.address} udp dport 25565 accept ip6 daddr ${aa.simpcraft-oci.internal.ipv6.address} udp dport 25565 accept
ip6 daddr ${aa.enshrouded-oci.internal.ipv6.address} udp dport { 15636-15637 } accept
return return
} }
chain filter-routing { chain filter-routing {

View File

@@ -153,7 +153,6 @@ in
simpcraft IN AAAA ${allAssignments.simpcraft-oci.internal.ipv6.address} simpcraft IN AAAA ${allAssignments.simpcraft-oci.internal.ipv6.address}
simpcraft-staging IN A ${assignments.internal.ipv4.address} simpcraft-staging IN A ${assignments.internal.ipv4.address}
simpcraft-staging IN AAAA ${allAssignments.simpcraft-staging-oci.internal.ipv6.address} simpcraft-staging IN AAAA ${allAssignments.simpcraft-staging-oci.internal.ipv6.address}
enshrouded IN A ${assignments.internal.ipv4.address}
mail-vm IN A ${net.cidr.host 0 prefixes.mail.v4} mail-vm IN A ${net.cidr.host 0 prefixes.mail.v4}
mail-vm IN AAAA ${net.cidr.host 1 prefixes.mail.v6} mail-vm IN AAAA ${net.cidr.host 1 prefixes.mail.v6}

View File

@@ -35,11 +35,6 @@ in
]; ];
url = "https://git.${pubDomain}"; url = "https://git.${pubDomain}";
tokenFile = config.age.secrets."gitea/actions-runner.env".path; tokenFile = config.age.secrets."gitea/actions-runner.env".path;
settings = {
runner = {
timeout = "8h";
};
};
}; };
}; };
}; };

View File

@@ -47,10 +47,10 @@ in
}; };
ipv6Prefixes = [ ipv6Prefixes = [
{ {
Prefix = prefixes.jam.v6; ipv6PrefixConfig.Prefix = prefixes.jam.v6;
} }
]; ];
routes = [ routes = map (r: { routeConfig = r; }) [
{ {
Destination = prefixes.jam.v4; Destination = prefixes.jam.v4;
Scope = "link"; Scope = "link";
@@ -64,8 +64,8 @@ in
serviceConfig = { serviceConfig = {
CPUQuota = "400%"; CPUQuota = "400%";
MemoryHigh = "infinity"; MemoryHigh = "4G";
MemoryMax = "4G"; MemoryMax = "4.5G";
}; };
wantedBy = [ "machines.target" ]; wantedBy = [ "machines.target" ];

View File

@@ -50,6 +50,11 @@ in
group = "matrix-synapse"; group = "matrix-synapse";
}; };
"chatterbox/syncv3.env" = {
owner = "matrix-syncv3";
group = "matrix-syncv3";
};
"chatterbox/mautrix-whatsapp.env" = { "chatterbox/mautrix-whatsapp.env" = {
owner = "mautrix-whatsapp"; owner = "mautrix-whatsapp";
group = "mautrix-whatsapp"; group = "mautrix-whatsapp";
@@ -75,21 +80,32 @@ in
matrix-synapse.extraGroups = [ matrix-synapse.extraGroups = [
"mautrix-whatsapp" "mautrix-whatsapp"
]; ];
matrix-syncv3 = {
isSystemUser = true;
uid = uids.matrix-syncv3;
group = "matrix-syncv3";
};
};
groups = {
matrix-syncv3.gid = gids.matrix-syncv3;
}; };
groups = { };
}; };
systemd = { systemd = {
network.networks."80-container-host0" = networkdAssignment "host0" assignments.internal; network.networks."80-container-host0" = networkdAssignment "host0" assignments.internal;
services = { } // (genAttrs [ "mautrix-whatsapp" "mautrix-meta-messenger" "mautrix-meta-instagram" ] (_: { services = {
matrix-sliding-sync.serviceConfig = {
# Needs to be able to read its secrets
DynamicUser = mkForce false;
User = "matrix-syncv3";
Group = "matrix-syncv3";
};
} // (genAttrs [ "mautrix-whatsapp" "mautrix-meta-messenger" "mautrix-meta-instagram" ] (_: {
# ffmpeg needed to convert GIFs to video # ffmpeg needed to convert GIFs to video
path = with pkgs; [ ffmpeg ]; path = with pkgs; [ ffmpeg ];
})); }));
}; };
# TODO/FIXME: https://github.com/NixOS/nixpkgs/issues/336052
nixpkgs.config.permittedInsecurePackages = [ "olm-3.2.16" ];
services = { services = {
netdata.enable = true; netdata.enable = true;
matrix-synapse = { matrix-synapse = {
@@ -177,10 +193,20 @@ in
app_service_config_files = [ app_service_config_files = [
"/var/lib/heisenbridge/registration.yml" "/var/lib/heisenbridge/registration.yml"
config.age.secrets."chatterbox/doublepuppet.yaml".path config.age.secrets."chatterbox/doublepuppet.yaml".path
"/var/lib/mautrix-whatsapp/whatsapp-registration.yaml"
]; ];
}; };
}; };
matrix-sliding-sync = {
enable = true;
createDatabase = false;
environmentFile = config.age.secrets."chatterbox/syncv3.env".path;
settings = {
SYNCV3_BINDADDR = "[::]:8009";
SYNCV3_SERVER = "http://localhost:8008";
};
};
heisenbridge = { heisenbridge = {
enable = true; enable = true;
@@ -259,12 +285,10 @@ in
avatar = "mxc://maunium.net/ygtkteZsXnGJLJHRchUwYWak"; avatar = "mxc://maunium.net/ygtkteZsXnGJLJHRchUwYWak";
}; };
}; };
network = { meta.mode = "messenger";
mode = "messenger";
displayname_template = ''{{or .DisplayName .Username "Unknown user"}} (FBM)'';
};
bridge = { bridge = {
username_template = "fbm2_{{.}}"; username_template = "fbm2_{{.}}";
displayname_template = ''{{or .DisplayName .Username "Unknown user"}} (FBM)'';
personal_filtering_spaces = true; personal_filtering_spaces = true;
delivery_receipts = true; delivery_receipts = true;
management_room_text.welcome = "Hello, I'm a Messenger bridge bot."; management_room_text.welcome = "Hello, I'm a Messenger bridge bot.";
@@ -307,12 +331,10 @@ in
avatar = "mxc://maunium.net/JxjlbZUlCPULEeHZSwleUXQv"; avatar = "mxc://maunium.net/JxjlbZUlCPULEeHZSwleUXQv";
}; };
}; };
network = { meta.mode = "instagram";
mode = "instagram";
displayname_template = ''{{or .DisplayName .Username "Unknown user"}} (IG)'';
};
bridge = { bridge = {
username_template = "ig_{{.}}"; username_template = "ig_{{.}}";
displayname_template = ''{{or .DisplayName .Username "Unknown user"}} (IG)'';
personal_filtering_spaces = true; personal_filtering_spaces = true;
delivery_receipts = true; delivery_receipts = true;
management_room_text.welcome = "Hello, I'm an Instagram bridge bot."; management_room_text.welcome = "Hello, I'm an Instagram bridge bot.";

View File

@@ -8,6 +8,5 @@
./object.nix ./object.nix
./toot.nix ./toot.nix
./waffletail.nix ./waffletail.nix
./qclk
]; ];
} }

View File

@@ -94,14 +94,6 @@ in
}; };
}; };
nixpkgs.config.permittedInsecurePackages = [
# FIXME: This is needed for Sonarr
"aspnetcore-runtime-wrapped-6.0.36"
"aspnetcore-runtime-6.0.36"
"dotnet-sdk-wrapped-6.0.428"
"dotnet-sdk-6.0.428"
];
services = { services = {
netdata.enable = true; netdata.enable = true;

View File

@@ -71,12 +71,14 @@ in
RouteTable = routeTable; RouteTable = routeTable;
}; };
wireguardPeers = [ wireguardPeers = [
# AirVPN NL
{ {
# AirVPN NL
wireguardPeerConfig = {
Endpoint = "2a00:1678:1337:2329:e5f:35d4:4404:ef9f:1637"; Endpoint = "2a00:1678:1337:2329:e5f:35d4:4404:ef9f:1637";
PublicKey = "PyLCXAQT8KkM4T+dUsOQfn+Ub3pGxfGlxkIApuig+hk="; PublicKey = "PyLCXAQT8KkM4T+dUsOQfn+Ub3pGxfGlxkIApuig+hk=";
PresharedKeyFile = config.age.secrets."${pskFile}".path; PresharedKeyFile = config.age.secrets."${pskFile}".path;
AllowedIPs = [ "0.0.0.0/0" "::/0" ]; AllowedIPs = [ "0.0.0.0/0" "::/0" ];
};
} }
]; ];
}; };
@@ -92,7 +94,7 @@ in
matchConfig.Name = "vpn"; matchConfig.Name = "vpn";
address = [ "10.182.97.37/32" "fd7d:76ee:e68f:a993:735d:ef5e:6907:b122/128" ]; address = [ "10.182.97.37/32" "fd7d:76ee:e68f:a993:735d:ef5e:6907:b122/128" ];
dns = [ "10.128.0.1" "fd7d:76ee:e68f:a993::1" ]; dns = [ "10.128.0.1" "fd7d:76ee:e68f:a993::1" ];
routingPolicyRules = [ routingPolicyRules = map (r: { routingPolicyRuleConfig = r; }) [
{ {
Family = "both"; Family = "both";
SuppressPrefixLength = 0; SuppressPrefixLength = 0;

View File

@@ -239,9 +239,6 @@ in
]; ];
recommendedTlsSettings = true; recommendedTlsSettings = true;
recommendedBrotliSettings = true;
# Uh so nginx is hanging with zstd enabled... maybe let's not for now
# recommendedZstdSettings = true;
clientMaxBodySize = "0"; clientMaxBodySize = "0";
serverTokens = true; serverTokens = true;
resolver = { resolver = {

View File

@@ -2,7 +2,7 @@
let let
inherit (builtins) mapAttrs toJSON; inherit (builtins) mapAttrs toJSON;
inherit (lib) mkMerge mkDefault genAttrs flatten concatStringsSep; inherit (lib) mkMerge mkDefault genAttrs flatten concatStringsSep;
inherit (lib.my.c) pubDomain home; inherit (lib.my.c) pubDomain;
inherit (lib.my.c.nginx) proxyHeaders; inherit (lib.my.c.nginx) proxyHeaders;
inherit (config.networking) domain; inherit (config.networking) domain;
@@ -35,6 +35,7 @@ let
# For clients # For clients
(mkWellKnown "matrix/client" (toJSON { (mkWellKnown "matrix/client" (toJSON {
"m.homeserver".base_url = "https://matrix.nul.ie"; "m.homeserver".base_url = "https://matrix.nul.ie";
"org.matrix.msc3575.proxy".url = "https://matrix-syncv3.nul.ie";
})) }))
]; ];
}; };
@@ -144,7 +145,7 @@ in
"pass.${pubDomain}" = "pass.${pubDomain}" =
let let
upstream = "http://vaultwarden-ctr.${domain}:8080"; upstream = "http://vaultwarden-ctr.${domain}";
in in
{ {
locations = { locations = {
@@ -181,6 +182,10 @@ in
]; ];
useACMEHost = pubDomain; useACMEHost = pubDomain;
}; };
"matrix-syncv3.${pubDomain}" = {
locations."/".proxyPass = "http://chatterbox-ctr.${domain}:8009";
useACMEHost = pubDomain;
};
"element.${pubDomain}" = "element.${pubDomain}" =
let let
@@ -201,8 +206,7 @@ in
# Currently it seems like single quotes aren't escaped like they should be... # Currently it seems like single quotes aren't escaped like they should be...
conf = { conf = {
brand = "/dev/player0 Matrix"; brand = "/dev/player0 Matrix";
show_labs_settings = true; showLabsSettings = true;
default_country_code = "IE";
disable_guests = true; disable_guests = true;
default_server_config = { default_server_config = {
"m.homeserver" = { "m.homeserver" = {
@@ -210,8 +214,9 @@ in
server_name = "nul.ie"; server_name = "nul.ie";
}; };
}; };
room_directory.servers = [ roomDirectory.servers = [
"nul.ie" "nul.ie"
"netsoc.ie"
"matrix.org" "matrix.org"
]; ];
}; };
@@ -391,28 +396,6 @@ in
}; };
useACMEHost = pubDomain; useACMEHost = pubDomain;
}; };
"pront.${pubDomain}" = mkMerge [
{
locations."/" = mkMerge [
{
proxyPass = "http://stream-hi.${home.domain}:5000";
proxyWebsockets = true;
extraConfig = proxyHeaders;
}
(ssoLoc "generic")
];
locations."~* ^/webcam/(.*)" = mkMerge [
{
proxyPass = "http://stream-hi.${home.domain}:5050/$1$is_args$args";
extraConfig = proxyHeaders;
}
(ssoLoc "generic")
];
useACMEHost = pubDomain;
}
(ssoServer "generic")
];
}; };
minio = minio =
@@ -424,13 +407,10 @@ in
ignore_invalid_headers off; ignore_invalid_headers off;
''; '';
nixCacheableRegex = ''^\/(\S+\.narinfo|nar\/\S+\.nar.*|serve\/.+)$''; nixCacheableRegex = ''^\/(\S+\.narinfo|nar\/\S+\.nar\.\S+)$'';
nixCacheHeaders = '' nixCacheHeaders = ''
add_header Cache-Control $nix_cache_control; add_header Cache-Control $nix_cache_control;
add_header Expires $nix_expires; add_header Expires $nix_expires;
brotli on;
brotli_types application/x-nix-archive;
''; '';
in in
{ {
@@ -472,11 +452,9 @@ in
"nix-cache.${pubDomain}" = { "nix-cache.${pubDomain}" = {
locations = { locations = {
"/" = { "/".proxyPass = "http://${host}:8069";
proxyPass = "http://${host}:5000";
};
"~ ${nixCacheableRegex}" = { "~ ${nixCacheableRegex}" = {
proxyPass = "http://${host}:5000"; proxyPass = "http://${host}:8069";
extraConfig = nixCacheHeaders; extraConfig = nixCacheHeaders;
}; };
}; };

View File

@@ -31,13 +31,6 @@ in
{ {
config = mkMerge [ config = mkMerge [
{ {
fileSystems = {
"/var/lib/harmonia" = {
device = "/mnt/nix-cache";
options = [ "bind" ];
};
};
my = { my = {
deploy.enable = false; deploy.enable = false;
server.enable = true; server.enable = true;
@@ -55,7 +48,6 @@ in
group = config.my.user.config.group; group = config.my.user.config.group;
}; };
"object/atticd.env" = {}; "object/atticd.env" = {};
"nix-cache.key" = {};
"object/hedgedoc.env" = {}; "object/hedgedoc.env" = {};
"object/wastebin.env" = {}; "object/wastebin.env" = {};
}; };
@@ -66,7 +58,6 @@ in
9000 9001 9000 9001
config.services.sharry.config.bind.port config.services.sharry.config.bind.port
8069 8069
5000
config.services.hedgedoc.settings.port config.services.hedgedoc.settings.port
8088 8088
]; ];
@@ -77,26 +68,14 @@ in
}; };
}; };
users = with lib.my.c.ids; mkMerge [ users = with lib.my.c.ids; let inherit (config.services.atticd) user group; in {
(let inherit (config.services.atticd) user group; in {
users."${user}" = { users."${user}" = {
isSystemUser = true; isSystemUser = true;
uid = uids.atticd; uid = uids.atticd;
group = group; group = group;
}; };
groups."${user}".gid = gids.atticd; groups."${user}".gid = gids.atticd;
})
{
users = {
harmonia = {
shell = pkgs.bashInteractive;
openssh.authorizedKeys.keyFiles = [
lib.my.c.sshKeyFiles.harmonia
];
}; };
};
}
];
systemd = { systemd = {
network.networks."80-container-host0" = networkdAssignment "host0" assignments.internal; network.networks."80-container-host0" = networkdAssignment "host0" assignments.internal;
@@ -114,9 +93,7 @@ in
MINIO_BROWSER_REDIRECT_URL = "https://minio.nul.ie"; MINIO_BROWSER_REDIRECT_URL = "https://minio.nul.ie";
}; };
}; };
sharry = awaitPostgres; sharry = awaitPostgres;
atticd = mkMerge [ atticd = mkMerge [
awaitPostgres awaitPostgres
{ {
@@ -127,15 +104,6 @@ in
}; };
} }
]; ];
harmonia = {
environment.NIX_REMOTE = "/var/lib/harmonia";
preStart = ''
${config.nix.package}/bin/nix store ping
'';
serviceConfig = {
StateDirectory = "harmonia";
};
};
}; };
}; };
@@ -215,8 +183,8 @@ in
}; };
atticd = { atticd = {
enable = false; enable = true;
environmentFile = config.age.secrets."object/atticd.env".path; credentialsFile = config.age.secrets."object/atticd.env".path;
settings = { settings = {
listen = "[::]:8069"; listen = "[::]:8069";
allowed-hosts = [ "nix-cache.${pubDomain}" ]; allowed-hosts = [ "nix-cache.${pubDomain}" ];
@@ -235,14 +203,6 @@ in
}; };
}; };
harmonia = {
enable = true;
signKeyPaths = [ config.age.secrets."nix-cache.key".path ];
settings = {
priority = 30;
};
};
hedgedoc = { hedgedoc = {
enable = true; enable = true;
environmentFile = config.age.secrets."object/hedgedoc.env".path; environmentFile = config.age.secrets."object/hedgedoc.env".path;

View File

@@ -1,115 +0,0 @@
{ lib, ... }:
let
inherit (lib.my) net;
inherit (lib.my.c.colony) domain prefixes qclk;
in
{
nixos.systems.qclk = { config, ... }: {
system = "x86_64-linux";
nixpkgs = "mine";
rendered = config.configuration.config.my.asContainer;
assignments = {
internal = {
name = "qclk-ctr";
inherit domain;
ipv4.address = net.cidr.host 10 prefixes.ctrs.v4;
ipv6 = {
iid = "::a";
address = net.cidr.host 10 prefixes.ctrs.v6;
};
};
qclk = {
ipv4 = {
address = net.cidr.host 1 prefixes.qclk.v4;
gateway = null;
};
};
};
configuration = { lib, pkgs, config, assignments, ... }:
let
inherit (lib) concatStringsSep mkMerge mkIf mkForce;
inherit (lib.my) networkdAssignment;
apiPort = 8080;
instances = [
{
host = 2;
wgKey = "D7z1FhcdxpnrGCE0wBW5PZb5BKuhCu6tcZ/5ZaYxdwQ=";
}
];
ipFor = i: net.cidr.host i.host prefixes.qclk.v4;
in
{
config = {
environment = {
systemPackages = with pkgs; [
wireguard-tools
];
};
my = {
deploy.enable = false;
server.enable = true;
secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC1kcfvahYmSk8IJKaUIcGkhxf/8Yse2XnU7Qqgcglyq";
files = {
"qclk/wg.key" = {
group = "systemd-network";
mode = "440";
};
};
};
firewall = {
udp.allowed = [ qclk.wgPort ];
extraRules = ''
table inet filter {
chain input {
iifname management tcp dport ${toString apiPort} accept
}
chain forward {
iifname host0 oifname management ip saddr { ${concatStringsSep ", " lib.my.c.as211024.trusted.v4} } accept
}
}
table inet nat {
chain postrouting {
iifname host0 oifname management snat ip to ${assignments.qclk.ipv4.address}
}
}
'';
};
};
systemd = {
network = {
netdevs."30-management" = {
netdevConfig = {
Name = "management";
Kind = "wireguard";
};
wireguardConfig = {
PrivateKeyFile = config.age.secrets."qclk/wg.key".path;
ListenPort = qclk.wgPort;
};
wireguardPeers = map (i: {
PublicKey = i.wgKey;
AllowedIPs = [ (ipFor i) ];
}) instances;
};
networks = {
"30-container-host0" = networkdAssignment "host0" assignments.internal;
"30-management" = networkdAssignment "management" assignments.qclk;
};
};
};
services = { };
};
};
};
}

View File

@@ -83,7 +83,7 @@ in
DOMAIN = "https://pass.${lib.my.c.pubDomain}"; DOMAIN = "https://pass.${lib.my.c.pubDomain}";
ROCKET_ADDRESS = "::"; ROCKET_ADDRESS = "::";
ROCKET_PORT = 8080; ROCKET_PORT = 80;
SMTP_HOST = "mail.nul.ie"; SMTP_HOST = "mail.nul.ie";
SMTP_FROM = "pass@nul.ie"; SMTP_FROM = "pass@nul.ie";
@@ -99,8 +99,6 @@ in
}; };
borgbackup.jobs.vaultwarden = { borgbackup.jobs.vaultwarden = {
readWritePaths = [ "/var/lib/borgbackup" "/var/cache/borgbackup" ];
paths = [ vwData ]; paths = [ vwData ];
repo = "zh2855@zh2855.rsync.net:borg/vaultwarden2"; repo = "zh2855@zh2855.rsync.net:borg/vaultwarden2";
doInit = true; doInit = true;

View File

@@ -86,7 +86,7 @@ in
interfaceName = "tailscale0"; interfaceName = "tailscale0";
extraUpFlags = [ extraUpFlags = [
"--operator=${config.my.user.config.name}" "--operator=${config.my.user.config.name}"
"--login-server=https://hs.nul.ie" "--login-server=https://ts.nul.ie"
"--netfilter-mode=off" "--netfilter-mode=off"
"--advertise-exit-node" "--advertise-exit-node"
"--advertise-routes=${advRoutes}" "--advertise-routes=${advRoutes}"

View File

@@ -94,8 +94,8 @@ in
device = "/dev/disk/by-label/minio"; device = "/dev/disk/by-label/minio";
fsType = "xfs"; fsType = "xfs";
}; };
"/mnt/nix-cache" = { "/mnt/atticd" = {
device = "/dev/disk/by-label/nix-cache"; device = "/dev/disk/by-label/atticd";
fsType = "ext4"; fsType = "ext4";
}; };
}; };
@@ -140,10 +140,10 @@ in
}; };
ipv6Prefixes = [ ipv6Prefixes = [
{ {
Prefix = prefixes.ctrs.v6; ipv6PrefixConfig.Prefix = prefixes.ctrs.v6;
} }
]; ];
routes = [ routes = map (r: { routeConfig = r; }) [
{ {
Destination = lib.my.c.tailscale.prefix.v4; Destination = lib.my.c.tailscale.prefix.v4;
Gateway = allAssignments.waffletail.internal.ipv4.address; Gateway = allAssignments.waffletail.internal.ipv4.address;
@@ -152,11 +152,6 @@ in
Destination = lib.my.c.tailscale.prefix.v6; Destination = lib.my.c.tailscale.prefix.v6;
Gateway = allAssignments.waffletail.internal.ipv6.address; Gateway = allAssignments.waffletail.internal.ipv6.address;
} }
{
Destination = prefixes.qclk.v4;
Gateway = allAssignments.qclk.internal.ipv4.address;
}
]; ];
} }
]; ];
@@ -211,12 +206,11 @@ in
object = { object = {
bindMounts = { bindMounts = {
"/mnt/minio".readOnly = false; "/mnt/minio".readOnly = false;
"/mnt/nix-cache".readOnly = false; "/mnt/atticd".readOnly = false;
}; };
}; };
toot = {}; toot = {};
waffletail = {}; waffletail = {};
qclk = {};
}; };
in in
mkMerge [ mkMerge [

View File

@@ -52,7 +52,6 @@ in
valheim-oci = 2; valheim-oci = 2;
simpcraft-oci = 3; simpcraft-oci = 3;
simpcraft-staging-oci = 4; simpcraft-staging-oci = 4;
enshrouded-oci = 5;
}; };
configuration = { lib, pkgs, modulesPath, config, assignments, allAssignments, ... }: configuration = { lib, pkgs, modulesPath, config, assignments, allAssignments, ... }:
@@ -67,7 +66,6 @@ in
./valheim.nix ./valheim.nix
./minecraft ./minecraft
# ./enshrouded.nix
]; ];
config = mkMerge [ config = mkMerge [

View File

@@ -1,35 +0,0 @@
{ lib, config, allAssignments, ... }:
let
inherit (lib) concatStringsSep;
inherit (lib.my) dockerNetAssignment;
in
{
config = {
virtualisation.oci-containers.containers = {
enshrouded = {
image = "sknnr/enshrouded-dedicated-server@sha256:f163e8ba9caa2115d8a0a7b16c3696968242fb6fba82706d9a77a882df083497";
environment = {
SERVER_NAME = "UWUshrouded";
# SERVER_IP = "::"; # no IPv6?? :(
TZ = "Europe/Dublin";
};
environmentFiles = [ config.age.secrets."whale2/enshrouded.env".path ];
volumes = [
"enshrouded:/home/steam/enshrouded/savegame"
];
extraOptions = [
''--network=colony:${dockerNetAssignment allAssignments "enshrouded-oci"}''
];
};
};
my = {
secrets.files = {
"whale2/enshrouded.env" = {};
};
};
};
}

View File

@@ -123,7 +123,6 @@ in
within = "12H"; within = "12H";
hourly = 48; hourly = 48;
}; };
readWritePaths = [ "/var/lib/borgbackup" "/var/cache/borgbackup" ];
# Avoid Minecraft poking the files while we back up # Avoid Minecraft poking the files while we back up
preHook = rconCommand "save-off"; preHook = rconCommand "save-off";

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 MiB

View File

@@ -94,7 +94,7 @@ in
extraOptions = [ "-A /var/log/smartd/" "--interval=600" ]; extraOptions = [ "-A /var/log/smartd/" "--interval=600" ];
}; };
udev.extraRules = '' udev.extraRules = ''
ACTION=="add", SUBSYSTEM=="net", ENV{ID_NET_DRIVER}=="mlx5_core", ENV{ID_PATH}=="pci-0000:44:00.0", ATTR{device/sriov_numvfs}="4" ACTION=="add", SUBSYSTEM=="net", ENV{ID_NET_DRIVER}=="mlx5_core", ENV{ID_PATH}=="pci-0000:44:00.0", ATTR{device/sriov_numvfs}="3"
''; '';
}; };
@@ -188,13 +188,6 @@ in
VLANId=${toString vlans.hi} VLANId=${toString vlans.hi}
LinkState=yes LinkState=yes
MACAddress=52:54:00:ac:15:a9 MACAddress=52:54:00:ac:15:a9
# sfh bridge
[SR-IOV]
VirtualFunction=3
VLANId=${toString vlans.hi}
LinkState=yes
MACAddress=52:54:00:90:34:95
''; '';
}; };
"60-lan-hi" = networkdAssignment "lan-hi" assignments.hi; "60-lan-hi" = networkdAssignment "lan-hi" assignments.hi;

View File

@@ -66,7 +66,6 @@ in
]; ];
services = { services = {
fstrim.enable = true;
netdata.enable = true; netdata.enable = true;
}; };

View File

@@ -129,12 +129,6 @@ in
hostnqn = hostnqn =
"nqn.2014-08.org.nvmexpress:uuid:2230b066-a674-4f45-a1dc-f7727b3a9e7b"; "nqn.2014-08.org.nvmexpress:uuid:2230b066-a674-4f45-a1dc-f7727b3a9e7b";
serial = "SPDK00000000000002"; serial = "SPDK00000000000002";
}) ++ (nvmfBdev {
bdev = "NVMeRaidp3";
nqn = "nqn.2016-06.io.spdk:sfh";
hostnqn =
"nqn.2014-08.org.nvmexpress:uuid:85d7df36-0de0-431b-b06e-51f7c0a455b4";
serial = "SPDK00000000000003";
}); });
}; };
}; };

View File

@@ -2,7 +2,6 @@
imports = [ imports = [
./cellar ./cellar
./river.nix ./river.nix
./sfh
]; ];
nixos.systems.palace.configuration = { lib, pkgs, config, systems, allAssignments, ... }: nixos.systems.palace.configuration = { lib, pkgs, config, systems, allAssignments, ... }:
@@ -58,11 +57,11 @@
systemd.services = systemd.services =
let let
awaitVM = system: { awaitCellar = {
after = [ "vm@${system}.service" ]; after = [ "vm@cellar.service" ];
bindsTo = [ "vm@${system}.service" ]; bindsTo = [ "vm@cellar.service" ];
preStart = '' preStart = ''
until ${pkgs.netcat}/bin/nc -w1 -z ${allAssignments.${system}.hi.ipv4.address} 22; do until ${pkgs.netcat}/bin/nc -w1 -z ${allAssignments.cellar.hi.ipv4.address} 22; do
sleep 1 sleep 1
done done
''; '';
@@ -82,13 +81,13 @@
vtapUnit = "sys-subsystem-net-devices-vm\\x2det1g0.device"; vtapUnit = "sys-subsystem-net-devices-vm\\x2det1g0.device";
in in
mkMerge [ mkMerge [
(awaitVM "cellar") awaitCellar
{ {
requires = [ vtapUnit ]; requires = [ vtapUnit ];
after = [ vtapUnit ]; after = [ vtapUnit ];
} }
]; ];
"vm@sfh" = (awaitVM "river"); "vm@sfh" = awaitCellar;
}; };
my = { my = {
@@ -183,10 +182,6 @@
index = 0; index = 0;
hostBDF = "44:00.3"; hostBDF = "44:00.3";
}; };
et100g0vf3 = {
index = 1;
hostBDF = "44:00.4";
};
}; };
}; };
}; };

View File

@@ -10,7 +10,18 @@
let let
inherit (lib.my) networkdAssignment mkVLAN; inherit (lib.my) networkdAssignment mkVLAN;
inherit (lib.my.c) networkd; inherit (lib.my.c) networkd;
inherit (lib.my.c.home) vlans domain prefixes roceBootModules; inherit (lib.my.c.home) vlans;
lanLink = {
matchConfig = {
Driver = "mlx5_core";
PermanentMACAddress = "52:54:00:8a:8a:f2";
};
linkConfig = {
Name = "lan";
MTUBytes = toString lib.my.c.home.hiMTU;
};
};
in in
{ {
imports = [ imports = [
@@ -19,17 +30,29 @@
config = { config = {
boot = { boot = {
kernelModules = [ "kvm-amd" ]; kernelModules = [ "kvm-intel" ];
kernelParams = [ "console=ttyS0,115200n8" ]; kernelParams = [ "console=ttyS0,115200n8" ];
initrd = { initrd = {
availableKernelModules = [ availableKernelModules = [
"virtio_pci" "ahci" "sr_mod" "virtio_blk" "virtio_pci" "ahci" "sr_mod" "virtio_blk"
"8021q" "ib_core" "ib_uverbs" "mlx5_core" "mlx5_ib" "8021q"
] ++ roceBootModules; "rdma_cm" "iw_cm" "ib_cm" "nvme_core" "nvme_rdma"
kernelModules = [ "dm-snapshot" ]; ];
kernelModules = [ "dm-snapshot" "nvme-fabrics" ];
systemd = { systemd = {
extraBin = with pkgs; {
dmesg = "${util-linux}/bin/dmesg";
ip = "${iproute2}/bin/ip";
};
extraConfig = ''
DefaultTimeoutStartSec=50
DefaultDeviceTimeoutSec=50
'';
network = { network = {
# Don't need to put the link config here, they're copied from main config enable = true;
wait-online.enable = true;
links."10-lan" = lanLink;
netdevs = mkVLAN "lan-hi" vlans.hi; netdevs = mkVLAN "lan-hi" vlans.hi;
networks = { networks = {
"20-lan" = { "20-lan" = {
@@ -47,6 +70,9 @@
hardware = { hardware = {
enableRedistributableFirmware = true; enableRedistributableFirmware = true;
cpu = {
intel.updateMicrocode = true;
};
}; };
fileSystems = { fileSystems = {
@@ -70,7 +96,6 @@
boot.thin.enable = true; boot.thin.enable = true;
dmeventd.enable = true; dmeventd.enable = true;
}; };
fstrim.enable = true;
}; };
systemd.network = { systemd.network = {
@@ -89,16 +114,7 @@
}; };
}; };
"10-lan" = { "10-lan" = lanLink;
matchConfig = {
Driver = "mlx5_core";
PermanentMACAddress = "52:54:00:8a:8a:f2";
};
linkConfig = {
Name = "lan";
MTUBytes = toString lib.my.c.home.hiMTU;
};
};
}; };
# So we don't drop the IP we use to connect to NVMe-oF! # So we don't drop the IP we use to connect to NVMe-oF!
@@ -118,14 +134,6 @@
}; };
}; };
netboot.server = {
enable = true;
ip = assignments.lo.ipv4.address;
host = "boot.${domain}";
allowedPrefixes = with prefixes; [ hi.v4 hi.v6 lo.v4 lo.v6 ];
instances = [ "sfh" "castle" ];
};
deploy.node.hostname = "192.168.68.1"; deploy.node.hostname = "192.168.68.1";
}; };
}; };

View File

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

View File

@@ -1,65 +0,0 @@
{ lib, ... }:
let
inherit (lib.my) net;
inherit (lib.my.c.home) domain prefixes vips hiMTU;
in
{
nixos.systems.unifi = { config, ... }: {
system = "x86_64-linux";
nixpkgs = "mine";
rendered = config.configuration.config.my.asContainer;
assignments = {
hi = {
name = "unifi-ctr";
inherit domain;
mtu = hiMTU;
ipv4 = {
address = net.cidr.host 100 prefixes.hi.v4;
mask = 22;
gateway = vips.hi.v4;
};
ipv6 = {
iid = "::5:1";
address = net.cidr.host (65536*5+1) prefixes.hi.v6;
};
};
};
configuration = { lib, config, pkgs, assignments, ... }:
let
inherit (lib) mkMerge mkIf mkForce;
inherit (lib.my) networkdAssignment;
in
{
config = {
my = {
deploy.enable = false;
server.enable = true;
secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKdgcziQki/RH7E+NH2bYnzSVKaJ27905Yo5TcOjSh/U";
files = { };
};
firewall = {
tcp.allowed = [ 8443 ];
};
};
systemd = {
network.networks."80-container-host0" = networkdAssignment "host0" assignments.hi;
};
services = {
unifi = {
enable = true;
openFirewall = true;
unifiPackage = pkgs.unifi8;
mongodbPackage = pkgs.mongodb-6_0;
};
};
};
};
};
}

View File

@@ -1,157 +0,0 @@
{ lib, ... }:
let
inherit (lib.my) net;
inherit (lib.my.c.home) domain prefixes vips hiMTU roceBootModules;
in
{
imports = [ ./containers ];
config.nixos.systems.sfh = {
system = "x86_64-linux";
nixpkgs = "mine";
home-manager = "mine";
assignments = {
hi = {
inherit domain;
mtu = hiMTU;
ipv4 = {
address = net.cidr.host 81 prefixes.hi.v4;
mask = 22;
gateway = vips.hi.v4;
};
ipv6 = {
iid = "::4:2";
address = net.cidr.host (65536*4+2) prefixes.hi.v6;
};
};
};
configuration = { lib, modulesPath, pkgs, config, assignments, allAssignments, ... }:
let
inherit (lib) mapAttrs mkMerge;
inherit (lib.my) networkdAssignment;
inherit (lib.my.c) networkd;
inherit (lib.my.c.home) domain;
in
{
imports = [
"${modulesPath}/profiles/qemu-guest.nix"
];
config = {
boot = {
kernelModules = [ "kvm-amd" ];
kernelParams = [ "console=ttyS0,115200n8" ];
initrd = {
availableKernelModules = [
"virtio_pci" "ahci" "sr_mod" "virtio_blk"
] ++ roceBootModules;
kernelModules = [ "dm-snapshot" ];
systemd = {
network = {
networks = {
"20-lan-hi" = networkdAssignment "lan-hi" assignments.hi;
};
};
};
};
};
hardware = {
enableRedistributableFirmware = true;
};
fileSystems = {
"/nix" = {
device = "/dev/main/nix";
fsType = "ext4";
};
"/persist" = {
device = "/dev/main/persist";
fsType = "ext4";
neededForBoot = true;
};
};
networking = { inherit domain; };
services = {
lvm = {
boot.thin.enable = true;
dmeventd.enable = true;
};
};
systemd.network = {
links = {
"10-lan-hi" = {
matchConfig = {
Driver = "mlx5_core";
PermanentMACAddress = "52:54:00:ac:15:a9";
};
linkConfig = {
Name = "lan-hi";
MTUBytes = toString lib.my.c.home.hiMTU;
};
};
"10-lan-hi-ctrs" = {
matchConfig = {
Driver = "mlx5_core";
PermanentMACAddress = "52:54:00:90:34:95";
};
linkConfig = {
Name = "lan-hi-ctrs";
MTUBytes = toString lib.my.c.home.hiMTU;
};
};
};
networks = {
"30-lan-hi" = mkMerge [
(networkdAssignment "lan-hi" assignments.hi)
# So we don't drop the IP we use to connect to NVMe-oF!
{ networkConfig.KeepConfiguration = "static"; }
];
"30-lan-hi-ctrs" = {
matchConfig.Name = "lan-hi-ctrs";
linkConfig.RequiredForOnline = "no";
networkConfig = networkd.noL3;
};
};
};
my = {
secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAAaav5Se1E/AbqEXmADryVszYfNDscyP6jrWioN57R7";
};
server.enable = true;
netboot.client = {
enable = true;
};
nvme = {
uuid = "85d7df36-0de0-431b-b06e-51f7c0a455b4";
boot = {
nqn = "nqn.2016-06.io.spdk:sfh";
address = "192.168.68.80";
};
};
containers.instances =
let
instances = {
unifi = {};
};
in
mkMerge [
instances
(mapAttrs (n: i: {
networking.macVLAN = "lan-hi-ctrs";
}) instances)
];
};
};
};
};
}

View File

@@ -227,7 +227,7 @@ in
networkConfig = networkd.noL3; networkConfig = networkd.noL3;
extraConfig = '' extraConfig = ''
[CAKE] [CAKE]
Bandwidth=490M Bandwidth=235M
RTTSec=50ms RTTSec=50ms
PriorityQueueingPreset=besteffort PriorityQueueingPreset=besteffort
# DOCSIS preset # DOCSIS preset
@@ -251,7 +251,7 @@ in
extraConfig = '' extraConfig = ''
[CAKE] [CAKE]
Parent=root Parent=root
Bandwidth=48M Bandwidth=24M
RTTSec=50ms RTTSec=50ms
''; '';
} }
@@ -276,7 +276,7 @@ in
{ {
matchConfig.Name = "as211024"; matchConfig.Name = "as211024";
networkConfig.IPv6AcceptRA = mkForce false; networkConfig.IPv6AcceptRA = mkForce false;
routes = [ routes = map (r: { routeConfig = r; }) [
{ {
Destination = lib.my.c.colony.prefixes.all.v4; Destination = lib.my.c.colony.prefixes.all.v4;
Gateway = allAssignments.estuary.as211024.ipv4.address; Gateway = allAssignments.estuary.as211024.ipv4.address;
@@ -301,7 +301,7 @@ in
{ {
"60-lan-hi" = { "60-lan-hi" = {
routes = [ routes = map (r: { routeConfig = r; }) [
{ {
Destination = elemAt routersPubV4 otherIndex; Destination = elemAt routersPubV4 otherIndex;
Gateway = net.cidr.host (otherIndex + 1) prefixes.hi.v4; Gateway = net.cidr.host (otherIndex + 1) prefixes.hi.v4;
@@ -401,6 +401,11 @@ in
} }
''; '';
}; };
netboot.server = {
enable = true;
ip = vips.lo.v4;
host = "boot.${domain}";
};
}; };
}; };
}; };

View File

@@ -170,9 +170,9 @@ in
hostname = "${otherName}.${config.networking.domain}"; hostname = "${otherName}.${config.networking.domain}";
server = net.cidr.host (otherIndex + 1) prefixes.hi.v4; server = net.cidr.host (otherIndex + 1) prefixes.hi.v4;
}} }}
${elemAt routers 0} IN AAAA ${allAssignments."${elemAt routers 0}".as211024.ipv6.address} ${elemAt routers 0} IN AAAA ${net.cidr.host 1 prefixes.hi.v6}
${elemAt routers 1} IN AAAA ${allAssignments."${elemAt routers 1}".as211024.ipv6.address} ${elemAt routers 1} IN AAAA ${net.cidr.host 2 prefixes.hi.v6}
boot IN CNAME river-hi.${config.networking.domain}. boot IN CNAME router-hi.${config.networking.domain}.
@ IN NS ns1 @ IN NS ns1
@ IN NS ns2 @ IN NS ns2
@@ -199,7 +199,7 @@ in
shytzel IN A ${net.cidr.host 12 prefixes.core.v4} shytzel IN A ${net.cidr.host 12 prefixes.core.v4}
wave IN A ${net.cidr.host 12 prefixes.hi.v4} wave IN A ${net.cidr.host 12 prefixes.hi.v4}
; wave IN AAAA ${net.cidr.host (65536+3) prefixes.hi.v6} wave IN AAAA ${net.cidr.host (65536+3) prefixes.hi.v6}
vibe IN A ${net.cidr.host 13 prefixes.hi.v4} vibe IN A ${net.cidr.host 13 prefixes.hi.v4}
vibe IN AAAA ${net.cidr.host (65536+4) prefixes.hi.v6} vibe IN AAAA ${net.cidr.host (65536+4) prefixes.hi.v6}

View File

@@ -1,7 +1,7 @@
index: { lib, pkgs, config, assignments, allAssignments, ... }: index: { lib, pkgs, config, assignments, ... }:
let let
inherit (lib) mkForce; inherit (lib) mkForce;
inherit (lib.my) net netbootKeaClientClasses; inherit (lib.my) net;
inherit (lib.my.c.home) domain prefixes vips hiMTU; inherit (lib.my.c.home) domain prefixes vips hiMTU;
dns-servers = [ dns-servers = [
@@ -63,14 +63,7 @@ in
always-send = true; always-send = true;
} }
]; ];
client-classes = netbootKeaClientClasses { client-classes = config.my.netboot.server.keaClientClasses;
tftpIP = allAssignments.river.lo.ipv4.address;
hostname = "boot.${domain}";
systems = {
sfh = "52:54:00:a5:7e:93";
castle = "c8:7f:54:6e:17:0f";
};
};
subnet4 = [ subnet4 = [
{ {
id = 1; id = 1;

View File

@@ -36,6 +36,10 @@ let
virtualRouterId = routerId; virtualRouterId = routerId;
virtualIps = vrrpIPs family; virtualIps = vrrpIPs family;
trackScripts = [ "${family}Alive" ]; trackScripts = [ "${family}Alive" ];
extraConfig = ''
notify_master "${config.systemd.package}/bin/systemctl start radvd.service" root
notify_backup "${config.systemd.package}/bin/systemctl stop radvd.service" root
'';
}; };
in in
{ {
@@ -62,12 +66,7 @@ in
}; };
vrrpInstances = { vrrpInstances = {
v4 = mkVRRP "v4" 51; v4 = mkVRRP "v4" 51;
v6 = (mkVRRP "v6" 52) // { v6 = mkVRRP "v6" 52;
extraConfig = ''
notify_master "${config.systemd.package}/bin/systemctl start radvd.service" root
notify_backup "${config.systemd.package}/bin/systemctl stop radvd.service" root
'';
};
}; };
# Actually disable this for now, don't want to fault IPv4 just because IPv6 is broken... # Actually disable this for now, don't want to fault IPv4 just because IPv6 is broken...
# extraConfig = '' # extraConfig = ''

View File

@@ -43,38 +43,6 @@
}; };
}; };
services = {
mjpg-streamer = {
enable = true;
inputPlugin = "input_uvc.so";
outputPlugin = "output_http.so -w @www@ -n -p 5050";
};
octoprint = {
enable = true;
host = "::";
extraConfig = {
plugins = {
classicwebcam = {
snapshot = "/webcam/?action=snapshot";
stream = "/webcam/?action=stream";
streamRatio = "4:3";
};
};
serial = {
port = "/dev/ttyACM0";
baudrate = 115200;
};
temperature.profiles = [
{
bed = 60;
extruder = 215;
name = "PLA";
}
];
};
};
};
systemd.network = { systemd.network = {
netdevs = { netdevs = {
"25-lan" = { "25-lan" = {

View File

@@ -26,7 +26,7 @@ in
config = { config = {
# Hardware acceleration for Jellyfin # Hardware acceleration for Jellyfin
hardware.graphics = { hardware.opengl = {
enable = true; enable = true;
extraPackages = with pkgs; [ extraPackages = with pkgs; [
vaapiIntel vaapiIntel
@@ -78,14 +78,6 @@ in
}; };
}; };
nixpkgs.config.permittedInsecurePackages = [
# FIXME: This is needed for Sonarr
"aspnetcore-runtime-wrapped-6.0.36"
"aspnetcore-runtime-6.0.36"
"dotnet-sdk-wrapped-6.0.428"
"dotnet-sdk-6.0.428"
];
services = { services = {
transmission = { transmission = {
enable = true; enable = true;

View File

@@ -73,12 +73,14 @@ in
RouteTable = routeTable; RouteTable = routeTable;
}; };
wireguardPeers = [ wireguardPeers = [
# AirVPN IE
{ {
# AirVPN IE
wireguardPeerConfig = {
Endpoint = "146.70.94.2:1637"; Endpoint = "146.70.94.2:1637";
PublicKey = "PyLCXAQT8KkM4T+dUsOQfn+Ub3pGxfGlxkIApuig+hk="; PublicKey = "PyLCXAQT8KkM4T+dUsOQfn+Ub3pGxfGlxkIApuig+hk=";
PresharedKeyFile = config.age.secrets."${pskFile}".path; PresharedKeyFile = config.age.secrets."${pskFile}".path;
AllowedIPs = [ "0.0.0.0/0" "::/0" ]; AllowedIPs = [ "0.0.0.0/0" "::/0" ];
};
} }
]; ];
}; };
@@ -95,7 +97,7 @@ in
matchConfig.Name = "vpn"; matchConfig.Name = "vpn";
address = [ "10.161.170.28/32" "fd7d:76ee:e68f:a993:b12d:6d15:c80a:9516/128" ]; address = [ "10.161.170.28/32" "fd7d:76ee:e68f:a993:b12d:6d15:c80a:9516/128" ];
dns = [ "10.128.0.1" "fd7d:76ee:e68f:a993::1" ]; dns = [ "10.128.0.1" "fd7d:76ee:e68f:a993::1" ];
routingPolicyRules = [ routingPolicyRules = map (r: { routingPolicyRuleConfig = r; }) [
{ {
Family = "both"; Family = "both";
SuppressPrefixLength = 0; SuppressPrefixLength = 0;

View File

@@ -121,7 +121,8 @@ in
samba = { samba = {
enable = true; enable = true;
settings = { enableNmbd = true;
shares = {
storage = { storage = {
path = "/mnt/storage"; path = "/mnt/storage";
browseable = "yes"; browseable = "yes";
@@ -130,8 +131,6 @@ in
"directory mask" = "0775"; "directory mask" = "0775";
}; };
}; };
nmbd.enable = true;
}; };
samba-wsdd.enable = true; samba-wsdd.enable = true;
@@ -181,10 +180,12 @@ in
}; };
wireguardPeers = [ wireguardPeers = [
{ {
wireguardPeerConfig = {
PublicKey = "bP1XUNxp9i8NLOXhgPaIaRzRwi5APbam44/xjvYcyjU="; PublicKey = "bP1XUNxp9i8NLOXhgPaIaRzRwi5APbam44/xjvYcyjU=";
Endpoint = "${allAssignments.estuary.internal.ipv4.address}:${toString lib.my.c.kelder.vpn.port}"; Endpoint = "${allAssignments.estuary.internal.ipv4.address}:${toString lib.my.c.kelder.vpn.port}";
AllowedIPs = [ "0.0.0.0/0" ]; AllowedIPs = [ "0.0.0.0/0" ];
PersistentKeepalive = 25; PersistentKeepalive = 25;
};
} }
]; ];
}; };
@@ -212,7 +213,7 @@ in
address = with assignments.estuary; [ address = with assignments.estuary; [
(with ipv4; "${address}/${toString mask}") (with ipv4; "${address}/${toString mask}")
]; ];
routingPolicyRules = [ routingPolicyRules = map (r: { routingPolicyRuleConfig = r; }) [
{ {
Family = "both"; Family = "both";
SuppressPrefixLength = 0; SuppressPrefixLength = 0;

View File

@@ -14,7 +14,7 @@
cpu = { cpu = {
intel.updateMicrocode = true; intel.updateMicrocode = true;
}; };
graphics.extraPackages = with pkgs; [ opengl.extraPackages = with pkgs; [
intel-media-driver intel-media-driver
]; ];
bluetooth.enable = true; bluetooth.enable = true;
@@ -177,7 +177,7 @@
programs = { programs = {
fish = { fish = {
shellAbbrs = { shellAbbrs = {
tsup = "doas tailscale up --login-server=https://hs.nul.ie --accept-routes"; tsup = "doas tailscale up --login-server=https://ts.nul.ie --accept-routes";
}; };
}; };
}; };

View File

@@ -35,7 +35,7 @@ let
system = null; system = null;
# Put the inputs in specialArgs to avoid infinite recursion when modules try to do imports # Put the inputs in specialArgs to avoid infinite recursion when modules try to do imports
specialArgs = { inherit self inputs pkgsFlakes pkgsFlake allAssignments; inherit (cfg) systems; }; specialArgs = { inherit inputs pkgsFlakes pkgsFlake allAssignments; inherit (cfg) systems; };
# `baseModules` informs the manual which modules to document # `baseModules` informs the manual which modules to document
baseModules = baseModules =

View File

@@ -61,8 +61,8 @@
}; };
networking = { networking = {
# Will be set dynamically, but need something to satisfy `/etc/os-release` stuff # Will be set dynamically
hostName = "installer"; hostName = "";
useNetworkd = false; useNetworkd = false;
}; };
@@ -82,8 +82,6 @@
${pkgs.gawk}/bin/awk '{ print $1 }')" ${pkgs.gawk}/bin/awk '{ print $1 }')"
''; '';
boot.supportedFilesystems.nfs = true;
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
dhcpcd dhcpcd
lm_sensors lm_sensors

View File

@@ -52,9 +52,9 @@ let
({ pkgs, config, ... }: { ({ pkgs, config, ... }: {
boot = { boot = {
loader.grub.enable = false; loader.grub.enable = false;
kernelParams = [ "console=ttyS0,115200n8" ];
initrd = { initrd = {
kernelModules = [ "nbd" ]; kernelModules = [ "nbd" ];
availableKernelModules = [ "igb" "igc" ];
systemd = { systemd = {
storePaths = with pkgs; [ storePaths = with pkgs; [
@@ -68,8 +68,8 @@ let
nbd-client = "${nbd}/bin/nbd-client"; nbd-client = "${nbd}/bin/nbd-client";
}; };
extraConfig = '' extraConfig = ''
DefaultTimeoutStartSec=20 DefaultTimeoutStartSec=10
DefaultDeviceTimeoutSec=20 DefaultDeviceTimeoutSec=10
''; '';
network = { network = {
@@ -178,8 +178,18 @@ let
} }
]; ];
netbootArchive = pkgs.runCommand "netboot-${config.system.name}.tar.zst" { } '' netbootArchive = pkgs.runCommand "netboot-${config.system.name}.tar.zst" { } ''
export PATH=${pkgs.zstd}/bin:$PATH add() {
${pkgs.gnutar}/bin/tar --dereference --zstd -cvC ${config.system.build.netbootTree} -f "$out" . ${pkgs.gnutar}/bin/tar --dereference --zstd -rvC "$1" -f "$out" "$2"
}
add "${config.system.build.kernel}" "${config.system.boot.loader.kernelFile}"
add "${config.system.build.initialRamdisk}" initrd
tmpdir="$(mktemp -d rootImage.XXXXXX)"
ln -s "${config.system.build.rootImage}" "$tmpdir"/rootfs.ext4
add "$tmpdir" rootfs.ext4
add "${config.system.build.netbootScript}" boot.ipxe
''; '';
}; };
}) })

View File

@@ -1,4 +1,4 @@
{ lib, pkgsFlake, pkgs, pkgs', self, inputs, config, ... }: { lib, pkgsFlake, pkgs, pkgs', inputs, config, ... }:
let let
inherit (lib) mkIf mkDefault mkMerge; inherit (lib) mkIf mkDefault mkMerge;
inherit (lib.my) mkDefault'; inherit (lib.my) mkDefault';
@@ -12,6 +12,7 @@ in
inputs.impermanence.nixosModule inputs.impermanence.nixosModule
inputs.ragenix.nixosModules.age inputs.ragenix.nixosModules.age
inputs.sharry.nixosModules.default inputs.sharry.nixosModules.default
inputs.attic.nixosModules.atticd
]; ];
config = mkMerge [ config = mkMerge [
@@ -40,7 +41,6 @@ in
nix = { nix = {
package = pkgs'.mine.nix; package = pkgs'.mine.nix;
channel.enable = false;
settings = with lib.my.c.nix; { settings = with lib.my.c.nix; {
trusted-users = [ "@wheel" ]; trusted-users = [ "@wheel" ];
experimental-features = [ "nix-command" "flakes" "ca-derivations" ]; experimental-features = [ "nix-command" "flakes" "ca-derivations" ];
@@ -127,9 +127,6 @@ in
}; };
}; };
environment.etc = {
"nixos/flake.nix".source = "/run/nixfiles/flake.nix";
};
environment.systemPackages = with pkgs; mkMerge [ environment.systemPackages = with pkgs; mkMerge [
[ [
bash-completion bash-completion
@@ -145,10 +142,7 @@ in
fish.enable = mkDefault true; fish.enable = mkDefault true;
# TODO: This is expecting to look up the channel for the database... # TODO: This is expecting to look up the channel for the database...
command-not-found.enable = mkDefault false; command-not-found.enable = mkDefault false;
vim = { vim.defaultEditor = true;
enable = true;
defaultEditor = true;
};
}; };
services = { services = {
@@ -215,35 +209,14 @@ in
# python.d plugin script does #!/usr/bin/env bash # python.d plugin script does #!/usr/bin/env bash
path = with pkgs; [ bash ]; path = with pkgs; [ bash ];
}; };
nixfiles-mutable = {
description = "Mutable nixfiles";
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = with pkgs; [ util-linux ];
script = ''
nixfilesDir="${self}"
mkdir -p /run/nixfiles{,/.rw,/.work}
mount -t overlay overlay -o lowerdir="$nixfilesDir",upperdir=/run/nixfiles/.rw,workdir=/run/nixfiles/.work /run/nixfiles
chmod -R u+w /run/nixfiles
'';
preStop = ''
umount /run/nixfiles
rm -rf /run/nixfiles
'';
wantedBy = [ "multi-user.target" ];
};
}; };
}; };
} }
(mkIf config.services.kmscon.enable { (mkIf config.services.kmscon.enable {
fonts.fonts = with pkgs; [ fonts.fonts = with pkgs; [
nerd-fonts.sauce-code-pro (nerdfonts.override {
fonts = [ "SourceCodePro" ];
})
]; ];
}) })
]; ];

View File

@@ -1,6 +1,6 @@
{ lib, pkgs, options, config, systems, ... }: { lib, pkgs, options, config, systems, ... }:
let let
inherit (builtins) attrNames attrValues all hashString toJSON any; inherit (builtins) attrNames attrValues all hashString toJSON;
inherit (lib) inherit (lib)
groupBy' mapAttrsToList optionalString optional concatMapStringsSep filterAttrs mkOption mkDefault mkIf mkMerge; groupBy' mapAttrsToList optionalString optional concatMapStringsSep filterAttrs mkOption mkDefault mkIf mkMerge;
inherit (lib.my) mkOpt' mkBoolOpt'; inherit (lib.my) mkOpt' mkBoolOpt';
@@ -98,7 +98,6 @@ let
}; };
networking = { networking = {
bridge = mkOpt' (nullOr str) null "Network bridge to connect to."; bridge = mkOpt' (nullOr str) null "Network bridge to connect to.";
macVLAN = mkOpt' (nullOr str) null "Network interface to make MACVLAN interface from.";
}; };
}; };
}; };
@@ -116,17 +115,13 @@ in
assertion = config.systemd.network.enable; assertion = config.systemd.network.enable;
message = "Containers currently require systemd-networkd!"; message = "Containers currently require systemd-networkd!";
} }
{
assertion = all (i: i.networking.bridge == null || i.networking.macVLAN == null) (attrValues cfg.instances);
message = "Only bridge OR MACVLAN can be set";
}
]; ];
# TODO: Better security # TODO: Better security
my.firewall.trustedInterfaces = my.firewall.trustedInterfaces =
mapAttrsToList mapAttrsToList
(n: _: "ve-${n}") (n: _: "ve-${n}")
(filterAttrs (_: c: c.networking.bridge == null && c.networking.macVLAN == null) cfg.instances); (filterAttrs (_: c: c.networking.bridge == null) cfg.instances);
systemd = mkMerge (mapAttrsToList (n: c: { systemd = mkMerge (mapAttrsToList (n: c: {
nspawn."${n}" = { nspawn."${n}" = {
@@ -159,8 +154,6 @@ in
}; };
networkConfig = if (c.networking.bridge != null) then { networkConfig = if (c.networking.bridge != null) then {
Bridge = c.networking.bridge; Bridge = c.networking.bridge;
} else if (c.networking.macVLAN != null) then {
MACVLAN = "${c.networking.macVLAN}:host0";
} else { } else {
VirtualEthernet = true; VirtualEthernet = true;
}; };

View File

@@ -12,7 +12,7 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
hardware = { hardware = {
graphics.enable = mkDefault true; opengl.enable = mkDefault true;
}; };
systemd = { systemd = {
@@ -53,8 +53,6 @@ in
SUBSYSTEM=="usb", ATTR{idVendor}=="057e", MODE="0664", GROUP="wheel" SUBSYSTEM=="usb", ATTR{idVendor}=="057e", MODE="0664", GROUP="wheel"
# FT # FT
SUBSYSTEM=="usb", ATTR{idVendor}=="0403", MODE="0664", GROUP="wheel" SUBSYSTEM=="usb", ATTR{idVendor}=="0403", MODE="0664", GROUP="wheel"
# /dev/player0
SUBSYSTEM=="usb", ATTR{idVendor}=="6969", MODE="0664", GROUP="wheel"
''; '';
}; };
}; };

View File

@@ -44,8 +44,10 @@ let
toString (mesh.baseMTU - overhead); toString (mesh.baseMTU - overhead);
bridgeFDBs = mapAttrsToList (n: peer: { bridgeFDBs = mapAttrsToList (n: peer: {
bridgeFDBConfig = {
MACAddress = "00:00:00:00:00:00"; MACAddress = "00:00:00:00:00:00";
Destination = peer.addr; Destination = peer.addr;
};
}) otherPeers; }) otherPeers;
}; };
}; };

View File

@@ -1,23 +1,14 @@
{ lib, pkgs, config, ... }: { lib, pkgs, config, systems, ... }:
let let
inherit (lib) mkMerge mkIf mkForce genAttrs concatMapStringsSep; inherit (lib) mkMerge mkIf mkForce mkOption;
inherit (lib.my) mkOpt' mkBoolOpt'; inherit (lib.my) mkOpt' mkBoolOpt';
cfg = config.my.netboot; cfg = config.my.netboot;
ipxe = pkgs.ipxe.overrideAttrs (o: rec {
version = "1.21.1-unstable-2024-06-27";
src = pkgs.fetchFromGitHub {
owner = "ipxe";
repo = "ipxe";
rev = "b66e27d9b29a172a097c737ab4d378d60fe01b05";
hash = "sha256-TKZ4WjNV2oZIYNefch7E7m1JpeoC/d7O1kofoNv8G40=";
};
});
tftpRoot = pkgs.linkFarm "tftp-root" [ tftpRoot = pkgs.linkFarm "tftp-root" [
{ {
name = "ipxe-x86_64.efi"; name = "ipxe-x86_64.efi";
path = "${ipxe}/ipxe.efi"; path = "${pkgs.ipxe}/ipxe.efi";
} }
]; ];
menuFile = pkgs.runCommand "menu.ipxe" { menuFile = pkgs.runCommand "menu.ipxe" {
@@ -25,89 +16,31 @@ let
} '' } ''
substituteAll ${./menu.ipxe} "$out" substituteAll ${./menu.ipxe} "$out"
''; '';
bootBuilder = pkgs.substituteAll {
src = ./netboot-loader-builder.py;
isExecutable = true;
inherit (pkgs) python3;
bootspecTools = pkgs.bootspec;
nix = config.nix.package.out;
inherit (config.system.nixos) distroName;
systemName = config.system.name;
inherit (cfg.client) configurationLimit;
checkMountpoints = pkgs.writeShellScript "check-mountpoints" ''
if ! ${pkgs.util-linuxMinimal}/bin/findmnt /boot > /dev/null; then
echo "/boot is not a mounted partition. Is the path configured correctly?" >&2
exit 1
fi
'';
};
in in
{ {
options.my.netboot = with lib.types; { options.my.netboot = with lib.types; {
client = { client = {
enable = mkBoolOpt' false "Whether network booting should be enabled."; enable = mkBoolOpt' false "Whether network booting should be enabled.";
configurationLimit = mkOpt' ints.unsigned 10 "Max generations to show in boot menu.";
}; };
server = { server = {
enable = mkBoolOpt' false "Whether a netboot server should be enabled."; enable = mkBoolOpt' false "Whether a netboot server should be enabled.";
ip = mkOpt' str null "IP clients should connect to via TFTP."; ip = mkOpt' str null "IP clients should connect to via TFTP.";
host = mkOpt' str config.networking.fqdn "Hostname clients should connect to over HTTP / NFS."; host = mkOpt' str config.networking.fqdn "Hostname clients should connect to over HTTP.";
allowedPrefixes = mkOpt' (listOf str) null "Prefixes clients should be allowed to connect from (NFS).";
installer = { installer = {
storeSize = mkOpt' str "16GiB" "Total allowed writable size of store."; storeSize = mkOpt' str "16GiB" "Total allowed writable size of store.";
}; };
instances = mkOpt' (listOf str) [ ] "Systems to hold boot files for."; instances = mkOpt' (listOf str) [ ] "Systems to hold boot files for.";
keaClientClasses = mkOption {
type = listOf (attrsOf str);
description = "Kea client classes for PXE boot.";
readOnly = true;
};
}; };
}; };
config = mkMerge [ config = mkMerge [
(mkIf cfg.client.enable { (mkIf cfg.client.enable {
systemd = { # TODO: Implement!
services = {
mount-boot = {
description = "Mount /boot";
after = [ "systemd-networkd-wait-online.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = with pkgs; [ gnused ldns nfs-utils ];
script = ''
get_cmdline() {
sed -rn "s/^.*$1=(\\S+).*\$/\\1/p" < /proc/cmdline
}
host="$(get_cmdline boothost)"
if [ -z "$host" ]; then
echo "boothost kernel parameter not found!" >&2
exit 1
fi
until [ -n "$(drill -Q $host)" ]; do
sleep 0.1
done
mkdir -p /boot
mount.nfs $host:/srv/netboot/systems/${config.system.name} /boot
'';
wantedBy = [ "remote-fs.target" ];
};
};
};
boot.supportedFilesystems.nfs = true;
boot.loader = {
grub.enable = false;
systemd-boot.enable = false;
};
system = {
build.installBootLoader = bootBuilder;
boot.loader.id = "ipxe-netboot";
};
}) })
(mkIf cfg.server.enable { (mkIf cfg.server.enable {
environment = { environment = {
@@ -118,23 +51,16 @@ in
}; };
systemd = { systemd = {
tmpfiles.settings."10-netboot" = genAttrs
(map (i: "/srv/netboot/systems/${i}") cfg.server.instances)
(p: {
d = {
user = "root";
group = "root";
mode = "0777";
};
});
services = { services = {
netboot-update = { netboot-update = {
description = "Update netboot images"; description = "Update netboot images";
after = [ "systemd-networkd-wait-online.service" ]; after = [ "systemd-networkd-wait-online.service" ];
serviceConfig.Type = "oneshot"; serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = with pkgs; [ path = with pkgs; [
coreutils curl jq zstd gnutar coreutils curl jq gnutar
]; ];
script = '' script = ''
update_nixos() { update_nixos() {
@@ -161,7 +87,7 @@ in
cd /srv/netboot cd /srv/netboot
ln -sf ${menuFile} boot.ipxe ln -sf ${menuFile} boot.ipxe
ln -sf "${pkgs.edk2-uefi-shell}/shell.efi" "efi-shell-${config.nixpkgs.localSystem.linuxArch}.efi" ln -sf "${pkgs.edk2-uefi-shell}/efi-shell-${config.nixpkgs.localSystem.linuxArch}.efi"
update_nixos update_nixos
''; '';
startAt = "06:00"; startAt = "06:00";
@@ -210,15 +136,6 @@ in
}; };
}; };
}; };
nfs = {
server = {
enable = true;
exports = ''
/srv/netboot/systems ${concatMapStringsSep " " (p: "${p}(rw,all_squash)") cfg.server.allowedPrefixes}
'';
};
};
}; };
my = { my = {
@@ -226,6 +143,22 @@ in
"/srv/netboot" "/srv/netboot"
{ directory = "/var/cache/netboot"; mode = "0700"; } { directory = "/var/cache/netboot"; mode = "0700"; }
]; ];
netboot.server.keaClientClasses = [
{
name = "ipxe";
test = "substring(option[user-class].hex, 0, 4) == 'iPXE'";
next-server = cfg.server.ip;
server-hostname = cfg.server.host;
boot-file-name = "http://${cfg.server.host}/boot.ipxe";
}
{
name = "efi-x86_64";
test = "option[client-system].hex == 0x0007";
next-server = cfg.server.ip;
server-hostname = cfg.server.host;
boot-file-name = "ipxe-x86_64.efi";
}
];
}; };
}) })
]; ];

View File

@@ -1,280 +0,0 @@
#! @python3@/bin/python3 -B
# Based on `nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py`
import argparse
import datetime
import glob
import os
import os.path
import shutil
import subprocess
import sys
import json
from typing import NamedTuple, Dict, List
from dataclasses import dataclass
BOOT_MOUNT_POINT = '/boot'
STORE_DIR = 'nix'
# These values will be replaced with actual values during the package build
BOOTSPEC_TOOLS = '@bootspecTools@'
NIX = '@nix@'
DISTRO_NAME = '@distroName@'
SYSTEM_NAME = '@systemName@'
CONFIGURATION_LIMIT = int('@configurationLimit@')
CHECK_MOUNTPOINTS = "@checkMountpoints@"
@dataclass
class BootSpec:
init: str
initrd: str
kernel: str
kernelParams: List[str]
label: str
system: str
toplevel: str
specialisations: Dict[str, 'BootSpec']
sortKey: str
initrdSecrets: str | None = None
class SystemIdentifier(NamedTuple):
profile: str | None
generation: int
specialisation: str | None
def copy_if_not_exists(source: str, dest: str) -> None:
if not os.path.exists(dest):
shutil.copyfile(source, dest)
def generation_dir(profile: str | None, generation: int) -> str:
if profile:
return f'/nix/var/nix/profiles/system-profiles/{profile}-{generation}-link'
else:
return f'/nix/var/nix/profiles/system-{generation}-link'
def system_dir(i: SystemIdentifier) -> str:
d = generation_dir(i.profile, i.generation)
if i.specialisation:
return os.path.join(d, 'specialisation', i.specialisation)
else:
return d
def entry_key(i: SystemIdentifier) -> str:
pieces = [
'nixos',
i.profile or None,
'generation',
str(i.generation),
f'specialisation-{i.specialisation}' if i.specialisation else None,
]
return '-'.join(p for p in pieces if p)
def bootspec_from_json(bootspec_json: Dict) -> BootSpec:
specialisations = bootspec_json['org.nixos.specialisation.v1']
specialisations = {k: bootspec_from_json(v) for k, v in specialisations.items()}
systemdBootExtension = bootspec_json.get('org.nixos.systemd-boot', {})
sortKey = systemdBootExtension.get('sortKey', 'nixos')
return BootSpec(
**bootspec_json['org.nixos.bootspec.v1'],
specialisations=specialisations,
sortKey=sortKey
)
bootspecs = {}
def get_bootspec(profile: str | None, generation: int) -> BootSpec:
k = (profile, generation)
if k in bootspecs:
return bootspecs[k]
system_directory = system_dir(SystemIdentifier(profile, generation, None))
boot_json_path = os.path.realpath(f'{system_directory}/boot.json')
if os.path.isfile(boot_json_path):
boot_json_f = open(boot_json_path, 'r')
bootspec_json = json.load(boot_json_f)
else:
boot_json_str = subprocess.check_output([
f'{BOOTSPEC_TOOLS}/bin/synthesize',
'--version',
'1',
system_directory,
'/dev/stdout',
],
universal_newlines=True)
bootspec_json = json.loads(boot_json_str)
bs = bootspec_from_json(bootspec_json)
bootspecs[k] = bs
return bs
def copy_from_file(file: str, dry_run: bool = False) -> str:
store_file_path = os.path.realpath(file)
suffix = os.path.basename(store_file_path)
store_dir = os.path.basename(os.path.dirname(store_file_path))
dst_path = f'/{STORE_DIR}/{store_dir}-{suffix}'
if not dry_run:
copy_if_not_exists(store_file_path, f'{BOOT_MOUNT_POINT}{dst_path}')
return dst_path
MENU_ITEM = 'item {gen_key} {title} Generation {generation} {description}'
BOOT_ENTRY = ''':{gen_key}
kernel ${{server}}/systems/{system_name}{kernel} {kernel_params} boothost=${{boothost}}
initrd ${{server}}/systems/{system_name}{initrd}
boot
'''
def gen_entry(i: SystemIdentifier) -> (str, str):
bootspec = get_bootspec(i.profile, i.generation)
if i.specialisation:
bootspec = bootspec.specialisations[i.specialisation]
kernel = copy_from_file(bootspec.kernel)
initrd = copy_from_file(bootspec.initrd)
gen_key = entry_key(i)
title = '{name}{profile}{specialisation}'.format(
name=DISTRO_NAME,
profile=' [' + i.profile + ']' if i.profile else '',
specialisation=f' ({i.specialisation})' if i.specialisation else '')
kernel_params = f'init={bootspec.init} '
kernel_params = kernel_params + ' '.join(bootspec.kernelParams)
build_time = int(os.path.getctime(system_dir(i)))
build_date = datetime.datetime.fromtimestamp(build_time).strftime('%F')
return MENU_ITEM.format(
gen_key=gen_key,
title=title,
description=f'{bootspec.label}, built on {build_date}',
generation=i.generation,
), BOOT_ENTRY.format(
gen_key=gen_key,
generation=i.generation,
system_name=SYSTEM_NAME,
kernel=kernel,
kernel_params=kernel_params,
initrd=initrd,
)
def get_generations(profile: str | None = None) -> list[SystemIdentifier]:
gen_list = subprocess.check_output([
f'{NIX}/bin/nix-env',
'--list-generations',
'-p',
'/nix/var/nix/profiles/' + ('system-profiles/' + profile if profile else 'system')],
universal_newlines=True)
gen_lines = gen_list.split('\n')
gen_lines.pop()
configurationLimit = CONFIGURATION_LIMIT
configurations = [
SystemIdentifier(
profile=profile,
generation=int(line.split()[0]),
specialisation=None
)
for line in gen_lines
]
return configurations[-configurationLimit:]
def remove_old_files(gens: list[SystemIdentifier]) -> None:
known_paths = []
for gen in gens:
bootspec = get_bootspec(gen.profile, gen.generation)
known_paths.append(copy_from_file(bootspec.kernel, True))
known_paths.append(copy_from_file(bootspec.initrd, True))
for path in glob.iglob(f'{BOOT_MOUNT_POINT}/{STORE_DIR}/*'):
if not path in known_paths and not os.path.isdir(path):
os.unlink(path)
def get_profiles() -> list[str]:
if os.path.isdir('/nix/var/nix/profiles/system-profiles/'):
return [x
for x in os.listdir('/nix/var/nix/profiles/system-profiles/')
if not x.endswith('-link')]
else:
return []
MENU = '''#!ipxe
# Server hostname option
set boothost ${{66:string}}
set server http://${{boothost}}
:start
menu {distro} boot menu
item --gap -- Generations
{generation_items}
item --gap -- Other
item --key m main Main netboot menu
choose --timeout 5000 --default {menu_default} selected || goto cancel
goto ${{selected}}
:cancel
shell
goto start
:error
echo Booting failed, dropping to shell
shell
goto start
:main
chain ${{server}}/boot.ipxe || goto error
'''
def write_menu(gens: list[SystemIdentifier], default: SystemIdentifier) -> None:
gen_menu_items = []
gen_cmds = []
for g in gens:
bootspec = get_bootspec(g.profile, g.generation)
specialisations = [
SystemIdentifier(profile=g.profile, generation=g.generation, specialisation=s) for s in bootspec.specialisations]
for i in [g] + specialisations:
mi, cmds = gen_entry(i)
gen_menu_items.append(mi)
gen_cmds.append(cmds)
menu_file = f'{BOOT_MOUNT_POINT}/menu.ipxe'
with open(f'{menu_file}.tmp', 'w') as f:
f.write(MENU.format(
distro=DISTRO_NAME,
generation_items='\n'.join(gen_menu_items),
menu_default=entry_key(default),
))
print(file=f)
print('\n\n'.join(gen_cmds), file=f)
os.rename(f'{menu_file}.tmp', menu_file)
def install_bootloader(args: argparse.Namespace) -> None:
os.makedirs(f'{BOOT_MOUNT_POINT}/{STORE_DIR}', exist_ok=True)
gens = get_generations()
for profile in get_profiles():
gens += get_generations(profile)
gens = sorted(gens, key=lambda g: entry_key(g), reverse=True)
remove_old_files(gens)
for g in gens:
if os.path.dirname(get_bootspec(g.profile, g.generation).init) == os.path.realpath(args.default_config):
default = g
break
else:
assert False, 'No default generation found'
write_menu(gens, default)
def main() -> None:
parser = argparse.ArgumentParser(description=f'Update {DISTRO_NAME}-related netboot files')
parser.add_argument('default_config', metavar='DEFAULT-CONFIG', help=f'The default {DISTRO_NAME} config to boot')
args = parser.parse_args()
subprocess.check_call(CHECK_MOUNTPOINTS)
install_bootloader(args)
if __name__ == '__main__':
main()

View File

@@ -5,15 +5,7 @@ let
cfg = config.my.nvme; cfg = config.my.nvme;
nvme-cli = pkgs.nvme-cli.override { nvme-cli = pkgs.nvme-cli.override {
libnvme = pkgs.libnvme.overrideAttrs (o: rec { libnvme = pkgs.libnvme.overrideAttrs (o: {
# TODO: Remove when 1.11.1 releases (see https://github.com/linux-nvme/libnvme/pull/914)
version = "1.11.1";
src = pkgs.fetchFromGitHub {
owner = "linux-nvme";
repo = "libnvme";
rev = "v${version}";
hash = "sha256-CEGr7PDOVRi210XvICH8iLYDKn8S9bGruBO4tycvsT8=";
};
patches = (if (o ? patches) then o.patches else [ ]) ++ [ ./libnvme-hostconf.patch ]; patches = (if (o ? patches) then o.patches else [ ]) ++ [ ./libnvme-hostconf.patch ];
}); });
}; };
@@ -41,26 +33,9 @@ in
etc = etc ""; etc = etc "";
}; };
boot = mkIf (cfg.boot.nqn != null) { boot.initrd.systemd = mkIf (cfg.boot.nqn != null) {
initrd = {
availableKernelModules = [ "rdma_cm" "iw_cm" "ib_cm" "nvme_core" "nvme_rdma" ];
kernelModules = [ "nvme-fabrics" ];
systemd = {
contents = etc "/etc/"; contents = etc "/etc/";
extraBin = with pkgs; { extraBin.nvme = "${nvme-cli}/bin/nvme";
dmesg = "${util-linux}/bin/dmesg";
ip = "${iproute2}/bin/ip";
nvme = "${nvme-cli}/bin/nvme";
};
extraConfig = ''
DefaultTimeoutStartSec=20
DefaultDeviceTimeoutSec=20
'';
network = {
enable = true;
wait-online.enable = true;
};
services.connect-nvme = { services.connect-nvme = {
description = "Connect NVMe-oF"; description = "Connect NVMe-oF";
@@ -79,7 +54,5 @@ in
}; };
}; };
}; };
};
};
} }

View File

@@ -147,15 +147,6 @@ in
"/var/lib/systemd" "/var/lib/systemd"
{ directory = "/root/.cache/nix"; mode = "0700"; } { directory = "/root/.cache/nix"; mode = "0700"; }
# Including these unconditionally due to infinite recursion problems...
{
directory = "/etc/lvm/archive";
mode = "0700";
}
{
directory = "/etc/lvm/backup";
mode = "0700";
}
]; ];
files = [ files = [
"/etc/machine-id" "/etc/machine-id"
@@ -269,6 +260,18 @@ in
my.tmproot.persistence.config.files = my.tmproot.persistence.config.files =
concatMap (k: [ k.path "${k.path}.pub" ]) config.services.openssh.hostKeys; concatMap (k: [ k.path "${k.path}.pub" ]) config.services.openssh.hostKeys;
}) })
(mkIf config.services.lvm.enable {
my.tmproot.persistence.config.directories = [
{
directory = "/etc/lvm/archive";
mode = "0700";
}
{
directory = "/etc/lvm/backup";
mode = "0700";
}
];
})
(mkIf (config.security.acme.certs != { }) { (mkIf (config.security.acme.certs != { }) {
my.tmproot.persistence.config.directories = [ my.tmproot.persistence.config.directories = [
{ {
@@ -520,37 +523,6 @@ in
group = "mautrix-meta"; group = "mautrix-meta";
}) (filterAttrs (_: i: i.enable) config.services.mautrix-meta.instances); }) (filterAttrs (_: i: i.enable) config.services.mautrix-meta.instances);
} }
(mkIf config.services.unifi.enable {
my.tmproot.persistence.config.directories = [
{
directory = "/var/lib/unifi";
mode = "0750";
user = "unifi";
group = "unifi";
}
{
directory = "/var/cache/unifi";
mode = "0750";
user = "unifi";
group = "unifi";
}
];
})
(persistSimpleSvc "octoprint")
(mkIf (config.services.borgbackup.jobs != { }) {
my.tmproot.persistence.config.directories = [
"/var/lib/borgbackup"
"/var/cache/borgbackup"
];
services.borgbackup.package = pkgs.borgbackup.overrideAttrs (o: {
makeWrapperArgs = o.makeWrapperArgs ++ [
"--set-default BORG_BASE_DIR /var/lib/borgbackup"
"--set-default BORG_CONFIG_DIR /var/lib/borgbackup/config"
"--set-default BORG_CACHE_DIR /var/cache/borgbackup"
];
});
})
])) ]))
]); ]);

View File

@@ -82,10 +82,6 @@ in
# NOTE: As the "outermost" module is still being evaluated in NixOS land, special params (e.g. pkgs) won't be # NOTE: As the "outermost" module is still being evaluated in NixOS land, special params (e.g. pkgs) won't be
# passed to it # passed to it
home-manager.users.${user'.name} = mkAliasDefinitions options.my.user.homeConfig; home-manager.users.${user'.name} = mkAliasDefinitions options.my.user.homeConfig;
systemd.services.nixfiles-mutable.script = ''
chown -R ${user'.name} /run/nixfiles
'';
} }
(mkIf (cfg.passwordSecret != null) { (mkIf (cfg.passwordSecret != null) {
my = { my = {

View File

@@ -7,7 +7,8 @@ in
monocraft' = callPackage ./monocraft.nix { }; monocraft' = callPackage ./monocraft.nix { };
vfio-pci-bind = callPackage ./vfio-pci-bind.nix { }; vfio-pci-bind = callPackage ./vfio-pci-bind.nix { };
librespeed-go = callPackage ./librespeed-go.nix { }; librespeed-go = callPackage ./librespeed-go.nix { };
# modrinth-app = callPackage ./modrinth-app { }; modrinth-app = callPackage ./modrinth-app { };
glfw-minecraft = callPackage ./glfw-minecraft { };
chocolate-doom2xx = callPackage ./chocolate-doom2xx { }; chocolate-doom2xx = callPackage ./chocolate-doom2xx { };
windowtolayer = callPackage ./windowtolayer.nix { }; windowtolayer = callPackage ./windowtolayer.nix { };
swaylock-plugin = callPackage ./swaylock-plugin.nix { }; swaylock-plugin = callPackage ./swaylock-plugin.nix { };

View File

@@ -0,0 +1,6 @@
{ lib, glfw-wayland-minecraft, ... }:
glfw-wayland-minecraft.overrideAttrs (o: {
patches = [
./suppress-wayland-errors.patch
];
})

View File

@@ -0,0 +1,43 @@
diff --git a/src/wl_window.c b/src/wl_window.c
index 7c509896..db9a6451 100644
--- a/src/wl_window.c
+++ b/src/wl_window.c
@@ -2115,25 +2115,21 @@ void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title)
void _glfwSetWindowIconWayland(_GLFWwindow* window,
int count, const GLFWimage* images)
{
- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
- "Wayland: The platform does not support setting the window icon");
+ fprintf(stderr, "!!! Ignoring Error: Wayland: The platform does not support setting the window icon\n");
}
void _glfwGetWindowPosWayland(_GLFWwindow* window, int* xpos, int* ypos)
{
// A Wayland client is not aware of its position, so just warn and leave it
// as (0, 0)
-
- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
- "Wayland: The platform does not provide the window position");
+ fprintf(stderr, "!!! Ignoring Error: Wayland: The platform does not provide the window position\n");
}
void _glfwSetWindowPosWayland(_GLFWwindow* window, int xpos, int ypos)
{
// A Wayland client can not set its position, so just warn
- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
- "Wayland: The platform does not support setting the window position");
+ fprintf(stderr, "!!! Ignoring Error: Wayland: The platform does not support setting the window position\n");
}
void _glfwGetWindowSizeWayland(_GLFWwindow* window, int* width, int* height)
@@ -2359,8 +2355,7 @@ void _glfwRequestWindowAttentionWayland(_GLFWwindow* window)
void _glfwFocusWindowWayland(_GLFWwindow* window)
{
- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
- "Wayland: The platform does not support setting the input focus");
+ fprintf(stderr, "!!! Ignoring Error: Wayland: The platform does not support setting the input focus\n");
}
void _glfwSetWindowMonitorWayland(_GLFWwindow* window,

View File

@@ -1,10 +1,10 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyBrMXND YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyBJYzdr
Zm1ma0FoNE5lWTFNTGlyeUQzdUZxMkxyVlU0cWdrcTJEakhDVXg4ClkyczJDR1FL b1d2aEtVd3lVb3NBamRwVFpTaTRjZFlCczk4MVIwQUoxWklwN0NrCmFFekpPYUlO
eXE3QWFTM0wyeDNvL1gvcmx6eGE4elNuZW9wRHhJZ3Aya2cKLT4gWDI1NTE5IDhO YlgvVlQ2WDR6amZDN0ZSY0Q3WWtTME5pUmhQeks1c3dGOVUKLT4gWDI1NTE5IHVK
S2JWNDhlclpERFFUTktyUG5HbnNxcVQvWmphOGp1cmNpK0NGZWVTejQKN0dybHl5 bUZvUVAvL0NmQzFkY3BuYm1wMjcwbFpLRUNpZjJCaW15SEVDUDV0REkKRXFMQ2d1
eHhicFNpUHQ3WFZDQS90NG5VZW5zVm8rcUxCdkZkOFVqdVFzRQotPiBBLWdyZWFz NlFBejBvTlJrcUtCYWZxSDBkbmxIdExBNTU0aC8zRW5OVWllVQotPiBDLWdyZWFz
ZSBaIDMiRCBYO1g6IF9EawpJZwotLS0geXhWb1FORm00RVJoMm4zQjhBT0hERyt3 ZSBkeC4oTFUgO0FtJG9+RyB2IF1QXGhxVwpJS213MXBRMWY1cXlHZwotLS0gRUF2
ekM1YXNzdTgzUTVMeHNsNDUwbwqSjgIVhg9bqtIydYC1FCA4ly2gurTcb1SUCMG8 ZkswNlhvcDhTc2tybCs1dldwa2l6SDZZVmNkNUNjNGlkV1ZVa09pOAp88dxHGxVU
XA9WAx1jv05xje+U97tRTTongJEW5vw= vuFQO6JcroY9MF5Te/YV+wMc3hVxksibMnH1TWGh207prwcOWNOEz2iEkZY=
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,17 +1,15 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyBjQmZr YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyBLVlg2
VDl4TVlzK0lCc0YwdFM3TEptU3Q3cWZ1d0FJQUI4Q1g1TVNyOENFCkU4NE5lYVhI ZUdtUlFUQXBLT3B5YmkycWJnMXJyKzltbyt6K2dJK1RBUm5ydWwwCmRUdjJFSEYz
d3B0amFJT1A1RTRSaUdUSmZ1WmU1SkVhTU9sdFZJR0p6UXcKLT4gWDI1NTE5IG5O Wnp4cGtzTXZwc0s0SUJQUjRlOUJlQUoyQ3BETXZmY0ppWG8KLT4gWDI1NTE5IGR5
RG1SQnZtSUk0SThNYkRpOHFPS29kbjdUenZyYjBBSTJKdXNUaGpYMG8KME8waXJ0 QUJzeG1DQTRLUmRwNnNSRUJRSFFtUDl5VjB0clVLYUp3R1g4TEVKaTgKb09tVlhF
NWR2NHoyUkN1UUJoaVRxYXVMZlNvTHZqRmYvS2h4QjZpZm5NZwotPiBPclJULlkt R0tmcmIxMHVHcG80RGxRTEhBcngvT3MrdnNPbmpCTlRyZW5xQQotPiA6RzEtZ3Jl
Z3JlYXNlIEVdKEBXIDUgXTBzIi58TwpweFJEcUFpR0x2WWhiVDlOTFArenhjNXBB YXNlCldSUlN2ejB0MGpyUHYzNS9OQmJTK3MvcXRDakdBVlhuUEt6SFE4QmhnWVN0
dVo2d1JQWEJyVHlTRnUzdUlFUE45RWlLU3ZRS0c4UWs5Nm1qVHorCko1RVdqOVdz V1JMOE1oaEp5QQotLS0gYW1OMTcxNWJrUndmR2h0ZmRDWk5CYnJjc29pSERUMnNk
aVAwY09KOUx4WktIVFBQclFXdFJZMTNVWHNKcTZFbDU5Q0xLaExvNVdlZ0pTczUr d2VhTGdpOW4yUQrEeH2E9m0YycuW60QrdlRetO1kNU5FaKXRQt46iA9lACIWD4rC
SkVDTzhDUysKCi0tLSA2VGJMM2lrNkViaU0wcnArSG9PemJrQ3lrUFNnRDRVeE1p Cx6WxhCBgz3hvm9x6iuYiiQxZzgJNK7qXcV2MBeQdivazeEbC7blAKVPhwD/dl+b
V3lxeG1iN3I4Ckf36lD/b7agsT0qW8eGDnxsVor8hEmLBSa35/eeAxqMd0xPvQko PzBDXRXG3c3jMjeZFT69fIBGJfZrrLGKpTALVE4dTVXmQmVVQDTp19IC+jUXHBti
REzIxPuEHRQM5dE4s4H/mySTC/AVsiwfcMrnOXInm4o3MNAC9PREcef4NBOP3IMl Pj6Dpc7452s8zPkzZyRbasO9b4PYTwq8IHT6X7ITwbzZZm8gexDYe2SzRZ5VcPz3
Mcoifar27EXs21XdXw/lLOVNDX7oDKZh1zXVX4lFTcRW0v8abbwchvuTiayKePMG El+yoULZ92WbXPSQIP/Slx4BEZjmsQS+sm0N8AnBRNZkWVbHPF9IZRg3VjDAn2i8
DrcyFsj4jiwpJ5MmY/Q+n0lZmoAlAJkeTHRUptJxGMq+pWVEGMa8p1vUdrVwWq7G F3un5js=
YYO5lPlms01BFJfUsysh07HY1HPkOyFHeEkviZtt4N8hopx0pP4fyAZYYdrBAIdt
CLpQFQ==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,12 +1,13 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyBETE9p YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyAyMWox
VVVHeThGT3daNW1xZjBDblFwQWozQ2VSUmR3NlJVak12YXdWUDNNCitTWnBHd1Mv cEFDWWUrVzJSM1o2azJqei9HV2xFY25oQXV5SzM3akxEaUJiN1J3CjkrQVhjWHY5
L2ViUWJvR0dtckpTQnRNMWZtazZHQ0tON0RhM0Z3cTlYVUUKLT4gWDI1NTE5IGhV Uk01eGp5Q0RKNVREVXJVZytndTM0SXNZSGIvUVp1TnRiNXMKLT4gWDI1NTE5IFZn
ZEFqcW9CcHUya0s5dmgxc1JqUWRicmpXTllIckxaWjhtYzMrOFp0R2MKNUcxVllk WjAyR1RMajEyMnFSYnNGT2EyekROVWNoakFJQVZxaFc0YThOMHVyanMKWldrdlAv
WWJ2cEkzdXdiVFNDQVN2cUVNRnlMQ1BZWEx0QTI2M0FKSHE1ZwotPiBHaCJASk9u cVg0OTFHL2loeGJ3RHA0MnlnckN3czF4RUgyc1NjYXVOSXF5cwotPiBvTFQtZ3Jl
LWdyZWFzZSBsIFxuClVieGM0alFSdmttVjVsNDZIT2hjSTdWc1Z2VXRIUC9BbXNL YXNlIDRsSDp6eikgT1ojIGEzOFZMIFc3MUZGCkttZ3ZLNGxucnlJc01kRXFZTGpC
MXArcHI2eDM4QWwyeXhtMU41cEtLQ2tkVllJdjkKTjMvNENSNXd1UjV2bGQzbnJx eCsvRzl5WnFUMUIyTWNVWGk4SjQyN3V0bXQ4VzFuM1RjSzVMcDJkaW1JYXMKQkE4
U3RubVRxQXVSSzJXbG5uQmcKLS0tIFFIeEVhR29qY3FBaUlJd1M4K3FvdDNybHZB YWI1Mmg3MkpjdVpVYWJkczJQMnM1SVMvNkZhOXBDVEZPCi0tLSB3SVIyU3M5RHBE
MmVMZGxyYUYxVDNydjZLbXMKiPpxBn4WtzaH2iTFfjayYgNFPa0Mi6tIH0LOqkAj VFRtMFU4OUFLbkNjbkJmVmhlc2VsYzdsd0pFaFkrUmkwCs+h2KlXoyZ8U++A9wmV
RyHNF/6vgWlmnivbhP+74dVaqR8IwUdFQN7S8/fx7eW/7qvtlg== kh4N2YyI/a84yPGDNoFdSlXaU8jxUzolnadImXSXyB4CroqQLvGEbkZZlWqPLVfh
Iav7Ja8=
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,33 +1,31 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBSS3E0 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USB5WDhJ
YWsxbHZXQXo1R3BzL1BDdERxN3d2ek5acFZWK3F6andTeGVacVNVCnhPR3I4dXFV U3BNdEFYR2xVb21wQmhuM3h2TWpwSm40aW5ycjJJZ0NQNjNEdDBNCllpZlRtcjFM
dFd0N2lsTU5NOCtsM3Z1YUdIaER4YjlrdkNXT1g4dGZXNFkKLT4gWDI1NTE5IDBQ UE1TbE02ZStsMk44YVZ2T1piZmh3REFlV0Q0RWVGMERaRkEKLT4gWDI1NTE5IFRz
cHBYSG04eHA1ZG9KN1Q5bFk0eXk0T0o4c2pLVUdNbEtWaDdwckdJVmcKd3lkZmVY T1grT3ZMRmVUaWhFU1BJbnpDTDYvRUUwUTZYUFQ2OXhQbS9KeTlUWHMKQU9UaThT
cDc3dGdXSWViNGlMVW9jZENUWXd5MVNheStiVU1adG5MNEpnNAotPiBfJWZ0eWtP bHFaYXM4VWhPU0xBZFI1WDkzdzlQUGlJNStjT2UwblZ0S1V4VQotPiBbbGBjW3wt
LWdyZWFzZSA/VGRDTT5kSCB4QH05QF96eyAtfUpxQ1ggZU5FQEhZbGMKa2xDUlMw Z3JlYXNlICUgRiVYCk4rMVEzMnVMSTg4VHpPcTIvRkZZd20yMVlJbXdTK3UyTkVn
Wml2QldxcS96YXVJT0hPVStqelhmUEd4K2R3ZDM4Uk83MXV6VlVoKzRiMWhxVlJx V3B1OFZiNCs1R0F0WmFYc3BDaW5FajNCUgotLS0gajBSMklJUDgzZlNFTlFkZTFm
Ykg4ZTJ6SSswTQpTdjYzUkhMWjFwblhzRWV4bFZOVnRjRGMveDFaUTJWM3diK3lj amNxblljWkVsc2w5NUVZM0x4VGl2NWZDNApDqGhViG2eQSuIEEwEh2rxVBAVkCBj
MUE3dFlhUEVENAotLS0gd2lKQ05PRUF1b1RzZEs0ckY0eFlPaFFBNHRQZ01rZzBV EXUYBqrcqlRFRT+cN8EM+aT6ppUeVuuOv3aTYx+tM2M2yzjWvrckeVj0fr5GwpIT
SW01L0VzUUpYSQrJxWuL6pjjZs+hCS0f6DTNwW6HSD33bUwdBpyTCLeLMyDT646H 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 kxRFPfNaJA1y1NaD33t+gis7SA==
rfHgC8uFj7Ozh0nvsPbviwHCw6F+Z3lOT2qaFjzWKMuhnB8s3C//vmMFCfY2XglJ
Tmcz+A==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,14 +1,15 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBBTHhU YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBhVkhZ
TVdvcWhvb0c3NjlTT1JBWlRaRXBYSlFySFJhQVZHRUsxcTFVT1ZzCmVaZW1ucTRG azNHVFdNUnJ6MVpJaGo0T0h0L3ZMbHB3RG9Ic2ZZajQ4amt1S3dVCmo0YnZxL0p3
MVN0VnZEWndlVS9iclNhRlB2dkZPT241dHRxcjBRc1BpVncKLT4gWDI1NTE5IGh1 Y2RHVWFUSVlySTNDNThYMks0aGdOdHdGQjdrRTZZdTFpdlUKLT4gWDI1NTE5IGxZ
aitYSmVudUZPS0FHbUliUjFCWXJaTWI1RzRlK1Q0ZlpQNmRwN0haemcKaHhQS1JO elhYTEtMUHR6VlR2b0VwM01XNnFNR0tuK2hFenlhWTIwS3hSMlVIR0kKbVNLWFRZ
UVYxYUU1OTR0dXJhTm1EMGdER0hYUXVRd2VmNURwTEdVV09tVQotPiAnbHAtZ3Jl c0ZrK3YraTdhR1IzL3FxMEFQYndsYm5NUmpDd3M4Sm43aUJ3VQotPiBuZ0BNPnxi
YXNlIH0gLCJ9IDwhIEB2QW0lfSkKMUJLd21ubDVQdWJOR1VvCi0tLSB3N2dJV2o1 Ny1ncmVhc2UgUHIgJ0hvbT0oCmMwcmVHR2dTd3VaSFpHUWh1ajA5M1FUTS9WQkNQ
WGF2TENYNE8vSzI2UzVPZW01RzRtK1VCaUVKemN1RzVhaGlvChPEVtylQsq+EWK4 UzZqK0JETmlUOU44eFQ4emw0Ci0tLSBhT01BQ3VVdHBQK29GdmN0VEtoazNCcFpY
X6HxFl3JY+M9clfpicNlSqUjPcB3roEMpD9BmGcG46nVSZVDguVjPzwTltAGE72Q WFhIeTh4VTlHeDBhcG1lNUhrCmxtBrEH3ornrPQi4eIIOskkKMTDs1Ow3Z70WuEd
Q4RP8/yhssA2rrLEuWz+JKcaASF/yEmu9QBILrWBIWz0rQyHfTRvBC9d83MdHS5f FyXGsYXFwpibxFxAWWLwAYiq7cMTEE0GmYRlNYt7bWwJn12Kv5LVZCL8HXTNXCLl
DQl1abC7Lv8imVm0pJ9vthvB56mXlGgm16fnsd/UhgMQSWZuVLSitaoDEFCz/LWi xf0za7pHvXF8XWaZwU2eMMZRdkzE6HNnbLt+DB0TKS9vf33i7tmwduqJ8oiUtTRD
QAUKYTRVL2UcomgHsQqMx+2g3HT0RYQu1Ud3M5rT9eMSSqPG7IzyjNA3HmH5dw/4 XTm5IPyULH2rikDuDm0aAvaZhSFlzPIe1MKr93ZaHGrvcnbzhADyt5DRmmDuYSk4
EdnilIaW7c6k1RAYMFY270E6qlxqdQ== SSSrhHP3P0LB0OoMGVU8DM9O7QNVwScs07T7ll238Jc/JG/KHj1kT2K9LYAiNl4Q
JfhOOA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,15 +1,14 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USB1QUhX YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBOb1dR
dTlNY3h2SElIMytCTGlmY2syMmlTL1VMeDFnanN2UE9QK3RvRlUwCkVMM3ZKMU52 V1hVcGZMRm1yeUtKTUdBdkVjazJsS3l1aHR1Zzc4VGx1SmVyNHhZCkxZY2RLNW1m
ZmIrZ1VxUDNWZm1lU2MrWnpkUzBLcDB5cUFCSXZmQ3RXR0UKLT4gWDI1NTE5IE5W eFVzRG00eGN3eGNoOGh0ZHhNZWZhcmxoVzV5elM4bGdxUTAKLT4gWDI1NTE5IGw3
cE5uSlpRd3dIRXEyRnpSZ0VHZ253OE1ZVTd1OTJQYkZVd1NRdnh2aE0KNTFTaHJM ZThQM1JESU1lZk9Pc1ljanU4dVUwb0xuZENWSFcrZ01vejhRT3E5ZzQKTXZ4Q0Zn
OE9tc0VkMHFHUGN2dFZVSGFBdTh5Tzk0TGU4SWwzYTBOb3FtdwotPiB9WnwtZ3Jl OWFHb0xoZi9UL1NSUWNEQytmd0dqVXFydUduYnZGVGhKK0JVTQotPiBPc0RaXl5+
YXNlIHZVYHxaIEBSbmZ9XiAhfF52YCNwCld0K0RCTFlQamNLeitWM0kwUnVJdXFV Wi1ncmVhc2UKYUtBRGZhVlY2MlAzRjJ5YQotLS0gSllJbHVXbDZtZGFac1JqN1I4
QjNFcEYxWFBkVjJ3QlAwTGVvTE1GTkxCTEdDcmlZMC9xbUcrSHp2V3cKdzJLb011 bUdyNSs4c3VLSEJUVmo5VkpZVmkzRzlHOAow5ki6UNCCQQt0YXMr6OGjsDg9yYkH
aEM3a0V4eXBTMjhnCi0tLSBOWHozZTRjRldrOXBmM05BZ1lPRDYwaDFCcHBPNHhQ ssU+hO1wKXepVj6QSROZubLLTyV4Cm5rHWESMiSGTV3rcGNDUuphrS1va+stkJqK
SzlaWGM2RXY1THI4Cj4RzG3G1yGkmDyqxCBciqMNPAQYge4mXOib7mqOuyIbkT+k O7ZHP68QmCPLdlu1ghNXw7etm0K+BqqQTpPfgrusW9emUV8gIY5/SWmK6hDQLR/T
qrJ8fLnW7Jbnb7+Rzr7BAEC5/dpOfjkyY9JPeg0FRutlkKyPIhRMAEhSsNvUFzXg ibC6GqP+ZCEQOL5OgB59PUCKwEjia6O6xFKPHVLNzfhg4ZmMCNNS70gqpTFRyN/E
uwNbnSBI+9Str6nTKI5c9IWT5eT/8zsKwtK1/pr39mApRY/y6NlA5X7ZRIFeku3K s9HMiwYVuvKjEODV9kM2jhfTTD3Ri10SmHurBqdbpzWhOoLz3oMTQTyW206Air/G
6I/bCI5cT0qhIMJbF5D0KiCnMCnMdmRLrwLzM2zcJoisxRAvj4dNfLktsUQOauZ+ 8RoM1RYcVS3DI69rNg==
Gta96qQkAewvrdfz8Z4lTYJQmEqeOs1vTA6sAMf4iLp5EhPE0jN0n6D8v7Lq7+2b
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,14 +1,16 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBJbWVs YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBTZGdy
bkt4a1RBaU14cjJzRm9KUGhydnZlWGU0NGVYK0NmWXRsclpjVUU0CmNiVDJTODFw cnNwTkkzOHBlcngzYTZycE11RlljK1RtSCthVkxSa1B0SllGZW1jCk1RbzVSMldJ
TnloNW1LMUliVmlnUGt0SFFzWmxVTWxZQ3crNWVHVy9IL0EKLT4gWDI1NTE5IDcw SFg4ZlFnT3ZJTTlsM0lWYlRTRkdMZU5YS2FpTmxCaVNSOGcKLT4gWDI1NTE5IFRU
TUQva3UxN3o1MXJ5QmVmQWVmeTFLejVwOVdQZks3a0dVQUJTdUdZdzgKajBFK2dX RVF0NXV4bFB2ektiQVN0SkFvOXN3MGZFeDdHK25NQXBqelBvaVg3alkKaWhCRTkz
R1NNR3l5d010MnJGUktNWldwVjY2cDIwbU1laEMwOWJITEg0NAotPiBeLS1ncmVh S2o5bjFWQ0VuZzZxTGpsOXBRajlGSmt3bURQN254SXhyRm8zNAotPiB7MFM0TDEr
c2UgJjhQIF0pcSB4Ci90SVhIZzRGVlcrd0hRCi0tLSBKdVgwZ0pidC93aEFscm9w Si1ncmVhc2UgJG0gNkggLAppL0RJQnJRQ09yb3IzaTNiQTBBOGlrbjEzNjhBNWdU
Mm5GbEc3RDdZRDRpeTdONHpWN0xHYXkvVU5zCjjFfwumbetHbq8MKrBIx18YXmny Z0VFZ1o1OEI5M3lOaHg3eW0xQlUvbVBGOEpwRXdDZlZXCjB1SSsvZmZtSlU2RzhY
z+0ifVbksJhYLYk7hViSUDy+F3RRad23dSPvDdd7JCEpj+2PvcezBLkwfUkFdQe7 ak5lcy9FbjVlZlVmMFUKLS0tIG5ZMXZhMDYrMU1DOThYNEZxTnI1d0I0TXlNeDU3
uQhUJJ9c62oKSX7PMbQeW1tyX10SVkt/P20z6HPXvBlY715lsXspjZERi+DheZk0 ZkFoWnBVOEx1WjRmTncKZcV/oJCkeY+Tp4Xwdy5s+vuMpnhy0cndBUE4KrfkX7xd
ZDc3dPYMeyoAIWicf40ZxH8C6rWl5HOLIaTMbCOKwpD+wPjpzeZHat605YWReFxR NXTWQ1mQdy9W5MII8s1aFtxYoShZPsoNTikzZIAqxhTMHloUqKaAG0XKCKj1ZzcV
Yd3cKCRqSb2QdAdtZ0XUDSPl7HVwkw0xobCsvtPzmObA3YbLopBq7Dvrvh7XW5ns WMj8+IOnPD1y7uwETg7l0lw0u/L2bb37zrlvrf6JjA5b4iO79+wg9AvJigdbkNou
BPlTaI8WnrI03CplGP00 gfNFyZuxaIwM7FOakVWV8hKhKPYd1X0y3cUQCSb0/oiogHT+9KREXsL5Jt8hVoQ0
r0asxVOASXxVRkEDQDe9RHnEMEo3+UOBtAB0DVSeGOa4LEt8SEoCfas5vo+LqMZs
fDA=
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,12 +1,13 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USAwa1k3 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USB2WFY2
S3dka3ZjcVdIQ2hSN0xsb0hTNEhneXFYS3BXNWZDVlBNc2toQ25vCldqSlMrT0hB MzFnVFYvb0wzc3grRDBrUi9teW1tNmx5dVBIRVc5OUdlcjdvTDJFCmpJL2tlYXND
Rkg2aDZUYlY4U1E4Y2djMVdwT1VsbGdpUm12Z3gzditmMncKLT4gWDI1NTE5IG13 bVJKbzd2S3JkSFVMdG40MS84V0lPTVJSNHVBQlNXSkN1eTAKLT4gWDI1NTE5IFBM
YXF4WWdmNFRPR1JDWkk4OFZkSjdzRS9BbXVzSC9YNG5FRnpqUXJZVk0KV0tOSG9N ZGo3L2VlNUZqOEE1UHBuMHdqc1pyYlQ3R29ucE9pajU0bHMzamlXRDAKcG1Qdmw2
c2VVWE10WkxUZXpqZjBZZUQyWE14TUFsdStMeWVlcFdJaTRVUQotPiBWaHxWdCYt cUlncDFWNXBOWnpIeDNZSFA3d1E1bjNaVVpKU3lMRjRaSHNtMAotPiB2XUh8eF4t
Z3JlYXNlIDYgdDsgcW97Ii5yIE95Clhqa3RVUmJENngwTDNoR3BCNjlaTkVYc2JR Z3JlYXNlICUrO0cxIH4gaTRoIF81SEpTN0Q5CnpWdEZpb1hZa2t5YkE5RnJFMHVZ
ZWQwb2FOVy9sc2d5MmtkeUhkajJBOFE3TWJTOWViWVlJSTkxWQotLS0gN01aNGdm WkhkQ2o0eWtyOE9ueDJkeGd2aUhmLzRUUGs1aUc1NURIOTYxczZhOEVmT0EKd2xk
VjR0ai96VzRqb3QzYU4yRzVCby8ycVhXVlpubVptam5mYldoOAoZnbsXB5we9BQ5 TXFHN051d25PQmtNUVZkVEFGUVliZjdmZDF3RWFkaEhNTzd3ZVd5N3dlNzQKLS0t
AXQ08mXmMxRMg9iH7qgyCVc1ywR/uo5Fcefhuw23TyluRkYt7tZ9yiuFJIx5Znsr IGZDR1Mxd24zOW05bitzQnN5WWVOOGtCNEc5aXIraEF4eXFUQm5CZUdCV2MKd44C
QEqaBioL1UfePVyDLi8LcBvUgnnx5uN05hUvTOt6gqaE /Trgg0OEZ89/jqbj56z/Hia1Ka3ZsEv6bXPI/kcRvFDBFTgtvG3KWCgMBtTUHXzY
TKBPoQqrUf7plH7a/mTx3KR+4Y+yF+1i86s7TzYjD8d1xfFH3BsVtg==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,28 +1,30 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBvdjZT YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBuQjBY
WWFyNzdXVENweXlVT1kxNElaUDFUSG1DSGMybTZlN3VKVDNNMGdBCklDRk9oaXdT K1ZTUzR0SmFoYUZLdzUzNUt2M1B4RFdPZzFkcW8rMWJLUjVHOUN3Cjd3ZHdMSzdp
MEhrR1VTcGE2NWwzdW9NQklwcGFsd1BWSXBpa1YzREdTUUUKLT4gWDI1NTE5IFN4 OWswditVWUhYNjZCdjV6M1d6U3pNak5hUlZjTHNqSkZPSk0KLT4gWDI1NTE5IGNG
Nlg1OXFNMjVzbDlRME01WW5iMTZvU05hUTExNnB4MFpUQ1QreXFXbmMKb3BzamRT ZytHazJQWTExMjNkZWV2aDUwcnZjUGcwcXRkZWl0M0F2R2JpUVlJekUKWTFlbkEz
OVM0TWZIdkJnYlByRjRQUXNtQWtXS1FXRVlFTkpSNHFVTWV3OAotPiBpQy1ncmVh YlN6dkgrMmFFcmlZMjQ0b2oySjlEMC85cUF5QlA4NGF3blBKRQotPiA8M1hbWS1n
c2UgJT9RYi1YewpadEZzVUpqc3F4U09zUQotLS0gWkg5ZWlxYUJGMUVDd2o0TTJT cmVhc2UgOmlZJFYmJgo3UExzUHhSVi9lbVRjNW4xTnVaUTVGSGVDNzRUNlJ2TnVu
OTk0WlJ2aE96Z3FGNmQrNEx6Z3N5UkRxbwrp1nF8mtgoTEYfQ/aE7KgzFOei1PVt U0wrWU5kd3dyR2phcUNVUHJCYjdzeWhjNVFOV011CmZMOVN0WDk5eUg3ajhwbStQ
cLAh3v7wo7C3lxhBOL0v8ToIAVgSoGP6cj9/4k7+9GngpOgot0IOdoXsThVdcg7w aHExT0EwblpreTBXVHh6Zk1HRkhzcmFQNnoyVUlaeStMUkgKLS0tIG1aY3Zadko3
soDjArsSWDYn6Th0yZf+trSXfA24BKIS5qQnAMT2ivQQtO9Kqxko2Zj6+wZO4LEj V3pDMGswSDZCeit4SVhSRCsrZVRVZVkvQkNsQWN1MXFMUGcKcK74YULWqWw9VvkI
DEr7cqRCWVFfvPLJurkfbCRjGlW2rKMlJotnLMYTE+Ot5SlSwVic5Nu3inGx1U/a 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
uQ== We/Pe62LyhV/MbLRA0nmU7Sf4IAnpHfa4kLtlYeB3xiqKd0McM//qzjuk5NoIgE4
nL0T8YXdGt8K01w+nt+j5bo5gFoRz5+1/ZZ9BgN2DOo4SClYnJWQ/x80X061yJ33
0SGv4eAC3vFi6xE=
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -0,0 +1,16 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USA3MEFh
YURySHY5RjVQa1c0QmMvTkZtZElNd1BIeDFpR1U1YXZ5dndnclUwClA2M0ZYMk90
RmlCZHVISkxZQTZXeEhZVUROSVRGRVg4TmZKZytSL05FcTgKLT4gWDI1NTE5IFY2
V2k3S0VQdGlQZ0hkU2ZoSWdOUG9rQ0p5Ukg3ZHU3MXVvNHlWYVN5VVUKcWtoWDJh
LzRwcktWUGQ1bnJvRzVBVlpHU3NhdzYwUDBPTmx3MFNrdWNQYwotPiBKQil6Km0t
Z3JlYXNlIFdlRTlUU2cgVlxLIzUgJlVyQiJ8Cng3NzF2b3d6MnlEdURQWHgrSFJv
Y1BMUkZyelJSdDJvUUUwY1k5R3ZBMnJaa1R4NWxlUll2azNseW5MQlpvVWUKYUdN
d1ZscXVxd1dxSGpzMjBYeWhhYyt5ZlNkSjhmV1ZTTDBTCi0tLSBBTG45VUJOSXZv
N3lYNVlyZldMVkpZdUMvS21NdSswVmU3VThZK2M2eis4CjwfWWJVR9Ty5dBXEr5s
U+QrifXvyMJJvqOKEfMYYomFLpt/VtbDAUwNlqLnFIk1VZ2xPUBisXPtReiCK3gq
P+i6bUONSmPYvmF82VgiuKDuz/kmWqVGg2iSBPIXAGLNIEojndQwmhnrsN9ex4Xy
lBHkvVsN8EamUJwZ+FEZe4+PjA5yEnANWpeTELOt2gA92/jwwnNIsr07eVTlkh8X
UmQ2owGwktXP7it6//NV3C7sAdazs2bX65WSnog2E8WPNAorKWI8RCYs33CshVFt
zzclZ4hRmlAmqMHYqFY=
-----END AGE ENCRYPTED FILE-----

View File

@@ -1,13 +1,11 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGo2N0ZYUSBmSkJo YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGo2N0ZYUSBoYlRq
UzFYMVBiNTRBbnliRHh1OXBpME05dUpyYjg1ZVY4WStxRXg4VTF3CkpGQ0Fia1Ew ckk2c21uMVZSR05SdlJpck5MT0FZeUpLTmpTRVN2WDkxWWxmVTBvCjlHZWtEQ2Jh
RnBsLzNJZEZMaER0emt2TFVSWHBGcEo5MnYzVDlvOEFrUVkKLT4gWDI1NTE5IHh3 YUdybjJLWkNsZkxabTVIR0JnMno5YlMvVmhodDU1bktrSzgKLT4gWDI1NTE5IFZT
UC80K1piWEdneVExSmQydHRqMFdTL1djd24wL2pDNFc3bjNxc3hZekkKTlI3Umh1 Um9lWXhqRFFLTWdNaTR3Sm1acmY4N0l6WE1FSW54ZEtQcEE5RHBRRHcKcE5KYmp1
SmdBM0Ziak5GRm12K0pMckZ3UGZXZTNPMm5hZ3lTV0NFVlYwMAotPiBHLWdyZWFz WVdCVk0wMHZ2SCtUR0xKWU10N0xETXlXZmgxcmZZOFBXYWtBawotPiBlRm1gKGxU
ZSBddkFIRWdHIyBjOXwkT3MgJiBOcUkqRwp6VUMva2JWd0J5ZjBpemFFM2djTzNC LWdyZWFzZSAqXF8gOkU8Tm96IGA4IC1TCjY3NUgKLS0tIDhjaTNrbG1iQ05iTWRS
RW5POHIzOUZFOG1zRElPMkZZZUxmbklpY1V2R3lqNUtOYnFlSUVMZXlrCnB6REdz UzIvNzA5TmVGS2ozZmYrYjlBY3J4Z1RRUGRNeWcKUTIEhWqr0fOODu86MDll7k3U
ZHFzbmRjMm5mM0RGU3NzeUl2bHBhTEx5MjhXRTJBLzJZRWgyUQotLS0gV1VlUkRD ThgmS9nlcUY3fMgXzZLtpHIJ/4ZSI+miu8RmLMaeC61qv6xNThGdx+MvU4tMBWKA
N1ZTZnMwTWN5SXEvQnJaK1NmcEUzMEJ6UVcvb2ptK3VYZU5zNAqgntLnLkQABERv Hv3XGi2MYL1jdHh2KYg5PgdqchYuHrFuBPS7c/tQow==
HpNr21t8+KR56PZ8nQS8xALzw/FzdexGvlt4Pzx6o0daBeh4aZx4mgcyG641PsRc
eDs4tJm8gmznr6y7B+WNC6WGrWPPIC3pHKU4g9PWzyEZcTEpL8Fp
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,80 +1,82 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGo2N0ZYUSBtVUdX YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGo2N0ZYUSBZVkFh
WWlWOU5Pck0zSWFETUhMZVI5bjNUUk9pc0dRVC83TEJIN0V6aHlBCjJvWkxSaGNq RDNNZCtySlNQTTZFbzJvZmF2TEZKVUM5VjFjQWNSeHlNc1JNZ2hNClVac2pEdWdw
WmxJSEhFekRLSE56K0pDTkxNRlJhOGZTWC9RdEZ4ZGJQNkkKLT4gWDI1NTE5IHNy OVpOTmhWWklVRDA3UzZWWk9QVG1ySUFmTzRSVlFReVdFVFEKLT4gWDI1NTE5IDVD
S2lZdjFYM1M0dksvZlZ1NkFENkhLdHFRVm1rM3B2YmJ3REZEa3poUk0KSURPMW9F eWN2S29aWVNVTTdldXFxZG1vWUNYK2RrajI0OGNGaklzdFByTzlPUkUKTmsvdTE3
T0pWVHh5MnBjNThRcE9WY0E0Z3JtMko4eDFiS1k4L2RBa2wxNAotPiBgWn4tZ3Jl ZFBvalZsdENxR0VnV3FVSnFxTitBRlFWR1BzcjJWd1h0U3hpYwotPiAyOkUlJC1n
YXNlIFdRamBzSyBlP1wKSHpqbmFWZGpJbkhyRENTZlZtdFgKLS0tIENud0RDdjRt cmVhc2UgIWFOMiogVDc8IFZETk9BSDVTIHEKQ01rc1ZoNXQxUDdtWGRQUlRCV3k1
bFhpbVhQbkxXZXJRSHpDZWovUEowUWJxaUkwNGN2aVU3ZVUKlXMwhyxmFiFHHHDQ djNZeEtOaUl6Tkl5TDA1S2ZXWTFQZEFiV2pWMDJpZ2dkYXdBOGhSTVA2ego4UnBz
FDtswK4HmApIhnW3TORhJyKIG6WBKFE1wDN5cDLppbjLdWAZecQbw0Qe8UQP50CM ZGhXcklMd0NVWlhsc0Voem1wUzMyREViUllCRAotLS0gMU5GQjdJaVdlUFJGMG82
iSZOYSSpS4J6jo2kFCIQELXjXMi7YhmkIa+Svz7kcr+vVROOikBdTr37ZOXp51Dy YnZCUm05ak9qcmVyUVJSS0tHaWRRTld3ZkNPMArRgojrBQvlyjMhChn8jgUNDysj
O+Ygl8rPaDkTV1elWCgwX/Y5KM9wvS/OEVBSKyc5vz83i0lsHMTOgb0QxMrqiAUC 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
S3Pp6kYXW8wcFAFRluM+LCFzO9VFnZ8BEh5nDX4= aLqLJz+JH+idcsVDlw8jJzFW6pQFbM3VxXObvCg9ou5+P+Pc5XYyALJzIlmoOrN+
ns5Z+U/2XKGyySQASUyFXUNml6csSrTd+ejz1QvEX9POU1nLmvS1+aojgnptgdpn
sAtksQHMt1Njo1oRug3+/0iC6XWEig==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,33 +1,35 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyBqaFcw YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyB3QTU1
aURxK3cvaktEVkJIQ2dOOEtqbVVGRDN0SXpXdGI3NzhQV3FmaEJrCmVtclBDY2Zr TEdvbFNaUmE4U1lCNzI1dlloVDBTNXdURjZ2akRMV0R6dm5ST0FNCk9YclRSakhT
cVMvUld4dDNybnJ4bHZOODFpNGpJVXdRaDJKY1ZxMy8yMjQKLT4gc3NoLWVkMjU1 NlV2UVJwak9Fa3dQNTNBK0xKWGlkNXdwZTBEMm4xZzc3azQKLT4gc3NoLWVkMjU1
MTkgakk4UkFnIEtDRTNkdi9VdGFnNkQvdE1UdHQyRmJXR1RtR21HTXMwa2hiK2xM MTkgakk4UkFnIGNBMHNrdG84cUQxd1lqQmJIczlScU1jNk52Y3BtR2tXeDNWdWRX
Ym9xa2sKYTFVQmVCNmJId2pPQk4wd3g4N3pOc1lHcjg3YlBEa0FsQlVsb0RKRjYw cEFCR0UKVU5vem5MZUFPbGhoQzJTYnF4OTd3OW9jYTRkazdocVJkZ0pRRGNLek93
RQotPiBzc2gtZWQyNTUxOSBnU3hQMFEgOVM3K2NwalE0Vk1rbWdSL2srbXg2bkF2 cwotPiBzc2gtZWQyNTUxOSBnU3hQMFEgQ2RUaEUyV1ZGbGRtZnlIUEtTQXk5MUZF
MTduekNpMFA1QkFBNHJidERpYwpCbWQreWk4cTllUnluWHZaMXZWREpqZnlwL1Ex djYxZ0hBUThlV2tXTHNvdXpVSQpMdiswMy9QNUtCb1hkbGRqR0Nia3FXTzE1ajZL
R3k0cWhHSGg2SkJPSkNZCi0+IHNzaC1lZDI1NTE5IFZGY3c1ZyBwdS9CeklwWmpt UXljSTZqM2YvbzVuWUFzCi0+IHNzaC1lZDI1NTE5IFZGY3c1ZyBYL1NrRjRaRnFn
TkxWYnhTTjVxNVREOFBqQXhRWHlza3FLY202K0wxM1RNCi93YVFOTGJGNmYzZzhF RlNLdWJ3cThteDM3WmNaY210d3RmZzhCYmNpVXBwVGlVCjBkM0IzZC9zNjhmTTZV
WkpFMDd6V1JIcjR6ZXcwUys5UkE1ejdFOW91MWMKLT4gWDI1NTE5IEk0aGh0c09n R25ySkVoQWxQQ252WWFlWWZFMlc5dWtUN3VvVTgKLT4gWDI1NTE5IE8yUU1pWGFr
T3B0ZkNSc3NTa2doUGs2c0NKTTVMOENPRjJ6KzlodnBxR1EKUnB6azR1V3NHUnRR NzUvZVpwalB6aklkWmJGWUQzTnJiRjNzdzY2MUp6MkY5M1UKR1VIWDVyTFpxem5F
WmNrWHArZ2dmMUdEaGovYUdndDVNNlB2UW5VaVdnOAotPiAsLWdyZWFzZSAlUSA1 TmRNWE9zZStLanRTdlU5d0NOSEJKdWhDUjBCdy9vOAotPiBTJCd2NyFYey1ncmVh
WX0gJwpCMG1tNjBPMVJRMGRlQ25KLzJsblFzZkN2LzNDOGcwWEdSSXlBUjNwCi0t c2UgfE4mYSBXfms0TC5FPiBiYmx8IGRFV35mciNoCjVZdHRiVUtMMWxEMlJ4b1F1
LSAyY2hHNFNmWFBQWEsvb2hxTUxVUXdKL2p3ZkZWSHRDdFlkREJyaWJrVDg0Cis5 TGgxY01XTlZpTEtndkg0T0hRVjlqVUJGMUpSaE5tVlZWR3VGenpkUXY2eXJtbmkK
gfdBAb92J5/DuoXUt8OirgM7bXucabAp8/U5Az0nmRkGawpSZidB9ecPYHfcdUGp ZCtqRVN4dnZENXdoYkpjNHRWYXkvN2laY1p4YjV0WQotLS0gOHlEVTVOSmlNemNQ
VIv8roO6P0RbbfYXh3szT1YmEMyOXMHFM0+Yunq3u1ca1EHCZDV6Feb+i+lXIBJU TW5ISk1DeDlEM1RoQ2JtUFlyTXRKQjdnT0hiend2VQqrUFvr+76sKn0ldBmZMlEW
GST4oupwMET+ChVT1/yg7A9o4FY68+FgLjGwE1qeHN8gQr6aMz6/yml/z1WzBEXW U2k85DLo2KU+/+GtbkZwVXxxIZHMLpoJgghHk9ptdalUgLGcl0X15x9jVaw8aeta
XEv5fVxGj39eBiq08Z/kCgt5zVDod8RxEq3S3kt1KX5JD+mpGYn2z5CMGhn7fclM hbeOHotRHY7bC3z0S74riTk3xDMR1eT0QGhDMWHjfo8SkCftOYBlFfhTftevdep3
mj37LaVbcKfyVnwRlLPoN19NeqR+ltM3mu6ibjC7cOQ0E1D/zjQMIxtzNzmZRFgB pKMZsuQMwH9JzxgUfcxIcWE975cZzrEJ85nfWMGvdSjcg51KNxP/UUPRxDlcbCEf
l/BEOsX25Zv5vJgLZBU9rMfybNVAjDroG5V1cCVDRR76TP6HVJIXSriyOW5xSFCy 9XX5apSzNsTI3ibGD1n6Qwq8bdVYDMHmy5pAhw4l8L+SdoU1tGdw7JOA16sMCJbx
Li/VyhWaUXRboGq0Nt4vXWuOTlU/tenlBnBc+d48x35VCExi9IEFpIHj1fUwM/0V T4bV0ky/PGRonjJuCyDBj8oe9vMe1ZI1O/ITtktekS+wocxBs6QXlY7pIZMlGUn2
dgOfY2WRH9C2cObUc6W51FIARkp777uPXRbT4ZXRDjV18vb18CmwLQQwYupQYnZk 6m59ZEEaf7R4/MdnmBDNDkQuyXaKc7SaTc6h5sKWzXdYScGUKvgUQ7U/WJ2ItUTC
c0hZHvoxDwg5QirWxPhuO3bWDqIvHiKy1LYgRrlvr4Wpcb1l0lAYSGX2r1+QVj8z N/Xq07GkZZMt5MYBlyEr+/mKWlcy+ylJPGb7EswvQWaHoeM1QF0XLZ1v+W/Xsso0
tA+zJcUaPkjUSpaqF4LNVWXrTWEN330gQrVk1knWqPl+hFPoyFEHP50PNYr3yxS0 seIoz+geSu9a02kwfsa8WvWXdIAT5X2pNGPClVNzjQ23pfQfQuW8ZQrGmIFR4g5A
VxbSpg46cXyxi89ghwlXBqI4LRtWlheUoIOuNyLxvXZECwCI2kmt+XBFph5lbG7F 58T1K+vGLdShqqVGyJFMVrSuOzqX5FVmZalu7/++1IQfiRGUlrHKoPlKWnCfFEOu
UQaH+ve+trb3oYkkG8ZprCljUC7HvSyt31UIRF3l4sLsULQKHqWwVD/2M4B0N5wQ AYjaPeEFX2ByxcqfMK1YVPvUufdISUQeaQOO7mXGE3FqB0oUqmRIUiWZATwhq3Pw
IzIJkiuWBBE8IX/tI5vUlGx+QWSxmKdHD2mMb/GeMsbo7lOY51cWe8oxe9WcYPhB p5QdcySTnmMpD/w05hvwski77kCdmYuHlMlLZez/kfhTnIGXris+Vwi/V19bsZ8G
m4h1xPm4FLo0vHCnWIkXy2o8JYr6fmpjzslC++wYMEbIH3gRBKUVjgUGHywVIXSa zwaZ/Xr6WNC+df5JqSfTGREnXZPFRDkaTt3ri5/eEm6BqliuYjGbuiKsDECi4+JX
uwzRULUiD8uXFNT3cZ+YDnAvZkuYz528DBKjd5jNen4akah35wQ+oYoGuIhUKkGL bHpH6LBBoKQ6ms7jCAn0Ls4cUKF37PcjGAOuWnzCSBU+REht1EDfHzx4C7hNiP8X
K59+hTyctWyEGi+fCl1gah2JJ6aF1CXK69ON11YkCEVCI1SK1o1no/0NZj2XtepU 87NjEqJbwE9lORho0hQJRTn8uriQcidlVoB3se2SYKbMy8UA4NNnxN9PTj0TuQjL
MgXln0Pz+pOTZzcjCWhYTO/dNl+Xj6EeeSjjWHqDYg== OD3LtqHBElqNPbGNyyEAAJmMBmmkUvPPXlGQ0D99b1+jIdHzYSRtOLshBFykqWYQ
LJD61duhGqcQqcLx4+JdQ+oVcfAI2nG7YINnHB0OmS2DOZvvwqQ7ASScSujUWIjA
LNQxu3ruMz+bw/G0tYZBBiE=
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,12 +1,11 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IG44Q3BVdyBvL0hp YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IG44Q3BVdyBEcDNm
WUs1VWxPVlpydU01cjd3Qk9qd3hvWVdvK1VMaUZNT1YzQ1BjdWhvCmJlSDRDSFBj ajc3a0gwYmVSdkowak1aakJ3VWZ1Rk50S1JIS0ExVktVSW9OVWljCjJqbUEySlNK
ZGVmVGV3Vmp5YitGbm50aU56VDZCc1hTdjJmSGhEa2dvZWcKLT4gWDI1NTE5IEsy a0xyT3NPK1BBMjZzN0RrLzhwVitvS0pzQ25iSnJSc3FmM0EKLT4gWDI1NTE5IHk0
RHVVT1F5d0kxN2VBMG56NnJWYTlEeFFXaHg2VnNqdlJKTHhoR052akEKZjNObUtk M2pkWHgyMHR1WHc5bE4xWTFDTndKdkhRdTg5bzZIWEU2cm02UDZBQjgKUUY3dS9p
RCt4Q2l2R055TnJCSDBrY1lWaUZibk5iUDhnMlhvZkxRRkhpOAotPiB2LWdyZWFz U3h1L1ZvTkFPdURLZ2tSYXJXOGNZZ21KVGdIbXdhSUJrd2puYwotPiAoL0RtO0lH
ZSBMdUErIHQpI01mVENmICFrK2dRdjBbIFU5UyI+KjQjCitmdU4ySDhJMDRlbklD OS1ncmVhc2UKVGthN0ZSU0ZFTTg5YW9UOXMwa3RnSzFlMjE2VTN3Ci0tLSBwMEMx
aUcvREFqdVNtb1lFZWwxZWo5VXdNUGZQWGt6SVRKaUI4cTcrWEx3NThWZ3VORkor Q0tQckd3SzBwUUE4SndMV01kUjVrOTdDWmxlcWs2Zy9TZk5yMzhvCrBXyLBZGuSD
cy8KbG9EaGV1dGVDQQotLS0gQlFJdWpudnkrcmQvbEhpOUM5Y3RCWWRGMEQ2TUV5 dJodNI13obTM3UvX6hSgQ8Su+J3fOKr5NibkhQ0Auvlr2tUXhhDm2WOUlHjqVTq+
eTBFSnBkd0xnYjUrUQrxdaCf14h8hqRfdnMorggnbuCDMRHY7nAnGQ1ET4CBlCog jWLSyhioDlIEyBgk8Zrl7KGeDzBi
/Rp52aNZHfLh+BFFZazenI7qrvVvEaaB2ZVKa0Z/F8adsGHSGSwz+saqWw==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,13 +1,15 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IG44Q3BVdyBrVktQ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IG44Q3BVdyBzaEo5
Y05RdDFyeUhGNDBiK3VHNzlrMVhKWlBJQnhodkUvTTlINUZ5K1hVCjJ5bXo2cTd1 RzNndHBLMUl3Z2txdVZoOVJBbWsrTVJwY01WeHQ0VTBaSm5VclY0CnJLYStYNEI5
a3FCaHJTNVNaL1ZRcDhuTENuZVlhWlpJUUVndVErbDVoR2cKLT4gWDI1NTE5IEVj VTN3dEQ0ZjBKaU1PZSt3d0lldkE5VC9wNHdWazNWV2F6WWMKLT4gWDI1NTE5IEJ5
VTErMFVTdHBoVmtMY2R5SmJSdHV0aTJ2SWZNc1hrN0h5S2dKUnFxRFUKTHpyaHV6 amlzTDhCOFF0TllPd2RsME5Cb1lRQUZPTGNvOEZnL1J2Wlpnb29GblUKT2t1NFZy
WWFYME5xNndlSklvNU9GSEFrTFpnc1cya0NMQUlqc1Fhd0hNNAotPiBoRSMmKiNW blNZSHdxZjlHTlZmaTFYT0laQ1IwOCtDZ21vTjhxM0owdTAvawotPiBLYS1ncmVh
Pi1ncmVhc2UKZDQrM2piclMxdExSdUZqcmhVV3l1K3RHVFlOcFZzN1IycnU0d09k c2UgRX0nVGtpSCUgNVNDWCVwIDBuPjM3MwplK2cwc2htQ2RLcFhUZ0RSc21uQlFV
V1dwREZDaEcreDQ0enJYd1FXMDd3d3BVNAowYlpwK1EKLS0tIEwrL09nY0FpSTlq Y1QwSStOK3lKYmVVQ0J5RXA3Zytaa0JoMWtlWU9qMHBLNktFZWxtbFpDCnJyS0JJ
bFhQTUtHOWt2NWV0TDArRy9iaFRFTEIxbms4SmI0ejgKmJRGof5FAIPpGn+u6PDh WEcwbndYbERreFhLZlRyQ3E0czB5NkREancxZk5BTGdWRkR6N2NrZmFrbnhSYlZZ
xSQMKrpFnGvjKs2FicG7K3C19YGVwvMds9XGYzLLdugvZgykzZhq13XK/mSk2b9r NElHNEEKLS0tIGVLdXAxU0ZaZVkxaHV4dEZNNUVuc2J4N3VRMzZzTktSMDY3bDVB
9xkhAvCQ0p1ikQDyX6SuLwJzsJpa7V7wHbEF5HJXQ5NrJUOFwftzxSqYodtP29L4 bWtmUVkKigIZ3J0s23vNzmbzJGjSMGBXK6o6xnsA9HXeQZ13VgKv5Qv+UHu+Z0g2
LiA8sxPzNeqhFYT/C8Ea4lDzgnXCjoWtMcZCpfWMMtOJh8fLLw== TeKdQSrHbDB3ydIxaiXsi2ivULdrIMCyd96rEJFxrkVuVqSZE0ehG5j+o8lKk4OU
PDe70slbZrVYDSu+OOUOCVRSopZreCURlYn2Pc4rjvrMAn5r1r+/AxjZMdkmmQZ0
l0wMBTus5zZzKg==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,13 +1,15 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IG44Q3BVdyA3enI5 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IG44Q3BVdyBoZUI4
NkVZMkxncHRiSFkzRm9seGdwdGNPM2ZFckRoWkZFNlV3Rkl4U0UwClJ0bUZlUlFs bEdWSW1pcDdMYVRJLzdQOWhsdTlZMmlyZjRVeEFwU3Z3NzVFa3lBCkxRZ1FYeU9D
MVNsNmZ6aFFYRjJSQmNWdjJMc3F4cTNrejMyME1YRGdQVU0KLT4gWDI1NTE5IHlR L2dramp4WFFlREZ3NTFnWUs3clVEcnBhLzExclVac1M2SG8KLT4gWDI1NTE5IHVZ
VlI3eGVMcS96a0ozWkx2b29wTWtIbFFCcDJEa0g4dWJvdnhGQWFwMUkKZjQ0MzlQ bk9QYy94Tk50c1dVanNvNzhpYWNqeFMzVVR0eTQ5OXozMmp2VFlad2cKaEdvUnR5
VDlGdkdxNG91bDV2MFZXazM5SlIrUmduYTJacGtXQitnTXU4UQotPiBNQktGOG4t ZjhsQ1FRaittQXFkbnRZei85MmtWb3pXRVFsc0RzNzBPMXFMWQotPiAzSXJZb0RE
Ky1ncmVhc2UgZzddIElDKW0KZTFiNlIvcEt6aHUvY3h5VFVtb29ZQ0RGODBtTUF1 LWdyZWFzZSBudCBGIDklTWIjVnwgM3YvCjRVYUd2TForc0gycnRBR05MbU90QmNu
TS9Ta2lZZDJJUFNyOGp0aU9LCi0tLSAxa0ZNWnM2b2loNzNFMmd4U1V4NUFnZ2RO dXlmQVB2bnZyME5heXlyMUdGTmR6SVd5SHcrTThrZEJYRlpnUmdmWnkKU1lyNjQ3
SVRaUDVpNHVHMUFSczNOcVZzCiJKbkbVr3dPswaIeb/dlP5REMZW0NoxMluj8R73 T0J6b3NPQ1FYZnhxTjFrYmN1UUJzMjEwcDBwSTJkTnlmeHl3WmFFTXB4eUVMWm9i
AcCimbLRWY2KAOx5XU/ci2auvMqjlqMExlp608OwaGHcpmoijNZQsKgTAW8Z4z28 NExUZzM2SHlLLwpiZjQKLS0tIHdqakpMSUNOdnlBcVA4RGJHR2d5QnJNT2dVclZN
9UbAMOmSWByLfgAzhoN4Xob5/40JjI2f3wFYwsAf0f/j6dLc2lmqxkhd+Zcj76Yj djd4WXBLSUhORktzZ2sKzMjxqL3UPrtGmXDijdfu0AwxLJooK7ZKauYvXWSuZUrR
t2WbVgPlBMqPQIoFd6TtwJweqzzGmLI= vl5i1QPMEEBYEl+NaZIFgxAFqWpAXHQ1VxSijMWxNjKUd1Chq0tbLrpbh9wXJflK
SW19Wyqc9eTb8BnFoOSYWpDvAs2Lbyr2kJkOj2TNrwMv8nDJdOB8XIPlV5drCj1q
Dx/1zWqm6NMYxsep6eZkv4AzxA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,13 +1,13 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IG44Q3BVdyA0N01m YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IG44Q3BVdyBrd0pM
Z1RiUHFFbmlDVVgwTWQ5Nmw3WU1NckVFcWQ1SGVsQlZLdGIxSFJzCnZpL3dmRWdY TGw1anJNaGoyQ3lMUis1cHVtRWFPcFFNZk9Cdm9TMEh1QTdKc25ZCm9VNzVQcUxE
UlVaOW0yT1ZmUXU0VkFHNmRzbFk4cEt3dW91MHdnR240eVEKLT4gWDI1NTE5IGtC Njh2Wi80RWszSU5NczRNcHpVYXpRMzJNcDRsdGxyWVZsUDgKLT4gWDI1NTE5IFpT
RTg1eThyRHlSZ0VsUEVzUm1EYVFIVHZZaHNvY21mOS9mTnlRbW03aEkKQjIraStT MEJVUkcycVFJaVFOUURoL29VT3R0MVJCWW04NXVRVEpKY3hlY1lWRkEKcENya1Jx
WE5sRUx3S29CcTRobHZVQXJDQTQ1YXg4Z2c4cS9zSVhVVElXcwotPiBoM09vUG0t VnBCMVBrZkc4VDkvMnZoTllCL09vQ0VOZytuMnRvYVQxL2FldwotPiAzLWdyZWFz
Z3JlYXNlIF4nRnwkeSEgKTRZIHIKT2FXTWZmbW9jSnkrYmp0WWVDVTZHdFFxcXJt ZSBCNX0gIiB7InIsfCAkOT9uM2UKUWpSYTZ1dUo3SHNaUlFibTl0UDhTaFh5Mk1n
Rkg3S08xVGZ0TVVjTHQwaExFbkh3WDB6bWJkVEFKYXpQUDEvSQpGNXY0ZS94SVY5 bFp2cjM5RGhqU0s0Qm50Zk1pUVZmT0R6ZjBoUG1EUGlKbHFzVwozQ2t1cWVDVVAv
anViSzJ3NlNOUmp0eUliYms1Smd0RUVXVGhxdlV6TkFNVkpzcwotLS0gQnc2Y0ZS Q21QTjF3NW5UdTBZRldnL0RmSlV3QndHcDB0d0lvZ1RHTTByS1ZwNkNVQnU3WmVn
aGNtL2RwUjVxZE9uYlpBeVMwd2M4RTNsdW0wVWpDd2hLLzJSWQq07wZpB40EpZog ZwotLS0gb0Fxb2FsYzgwRjJwSUF3ei9hZVR2Vk1ORDlIMWoyZ2RTd09hUmtvMWpD
fW3t5Uokt7EZL4V4RX9PFyd48SaEd/xR1FiEL7jg8IJp0dY7hdfnzObQbueCwUOi cwrEjdaYfoGZ9i/S97xL9QvA/yii+sJLeuUzzv7a3DE661eQ5ezurV8Qz1tIhxWG
lWOfF3n8XpzS8uo5TgLWLtY= RsOppaaj1podFx3U1x7QQbLO6zQbJA458RMjYgc=
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,12 +1,13 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IG44Q3BVdyA4bGQr YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IG44Q3BVdyBHNWg0
dzJZbU4reWI1Sk45QTR3UkRoc0NvaDBFcUwrVWlCYWUrcWtYZGpNCm1PWjVzRVlt WGRGZnlTdEhsRm96T0ZMOWx4UUxkTitJa3hMWDE1dVkreEtEa0RVClpvR2I5NGpz
UDFKY2ZSZTg4S2pVZ0pDNzR1WklYQ3pEclJZLy9kKzdGTGsKLT4gWDI1NTE5IHFO aUF0N1VZU05oWXUzTEI1TVBLYlVVang3Zzgwbi9teDVlQlEKLT4gWDI1NTE5IG4v
TXVRK2d3azg2cHpRanhUNXp6YnRsZW1MUDJqc3l1bnNYNUhHaTIzMVkKWXp1M09H OXRIbzhaZEdXc1pjTnRRWHVxc2ZTcmozSlJkY3lyOGtvd1BVeGprVUkKdUNqSW94
TnJIazRmb0tOSnE1Q0E1dERiaHZCQkh2YzE1cS9zRUhwaEovMAotPiBzPj5nLWdy SUIyOWtsNU83cnVOTUxNR1BvWHJPczdzUWc4aGp1MjlpZm5ESQotPiA2KSV2PVx5
ZWFzZQozSThRWnJCcVFFRHpoSi9tZnZMdnJoRlFud2VISHBHSThMem9qZVVWdS9C LWdyZWFzZSBqezVxOHc9biA+aD4tP20mXwpwRCtMUDhmcVhGNXpCZlFmSllpdDVp
VFBDVEVzbUVCdFU2Qy9PaGdyc0FaCmk3UFZma2ZiR3hmWG1sa053bDBnY04yZ1VZ SmFZelNhZnJlR25DS2l2MlQ3ZGFtdGxkZEdEWVNrRlk1VEZBRm9GMHBFCkVlQ1hp
TW9jZwotLS0gMDVSaE5aakxHenFPVXpXa1JxczlWQ2x2VGNuQzdwaWZFTTFTaUp6 WnhOTGl2R2s5RDRKN0p5TmF6Y0cyN3ZlR2pDZlhMVjQ1c0FJN3hCbFEKLS0tIEFT
cnRmZwoomylfwjD5A3N21/mk1Wtt8f4bsK747iZz7KT34kqmoX597rbGYxyip5lg bjFiRStXMmJueHdsRm1nU084dDRpS0tBT21ENzZFclJXbE11NWJETm8KyMHU+tZY
VLZV6CY4LLRjnnSKoC2hIXU0dgudAmvxhztuaQ42fOc= QELtZCbXKWnP8QC6V84JIFAxoRslACwsIJZpogcZO/IFIV2RGunGjCJk6QBmhOPV
kJXRcGO/ndYjWfuU0U3+9HtPocnO
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,13 +1,11 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGpJOFJBZyBzc05k YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGpJOFJBZyBOZ1RV
SWtwMW9tdzAvL1hYenU4Wm9MTGF5MDIzS1Q1eHR5TDNlRHkzWEVBCjBWa1IyaHFr VVpOZ0Jhd2x4YklMOHdkNkd0MEM4ekZiYXFKMjRIdXlZVDFkOTFZCkRreDZlK3Bo
MW1Xb0dSU2tVTlhuT09rTUF1Tnp0Um1EdExGSjk0ejJJSDAKLT4gWDI1NTE5IG55 WmJ1MDBxSU5UYzRuUDMvdnpVc0prNFF4MjM0M1FaZmg4V1EKLT4gWDI1NTE5IEkz
M1RVRy9YK1dhZnRFMWdpakptVkNmaXJyOWJxSUlLcHV3a2NHa0N3RWcKQ00wUmhY THNsVDVCbU9KYWpXL010OVRmNjBVVmVyVzhRZW5McVFJcnA3ZWJvZzQKOE1lQnVX
UExuTXZ0bWhjQllQOVB3WnAwbnk5WjlURDdpQ0pqNjVvMExjbwotPiBPfj14Slot Nk1rWVAvS1lpbDEzb2ViUUE4RlB5NnJOZmNoUGdUMGNuMk1iMAotPiBuYVwtZ3Jl
LWdyZWFzZSBEPyB1O3spbCBYPCx0b0RQIFtTUmJUOAovelJwVUZibjBibWp0MmZ6 YXNlIHdYXzh3MSB0TyREIGpdTjheeQpJZ2pYUyt6UC9vVmRNZU1uaDdvR2ZUNG0K
WFNVMDZkbFJOMExlaEFUbFBBWnROWVVtMkNvR29ham9pV1dHVDV6M1BVWjBldU1L LS0tIHNCRno2V21tZU9XV1UwR2IvZDdkWEMzZDI4V25Yb0lvdmJadXNEZFV6TEEK
CkptRVEyWjNBc3dXdkFWN0NlTld4M3lnCi0tLSByMk13SzY1L3R0NlRCVG9lcVor 81uT8S3QJNe+mVadi/VpXSPEP0Ygzm0/+1pB5qqYlSQEWTHqS55gCyFCwu+sjaDq
NVVmT1hxdnpSL0QrU0k2RWxlRUY5SldvCiBWgIk3pt8hcWFRsH6oleoX56bT+nz8 DpYTSm1JAk5ql9NRj4fJvCS53lJZ4zo+5c0iJKmuRg==
BZx959QwOE0of9n8Prfnviq15L9Uan8yL/CadSS+0kyir8AHhl3sV/VLFe9nlZZ6
Zg81EdhQXSQ=
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,10 +1,11 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGpJOFJBZyA3TXZY YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGpJOFJBZyBBOVJi
OTBpcmd0WmplOWFEbmMwTjVidC9BSFh2OUVqZXo1bzRvcEFvS3hvCkx0NytPaE1Y SXdGVDlXWmVGZUM0OTJPUWFYem5qZzAwZWxhNzhpT2t1VjdZU0ZrCjYxWUE2VW5o
NDliWk93SnNxb3lOdlV6em04bllsVmZuVllwYnZ0SytLZlUKLT4gWDI1NTE5IHFu cGFLZ3g3Y3BpUWlWOUtUYTg4MGZXVHZvdVV3eU9iZW0ybE0KLT4gWDI1NTE5IDIw
bTgzM1NLWXZmWFVqVTQ0em5XajVEbkQvV1JxSXp3anZFc3EzeTdHQVEKYTc3eTVv QmxaWTY0WjJFZUd6TUxqaHhRelpRQ1hGZVBEcm43d3JYUVhpTWp4aGcKVzhJdFFu
cUFyYjU0UGErc01GclRhU0xtUWNzQ1F1cm45d2NVdHdDNWNWOAotPiBvWFhMLWdy SEhUUUZVNVk1N2tzekpzUS9RazRCcFBhb2xxbkhRNEwzVys5cwotPiBkeE19PHEm
ZWFzZSBQMV9mNiBrdzVuNSBOOSkKOU9BZE5WUzdIbncKLS0tIGplTzYyQVNBR1g2 LWdyZWFzZQpwR0xsb05JVlFXQTZZQkJSWHY0akNRdjh1eXFnbmFDWUlCM0xLWXBi
N3VUUHRCVjY4cjBGYTV4akpEbGNPUm9SRXhvUzRzcDQKhBEb7xKAjU3SMSgsVxBa QkVuanloRQotLS0gZTkrT212MXdsZy9Kb1AwMkFHU3VsTElweGNlYkZ2UWVXRzkr
8KA0Rh6lgJ0HOLgfBI8cZTzHcNXeIOgOTae1GmStyVjUkw== dnB0SHRnYwrveLSY6SdUDO+QH7WGniLIOPcECTQ7CiTj9lwD5Hm0rYLdvizolb33
CsGX/kSEI2bD
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,11 +1,12 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGpJOFJBZyBsOXZu YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGpJOFJBZyBrTW1E
WENWTnkzdzgxVDVFY3BXSTBOUGgwY2xyMm1EQklDTG45V3JraEZrCmk1TjFMbGg3 ZDFSRXIwbXZXUlNJbHZCVjFzMzRxTmdtbDQ5eWVOWWp3SEdSUERrClVMeFRLOGUx
WHB5b2s2WEZjV0lIT2pGci9TbC8rbUY4eVhhZVFDdVpHWkUKLT4gWDI1NTE5IG0w U0dmT2ZUUXlCSGhJdE5ibkZLMmZ2VmZFWU9PQXpGZFRPQkkKLT4gWDI1NTE5IDIw
RGpobG1sNXFBOSttVUdEd0RjSHpORm5tTVBLSG5iMnlHeDd3MVJ6MjgKNktpT0N2 VXd5N2EwTVdhdkRYeVF3c201SnV3TmxnUGpOZWY5bFJaQWRWMWxQVmMKR2RNc2pE
RDg5S3A4clR0RmltNmZ6bVdBYklONGwycU00ZnFQMTJmcEhpYwotPiA0bFlqMi1n aUs4ZW1XSGU1RzM4bHZYQks2cHZWUkhZN1hob2d1QnM3cCtlMAotPiB0XENxMSct
cmVhc2UgU3ZAOyArVndDWCB7RmZiIVd6YQp2dnlBOExZQ204TEpuVy9vOHVNc1ND Z3JlYXNlIC5LIEIoJ1w6Ci93eE5lMUxDQjE3dWI4a05wUE5sV2dWN21ZN2lFRThv
d3dQc0ZPTUJaWXJJVFFjRzhqMWt0UTBzMzZ5elhiRTd2dE1qRFpBa0EyCgotLS0g YVJGNXNWaEtmbjVMaXhnemVuTXhOMXFtNkQvbGNuS3oKalZ6bEtGdHcxYnZNb0Zy
K2FnWmJNampDL1hiR1diR1lKNEdtR1NGanhGZEtpVkN5Ynk4QnlLNDNzbwoKzCe8 YnlGTDdoVVdyeTJpYjJjZkc3alUyV2ZGa0taeEFIYTdiRnZmYmRjR3BzNUp2Ci0t
S+esi+100HykYeL6bKhoa3tuo05x8qCn2d/fAehnJDecPEnpqYdDXWOWc/3x LSBROCtSMzFNR3hTK1p5NVhGcFpqM0U0L0MwbWpzNUNTUWUyNEVXbzFFMGpjCnot
A6mYbp+jhpoyjZidXQfzLVcu6y34WqAfJZsfT6l5SJONVfSvSw+iP7XXW2T5OnE=
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,12 +1,12 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGpJOFJBZyBOd0ZS YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGpJOFJBZyA3dDEx
aUp4RW1DaWxTOUtrbEtUaGRyNVYyb2hXMWdmN1pqd2poSXM3ZFE4Cm0zMCszMGpK SUw4QVh5T3QySHFFemo2N1JWTjNCSGRiS1lmRTkxVEQ3S1NKR2dNClZNM1Vwc3dF
Tks2UjBFZnhGVnhWYnBEcDhYakE4Q1d0aythcnhTWHlxMUkKLT4gWDI1NTE5IFlI elB0Unk1OWpUb1RQMVpSTUpJUDNrZzFMWkhKK0l1dXVBYlkKLT4gWDI1NTE5IGRF
Vmw1eWxPRHg3REhrOXlORURiSzJJcXAzYTF1KzZLYXlNSGUyR2RTbTgKNS9nZGZT TTZlMjdaamlwTUJzYlVkcVIxbmtybkFwakVtK2craXVBNVZraGZ1VlEKN2VvaU5r
MkZIalVGc3dLMUN4VmtxZSt2NEV0ZTc4KzgzSTlXelNlNWR1cwotPiBIL09daUJh VjNRS2I5WE9kVDhES2dWTUV2cEVJaXZxNzRUcFo5blhGTDBaawotPiAxXCJQemxa
fi1ncmVhc2UgNmVkIwpOOFQrV2FNS1Y3RVUrQjB3cWJWZ2xBU1ZEUmg5UElMVEtC dS1ncmVhc2UgcDphKHFVTGUgIUonYydBPgowQnc2Wk5yS0E1bVBCWmpOc25MWWs2
Yi9hR3dJWW9QZDl6UDNXSVVFMFBUTHVqY2lJL2IyCjRlNWd6b2RETXhGMUxiTnVR UTR1dVlJbnNXYUVJSkx5bWFIcmtpT1lPSVE3b2Zpd0JaTGZWcEtjelFDCitQcy83
amtYCi0tLSByclhCU2VUK2lqTmdQRUhZUEdCV3RoYlpLRXVtUWZpT0R0WXBiaml6 bEVvM3FNTEhyWVVFS21tS0VQWG5OOHFza28KLS0tIEZZeUZwVGxUdEdtQTZuYk5K
aUdJCnhOnafCdWyJ8JDkXonlnrNbq6oJfkwA9eaksl8otOfQ0pfplHq1/EMtNH3Q SHJaUDhHZ0JqbGNFSjJCaVlQTVo0OStkMWcKz/w0SnoHxnw71gr5DbXgMl59Kgjy
AWkX50A= SW4tzNGeRcX2j4YdRjr77TP5UAzpQE30tEcrtw==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,14 +1,13 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpOcUlvZyA5dnBy YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpOcUlvZyBNalB5
YkRENmpNaSt4Y3lOKzhkSm9DbUM5RjQySzZHWms4QXYxNXdLSjFzCkM4M2djbmxt RUZRNE1CTUJsbW1kSkxBSWVIcG1RUnBKd1gvcnRQVkZCUXFOQmhvClJUN2ltbnNk
NG5lZlh6V3JNVVpaWjZHOHhadWRlWUl3L2xHK0Y0YjFCYncKLT4gc3NoLWVkMjU1 T1grdVJSTzIyNTBTTGVEckVGQXdYNHdwOU5NbW1md3lGM0kKLT4gc3NoLWVkMjU1
MTkgcytxUmZnIEU3TzM2cXBXVDZYVUN1Q0E0eGxyZVJQTm1sMTJtRnJ5dGNsMUcz MTkgcytxUmZnIHZ4bFZSS0huWFBDbUhNcTd2MFhvV0lOY1l3d3ZXNU4vT3dwMmlI
WTcvMGMKQkJaVDUwQXEwVWhHUW5IRW5veGIxLzRmUHpEay9LNU5QYjd4TkJDTmU5 emhoV0kKcDF4M0FPK0JpclI5Q3Q5WGxpZWVYbHVWbkNWdTArclZsN09XK3VJSXc1
VQotPiBYMjU1MTkgNTVKMGZnV2ttMjArV1hYZUEwV1YyZVRMcmxuOFpZbXY5QlI5 awotPiBYMjU1MTkgRjRCNVZmcXVnQnJ4KzZoM1ZkdWxYUkJTM1JuK3ZlRWJYdkFR
UElFRld3RQp3OHA3czM3UnVMdlo1L09VQW1IMlBodCtueHE5RjV3cFllSGxndUdN WXpFSmR4NApTbU5qR3ZuN0ZmbzIvMTFsMkdNSGJXSVlrVmZPdnZvcHFiZW45SW9I
Sm1RCi0+IE5YTiMray1ncmVhc2UgWEQzbDsgO1A7YCV8PjAgNTpiODp9IFVZCmJh endJCi0+IDEoIjlcJi1ncmVhc2UgJUE4IWl5ODkgfGVdLihEfT4gWCAreSduPS4K
c2VsZFBZOVAxRHVQajlielI3WkFrVzRTSU1HOTMxZmcKLS0tIENiSUsxc3E5Q3I2 bkI2Wm9LRGJXdW11aDl2VgotLS0gTENqYjZEUUZaWVZEcWQvWW5yTzJEdHRLeDJm
UlFvMGJBaFd1SUtad2dzVVB1bkcvQUU5OTdQYldNVlUKo5ZSBZdm7MMSTJrX7RdF QUl5aytXdDE5QVMwVHZVSQo+aDbaGNOrz+hTSUQ4IAjDC9EfNwrlXDZtBqw8HkRv
p3+z1XKPeVBpaQmH4593iCVgxF1OTv6bOL3vS0EwtduRT/htoBbXJmgUeUpTfEUo 1/Rr737scjrM7Bgt9zuKn6CB0zdeHTW5u685V2hCW/3aTy1eppWMWj3r
IY3DkohGqSbCVg==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,14 +1,16 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpOcUlvZyBhd2dJ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpOcUlvZyBFb2hL
UllxNVZpK3M1R1FwYmM3OWs3VVpSZzhSeGVudnE0WFdlbDVET2p3Cm9BSy83SERa MCt6c0I4Nm5SMFhEaWNZRTRtNkpYeVQvVGFVZzVqd0E3L2dZdzFBCiszUXZSVENo
cHQ1a05kVnJiODIvdVE3eFZ5SGJ1VU9xQjd2RDVKLzg2eEEKLT4gc3NoLWVkMjU1 cmxqdVFwMFA0elpFOGZoM3B6SW80MEhCNlJoRXV0WXpUeG8KLT4gc3NoLWVkMjU1
MTkgcytxUmZnIE5hUVpyQ1h1Nm9EWmJ1cEZCK3hVTHcwV3hRQnRZTS9ucUptQS9h MTkgcytxUmZnIHQxR2MrakZmRFJMcjhabGFON2xQU2RBSDNvRCtuV3NwNGJ2bjZF
Vmc4VWsKYzhGenphTjFSalY2blJzVUIwQmNkTnVhTjczWk1ka2d5eGlVcll0Z2dp b2lCQVUKcFNzM3paS1ZnWk8xY1VzVmdTWndMK0JCTU14bUJvM3E2bjR2TmlTY2tF
QQotPiBYMjU1MTkgT1VnMFY2MHhYaVBRV0hVYU1STW5ETTZaZU5zUHJhMFJ1alJj NAotPiBYMjU1MTkgY1MrT3ZkN1pUd0JVb0JWSDByNUNRd1NUd2ZiNVJrc0JCb0J5
emVuQWozWQpHR1NQeDgzZDdGRVBGaEZ1bGl1bnBnZnFyM0NEL2E1eWx4cm1NbEsz NENrU0MySQp0bFpwRXRZcHRVdnN3eitkNHlWc0c0a0NmUjVYSVFXSVNFVHI0b0ZB
bnFNCi0+ICstZ3JlYXNlIEsofSRTLz8KQzZuTW5taUNCaWs2NHNFNHBoYkxhKzI3 U3kwCi0+IHQmKm9ERFdfLWdyZWFzZSBJIFkvRG5JIC9ZI002bmkgNX1hQHcKc2l4
ZWJGUWdmWExMbUtnalhHWWEyUjBTNzlhVFd0aUo4cU5xc2ZoeDVWTQoKLS0tIFJn S0N4YzgvK2xqZm1YVkl4ZlF1REVOTGRWOVZRQm80R2NnczlsdFlhTEd1RmVoNjZa
SjJleTVGU1o3YXhQZ1dWZHFIVm9FSE80VWdyZTg5dmhLWlhINmVWTUEKD84LkcH4 KzlkVXNpbGZsNTRybAp4RDlIWmRqR0t3VjF6WVlSeTJ4aGZBd1dDNEpMTUhZenZS
FE9srKKG3yPpq//XXR+dsm3bIUd5rYZazszxqV8XyNqKHD44azPYTqyXwfBWeEoV WjZCK0FZcXJORkJwc1piS1FvSlkzc3R5T2s3Vk0KLS0tIDFPODlkZ1BSWEhHUHJK
2vn/iMIpyCCMlSUDzDsyNvrFX48s QjdZOE1KcFNvcUYxYlFkL1FLNVJETTkySVNYRTgKOipmWGTV9SvGE4KVqgQqGw4e
CLP4PYlgdSmOATTIg32G/GVTM8NlvaII3q2GNS0Enx7Y8YwnwS2dGkYKVN3Da3b2
WJwMiBZRu/PC
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,14 +1,15 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpOcUlvZyBlODZr YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpOcUlvZyBjbUF2
RHpJcFdFaVNYM0x1d3QxVmhKTFBkMndrakFYS3FxWk00YWxXejNzCkFqWFlCWUt2 VXYyVkRud3JFU0tDQThjQlVMTTFaaW5uTkt3K2dmd1pleTFOQm5jCkNUeEVqSXVX
cGluRGtxODQzbElhRWt1TGFVeTE1UU5SSkdZejJzNVdhZ3cKLT4gc3NoLWVkMjU1 RGUxcU14Z04zMlRubVIxV0VwazhlZlFtTCtXT2dVS3l4b2MKLT4gc3NoLWVkMjU1
MTkgcytxUmZnIFRpeVNsT2Jqc2I4dzB3cEFWK2ZEZlpJQklWSnhJM3o0Ukhsc1lz MTkgcytxUmZnIG5SRTFOWWVIMU5yK3VTdkVtc0VYNnFkRXFrdEpiNTJIRHBvVnky
REZ0VFkKWWJPckVSNlZHREJIVVgwNVNBSkpSbHRPcUxIWVo4ZTlyVkovTGRpZThL OHRyWEUKVXVvZlBBR0dsUXFMa2dSZ1FWVWpvZGlwcHJ3YXRscnBoaU1FWlVFYTdt
MAotPiBYMjU1MTkgUGxhR2d3TVh1dnJwQjNoY0pjV09halZKZFhybVk3Vjk3Tmwr dwotPiBYMjU1MTkgMWlBWCtSU0I4Q1I0T0JrZ1ErYzlHRTZsUHhZQkpYQVJGNnFy
bDd5ckp6MApBcW8zbUl1SnhmOXZwOFRNUG1EZUNacDlXdXJSbWFUeG5GNjM3eXJo U3ZPeU9RTQoxaGZDYnRaNjBRRGQzMGNsTmZwcjhBRXdLeEFqVWxoT3hNNHk5cU9C
RmR3Ci0+IDstZ3JlYXNlICRoICVbfmU2fQpFYzNyZXBxVU5jT3JSY1NFMGEzUnVF Qk00Ci0+ICF8Q0EuPSIhLWdyZWFzZSBKcCp6MgpaTXQwdEllbmhRVDhOQTdpb0RU
WFQ2MmR2SGQ0Vnd6V0VxQlp5bE5LZ2NML2hyd09LOEVPL2lGREdLR3FMCmVGN09J T1VGZmdZK1VEMWdPUXduYWQ2YWx5aDFTQ3ZzRnRWbFRGN0lWUU5iQWdPakpZCnl6
OUNscVh1d0VSdwotLS0gbTB1NnZ4Q3B6WE1KVzJjbmVwL2dEVjc4WnRXZTlYbFBG MnI0SE5sS0x2MUZibW96SllDQVVOK2grRldPOWo0VSs3SkFUN1dqS3RqTTdPZG1M
T3htUHBWang2awr0OgkUO6XPZji5ZBNpqGwOlwpa605t38QCmFSXvPQhvT4Gj/0+ eHI0T1BHK1F1cWlINAotLS0gckFnWkoydklhWHZhZHBkSkN5ZmdadVdiMU1QOUZW
rUvg7zWf5Yb4c86EDD05CsqGEUQTOKEz08z0lewN5kuFfZmrYQY= VkJENWlHVWNXcEVsWQqYscIBmSi//ev3IN2ax0Ei7p8Atu4nYQui7yoY/1fiyGQL
DB5+R9Dm4YUNHt3bjrBYclLohDGdLUnOB00BXUqNmlLm4psL4Ey5Go8=
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,11 +1,11 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGhNYTRudyByTFRp YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGhNYTRudyB1N0V0
NHZMQ3BJMmt6cUhYRFMxVWNaNDc5SytSelBLMnZJZmJzLzhpSXdFCkkycmZqUzMz UW5ZKzQrSlFUMnR5QUE5N2Mzd0FvK3JCeFM2RVRtUklVQkNkU0dNCnJuUUxjQjcw
VXFGM2QvenFUQWtrQUdCc2lmbFVyZEQxNHFWeDVpR1E3WGsKLT4gWDI1NTE5IDdV NURFOFRWRG5WSnBPT1dOVjFNQWZVUjJUSU9WVTExeS9XZkEKLT4gWDI1NTE5IHdq
Zis5U3F4MjlsOHI3WHlSczNKbHkrbzJ4bzByL0ZoMC80dkV2MXpUd2cKblI0VjNE eDhJSTZKN1lQRXNaZzNIWEx4NTZINzZpdFRPZWJGcys5SUV6bmc0Q1EKeGlqTjF6
bktDV1VXa1d4SGQ3Z1ZPaXo3a3hLNHFZeXMxVHIxWFluTXlPMAotPiBvQXpvLWdy b3Y3ZWNhcjF4WlpOcXh1OHBucmNCZmp6VTI1MXRjN1FlNlA3VQotPiBtQ01Dey8t
ZWFzZSBuIFF7SnwKaHhzbXNZNXpHcXJhSytHSGdJQnNwNUkyOFEKLS0tIFZxWEFp Z3JlYXNlCnFKKys4Y0I3RkE3bzl2NDJ2aDNMeTRTUUU4dFFwelV3SjVReExnCi0t
RUZBbi9XRXRBdjZsbGFneXI2cnZzM3hNZDJhSDZHbWRGbG9ScFUKB2WtnELEus7i LSA1QSthdHR0cVE4bXhiczZqUTNJdzkzdnZ2TEpESWwwQ3BWNnoyNmp4ZXdrCl1g
27VmQAnoUhEGgVjC8tDqeDMljeXNeAU1UiZ5DcehmR4Gm2hdLoZenqWT9z/D8WcY oNwCvlTrPx5b5l0OUymxMo1HMCV9fsQ9zyaoJoPFN1hv7l4hjjX5oVoj/IdTJbbe
eQwvOK6QDikhccYA41KQ5MH0iuk= ZMs1yqa7YbR4+HG9GG8nPhU36hchSN2whoz8
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@@ -1,12 +1,11 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGhNYTRudyB5QkR2 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGhNYTRudyB6dGZN
d0dCdmd5ZUhXYWNRemRyYkJVUzA1eDE3Y1c5NFR6MzhMUzJDN1g4Clk5cjhXaGxE VDF3ME9IWWJMQUVrbmlKeXhZbzE1THUwVWhBc2ZBQXdUUkpod0FzCkVncGlyTXVv
SHFzeUt3TUlCMFBBamQ4MTRxYVlHK2NNS2ZEa1M1U3dkNGcKLT4gWDI1NTE5IEhL bmxPN0F3ODdvUmw3Sit1cERNTXN6YWZlU2IvYUhoUThER3cKLT4gWDI1NTE5IGQ2
dG9vdW1VKzlteHVuQU9sdGlvV3c4OWxiK1RpVXNZUVpnU2RjSmlmQ00KRFh2ZURH RzdCWUw2N1BHWVhiOGhvNEdzQVlUanR3emdDV3FUTFRXUDB3RDdrMmsKZDkvWWgv
NE9UbnViWXFISlUrMjdsZVNjV1pCU09vSlVndHFyaWw3cnFTZwotPiB+LG83XWM9 MFZhbHZtVDVQSWVEQ2NxQUZrOXFMVmYxbEU0STFJTVBzZm16ZwotPiB+Ty1ncmVh
MC1ncmVhc2UgJFcgdXIxSSBPClIxQlY0MUpMQjhHb3V5TzJ3NTBlbE1GWjNKbGhS c2UgMnpCPlV9ClY2TzJGcnBrbUJTU3lyNVlrNDdwYTd3Ci0tLSBHaU9ZVnZoUkx5
YnhuNlRtVFpFTVFuQ1dXTG4vV0crRmV5WWxsOWRicEh4UHoKUjRqVGduQ1NHRE14 QnE4UXhMdEg1elE1dDRoQWx4bDhBMHNwS1BlQkRaUm93CspT9YnuzfpKxC9y6SWJ
OUl5clVtdFlVVnlobGtrMUx3Ci0tLSBzcnVhRGlzaVJ3anNBTTR6NVNQd2ZOZUlL JRyT8aFEJTjoDEqN2I/DBwRikSxKyspHi7grCwFaoofylqJzsP/In7Xlf91xbMXz
TzgzSDZxaDZRRVFHRFFVZExvChMoRTQYrv8kdYqs3Ko7LzBRt17H5ljK0GIAMYNx njjXbBQQP9PG3Z2c0OHk
Gvrdv6HgzLq8gG6J4Rm/du8oyTKRjsHDS0yFuqKdbUjmckTcZurzW/qU57dNepnH
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

Some files were not shown because too many files have changed in this diff Show More