54 Commits
Author SHA1 Message Date
Greg Hellings 7243c7b1c0 fix: update gitea base URL
buildbot/nix-eval Build done. (1 warning)
buildbot/nix-build Build done.
buildbot/nix-effects Build done.
2026-08-08 01:00:46 -05:00
Greg Hellings e89b5ca5d1 fix: use IP address for nextcloud host 2026-08-08 01:00:12 -05:00
greg 076df9f924 Merge pull request 'fix: correct pve1 IP to 10.42.0.4, rename stale joel/opnsense refs' (#32) from emily/nixos:fix/pve1-ip-correction into main
buildbot/nix-eval Build done. (1 warning)
buildbot/nix-build Build done.
buildbot/nix-effects Build done.
Reviewed-on: #32
2026-08-08 05:58:50 +00:00
emily fcb5a89727 fix: correct pve1 IP to 10.42.0.4, rename stale joel/opnsense refs
buildbot/nix-eval Build done. (1 warning)
buildbot/nix-build Build done.
pve1 is a static/DHCP-reserved Proxmox host at 10.42.0.4 (previously
mislabeled 'joel' in some places). 10.42.1.1 is the UDM Pro gateway
IP, not pve1 -- OPNsense was retired in favor of Ubiquiti. Removes
the stale duplicate PVE1 DHCP reservation at 10.42.1.1 and drops the
now-redundant 'joel' entry from network.json (consolidated into
pve1).
2026-08-08 00:44:21 -05:00
Greg Hellings c9671121dd fix: restore matrix well-known server
buildbot/nix-eval Build done. (1 warning)
buildbot/nix-build Build done.
buildbot/nix-effects Build done.
2026-08-07 17:19:45 -05:00
Greg Hellings a00773c97a fix: remove builder2
buildbot/nix-eval Build done. (1 warning)
buildbot/nix-build Build done.
buildbot/nix-effects Build done.
2026-08-06 22:53:34 -05:00
Greg Hellings 6bf0bcc0ef fix: restore immich access
buildbot/nix-eval Build done. (1 warning)
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.nixos-builder2 Build done.
buildbot/nix-build Build done.
2026-08-06 21:43:28 -05:00
Greg Hellings 7619bf6258 chore: default actions packages 2026-08-06 20:36:41 -05:00
Greg Hellings 029b71d0d4 Pass traffic through genesis
* keepalived does not work with Nebula VPN
* update Genesis firewall to allow passing through local traffic
* target all traffic directly to the LAN IP using genesis's routing
2026-08-05 22:57:58 -05:00
Greg Hellings d779d275f2 Expose kubernetes on LAN 2026-08-05 20:07:35 -05:00
Greg Hellings 0196f1fd07 chore: re-enable linode gitea-runner
buildbot/nix-eval Build done. (1 warning)
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.nixos-builder2 Build done.
buildbot/nix-build Build done.
2026-08-04 10:14:56 -05:00
Greg Hellings 6a13d843d7 chore: point homepage to new registry url
buildbot/nix-eval Build done. (1 warning)
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.nixos-builder2 Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.nixos-hosea Build done.
buildbot/nix-build Build done.
2026-08-04 09:26:28 -05:00
Greg Hellings 8673d6193b chore: immich backup to Garage 2026-08-04 09:19:53 -05:00
Greg Hellings bbdfe1e1de chore: update Gitea to backup to Garage 2026-08-03 20:46:48 -05:00
Greg Hellings 71486e9ab3 chore: update Longhorn version 2026-08-03 20:46:20 -05:00
Greg Hellings 8a8664287f chore: remove gitea-runner 2026-08-03 18:56:23 -05:00
Greg Hellings 4965d42e59 chore: remove smokeping and donetick from k8s 2026-08-03 18:55:07 -05:00
Greg Hellings 03e174367d chore: uptimekuma migrated to NixOS 2026-08-03 18:52:01 -05:00
Greg Hellings 21cb84ac7a Major update for linode and Nebula
* Consolidate Linode into a single file
* Convert gitea and matrix to using Nebula connections
* Have Linode proxy to Nebula connections instead of Tailscale
* Update Acme to use DNS-01
* Update Flake to pull from branch that supports ACME 5.x client
2026-08-01 14:38:01 -05:00
Greg Hellings 1c52f8a6b9 chore: baseline nixos for proxmox configuration 2026-07-28 22:42:21 -05:00
Greg Hellings d9334a237d chore: first bit of local IP querying 2026-07-28 22:41:01 -05:00
Greg Hellings 93a847c658 chore: get kuma up and running 2026-07-28 22:40:17 -05:00
Greg Hellings b9051d017e chore: add java web start to exodus 2026-07-28 19:50:24 -05:00
Greg Hellings b9dcd227e8 chore: fix wait-forever bug in updater
buildbot/nix-eval Build done. (2 warnings)
buildbot/nix-build Build done.
buildbot/nix-effects Build done.
2026-07-27 07:27:34 -05:00
Greg Hellings 2d816d50e0 chore: update zim pins 2026-07-27 07:19:37 -05:00
Greg Hellings 5f951c6c12 chore: fix zims updater
Zims update script has been slightly mangled since nix-prefetch stopped
working.

Now it is updated to use nix-prefetch-url and no longer pulls from the
Torrent sources. That script exports a regular SHA256 hash and not an
SRI signature, so we now convert that to SRI as a second step in the
pre-fetch pipline

Also adding a cron to run the tool every month on the first, in order to
keep it up to date.
2026-07-26 21:36:46 -05:00
Greg Hellings 42efe476db chore: update framework firmware settings 2026-07-26 21:36:46 -05:00
greg 07e85d35ab Merge pull request 'chore: update flake.lock 2026-07-19' (#29) from auto/update-flake-lock-20260719 into main
buildbot/nix-eval Build done. (2 warnings)
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.hm-builder2 Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.hm-linode Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.hm-jeremiah Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.hm-zeke Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.hm-exodus Build done.
buildbot/nix-build Build done.
Reviewed-on: https://src.thehellings.com/greg/nixos/pulls/29
2026-07-25 20:54:30 +00:00
Greg Hellings b4ab1bde50 chore: cleanup defunct CA infra
buildbot/nix-eval Build done. (1 warning)
buildbot/nix-build Build done.
buildbot/nix-effects Build done.
2026-07-25 15:49:49 -05:00
Greg Hellings 4e7ca2910a chore: remove compose files that are now unused 2026-07-25 15:48:26 -05:00
Greg Hellings 64a253e9e4 chore: remove proxmoxtemplate entries as well 2026-07-25 15:48:04 -05:00
Greg Hellings e4008a0beb chore: remove icdm-root as well
buildbot/nix-eval Build done.
buildbot/nix-build Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux Build done.
buildbot/nix-build gitea:greg/nixos#checks.aarch64-darwin Build done.
buildbot/nix-build gitea:greg/nixos#checks.aarch64-linux Build done.
2026-07-25 15:45:21 -05:00
Greg Hellings 363098c0a1 chore: remove references to hermes
buildbot/nix-eval Build done.
buildbot/nix-build Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux Build done.
buildbot/nix-build gitea:greg/nixos#checks.aarch64-linux Build done.
buildbot/nix-build gitea:greg/nixos#checks.aarch64-darwin Build done.
2026-07-25 15:43:27 -05:00
Greg Hellings a07068a4fb chore: remove unused attic reference
buildbot/nix-eval Build done.
buildbot/nix-build Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux Build done.
buildbot/nix-build gitea:greg/nixos#checks.aarch64-linux Build done.
buildbot/nix-build gitea:greg/nixos#checks.aarch64-darwin Build done.
2026-07-25 15:39:30 -05:00
Greg Hellings ec53199532 chore: remove attic-client 2026-07-25 15:38:40 -05:00
Greg Hellings 389798c4f0 chore: buildbot over Nebula 2026-07-25 15:38:28 -05:00
Greg Hellings 475fe50d19 Expand Nebula
* Add Nebula to Kubernetes node
* Update k3s nodes to support nebula keepalived
* Move external IPs to a separate structure
2026-07-25 15:18:15 -05:00
Greg Hellings 0d1d846884 chore: update deprecated nushell pipe 2026-07-25 13:49:47 -05:00
klaatuandgreg 1d9921f1ae chore: update flake.lock 2026-07-19
buildbot/nix-eval Build done. (2 warnings)
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.pkg-setup-ssh Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.hm-builder2 Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.hm-icdm-root Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.hm-hermes Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.hm-linode Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.hm-jeremiah Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.hm-zeke Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.hm-exodus Build done.
buildbot/nix-build Build done.
2026-07-25 17:06:07 +00:00
Greg Hellings 7388715d30 chore: where possible, use nebula 2026-07-25 12:05:07 -05:00
Greg Hellings b3304c0ef5 chore: migrate to Garage 2026-07-25 11:40:35 -05:00
Greg Hellings e955ea82f3 fix: update hermes secrets
buildbot/nix-eval Build done. (1 warning)
buildbot/nix-build Build done.
buildbot/nix-effects Build done.
2026-07-21 20:50:07 -05:00
Greg Hellings 067c00330b chore: enable Hermes agent Matrix connection
buildbot/nix-eval Build done.
2026-07-21 20:49:26 -05:00
Greg Hellings 60e2450c66 chore: proxy hermes dashboard
buildbot/nix-eval Build done. (1 warning)
buildbot/nix-build Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.nixos-hermes Build done.
2026-07-21 20:04:23 -05:00
Greg Hellings 3185a5a375 chore: add tools to Exodus 2026-07-21 19:21:10 -05:00
Greg Hellings 348a1d7301 fix: get Hermes host built
buildbot/nix-eval Build done. (1 warning)
buildbot/nix-build Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.nixos-hermes Build done.
2026-07-21 19:07:39 -05:00
Greg Hellings 33eda7d2cb chore: add hermes key secret
buildbot/nix-eval Build done.
2026-07-21 18:57:47 -05:00
Greg Hellings 34ca5aec6b chore: add nebluaIps nushell function
buildbot/nix-eval Build done. (1 warning)
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.nixos-hermes Build done.
buildbot/nix-build Build done.
2026-07-21 17:17:04 -05:00
Greg Hellings d2f7b85283 chore: bring hermes into nebula 2026-07-21 17:16:37 -05:00
Greg Hellings d12ef9faec chore: rekey to add hermes visibility 2026-07-21 16:15:32 -05:00
Greg Hellings 3e60f73251 chore: initial configuration for Hermes
buildbot/nix-eval Build done.
buildbot/nix-build gitea:greg/nixos#checks.aarch64-darwin Build done.
buildbot/nix-build gitea:greg/nixos#checks.aarch64-linux.pkg-hms Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux Build done.
buildbot/nix-build gitea:greg/nixos#checks.aarch64-linux.pkg-dockerCompat Build done.
buildbot/nix-build gitea:greg/nixos#checks.aarch64-linux.pkg-create_ssl Build done.
buildbot/nix-build gitea:greg/nixos#checks.aarch64-linux.pkg-adblock_update Build done.
buildbot/nix-build gitea:greg/nixos#checks.aarch64-linux.pkg-gcc-tune Build done.
buildbot/nix-build gitea:greg/nixos#checks.aarch64-linux.pkg-inject Build done.
buildbot/nix-build gitea:greg/nixos#checks.aarch64-linux.pkg-inject-darwin Build done.
buildbot/nix-build Build done.
buildbot/nix-build gitea:greg/nixos#checks.aarch64-linux.pkg-setup-ssh Build done.
buildbot/nix-build gitea:greg/nixos#checks.aarch64-linux.pkg-upgrade-pg-cluster Build done.
2026-07-21 16:11:39 -05:00
Greg Hellings bc986f0e51 chore: add hermes
buildbot/nix-eval Build done. (1 warning)
buildbot/nix-build Build done.
buildbot/nix-effects Build done.
2026-07-21 16:00:52 -05:00
Greg Hellings 214f6a4d2a chore: add bmc IP addresses
buildbot/nix-eval Build done. (1 warning)
buildbot/nix-build Build done.
buildbot/nix-effects Build done.
2026-07-20 08:50:03 -05:00
Greg Hellings 41d02d19ea chore: forward ssh-agent 2026-07-13 20:04:00 -05:00
133 changed files with 1617 additions and 2281 deletions
+51
View File
@@ -0,0 +1,51 @@
name: Update zims pin
"on":
schedule:
- cron: "0 2 1 * *" # 0200 on the first of every month
workflow_dispatch:
jobs:
update-flake-lock:
runs-on: nix-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Update flake.lock
run: nix run .#zim-updater -- --output pkgs/zim/blobs.json
- name: Create PR if changed
env:
GITEA_TOKEN: ${{ secrets.KLAATU_TOKEN }}
GITEA_URL: https://src.thehellings.com
REPO: greg/nixos
run: |
if git diff --quiet pkgs/zim/blobs.json; then
echo "blobs.json unchanged, nothing to do"
exit 0
fi
BRANCH="auto/update-zims-$(date +%Y%m%d)"
git config user.email "klaatu@thehellings.com"
git config user.name "klaatu"
git checkout -b "$BRANCH"
git add pkgs/zim/blobs.json
git commit -m "chore: update zim blobs.json $(date +%Y-%m-%d)"
# Push branch using token auth
git remote set-url origin "https://klaatu:${GITEA_TOKEN}@${GITEA_URL#https://}/${REPO}.git"
git push origin "$BRANCH"
# Create PR via Gitea API
curl -s -X POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
"${GITEA_URL}/api/v1/repos/${REPO}/pulls" \
-d "{
\"title\": \"chore: update zims $(date +%Y-%m-%d)\",
\"head\": \"$BRANCH\",
\"base\": \"main\",
\"body\": \"Automated monthly zims update.\\n\\nGenerated by Gitea Actions.\",
\"assignees\": [\"greg\"]
}"
-12
View File
@@ -1,12 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIByDCCAW+gAwIBAgIRANS+dPEH5Vqug7OWhCMmcx4wCgYIKoZIzj0EAwIwLjER
MA8GA1UEChMISGVsbGluZ3MxGTAXBgNVBAMTEEhlbGxpbmdzIFJvb3QgQ0EwHhcN
MjQwMjIwMjEyNzIxWhcNMzQwMjE3MjEyNzIxWjA2MREwDwYDVQQKEwhIZWxsaW5n
czEhMB8GA1UEAxMYSGVsbGluZ3MgSW50ZXJtZWRpYXRlIENBMFkwEwYHKoZIzj0C
AQYIKoZIzj0DAQcDQgAErZUhPfx5MpNbNVyqHDrIgUGnb6Hitl8hXlpH+kgjBzCi
7I/+TQnl9Tc0VVNOFOYLOfBi7hV3/QudUtLGk0FKeaNmMGQwDgYDVR0PAQH/BAQD
AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFMZR8LDd+hNy+TmtEHvt
zRzXboh2MB8GA1UdIwQYMBaAFAlH11TwIFGB/K75qZ3e0S+fN3JUMAoGCCqGSM49
BAMCA0cAMEQCIBxHK6r8pMX5hrTwYKRfMmRIt44m0KtNejA2T5t09hs+AiBfvmHb
LfoE4qoC6NgpvXorAbx+O7xkem/9svF0Ob+RsA==
-----END CERTIFICATE-----
-11
View File
@@ -1,11 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIBoTCCAUagAwIBAgIRAL/1mvE8+73nRFGsvzaaVSAwCgYIKoZIzj0EAwIwLjER
MA8GA1UEChMISGVsbGluZ3MxGTAXBgNVBAMTEEhlbGxpbmdzIFJvb3QgQ0EwHhcN
MjQwMjIwMjEyNzIwWhcNMzQwMjE3MjEyNzIwWjAuMREwDwYDVQQKEwhIZWxsaW5n
czEZMBcGA1UEAxMQSGVsbGluZ3MgUm9vdCBDQTBZMBMGByqGSM49AgEGCCqGSM49
AwEHA0IABEgNBjlT/7gmzNp9vKJvGPJn9/IizuMGVpucdrN9+J1u1ABkLNRzj5p2
g7s3e/BG+EJnnTf/2tuq3p/wPqmQkdujRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNV
HRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBQJR9dU8CBRgfyu+amd3tEvnzdyVDAK
BggqhkjOPQQDAgNJADBGAiEA/uBclcFCOpkEgAeBAVurktYB82sMdIyyDGHcjlwi
pvkCIQC2kuZ/nXRjibeIebQIVTBskQ1LxlLxnx7zNSjtr3kFfQ==
-----END CERTIFICATE-----
-54
View File
@@ -1,54 +0,0 @@
services:
attic:
container_name: attic
image: ghcr.io/zhaofengli/attic:latest
command: ["-f", "/attic/server.toml"]
restart: unless-stopped
ports:
- 8080:8080
networks:
attic:
pgattic:
volumes:
- /mnt/all/configs/attic/server.toml:/attic/server.toml
- /mnt/all/containers/attic/data:/attic/storage
env_file:
- stack.env
depends_on:
pgattic:
condition: service_healthy
healthcheck:
test:
[
"CMD-SHELL",
"wget --no-verbose --tries=1 --spider http://attic:8080 || exit 1",
]
interval: 15s
timeout: 10s
retries: 10
start_period: 15s
deploy:
resources:
reservations:
cpus: 1.0
pgattic:
container_name: pgattic
image: postgres:17.6-alpine
restart: unless-stopped
ports: []
networks:
pgattic:
volumes:
- /mnt/all/containers/attic/postgres:/var/lib/postgresql/data
env_file:
- stack.env
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
networks:
attic:
pgattic:
-9
View File
@@ -1,9 +0,0 @@
services:
pinchflat:
image: ghcr.io/kieraneglin/pinchflat:latest
ports:
- "8945:8945"
volumes:
- "/mnt/all/configs/pinchflat:/config"
- "/mnt/all/video/yt:/downloads"
restart: unless-stopped
-19
View File
@@ -1,19 +0,0 @@
# Demo of rest-server with prometheus and grafana
version: "2"
services:
restserver:
image: "restic/rest-server:0.14.0"
volumes:
- /mnt/all/backups:/data
- /mnt/all/configs/certs:/certs
environment:
OPTIONS: >-
--tls
--tls-cert /certs/nas1.shire-zebra.ts.net.crt
--tls-key /certs/nas1.shire-zebra.ts.net.key
--path /data
--prometheus
--debug
ports:
- "30248:8000"
Generated
+57 -57
View File
@@ -31,11 +31,11 @@
"treefmt-nix": "treefmt-nix" "treefmt-nix": "treefmt-nix"
}, },
"locked": { "locked": {
"lastModified": 1783231291, "lastModified": 1783833875,
"narHash": "sha256-iaoW3Enrb51mCT4AIixKXgkb1LdI/ikpCV9sV+zmkYU=", "narHash": "sha256-G+hRtNJ/Nnr6VFMQp2UZdx/ckJDR/RJoK0Fy/yx1/YY=",
"owner": "nix-community", "owner": "nix-community",
"repo": "buildbot-nix", "repo": "buildbot-nix",
"rev": "d8a926f66587ed37df1a422205d7aeb1692700f8", "rev": "147af587241e2af85399402da60a4f44fdb1e5d7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -53,11 +53,11 @@
"stable": "stable" "stable": "stable"
}, },
"locked": { "locked": {
"lastModified": 1783265280, "lastModified": 1783909498,
"narHash": "sha256-n+TVzNkFtsW+ghl7JeFJYwIbXaZ2tn/WgjVMXwlzybI=", "narHash": "sha256-T9OfLPLuh1Bf1xojlpWXwooJ6IXapxvb8GM0p3YNy8g=",
"owner": "zhaofengli", "owner": "zhaofengli",
"repo": "colmena", "repo": "colmena",
"rev": "e4250e61da7e007e19e8e17d8675b88ad27d6c06", "rev": "76ba0daa542880b730faec81f4e87efcaa63bc57",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -95,11 +95,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1783395956, "lastModified": 1784362797,
"narHash": "sha256-AAbexQvDoK+6GFJdhY6kqjA+6ECKRkidgWxkn4gMwAA=", "narHash": "sha256-EP9b9b+OXDxHBPefFwMYCIaLq0fn3UkmrbfzbLUT7kQ=",
"owner": "lnl7", "owner": "lnl7",
"repo": "nix-darwin", "repo": "nix-darwin",
"rev": "d5bd9cd77aea4c0a8f49e7fd85545671a208ed15", "rev": "b4cccbd4bc299c1f71ae185b79c3cf99aa82805c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -242,11 +242,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1783436070, "lastModified": 1784407317,
"narHash": "sha256-F80z1JoiJgZyTT5D+3siLOVzqmCEphLR7t0Ym/I2CLI=", "narHash": "sha256-iZrxHToDJWnvt+5LGAtvuQMTy1NZYlNEKbKaVtBJNcc=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "f09af49406ffad37acb6538d3207189a1a1e0b7e", "rev": "39411a8e12a5526d992e65bc7e3dc9a4414d6713",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -284,11 +284,11 @@
"systems": "systems_3" "systems": "systems_3"
}, },
"locked": { "locked": {
"lastModified": 1783397047, "lastModified": 1784344393,
"narHash": "sha256-aXPvDeF7F0sKg2MWglAtSz6h1R6a9+V7Y2k24At2Q9o=", "narHash": "sha256-yAo2ZzSIdeBZg7cOKUpQxwflL+DRYN+1DMObZk2lP2Q=",
"owner": "Infinidoge", "owner": "Infinidoge",
"repo": "nix-minecraft", "repo": "nix-minecraft",
"rev": "ed748d3593082a7e02d2c49b7643ecac3a7efde4", "rev": "7297d14c52ec8ef39c6aeff2c1818541fd030473",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -303,11 +303,11 @@
"treefmt-nix": "treefmt-nix_2" "treefmt-nix": "treefmt-nix_2"
}, },
"locked": { "locked": {
"lastModified": 1783166611, "lastModified": 1784016977,
"narHash": "sha256-8xyWfpItjSdMiR2bRdUf+Nj1T1Vdctgn4K7jVUyAaOk=", "narHash": "sha256-TydDba3YD2u15uS0L+PDs7lMqPopnzWggljTKDqOCSw=",
"owner": "Mic92", "owner": "Mic92",
"repo": "niks3", "repo": "niks3",
"rev": "b45810677be67de714cbb4ff53f036bdb2e5f9a0", "rev": "b306808bf381e7e66e33de1e9446a1be0935f4e3",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -342,11 +342,11 @@
"nixpkgs": "nixpkgs_4" "nixpkgs": "nixpkgs_4"
}, },
"locked": { "locked": {
"lastModified": 1783370751, "lastModified": 1784310968,
"narHash": "sha256-E+3MIMvKuo9k+K+qLQ9YXzsBzkgHuyVLnsEbN2DFfuc=", "narHash": "sha256-rkSPTePrKqs4dg+i7ZFCq93+HrClac6oSwXX927SVjA=",
"owner": "nixos", "owner": "nixos",
"repo": "nixos-hardware", "repo": "nixos-hardware",
"rev": "662bd6e312d2c8b212e32cb377abaee190749320", "rev": "779c32a00155994c86cde8213a8dd4df139d4355",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -357,11 +357,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1782723713, "lastModified": 1783224372,
"narHash": "sha256-oPXCU/SSUokcGaJREHibG1CBX3+s/W7orDWQOZDsEeQ=", "narHash": "sha256-8i/87eeoqiGE4yOTjwSA3Eh/ziJRQEmd/unYU+K27sk=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "b5aa0fbd538984f6e3d201be0005b4463d8b09f8", "rev": "d407951447dcd00442e97087bf374aad70c04cea",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -388,11 +388,11 @@
}, },
"nixpkgs-lib_2": { "nixpkgs-lib_2": {
"locked": { "locked": {
"lastModified": 1783217952, "lastModified": 1783821755,
"narHash": "sha256-lItVCcSNUiL9NlB0+VoZwhtZk+0jAnfjJjch1g7U0bM=", "narHash": "sha256-eMPX9S6MKPyUnaOgeRfrG7OKUiAlc1AlcRinMbSB0WA=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nixpkgs.lib", "repo": "nixpkgs.lib",
"rev": "830143f1e74a5ce8aa6cdad9c41ae84b73e8b3be", "rev": "228ab8523d81526e57a6ca342e1a919fb6d246a8",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -419,11 +419,11 @@
}, },
"nixpkgs_3": { "nixpkgs_3": {
"locked": { "locked": {
"lastModified": 1782774429, "lastModified": 1783978241,
"narHash": "sha256-1tRFhlVVSBP2UAyJ4fWV3wRxofOZQCIWmbXJS/kQw7U=", "narHash": "sha256-7kK0Y/fIV2NTKArkd/eZGaFg+dEmgP8KDRsGK2vB5M4=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "c3db893991ef9cf1902c661c2d61249bcfb051dc", "rev": "a8b81d3cc8d35af7bc98694696bea61ad4f8fca7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -448,11 +448,11 @@
}, },
"nixpkgs_5": { "nixpkgs_5": {
"locked": { "locked": {
"lastModified": 1783279667, "lastModified": 1783915482,
"narHash": "sha256-/NAkDSsve+GNM0Bt6tleJdCGfsTlK89nPjkVOzZMo0s=", "narHash": "sha256-FmieJB8/OUvNxbkboi7+IGfIuSXY3nF/hZQm8kD0r50=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "f205b5574fd0cb7da5b702a2da51507b7f4fdd1b", "rev": "6cdc7fc76e8bf7fde9fa43a849fcaaa70e230dee",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -464,11 +464,11 @@
}, },
"nixpkgs_6": { "nixpkgs_6": {
"locked": { "locked": {
"lastModified": 1783224372, "lastModified": 1784356753,
"narHash": "sha256-8i/87eeoqiGE4yOTjwSA3Eh/ziJRQEmd/unYU+K27sk=", "narHash": "sha256-12KrbMiWLcf8m7pCvAtZh1ZrgF85ZXDXvfR/fWTKy84=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "d407951447dcd00442e97087bf374aad70c04cea", "rev": "61b7c44c4073f0b827768aff0049561b5110ea5a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -496,16 +496,16 @@
}, },
"nixunstable": { "nixunstable": {
"locked": { "locked": {
"lastModified": 1783224372, "lastModified": 1784700541,
"narHash": "sha256-8i/87eeoqiGE4yOTjwSA3Eh/ziJRQEmd/unYU+K27sk=", "narHash": "sha256-LcCdjhqwjFVrFTNW6tHm3KNYRrD1TA6bYRea30yIIjw=",
"owner": "nixos", "owner": "geri1701",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "d407951447dcd00442e97087bf374aad70c04cea", "rev": "3c598184d1f70c5d0beeea8b95d01ab0179e4ef7",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nixos", "owner": "geri1701",
"ref": "nixos-unstable", "ref": "lego-v5-acme-spike",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@@ -517,11 +517,11 @@
"systems": "systems_4" "systems": "systems_4"
}, },
"locked": { "locked": {
"lastModified": 1783349931, "lastModified": 1784057377,
"narHash": "sha256-aYE76ATiGBg7/cQ2dHASRq97WvNum4OOIPgZ8xIK0QI=", "narHash": "sha256-yycNej5//EsRbV10moBoh+/63vXEwZD1ZFEiRm6C9rQ=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nixvim", "repo": "nixvim",
"rev": "4fd45857deecb90d2732c87e0315daa48505515e", "rev": "07180a087e4a00720dc0731cbcd8dec796974381",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -537,11 +537,11 @@
"nixpkgs": "nixpkgs_6" "nixpkgs": "nixpkgs_6"
}, },
"locked": { "locked": {
"lastModified": 1783451984, "lastModified": 1784417922,
"narHash": "sha256-pOIx6pF9DJCeGuDostAegvtmWhbX0ze0bLCzXYHkt94=", "narHash": "sha256-19XZ56wJXArMKxjY25pKXkNp/FrYHGoo+HuQtW6teSM=",
"owner": "nix-community", "owner": "nix-community",
"repo": "NUR", "repo": "NUR",
"rev": "9d0a05bf73440e7e870c011a6c16e7e8636d98fd", "rev": "2c806d314605495dd7fd75b5950003a062e2b47a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -571,11 +571,11 @@
}, },
"stable": { "stable": {
"locked": { "locked": {
"lastModified": 1783021296, "lastModified": 1783625654,
"narHash": "sha256-WYOmcI0zSkkU4VpR7xda8o0AWNC9xuqkEM7n4tKjJY8=", "narHash": "sha256-pI1244/PJfTyKhlAr2QYQC55vR6UQdnGA0rJUgtO2IQ=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "d3474199ff806484bfccd1fdef7afc27fb8d74b5", "rev": "a0230bd8d5cbd13893b2263918d396a2c7dd0407",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -693,11 +693,11 @@
"nixpkgs": "nixpkgs_7" "nixpkgs": "nixpkgs_7"
}, },
"locked": { "locked": {
"lastModified": 1783396462, "lastModified": 1784343266,
"narHash": "sha256-0Q3WQGlhzTb6QAXnmleX55Pqn+La4lcXupW1ElN/gZI=", "narHash": "sha256-EGkegdTz2n6ESyih8s3dUuPyJQWlYfPp7U41J05g8PY=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nix-vscode-extensions", "repo": "nix-vscode-extensions",
"rev": "98798c612761584740eed894f3ca1e1a1a856ac0", "rev": "472a3e862c76c64ac3ad75a24d332cb5cdd5f1bb",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -714,11 +714,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1783336371, "lastModified": 1784058842,
"narHash": "sha256-ZisTtweyb7JUwPP54HAXE9TypT8m89dIxDI36Ak0hAs=", "narHash": "sha256-3u3tvbCIAid3Mv7RrJx13jusIEQC/HeKYhO/SUSxR3A=",
"owner": "nix-community", "owner": "nix-community",
"repo": "NixOS-WSL", "repo": "NixOS-WSL",
"rev": "a9620cfa43f0c1c30a46c31ae3c6e58cdb124a14", "rev": "24c8dc8e0f2170e1a377be24dfadc7d9d21dc1ad",
"type": "github" "type": "github"
}, },
"original": { "original": {
+3 -2
View File
@@ -28,7 +28,8 @@
nix-hardware.url = "github:nixos/nixos-hardware"; nix-hardware.url = "github:nixos/nixos-hardware";
nixpkgs-lib.url = "github:nix-community/nixpkgs.lib"; nixpkgs-lib.url = "github:nix-community/nixpkgs.lib";
nixvimunstable.url = "github:nix-community/nixvim/main"; nixvimunstable.url = "github:nix-community/nixvim/main";
nixunstable.url = "github:nixos/nixpkgs/nixos-unstable"; #nixunstable.url = "github:nixos/nixpkgs/nixos-unstable";
nixunstable.url = "github:geri1701/nixpkgs/lego-v5-acme-spike";
nurpkgs.url = "github:nix-community/NUR"; nurpkgs.url = "github:nix-community/NUR";
vsext.url = "github:nix-community/nix-vscode-extensions"; vsext.url = "github:nix-community/nix-vscode-extensions";
wsl = { wsl = {
@@ -100,7 +101,7 @@
{ {
deployment = { deployment = {
inherit (v) tags; inherit (v) tags;
targetHost = v.ts; targetHost = if (v ? "connectAddr") then v.connectAddr else v.nebulaIp;
targetUser = "greg"; targetUser = "greg";
}; };
} }
+42 -1
View File
@@ -12,6 +12,46 @@ def --env unlock [] {
} }
} }
def nebulaIps [] {
open /etc/nixos/network.json | get hosts | items { |h, e| $e.nebulaIp? } | where $it != null | sort
}
def localIps [] {
open /etc/nixos/network.json | get hosts | items { |h, e| $e.ip? } | where $it != null | sort
}
def genNebulaCert [ --ips: string, --name: string ] {
let public = $'~/SynologyDrive/nebula/($name).key.pub' | path expand
let private = $'~/SynologyDrive/nebula/($name).key' | path expand
let cert = $'/etc/nixos/secrets/nebula/($name).crt'
let ca_cert = '~/SynologyDrive/nebula/ca.crt' | path expand
let ca_key = '~/SynologyDrive/nebula/ca.key' | path expand
# Generate public key if there isn't one already
if ( not ($public | path exists) ) {
nebula-cert keygen -out-key $private -out-pub $public
}
# Clear old cert if there is one
if ( $cert | path exists) {
rm $cert
}
# Create and sign certs
(nebula-cert sign
-ca-crt $ca_cert
-ca-key $ca_key
-name $name
-networks $ips
-out-crt $cert
-in-pub $public
)
# Agenix update
cd /etc/nixos/secrets
cat $private | agenix -e $'nebula/($name).key.age'
}
def rebuild [ $target: string = "switch" ] { def rebuild [ $target: string = "switch" ] {
if (uname | get operating-system) == "Darwin" { if (uname | get operating-system) == "Darwin" {
sudo darwin-rebuild $target sudo darwin-rebuild $target
@@ -35,7 +75,8 @@ def deploy [ $host: string, $build: string = "" ] {
if $buildhost == "linode" or $buildhost == "genesis" { if $buildhost == "linode" or $buildhost == "genesis" {
$buildhost = "isaiah" $buildhost = "isaiah"
} }
nixos-rebuild switch --sudo --use-substitutes --target-host $host --build-host $buildhost colmena apply --on $host
#nixos-rebuild switch --sudo --use-substitutes --target-host $host --build-host $buildhost
} }
def ff [ $file: string ] { def ff [ $file: string ] {
+5 -2
View File
@@ -27,9 +27,12 @@
"*" = { "*" = {
DynamicForward = [ "10240" ]; DynamicForward = [ "10240" ];
ServerAliveInterval = 60; ForwardAgent = "yes";
LogLevel = "error"; LogLevel = "error";
SetEnv = { TERM = "xterm-256color"; }; ServerAliveInterval = 60;
SetEnv = {
TERM = "xterm-256color";
};
}; };
"10.42.1.4" = lib.hm.dag.entryBefore [ "10.42.*" ] nas; "10.42.1.4" = lib.hm.dag.entryBefore [ "10.42.*" ] nas;
-1
View File
@@ -8,7 +8,6 @@
home.packages = home.packages =
with pkgs; with pkgs;
[ [
attic-client
dig dig
jqp jqp
kubernetes-helm kubernetes-helm
+3
View File
@@ -23,9 +23,12 @@
mattermost-desktop mattermost-desktop
minio-client minio-client
mumble mumble
nebula
nix-index nix-index
adoptopenjdk-icedtea-web
pre-commit pre-commit
prismlauncher prismlauncher
rclone
restic restic
restic-browser restic-browser
tea tea
-4
View File
@@ -1,4 +0,0 @@
{ ... }:
{
}
+1
View File
@@ -30,6 +30,7 @@ let
modules = [ modules = [
{ {
nixpkgs.hostPlatform = system; nixpkgs.hostPlatform = system;
networking.hostName = name;
} }
# Imported ones # Imported ones
top.agenix.nixosModules.default top.agenix.nixosModules.default
-19
View File
@@ -1,19 +0,0 @@
{ config, modulesPath, pkgs, lib, ... }:
{
imports = [ (modulesPath + "/virtualisation/proxmox-lxc.nix") ];
nix.settings = { sandbox = false; };
proxmoxLXC = {
manageNetwork = false;
privileged = true;
};
services.fstrim.enable = false; # Let Proxmox host handle fstrim
services.openssh = {
enable = true;
openFirewall = true;
settings = {
PermitRootLogin = "yes";
PasswordAuthentication = true;
PermitEmptyPasswords = "yes";
};
};
}
+1 -5
View File
@@ -9,13 +9,9 @@
{ {
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
top.nix-hardware.nixosModules.framework-11th-gen-intel top.nix-hardware.nixosModules.framework-intel-core-ultra-series1
]; ];
age.secrets = {
compose-attic.file = ../../../secrets/compose/attic.env.age;
};
boot = { boot = {
loader = { loader = {
systemd-boot = { systemd-boot = {
+2 -3
View File
@@ -1,12 +1,11 @@
# Local hosts # Local hosts
10.42.0.1 switch switch.thehellings.lan # Core switch for the network 10.42.0.1 switch switch.thehellings.lan # Core switch for the network
10.42.0.3 ap ap.thehellings.lan # OpenWRT access point (static IP) 10.42.0.3 ap ap.thehellings.lan # OpenWRT access point (static IP)
10.42.0.4 joel.thehellings.lan # Proxmox 10.42.0.4 pve1.thehellings.lan # Proxmox
10.42.0.5 sanswitch.thehellings.lan # Core switch for the SAN 10.42.0.5 sanswitch.thehellings.lan # Core switch for the SAN
# Home servers # Home servers
10.42.1.1 pve1.thehellings.lan 10.42.1.1 udm router udm.thehellings.lan router.thehellings.lan # Ubiquiti UDM gateway
10.42.1.2 opnsense router opnsense.thehellings.lan router.thehellings.lan
10.42.1.3 printer.thehellings.lan 10.42.1.3 printer.thehellings.lan
10.42.1.4 chronicles chronicles.thehellings.lan nas.thehellings.lan s3.thehellings.lan 10.42.1.4 chronicles chronicles.thehellings.lan nas.thehellings.lan s3.thehellings.lan
10.42.1.5 genesis genesis.thehellings.lan dns dns.thehellings.lan smart smart.thehellings.lan speedtest.thehellings.lan nixcache.thehellings.lan gitcache.thehellings.lan 10.42.1.5 genesis genesis.thehellings.lan dns dns.thehellings.lan smart smart.thehellings.lan speedtest.thehellings.lan nixcache.thehellings.lan gitcache.thehellings.lan
+4 -4
View File
@@ -77,7 +77,7 @@ in
}; };
}; };
firewall = { firewall = {
enable = false; enable = true;
allowedUDPPorts = [ allowedUDPPorts = [
dhcpPort dhcpPort
dnsPort dnsPort
@@ -88,7 +88,7 @@ in
80 80
]; ];
}; };
nftables.enable = false; nftables.enable = true;
}; };
environment.etc."hosts.d/local".text = extraHosts; environment.etc."hosts.d/local".text = extraHosts;
@@ -130,10 +130,10 @@ in
lib.mapAttrs lib.mapAttrs
(domain: net: { (domain: net: {
master = true; master = true;
file = makeZoneFile (lib'.hostsByNet net metadata.hosts) domain; file = makeZoneFile (lib'.hostsByNet net (metadata.hosts // metadata.external)) domain;
}) })
{ {
#"shire-zebra.ts.net" = "tailscale"; "shire-zebra.ts.net" = "tailscale";
"nebula.thehellings.com" = "nebula"; "nebula.thehellings.com" = "nebula";
nebula = "nebula"; nebula = "nebula";
"thehellings.lan" = "lan"; "thehellings.lan" = "lan";
+1 -5
View File
@@ -60,7 +60,7 @@
reservations = [ reservations = [
# Static IPs for personal work # Static IPs for personal work
{ {
hw-address = "00:23:24:72:64:32"; # Joel hw-address = "00:23:24:72:64:32"; # PVE1
ip-address = "10.42.0.4"; ip-address = "10.42.0.4";
} }
{ {
@@ -76,10 +76,6 @@
#ip-address = "10.42.2.253"; #ip-address = "10.42.2.253";
ip-address = "10.42.100.6"; ip-address = "10.42.100.6";
} }
{
hw-address = "7c:83:34:b9:ee:ec"; # PVE1
ip-address = "10.42.1.1";
}
{ {
hw-address = "74:ee:2a:66:b3:51"; # printer hw-address = "74:ee:2a:66:b3:51"; # printer
ip-address = "10.42.1.3"; ip-address = "10.42.1.3";
+1 -1
View File
@@ -185,7 +185,7 @@ in
s3 = { s3 = {
accessKeyFile = config.age.secrets.niks3-access-key-id.path; accessKeyFile = config.age.secrets.niks3-access-key-id.path;
bucket = "niks3"; bucket = "niks3";
endpoint = "nas1.shire-zebra.ts.net:9000"; endpoint = "nas1.shire-zebra.ts.net:30188";
secretKeyFile = config.age.secrets.niks3-secret-access-key.path; secretKeyFile = config.age.secrets.niks3-secret-access-key.path;
useSSL = false; useSSL = false;
}; };
-11
View File
@@ -1,11 +0,0 @@
{ ... }:
{
# Bootloader.
boot = {
loader.grub = {
enable = true;
device = "/dev/sda";
};
};
}
-28
View File
@@ -1,28 +0,0 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ pkgs, ... }:
{
imports = [
# Include the results of the hardware scan.
./hardware-configuration.nix
./boot.nix
./filesystem.nix
./location.nix
./networking.nix
./wiki.nix
];
# Define a user account. Don't forget to set a password with passwd.
users.users.greg = {
isNormalUser = true;
description = "Gregory Hellings";
extraGroups = [
"networkmanager"
"wheel"
];
packages = with pkgs; [ ];
};
}
-13
View File
@@ -1,13 +0,0 @@
{ ... }:
let
in
{
fileSystems."serve" = {
#device = "10.42.1.4:/volume1/icdm-mysql/";
#fsType = "nfs";
device = "/dev/sdb1";
fsType = "auto";
mountPoint = "/srv";
};
}
@@ -1,53 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
modulesPath,
...
}:
{
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
boot.initrd.availableKernelModules = [
"xhci_pci"
"ehci_pci"
"ahci"
"usbhid"
"usb_storage"
"sd_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" = {
device = "/dev/disk/by-uuid/dab0d455-e25e-4445-8fa4-5320047d7e7b";
fsType = "btrfs";
options = [ "subvol=@" ];
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/5aedbb07-5761-423b-909d-2560405eae32";
fsType = "ext4";
};
fileSystems."/var" = {
device = "/dev/disk/by-uuid/57968536-c29d-417d-997e-85223d1d1f65";
fsType = "btrfs";
};
swapDevices = [ { device = "/dev/disk/by-uuid/09691dce-375a-43c6-8d40-4498d20a6d9a"; } ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.eno1.useDHCP = lib.mkDefault true;
# networking.interfaces.wlp2s0.useDHCP = lib.mkDefault true;
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}
-15
View File
@@ -1,15 +0,0 @@
{ ... }:
{
# Set your time zone.
time.timeZone = "America/Chicago";
# Select internationalisation properties.
i18n.defaultLocale = "en_US.UTF-8";
# Configure keymap in X11
services.xserver.xkb = {
layout = "us";
variant = "";
};
}
-63
View File
@@ -1,63 +0,0 @@
{ ... }:
let
dnsHosts = builtins.concatStringsSep "\n" [ "wiki.icdm.lan 10.42.101.1" ];
in
{
# If we have to do proxying in Bayonnais, we can start to work on that here
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
networking = {
hostName = "icdm-root";
useDHCP = false;
defaultGateway = "10.42.1.1";
nameservers = [
"100.100.100.100"
"10.42.1.2"
];
enableIPv6 = false;
interfaces = {
eno1.ipv4.addresses = [
{
address = "10.42.101.1";
prefixLength = 16;
}
{
address = "10.77.1.2";
prefixLength = 16;
}
];
};
# Allow traffic through
firewall = {
enable = true;
allowedTCPPorts = [ 53 ];
allowedUDPPorts = [
53
67
];
};
extraHosts = "${dnsHosts}";
};
services.dnsmasq = {
enable = true;
settings = {
domain = "icdm.lan";
dhcp-range = [ "eno1,10.77.1.10,10.77.1.255,255.255.0.0,12h" ];
dhcp-option = [
"eno1,option:router,10.77.1.1"
"eno1,option:dns-server,10.77.1.2,1.1.1.1"
"eno1,option:domain-search,icdm.lan"
];
expand-hosts = true;
log-dhcp = true;
log-queries = true;
# Upstream servers
server = [
"1.1.1.1"
"8.8.4.4"
];
};
};
}
-17
View File
@@ -1,17 +0,0 @@
{ pkgs, ... }:
let
wikiHost = "wiki.icdm.lan";
kiwixport = 8080;
in
{
services.kiwix-serve = {
enable = true;
port = kiwixport;
library = {
inherit (pkgs) zim;
};
};
greg.proxies."${wikiHost}".target = "http://localhost:${toString kiwixport}";
networking.firewall.allowedTCPPorts = [ 80 ];
}
+4
View File
@@ -47,6 +47,10 @@
enable = true; enable = true;
extraLabels = [ "bare-metal:host" ]; extraLabels = [ "bare-metal:host" ];
}; };
vmdev = {
enable = true;
host = "libvirt";
};
}; };
networking = { networking = {
+4 -3
View File
@@ -88,6 +88,7 @@ in
priority = 254; priority = 254;
}; };
nebula.enable = true; nebula.enable = true;
proxies."buildbot.nebula.thehellings.com".target = "http://buildbot.nebula.thehellings.com:8010/";
tailscale = { tailscale = {
enable = true; enable = true;
tags = [ "home" ]; tags = [ "home" ];
@@ -142,12 +143,12 @@ in
updateOutputs = false; updateOutputs = false;
}; };
}; };
domain = "${config.networking.hostName}.shire-zebra.ts.net:8010"; domain = "buildbot.nebula.thehellings.com:8010";
evalMaxMemorySize = 8192; evalMaxMemorySize = 8192;
evalWorkerCount = 4; evalWorkerCount = 4;
gitea = { gitea = {
enable = true; enable = true;
instanceUrl = "https://gitea.shire-zebra.ts.net"; instanceUrl = "https://src.thehellings.com";
oauthId = "7ec9107d-379b-47c8-870f-1191956d0500"; oauthId = "7ec9107d-379b-47c8-870f-1191956d0500";
oauthSecretFile = config.age.secrets.gitea-oauthSecret.path; oauthSecretFile = config.age.secrets.gitea-oauthSecret.path;
tokenFile = config.age.secrets.gitea-oauthToken.path; tokenFile = config.age.secrets.gitea-oauthToken.path;
@@ -155,7 +156,7 @@ in
webhookSecretFile = config.age.secrets.gitea-webhookSecret.path; webhookSecretFile = config.age.secrets.gitea-webhookSecret.path;
}; };
showTrace = true; showTrace = true;
#webhookBaseUrl = "http://${config.networking.hostName}.shire-zebra.ts.net:8010"; #webhookBaseUrl = "http://${config.networking.hostName}.nebula.thehellings.com:8010";
workersFile = config.age.secrets.gitea-buildbotWorkersFile.path; workersFile = config.age.secrets.gitea-buildbotWorkersFile.path;
}; };
worker = { worker = {
+76
View File
@@ -0,0 +1,76 @@
{
config,
metadata,
modulesPath,
pkgs,
...
}:
{
imports = [ "${modulesPath}/virtualisation/proxmox-image.nix" ];
greg = {
home = true;
nebula.enable = true;
proxies =
let
tgt = {
target = "http://localhost:${config.services.uptime-kuma.settings.PORT}";
genAliases = false;
};
in
{
"kuma.nebula.thehellings.com" = tgt;
"kuma.thehellings.lan" = tgt;
"kuma.shire-zebra.ts.net" = tgt;
};
};
nix.settings = {
sandbox = false;
};
networking = {
defaultGateway = metadata.infra.gw;
nameservers = [ metadata.infra.dns ];
interfaces.ens18 = {
useDHCP = false;
ipv4.addresses = [
{
address = metadata.hosts."${config.networking.hostName}".ip;
prefixLength = 16;
}
];
};
};
proxmox.cloudInit.enable = false;
services = {
fstrim.enable = true;
mysql = {
enable = true;
ensureDatabases = [
config.services.uptime-kuma.settings.UPTIME_KUMA_DB_NAME
];
ensureUsers = [
{
name = config.services.uptime-kuma.settings.UPTIME_KUMA_DB_USERNAME;
ensurePermissions = {
"uptimekuma.*" = "ALL PRIVILEGES";
};
}
];
package = pkgs.mariadb;
};
openssh = {
enable = true;
openFirewall = true;
};
uptime-kuma = {
enable = true;
settings = {
PORT = "3001"; # Default, but this allows us to explicitly use it elsewhere
UPTIME_KUMA_DB_TYPE = "mariadb";
UPTIME_KUMA_DB_SOCKET = "/run/mysqld/mysqld.sock";
UPTIME_KUMA_DB_NAME = "uptimekuma";
UPTIME_KUMA_DB_USERNAME = "uptimekuma";
UPTIME_KUMA_DB_PASSWORD = "uptimekuma";
};
};
};
}
+322 -18
View File
@@ -1,34 +1,85 @@
{ {
pkgs,
lib,
config, config,
lib,
metadata,
pkgs,
pkgs',
... ...
}: }:
let
homepage = "127.0.0.1:30080";
nextcloudPort = 8080;
sshPort = 2222;
matrixServer = pkgs.writeText "matrix_server" (
builtins.toJSON {
"m.server" = "matrix.thehellings.com:443";
}
);
matrixClient = pkgs.writeText "matrix_client" (
builtins.toJSON {
"m.homeserver" = {
base_url = "https://matrix.thehellings.com";
};
"m.identity_server" = {
base_url = "https://vector.im";
};
}
);
in
{ {
imports = [ imports = [
./git.nix
./hardware-configuration.nix ./hardware-configuration.nix
./podman.nix
./matrix.nix
./nextcloud.nix
./nginx.nix
./postgres.nix
]; ];
age.secrets = {
acme.file = ../../../secrets/acme.age;
nextcloudadmin = {
file = ../../../secrets/nextcloudadmin.age;
owner = "nextcloud";
};
};
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
bind bind
graphviz graphviz
nix-du nix-du
pgloader pgloader
podman-compose
pkgs'.upgrade-pg-cluster
]; ];
greg = { greg = {
backup.jobs = {
nextcloud-bkup = {
src = "/var/lib/nextcloud";
dest = "nextcloud-backup";
pre = lib.getExe (
pkgs.writeShellApplication {
name = "nextcloud-backup-pre";
runtimeInputs = [ config.services.nextcloud.occ ];
text = "nextcloud-occ maintenance:mode --on";
}
);
post = lib.getExe (
pkgs.writeShellApplication {
name = "nextcloud-backup-post";
runtimeInputs = [ config.services.nextcloud.occ ];
text = "nextcloud-occ maintenance:mode --off";
}
);
};
greg-postgresql-backup = {
src = config.services.postgresqlBackup.location;
dest = "linode-postgres";
};
};
gitea-runner = { gitea-runner = {
enable = true; enable = true;
extraLabels = [ labels = [
"vps:host" "vps:host"
"blog:host" "blog:host"
"nixos-linode:host"
]; ];
}; };
home = false; home = false;
@@ -36,20 +87,29 @@
nebula = { nebula = {
enable = true; enable = true;
isLighthouse = true; isLighthouse = true;
}; unsafeRoutes = [
proxies."immich.thehellings.com" = { {
genAliases = false; route = "10.42.0.0/16";
target = "http://localhost:${builtins.toString config.services.immich-public-proxy.port}"; via = metadata.hosts.genesis.nebulaIp;
ssl = true; }
];
}; };
tailscale.enable = true; tailscale.enable = true;
}; };
networking = { networking = {
networkmanager.enable = lib.mkForce false;
hostName = "linode";
domain = "thehellings.com"; domain = "thehellings.com";
nameservers = [ "100.88.91.27" ]; firewall.allowedTCPPorts = [
sshPort
80
443
];
hostName = "linode";
nameservers = [
"10.157.0.2"
"100.96.198.104"
];
networkmanager.enable = lib.mkForce false;
}; };
programs.ssh.extraConfig = lib.strings.concatStringsSep "\n" [ programs.ssh.extraConfig = lib.strings.concatStringsSep "\n" [
@@ -60,10 +120,254 @@
" UserKnownHostsFile /dev/null" " UserKnownHostsFile /dev/null"
]; ];
security.acme = {
acceptTerms = true;
defaults = {
dnsPropagationCheck = false;
dnsResolver = "92.123.95.3:53,92.123.94.3:53,92.123.94.2:53,92.123.95.4:53,92.123.95.2:53";
email = "greg.hellings@gmail.com";
extraLegoRunFlags = [ "--ipv4only" ]; # Force IPv4 only
#server = "https://acme-staging-v02.api.letsencrypt.org/directory";
};
certs."thehellings.com" = {
dnsProvider = "linode";
environmentFile = config.age.secrets.acme.path;
extraDomainNames = [
"*.thehellings.com"
];
};
};
services = { services = {
anubis = {
instances = {
git = {
enable = true;
settings = {
BIND = "/run/anubis/anubis-git/anubis.sock";
COOKIE_DOMAIN = "thehellings.com";
SERVE_ROBOTS_TXT = true;
SLOG_LEVEL = "DEBUG";
TARGET = "http://git.k3s.thehellings.lan";
};
};
};
};
haproxy = {
enable = true;
config = ''
global
nbthread 4
maxconn 80
log /dev/log local0
defaults
timeout connect 500s
timeout client 500s
timeout server 1h
listen gitsshd
bind *:${toString sshPort}
timeout client 1h
mode tcp
server git-isaiah isaiah.thehellings.lan:32222
server git-jeremiah jeremiah.thehellings.lan:32222
server git-zeke zeke.thehellings.lan:32222
frontend https
bind *:80
bind *:443 ssl crt ${config.security.acme.certs."thehellings.com".directory}/full.pem
http-request redirect scheme https unless { ssl_fc }
http-request add-header X-Forwarded-Proto https
http-response replace-header ^Set-Cookie:\ (.*) Set-Cookie \1;\ Secure
option http-server-close
option http-keep-alive
#option httplog
#declare capture response len 80
#http-response capture res.hdr(Location) id 0
use_backend git if { hdr(host) -i src.thehellings.com }
use_backend git if { req_ssl_sni -i src.thehellings.com }
use_backend next if { hdr(host) -i next.thehellings.com }
use_backend next if { req_ssl_sni -i next.thehellings.com }
use_backend matrix if { hdr(host) -i matrix.thehellings.com }
use_backend matrix if { req_ssl_sni -i matrix.thehellings.com }
use_backend immich if { hdr(host) -i immich.thehellings.com }
use_backend immich if { req_ssl_sni -i immich.thehellings.com }
use_backend web if { hdr(host) -i thehellings.com }
use_backend web if { req_ssl_sni -i thehellings.com }
backend git
mode http
balance roundrobin
option accept-unsafe-violations-in-http-response
retries 3
option forwardfor
http-request set-header Host git.k3s.thehellings.lan
server git-isaiah isaiah.thehellings.lan:80
server git-jeremiah jeremiah.thehellings.lan:80
server git-zeke zeke.thehellings.lan:80
backend immich
mode http
balance roundrobin
option accept-unsafe-violations-in-http-response
retries 3
option forwardfor
server immich-proxy 127.0.0.1:${builtins.toString config.services.immich-public-proxy.port}
backend matrix
mode http
balance roundrobin
option accept-unsafe-violations-in-http-response
retries 3
option forwardfor
http-request set-header Host matrix.k3s.thehellings.lan
server git-isaiah isaiah.thehellings.lan:80
server git-jeremiah jeremiah.thehellings.lan:80
server git-zeke zeke.thehellings.lan:80
backend web
mode http
balance roundrobin
option accept-unsafe-violations-in-http-response
retries 3
option forwardfor
http-request return status 200 content-type "application/json" file ${matrixClient} hdr "cache-control" "no-cache" if { path /.well-known/matrix/client }
http-request return status 200 content-type "application/json" file ${matrixServer} hdr "cache-control" "no-cache" if { path /.well-known/matrix/server }
server web-container ${homepage}
backend next
log global
mode http
balance roundrobin
option accept-unsafe-violations-in-http-response
retries 3
option forwardfor
#http-response replace-value Location http://localhost:${builtins.toString nextcloudPort}/(.*) https://next.thehellings.com/\2
server nextcloud 127.0.0.1:${builtins.toString nextcloudPort}
'';
};
immich-public-proxy = { immich-public-proxy = {
enable = true; enable = true;
immichUrl = "https://immich.shire-zebra.ts.net"; immichUrl = "http://immich.k3s.thehellings.lan";
}; };
logrotate = {
enable = true;
settings = {
postgresBackup = {
enable = true;
files = "${config.services.postgresqlBackup.location}/*.gz";
};
postgresLog = {
enable = true;
files = "/var/lib/postgresql/*/log/*.log";
compress = true;
compresscmd = "${pkgs.xz}/bin/xz";
};
};
};
nextcloud = {
enable = true;
package = pkgs.nextcloud33;
appstoreEnable = true;
hostName = "127.0.0.1";
https = false;
config = {
adminpassFile = config.age.secrets.nextcloudadmin.path;
adminuser = "greg";
dbhost = "/run/postgresql";
dbtype = "pgsql";
};
settings = {
default_phone_region = "US";
overwriteprotocol = "http";
trusted_domains = [ "next.thehellings.com" ];
trusted_proxies = [
"localhost"
"127.0.0.1"
];
};
};
# Move to :8080 so that we can run haproxy as the primary HTTP service
nginx.virtualHosts."${config.services.nextcloud.hostName}".listen = [
{
addr = "127.0.0.1";
port = nextcloudPort;
}
];
openssh.settings.PasswordAuthentication = false;
postgresql = {
enable = true;
package = pkgs.postgresql_15;
checkConfig = true;
ensureDatabases = [ "nextcloud" ];
#initialScript = pkgs.writeText "create-matrix-db.sql" ''
# CREATE ROLE "matrix-synapse" WITH LOGIN;
# CREATE DATABASE "synapse" WITH OWNER "matrix-synapse" TEMPLATE template0 LC_COLLATE = "C" LC_CTYPE = "C";
# GRANT ALL PRIVILEGES ON DATABASE "synapse" TO "matrix-synapse";
#''; # These are done manually in order to set the LC_COLLATE values properly
ensureUsers = [
{
name = "nextcloud";
ensureDBOwnership = true;
}
];
settings = {
log_connections = true;
log_statement = "all";
logging_collector = true;
log_filename = "postgresql.log";
};
identMap = ''
root root postgres
'';
};
postgresqlBackup = {
enable = true;
databases = [ "nextcloud" ];
};
};
systemd.services = {
haproxy = {
after = [
"nextcloud.service"
"network-online.target"
];
wants = [
"nextcloud.service"
"network-online.target"
];
};
};
users.users.haproxy.extraGroups = [ config.security.acme.certs."thehellings.com".group ];
# Actually serve the content from here
virtualisation.oci-containers = {
backend = "podman";
containers."homepage" = {
image = "src.thehellings.com/greg/homepage:latest";
ports = [ "${homepage}:80" ];
};
};
virtualisation.podman = {
enable = true;
dockerCompat = true;
dockerSocket.enable = true;
}; };
} }
-148
View File
@@ -1,148 +0,0 @@
{ config, ... }:
let
srcDomain = "src.thehellings.com";
sshPort = 2222;
in
{
greg.proxies."${srcDomain}" = {
target = "http://unix:${config.services.anubis.instances.git.settings.BIND}";
ssl = true;
genAliases = false;
extraConfig = ''
#proxy_ssl_verify off;
#proxy_ssl_server_name on;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Http-Version $server_protocol;
proxy_set_header User-Agent $http_user_agent;
client_max_body_size 100000m;
#proxy_set_header Host $host;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header X-Forwarded-Proto $scheme;
#proxy_set_header X-Forwarded-Ssl on;
# Ultimate AI Block List v1.7 20250924
# https://perishablepress.com/ultimate-ai-block-list/
if ($http_user_agent ~* "(openai\.com|\.ai|-ai|_ai|ai\.|ai-|ai_|ai=|AddSearchBot|Agentic|AgentQL|Agent\ 3|Agent\ API|AI\ Agent|AI\ Article\ Writer|AI\ Chat|AI\ Content\ Detector|AI\ Detection|AI\ Dungeon|AI\ Journalist|AI\ Legion)") {
return 444;
}
if ($http_user_agent ~* "(AI\ RAG|AI\ Search|AI\ SEO\ Crawler|AI\ Training|AI\ Web|AI\ Writer|AI2|AIBot|aiHitBot|AIMatrix|AISearch|AITraining|Alexa|Alice\ Yandex|AliGenie|AliyunSec|Alpha\ AI|AlphaAI|Amazon|Amelia)") {
return 444;
}
if ($http_user_agent ~* "(AndersPinkBot|AndiBot|Anonymous\ AI|Anthropic|AnyPicker|Anyword|Applebot|Aria\ AI|Aria\ Browse|Articoolo|Ask\ AI|AutoGen|AutoGLM|Automated\ Writer|AutoML|Autonomous\ RAG|AwarioRssBot|AwarioSmartBot|AWS\ Trainium|Azure)") {
return 444;
}
if ($http_user_agent ~* "(BabyAGI|BabyCatAGI|BardBot|Basic\ RAG|Bedrock|Big\ Sur|Bigsur|Botsonic|Brightbot|Browser\ MCP\ Agent|Browser\ Use|Bytebot|ByteDance|Bytespider|CarynAI|CatBoost|CC-Crawler|CCBot|Chai|Character)") {
return 444;
}
if ($http_user_agent ~* "(Charstar\ AI|Chatbot|ChatGLM|Chatsonic|ChatUser|Chinchilla|Claude|ClearScope|Clearview|Cognitive\ AI|Cohere|Common\ Crawl|CommonCrawl|Content\ Harmony|Content\ King|Content\ Optimizer|Content\ Samurai|ContentAtScale|ContentBot|Contentedge)") {
return 444;
}
if ($http_user_agent ~* "(ContentShake|Conversion\ AI|Copilot|CopyAI|Copymatic|Copyscape|CoreWeave|Corrective\ RAG|Cotoyogi|CRAB|Crawl4AI|CrawlQ\ AI|Crawlspace|Crew\ AI|CrewAI|Crushon\ AI|DALL-E|DarkBard|DataFor|DataProvider)") {
return 444;
}
if ($http_user_agent ~* "(Datenbank\ Crawler|DeepAI|Deep\ AI|DeepL|DeepMind|Deep\ Research|DeepResearch|DeepSeek|Devin|Diffbot|Doubao\ AI|DuckAssistBot|DuckDuckGo\ Chat|DuckDuckGo-Enhanced|Echobot|Echobox|Elixir|FacebookBot|FacebookExternalHit|Factset)") {
return 444;
}
if ($http_user_agent ~* "(Falcon|FIRE-1|Firebase|Firecrawl|Flux|Flyriver|Frase\ AI|FriendlyCrawler|Gato|Gemini|Gemma|Gen\ AI|GenAI|Generative|Genspark|Gentoo-chat|Ghostwriter|GigaChat|GLM|GodMode)") {
return 444;
}
if ($http_user_agent ~* "(Goose|GPT|Grammarly|Grendizer|Grok|GT\ Bot|GTBot|GTP|Hemingway\ Editor|Hetzner|Hugging|Hunyuan|Hybrid\ Search\ RAG|Hypotenuse\ AI|iAsk|ICC-Crawler|ImageGen|ImagesiftBot|img2dataset|imgproxy)") {
return 444;
}
if ($http_user_agent ~* "(INK\ Editor|INKforall|Instructor|IntelliSeek|Inferkit|ISSCyberRiskCrawler|Janitor\ AI|Jasper|Jenni\ AI|Julius\ AI|Kafkai|Kaggle|Kangaroo|Keyword\ Density\ AI|Kimi|Knowledge|KomoBot|Kruti|LangChain|Le\ Chat)") {
return 444;
}
if ($http_user_agent ~* "(Lensa|Lightpanda|LinerBot|LLaMA|LLM|Local\ RAG\ Agent|Lovable|Magistral|magpie-crawler|Manus|MarketMuse|Meltwater|Meta-AI|Meta-External|Meta-Webindexer|Meta\ AI|MetaAI|MetaTagBot|Middleware|Midjourney)") {
return 444;
}
if ($http_user_agent ~* "(Mini\ AGI|MiniMax|Mintlify|Mistral|Mixtral|model-training|Monica|Narrative|NeevaBot|netEstate|Neural\ Text|NeuralSEO|NinjaAI|NodeZero|Nova\ Act|NovaAct|OAI-SearchBot|OAI\ SearchBot|OASIS|Olivia)") {
return 444;
}
if ($http_user_agent ~* "(Omgili|Open\ AI|Open\ Interpreter|OpenAGI|OpenAI|OpenBot|OpenPi|OpenRouter|OpenText\ AI|Operator|Outwrite|Page\ Analyzer\ AI|PanguBot|Panscient|Paperlibot|Paraphraser\.io|peer39_crawler|Perflexity|Perplexity|Petal)") {
return 444;
}
if ($http_user_agent ~* "(Phind|PiplBot|PoeBot|PoeSearchBot|ProWritingAid|Proximic|Puppeteer|Python\ AI|Qualified|Quark|QuillBot|Qopywriter|Qwen|RAG\ Agent|RAG\ Azure\ AI|RAG\ Chatbot|RAG\ Database|RAG\ IS|RAG\ Pipeline|RAG\ Search)") {
return 444;
}
if ($http_user_agent ~* "(RAG\ with|RAG-|RAG_|Raptor|React\ Agent|Redis\ AI\ RAG|RobotSpider|Rytr|SaplingAI|SBIntuitionsBot|Scala|Scalenut|Scrap|ScriptBook|Seekr|SEObot|SEO\ Content\ Machine|SEO\ Robot|SemrushBot|Sentibot)") {
return 444;
}
if ($http_user_agent ~* "(Serper|ShapBot|Sidetrade|Simplified\ AI|Sitefinity|Skydancer|SlickWrite|SmartBot|Sonic|Sora|Spider/2|SpiderCreator|Spin\ Rewrite|Spinbot|Stability|StableDiffusionBot|Sudowrite|SummalyBot|Super\ Agent|Superagent)") {
return 444;
}
if ($http_user_agent ~* "(SuperAGI|Surfer\ AI|TerraCotta|Text\ Blaze|TextCortex|Thinkbot|Thordata|TikTokSpider|Timpibot|Tinybird|Together\ AI|Traefik|TurnitinBot|uAgents|VelenPublicWebCrawler|Venus\ Chub\ AI|Vidnami\ AI|Vision\ RAG|WebSurfer|WebText)") {
return 444;
}
if ($http_user_agent ~* "(Webzio|WeChat|Whisper|WordAI|Wordtune|WPBot|Writecream|WriterZen|Writescope|Writesonic|xAI|xBot|YaML|YandexAdditional|YouBot|Zendesk|Zero|Zhipu|Zhuque\ AI|Zimm)") {
return 444;
}
'';
};
#greg.proxies."registry.thehellings.com" = {
#target = "https://gitea.shire-zebra.ts.net:5000";
#ssl = true;
#genAliases = false;
#extraConfig = ''
#proxy_set_header X-Forwarded-Proto https;
#proxy_set_header X-Forwarded-Ssl on;
#client_max_body_size 25000m;
#'';
#};
networking.firewall.allowedTCPPorts = [ sshPort ];
services = {
anubis = {
instances = {
git = {
enable = true;
settings = {
BIND = "/run/anubis/anubis-git/anubis.sock";
COOKIE_DOMAIN = "thehellings.com";
SERVE_ROBOTS_TXT = true;
TARGET = "https://gitea.shire-zebra.ts.net/";
};
};
};
};
haproxy = {
enable = true;
config = ''
global
daemon
maxconn 20
defaults
timeout connect 500s
timeout client 500s
timeout server 1h
listen gitsshd
bind *:${toString sshPort}
timeout client 1h
mode tcp
server git-isaiah isaiah.shire-zebra.ts.net:32222
server git-jeremiah jeremiah.shire-zebra.ts.net:32222
server git-zeke zeke.shire-zebra.ts.net:32222
'';
};
};
systemd.services = {
haproxy = {
after = [
"network-online.target"
];
wants = [
"network-online.target"
];
};
};
users.users.nginx.extraGroups = [ config.users.groups.anubis.name ];
}
-70
View File
@@ -1,70 +0,0 @@
# Registration of new users is disabled for the public, but I can create
# them by the following commands:
# nix run nixpkgs.matrix-synapse
# register_new_matrix_user -k "B9EoPr2WV9hzwc7uL2Sx1JmvCeKDEOGCpB0uginQcQtEH4wzRtkSIdo7lltrjSQa" http://localhost:8448
{ config, ... }:
let
domain = "${config.networking.domain}";
fqdn = "matrix.${domain}";
in
{
greg.proxies."${fqdn}" = {
extraConfig = ''
error_log /var/log/nginx/debug.log debug;
proxy_ssl_verify off;
proxy_ssl_server_name on;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on;
'';
genAliases = false;
ssl = true;
target = "https://matrix.shire-zebra.ts.net";
};
services.nginx = {
virtualHosts = {
# Server the '.well-known' files to find the Matrix API server
"${domain}" = {
enableACME = true;
forceSSL = true;
# This is needed so that servers contacting hellings.com can find
# the actual application server at matrix.thehellings.com
locations."= /.well-known/matrix/server".extraConfig =
let
server = {
"m.server" = "${fqdn}:443";
};
in
''
add_header Content-Type application/json;
return 200 '${builtins.toJSON server}';
'';
locations."= /.well-known/matrix/client".extraConfig =
let
client = {
"m.homeserver" = {
"base_url" = "https://${fqdn}";
};
"m.identity_server" = {
"base_url" = "https://vector.im";
};
};
in
''
add_header Content-Type application/json;
add_header Access-Control-Allow-Origin *;
return 200 '${builtins.toJSON client}';
'';
};
};
};
# Open networking ports for the server
networking.firewall = {
enable = true;
allowedTCPPorts = [
80
443
];
};
}
-58
View File
@@ -1,58 +0,0 @@
{
config,
lib,
pkgs,
...
}:
{
age.secrets.nextcloudadmin = {
file = ../../../secrets/nextcloudadmin.age;
owner = "nextcloud";
};
services.nextcloud = {
enable = true;
package = pkgs.nextcloud33;
appstoreEnable = true;
hostName = "next.${config.networking.domain}";
https = true;
config = {
adminpassFile = config.age.secrets.nextcloudadmin.path;
adminuser = "greg";
dbhost = "/run/postgresql";
dbtype = "pgsql";
};
settings = {
default_phone_region = "US";
overwriteprotocol = "https";
};
};
services.nginx.virtualHosts."next.thehellings.com" = {
forceSSL = true;
enableACME = true;
};
# Otherwise nginx errors looking for the nextcloud sock file
systemd.services.nginx.after = [ "nextcloud.service" ];
greg.backup.jobs.nextcloud-bkup = {
src = "/var/lib/nextcloud";
dest = "nextcloud-backup";
pre = lib.getExe (
pkgs.writeShellApplication {
name = "nextcloud-backup-pre";
runtimeInputs = [ config.services.nextcloud.occ ];
text = "nextcloud-occ maintenance:mode --on";
}
);
post = lib.getExe (
pkgs.writeShellApplication {
name = "nextcloud-backup-post";
runtimeInputs = [ config.services.nextcloud.occ ];
text = "nextcloud-occ maintenance:mode --off";
}
);
};
}
-38
View File
@@ -1,38 +0,0 @@
{ ... }:
let
homepage = "127.0.0.1:30080";
in
{
security.acme = {
acceptTerms = true;
defaults.email = "greg.hellings@gmail.com";
};
services.nginx = {
enable = true;
clientMaxBodySize = "25000m"; # To help with uploading container images
# If there are recommended settings, let's use them!
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
};
# Actually serve the content from here
virtualisation.podman.enable = true;
virtualisation.oci-containers = {
backend = "podman";
containers."homepage" = {
image = "registry.thehellings.com:443/greg/homepage/gregs-homepage:latest";
ports = [ "${homepage}:80" ];
};
};
greg.proxies = {
"thehellings.com" = {
target = "http://${homepage}/";
ssl = true;
genAliases = false;
};
};
}
-13
View File
@@ -1,13 +0,0 @@
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [
podman-compose
];
virtualisation.podman = {
enable = true;
dockerCompat = true;
dockerSocket.enable = true;
};
}
-63
View File
@@ -1,63 +0,0 @@
{
config,
pkgs,
pkgs',
...
}:
{
environment.systemPackages = [ pkgs'.upgrade-pg-cluster ];
services.postgresql = {
enable = true;
package = pkgs.postgresql_15;
checkConfig = true;
ensureDatabases = [ "nextcloud" ];
#initialScript = pkgs.writeText "create-matrix-db.sql" ''
# CREATE ROLE "matrix-synapse" WITH LOGIN;
# CREATE DATABASE "synapse" WITH OWNER "matrix-synapse" TEMPLATE template0 LC_COLLATE = "C" LC_CTYPE = "C";
# GRANT ALL PRIVILEGES ON DATABASE "synapse" TO "matrix-synapse";
#''; # These are done manually in order to set the LC_COLLATE values properly
ensureUsers = [
{
name = "nextcloud";
ensureDBOwnership = true;
}
];
settings = {
log_connections = true;
log_statement = "all";
logging_collector = true;
log_filename = "postgresql.log";
};
identMap = ''
root root postgres
'';
};
services.postgresqlBackup = {
enable = true;
databases = [ "nextcloud" ];
};
services.logrotate = {
enable = true;
settings = {
postgresBackup = {
enable = true;
files = "${config.services.postgresqlBackup.location}/*.gz";
};
postgresLog = {
enable = true;
files = "/var/lib/postgresql/*/log/*.log";
compress = true;
compresscmd = "${pkgs.xz}/bin/xz";
};
};
};
greg.backup.jobs.greg-postgresql-backup = {
src = config.services.postgresqlBackup.location;
dest = "linode-postgres";
};
}
@@ -1,60 +0,0 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ pkgs, ... }:
{
imports = [
# Include the results of the hardware scan.
./hardware-configuration.nix
];
# Bootloader.
boot.loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
environment.systemPackages = with pkgs; [
];
greg = {
home = true;
tailscale = {
enable = true;
tags = [ "home" ];
};
};
networking = {
hostName = "proxmoxtemplate"; # Define your hostname.
# defaultGateway = {
# address = " 10.42.1.2";
# interface = "enp6s18";
# };
# interfaces = {
# enp6s18 = {
# ipv4.addresses = [
# {
# address = "10.42.1.8";
# prefixLength = 16;
# }
# ];
# };
# };
nameservers = [ "10.42.1.5" ];
};
services.qemuGuest.enable = true;
system.stateVersion = "24.11"; # Did you read the comment?
# Define a user account. Don't forget to set a password with passwd.
users.users.greg = {
isNormalUser = true;
description = "Greg Hellings";
extraGroups = [ "wheel" ];
packages = with pkgs; [ ];
};
}
@@ -1,50 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
lib,
modulesPath,
...
}:
{
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [
"uhci_hcd"
"ehci_pci"
"ahci"
"virtio_pci"
"virtio_scsi"
"sd_mod"
"sr_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" = {
device = "/dev/disk/by-uuid/507251f1-efe7-448d-8de8-91ee582a9afb";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/7115-EFA6";
fsType = "vfat";
options = [
"fmask=0077"
"dmask=0077"
];
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp6s18.useDHCP = lib.mkDefault true;
}
+4 -6
View File
@@ -32,6 +32,10 @@
enable = true; enable = true;
tags = [ "home" ]; tags = [ "home" ];
}; };
vmdev = {
enable = true;
host = "vbox";
};
}; };
hardware = { hardware = {
@@ -71,10 +75,4 @@
users.users.greg.extraGroups = [ users.users.greg.extraGroups = [
"podman" "podman"
]; ];
# virtualisation.virtualbox.host = {
# enableExtensionPack = true;
# headless = true;
# enableWebService = true;
# };
} }
-79
View File
@@ -1,79 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: donetick-config
namespace: donetick
data:
# Value pulled from
# https://github.com/donetick/donetick/blob/main/config/selfhosted.yaml
selfhosted.yaml: |-
name: "selfhosted"
is_done_tick_dot_com: false
is_user_creation_disabled: false
telegram:
token: ""
pushover:
token: ""
database:
type: "sqlite"
migration: true
# these are only required for postgres
host: "secret"
port: 5432
user: "secret"
password: "secret"
name: "secret"
jwt:
secret: "This is really a secure JWT secret now!"
session_time: 168h
max_refresh: 168h
server:
port: 2021
read_timeout: 10s
write_timeout: 10s
rate_period: 60s
rate_limit: 300
cors_allow_origins:
- "http://localhost:5173"
- "http://localhost:7926"
# the below are required for the android app to work
- "https://localhost"
- "capacitor://localhost"
serve_frontend: true
logging:
level: "info"
encoding: "json"
development: false
scheduler_jobs:
due_job: 30m
overdue_job: 3h
pre_due_job: 3h
email:
host:
port:
key:
email:
appHost:
oauth2:
client_id:
client_secret:
auth_url:
token_url:
user_info_url:
redirect_url:
name:
# Real-time configuration
realtime:
enabled: true
sse_enabled: true
heartbeat_interval: 60s
connection_timeout: 120s
max_connections: 1000
max_connections_per_user: 5
event_queue_size: 2048
cleanup_interval: 2m
stale_threshold: 5m
enable_compression: true
enable_stats: true
allowed_origins:
- "*"
-38
View File
@@ -1,38 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: donetick
namespace: donetick
spec:
replicas: 1
selector:
matchLabels:
app: donetick
template:
metadata:
labels:
app: donetick
spec:
containers:
- name: donetick
image: donetick/donetick
ports:
- containerPort: 2021
name: http
env:
- name: DT_ENV
value: "selfhosted"
- name: DT_SQLITE_PATH
value: "/data/donetick.db"
volumeMounts:
- name: config
mountPath: /config
- name: data
mountPath: /data
volumes:
- name: config
configMap:
name: donetick-config
- name: data
persistentVolumeClaim:
claimName: donetick-data
-15
View File
@@ -1,15 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: donetick-tailscale
namespace: donetick
spec:
ingressClassName: tailscale
defaultBackend:
service:
name: donetick
port:
number: 2021
tls:
- hosts:
- todo
-9
View File
@@ -1,9 +0,0 @@
namespace: donetick
resources:
- namespace.yaml
- configmap.yaml
- pvc.yaml
- deployment.yaml
- service.yaml
- ingress.yaml
-4
View File
@@ -1,4 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: donetick
-11
View File
@@ -1,11 +0,0 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: donetick-data
namespace: donetick
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
-13
View File
@@ -1,13 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: donetick
namespace: donetick
spec:
selector:
app: donetick
ports:
- name: http
port: 2021
targetPort: 2021
protocol: TCP
-56
View File
@@ -1,56 +0,0 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: gitea
spec:
interval: "24h"
url: https://dl.gitea.com/charts/
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: gitea-runner
namespace: gitea-runner
spec:
interval: 10m
chart:
spec:
chart: actions
version: "0.0.4"
sourceRef:
kind: HelmRepository
name: gitea
interval: "1h"
values:
rbac:
create: true
serviceAccount:
create: true
gitea:
instanceURL: https://src.thehellings.com
runnerToken:
existingSecret: gitea-runner
existingSecretKey: token
imagePullSecrets:
- name: image-pull-secrets
config:
runner:
labels:
# Ubuntu
- "ubuntu-22.04:docker://ubuntu:22.04"
- "ubuntu-24.04:docker://ubuntu:24.04"
- "ubuntu-24.10:docker://ubuntu:24.10"
# Fedora
- "fedora-41:docker://fedora:41"
- "fedora-42:docker://fedora:42"
# CentOS Stream
- "centos-stream-9:docker://quay.io/centos/centos:stream9"
- "centos-stream-10:docker://quay.io/centos/centos:stream10"
# Nix
- "nix:docker://nixos/nix:latest"
# ci-images (internal registry: src.thehellings.com/greg)
- "ci-builder:docker://src.thehellings.com/greg/builder:latest"
- "ci-vm-test:docker://src.thehellings.com/greg/vm-test:latest"
- "ci-sword:docker://src.thehellings.com/greg/sword-container-builder:latest"
- "ci-bitwarden:docker://src.thehellings.com/greg/bitwarden:latest"
- "ci-immich:docker://src.thehellings.com/greg/immich:latest"
@@ -1,6 +0,0 @@
namespace: gitea-runner
resources:
- namespace.yaml
- secrets.yaml
- chart.yaml
-4
View File
@@ -1,4 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: gitea-runner
-18
View File
@@ -1,18 +0,0 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: gitea-runner
namespace: gitea-runner
spec:
refreshInterval: 1h
secretStoreRef:
name: bitwarden-login
kind: ClusterSecretStore
target:
name: gitea-runner
creationPolicy: Owner
data:
- secretKey: token
remoteRef:
key: 11419680-5338-4f19-bdd9-b422007046af
property: password
+9 -9
View File
@@ -15,7 +15,7 @@ spec:
chart: chart:
spec: spec:
chart: gitea chart: gitea
version: "12.6.0" version: "12.7.0"
sourceRef: sourceRef:
kind: HelmRepository kind: HelmRepository
name: gitea-repository name: gitea-repository
@@ -35,7 +35,7 @@ spec:
storageClass: longhorn-default storageClass: longhorn-default
image: image:
tag: "1.26.2" tag: "1.27.1"
replicaCount: 1 replicaCount: 1
@@ -67,7 +67,7 @@ spec:
RUN_MODE: dev RUN_MODE: dev
server: server:
DOMAIN: "shire-zebra.ts.net" DOMAIN: "shire-zebra.ts.net"
ROOT_URL: "https://gitea.shire-zebra.ts.net" ROOT_URL: "https://git.k3s.thehellings.lan"
SSH_PORT: "2222" SSH_PORT: "2222"
database: database:
DB_TYPE: postgres DB_TYPE: postgres
@@ -85,15 +85,15 @@ spec:
DISABLE_REGISTRATION: "true" DISABLE_REGISTRATION: "true"
storage: storage:
STORAGE_TYPE: minio STORAGE_TYPE: minio
MINIO_ENDPOINT: "nas1.shire-zebra.ts.net:9000" MINIO_ENDPOINT: "nas1.shire-zebra.ts.net:30188"
MINIO_BUCKET: gitea MINIO_BUCKET: gitea
MINIO_LOCATION: us-east-1 MINIO_LOCATION: garage
# MINIO_ACCESS_KEY_ID: "" # MINIO_ACCESS_KEY_ID: ""
# MINIO_SECRET_ACCESS_KEY: "" # MINIO_SECRET_ACCESS_KEY: ""
MINIO_USE_SSL: "false" MINIO_USE_SSL: "false"
MINIO_INSECURE_SKIP_VERIFY: "true" MINIO_INSECURE_SKIP_VERIFY: "true"
webhook: security:
ALLOWED_HOST_LIST: loopback,private,*.shire-zebra.ts.net ALLOWED_HOST_LIST: loopback,private,*.shire-zebra.ts.net,*.nebula.thehellings.com,*.thehellings.lan
metrics: metrics:
enabled: false enabled: false
@@ -102,8 +102,8 @@ spec:
persistence: persistence:
enabled: true enabled: true
storageClass: longhorn-default create: false
size: "50Gi" claimName: gitea-new
# I will manage my Postgres externally # I will manage my Postgres externally
postgresql: postgresql:
+7 -7
View File
@@ -18,12 +18,12 @@ spec:
volumes: volumes:
- name: gitea-data - name: gitea-data
persistentVolumeClaim: persistentVolumeClaim:
claimName: gitea-shared-storage claimName: gitea-new
- name: dump-staging - name: dump-staging
emptyDir: {} emptyDir: {}
initContainers: initContainers:
- name: gitea-dump - name: gitea-dump
image: "gitea/gitea:1.25.4" image: "gitea/gitea:1.27.1"
command: command:
- /bin/sh - /bin/sh
- "-c" - "-c"
@@ -51,12 +51,12 @@ spec:
- | - |
set -e set -e
# Configure mc alias for MinIO # Configure mc alias for MinIO
mc alias set nas1 http://nas1.shire-zebra.ts.net:9000 \ mc alias set nas1 http://nas1.shire-zebra.ts.net:30188 \
"${MINIO_ACCESS_KEY}" "${MINIO_SECRET_KEY}" "${MINIO_ACCESS_KEY}" "${MINIO_SECRET_KEY}"
# Upload dump to backup-gitea bucket # Upload dump to backup-gitea bucket
DUMP_FILE=$(ls /dump-staging/gitea-dump-*.zip | head -1) DUMP_FILE=$(ls /dump-staging/gitea-dump-*.zip | head -1)
mc cp "${DUMP_FILE}" "nas1/backup-gitea/$(basename ${DUMP_FILE})" mc cp "${DUMP_FILE}" "nas1/gitea-backup/$(basename ${DUMP_FILE})"
echo "Uploaded $(basename ${DUMP_FILE}) to backup-gitea" echo "Uploaded $(basename ${DUMP_FILE}) to gitea-backup"
# Set 30-day lifecycle on the bucket (idempotent) # Set 30-day lifecycle on the bucket (idempotent)
mc ilm rule add --expire-days 30 nas1/backup-gitea 2>/dev/null || true mc ilm rule add --expire-days 30 nas1/backup-gitea 2>/dev/null || true
volumeMounts: volumeMounts:
@@ -69,10 +69,10 @@ spec:
- name: MINIO_ACCESS_KEY - name: MINIO_ACCESS_KEY
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: gitea-config name: gitea-backup
key: minio_key key: minio_key
- name: MINIO_SECRET_KEY - name: MINIO_SECRET_KEY
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: gitea-config name: gitea-backup
key: minio_secret key: minio_secret
+17
View File
@@ -12,3 +12,20 @@ spec:
tls: tls:
- hosts: - hosts:
- gitea - gitea
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gitea-direct
spec:
rules:
- host: git.k3s.thehellings.lan
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: gitea-release-http
port:
name: http
+29 -11
View File
@@ -1,5 +1,32 @@
apiVersion: external-secrets.io/v1 apiVersion: external-secrets.io/v1
kind: ExternalSecret kind: ExternalSecret
metadata:
name: gitea-backup
spec:
target:
name: gitea-backup
deletionPolicy: Delete
template:
type: Opaque
data:
minio_key: "{{ .minio_key }}"
minio_secret: "{{ .minio_secret }}"
secretStoreRef:
name: bitwarden-login
kind: ClusterSecretStore
data:
# MinIO credentials
- secretKey: minio_key
remoteRef:
key: dfb2f0c8-110d-4e96-83a7-b49c001c0897
property: username
- secretKey: minio_secret
remoteRef:
key: dfb2f0c8-110d-4e96-83a7-b49c001c0897
property: password
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata: metadata:
name: gitea-config name: gitea-config
spec: spec:
@@ -21,23 +48,14 @@ spec:
name: bitwarden-login name: bitwarden-login
kind: ClusterSecretStore kind: ClusterSecretStore
data: data:
# MinIO credentials
- secretKey: minio_key
remoteRef:
key: dcbcf704-7dce-48d7-bbd1-b3a801875b3d
property: username
- secretKey: minio_secret
remoteRef:
key: dcbcf704-7dce-48d7-bbd1-b3a801875b3d
property: password
# MinIO credentials for NAS1 # MinIO credentials for NAS1
- secretKey: minio_nas1_key - secretKey: minio_nas1_key
remoteRef: remoteRef:
key: c4c66ab3-2ade-4086-9c0d-b3a80172b1ba key: 33e8e4e0-eb90-484c-9ec9-b3a8018077a3
property: username property: username
- secretKey: minio_nas1_secret - secretKey: minio_nas1_secret
remoteRef: remoteRef:
key: c4c66ab3-2ade-4086-9c0d-b3a80172b1ba key: 33e8e4e0-eb90-484c-9ec9-b3a8018077a3
property: password property: password
# Postgres credentials # Postgres credentials
- secretKey: dbuser - secretKey: dbuser
+5 -1
View File
@@ -27,7 +27,7 @@ spec:
chart: chart:
spec: spec:
chart: longhorn chart: longhorn
version: "1.11.2" version: "1.11.3"
sourceRef: sourceRef:
kind: HelmRepository kind: HelmRepository
name: longhorn name: longhorn
@@ -141,6 +141,10 @@ spec:
number: 80 number: 80
- <<: *host - <<: *host
host: longhorn.kubernetes host: longhorn.kubernetes
- <<: *host
host: longhorn.k3s.nebula.thehellings.com
- <<: *host
host: longhorn.k3s.thehellings.lan
--- ---
apiVersion: storage.k8s.io/v1 apiVersion: storage.k8s.io/v1
kind: StorageClass kind: StorageClass
+6 -6
View File
@@ -33,24 +33,24 @@ spec:
access-key: "{{ .minio_key }}" access-key: "{{ .minio_key }}"
secret-key: "{{ .minio_secret }}" secret-key: "{{ .minio_secret }}"
rclone.conf: | rclone.conf: |
[nas1minio] [garage]
type = s3 type = s3
provider = Minio provider = Minio
endpoint = http://nas1.shire-zebra.ts.net:9000 endpoint = http://nas1.shire-zebra.ts.net:30188
access_key_id = {{ .minio_key }} access_key_id = {{ .minio_key }}
secret_access_key = {{ .minio_secret }} secret_access_key = {{ .minio_secret }}
region = us-east-1 region = garage
secretStoreRef: secretStoreRef:
name: bitwarden-login name: bitwarden-login
kind: ClusterSecretStore kind: ClusterSecretStore
data: data:
- secretKey: minio_key - secretKey: minio_key
remoteRef: remoteRef:
key: c4c66ab3-2ade-4086-9c0d-b3a80172b1ba key: 8fce2750-aa62-4892-b90c-b49c001f494b
property: username property: username
- secretKey: minio_secret - secretKey: minio_secret
remoteRef: remoteRef:
key: c4c66ab3-2ade-4086-9c0d-b3a80172b1ba key: 8fce2750-aa62-4892-b90c-b49c001f494b
property: password property: password
--- ---
apiVersion: v1 apiVersion: v1
@@ -128,7 +128,7 @@ spec:
--progress \ --progress \
--transfers 4 \ --transfers 4 \
--checkers 8 \ --checkers 8 \
/staging nas1minio:immich /staging garage:immich
volumeMounts: volumeMounts:
- name: staging - name: staging
mountPath: /staging mountPath: /staging
+1 -1
View File
@@ -32,7 +32,7 @@ spec:
containers: containers:
main: main:
image: image:
tag: v2.7.5 tag: v3.1.0
env: env:
DB_HOSTNAME: immich-rw DB_HOSTNAME: immich-rw
DB_DATABASE_NAME: immich DB_DATABASE_NAME: immich
+4
View File
@@ -22,6 +22,10 @@ spec:
name: immich-server name: immich-server
port: port:
name: http name: http
- <<: *host
host: immich.k3s.nebula.thehellings.com
- <<: *host
host: immich.k3s.thehellings.lan
--- ---
apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1
kind: Ingress kind: Ingress
-3
View File
@@ -10,7 +10,4 @@ resources:
- immich - immich
- monitoring - monitoring
- pinchflat - pinchflat
- smokeping
- uptimekuma
- donetick
- gitea - gitea
+17
View File
@@ -13,3 +13,20 @@ spec:
tls: tls:
- hosts: - hosts:
- matrix - matrix
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: matrix-direct
spec:
rules:
- host: matrix.k3s.thehellings.lan
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: dendrite
port:
number: 8008
+2 -2
View File
@@ -51,8 +51,8 @@ data:
static_configs: static_configs:
- targets: - targets:
- "10.42.0.3" # OpenWRT access point - "10.42.0.3" # OpenWRT access point
- "10.42.0.4" # Joel (Proxmox) - "10.42.0.4" # pve1 (Proxmox)
- "10.42.1.1" # pve1 (Proxmox) - "10.42.1.1" # UDM gateway (Ubiquiti)
- "10.42.1.4" # chronicles (Synology NAS) - "10.42.1.4" # chronicles (Synology NAS)
- "10.42.1.14" # nas1 (TrueNAS) - "10.42.1.14" # nas1 (TrueNAS)
- "10.42.2.57" # odoo - "10.42.2.57" # odoo
-50
View File
@@ -1,50 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: smokeping
labels:
app: smokeping
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: smokeping
template:
metadata:
labels:
app: smokeping
spec:
containers:
- name: smokeping
image: docker.io/linuxserver/smokeping:2.9.0
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
volumeMounts:
- name: config
mountPath: /config
- name: data
mountPath: /data
env:
- name: PUID
value: "1000"
- name: PGID
value: "1000"
- name: TZ
value: "America/Chicago"
#- name: MASTER_URL
# value: "https://ping.shire-zebra.ts.net"
# SHARED_SECRET if you want to run a cluster
# CACHE_DIR if you need to explicitly state that
restartPolicy: Always
volumes:
- name: config
persistentVolumeClaim:
claimName: smokeping-config
- name: data
persistentVolumeClaim:
claimName: smokeping-data
-14
View File
@@ -1,14 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: smokeping-tailscale
spec:
ingressClassName: tailscale
defaultBackend:
service:
name: smokeping
port:
name: http
tls:
- hosts:
- ping
-8
View File
@@ -1,8 +0,0 @@
namespace: smokeping
resources:
- namespace.yaml
- pvc.yaml
- deployment.yaml
- service.yaml
- ingress.yaml
-4
View File
@@ -1,4 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: smokeping
-23
View File
@@ -1,23 +0,0 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: smokeping-config
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn-default
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: smokeping-data
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn-default
resources:
requests:
storage: 25Gi
-15
View File
@@ -1,15 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: smokeping
labels:
app: smokeping
spec:
type: ClusterIP
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app: smokeping
-38
View File
@@ -1,38 +0,0 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: uptime-kuma
namespace: uptime-kuma
spec:
interval: "24h"
url: "https://helm.irsigler.cloud"
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: uptime-kuma
namespace: uptime-kuma
spec:
interval: 10m
chart:
spec:
chart: uptime-kuma
sourceRef:
kind: HelmRepository
name: uptime-kuma
interval: "1h"
dependsOn:
- name: longhorn
namespace: longhorn-system
- name: mariadb-cluster
namespace: mariadb-operator
values:
volume:
storageClassName: longhorn-default
image:
tag: "2.0.2"
externalDatabase:
enabled: true
hostname: mariadb-cluster.mariadb-operator.svc.cluster.local
database: uptimekuma
existingSecret: uptimekuma-mariadb-password
-15
View File
@@ -1,15 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: uptime-kuma-tailscale
namespace: uptime-kuma
spec:
ingressClassName: tailscale
defaultBackend:
service:
name: uptime-kuma
port:
number: 3001
tls:
- hosts:
- kuma
-7
View File
@@ -1,7 +0,0 @@
namespace: uptimekuma
resources:
- namespace.yaml
- secrets.yaml
- chart.yaml
- ingress.yaml
-4
View File
@@ -1,4 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: uptimekuma
-27
View File
@@ -1,27 +0,0 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: uptimekuma-mariadb-password
spec:
target:
name: uptimekuma-mariadb-password
deletionPolicy: Delete
template:
type: kubernetes.io/basic-auth
data:
username: |-
{{ .username }}
password: |-
{{ .password }}
secretStoreRef:
name: bitwarden-login
kind: ClusterSecretStore
data:
- secretKey: username
remoteRef:
key: 4df95656-9f9c-4916-8e34-b3a200376365
property: username
- secretKey: password
remoteRef:
key: 4df95656-9f9c-4916-8e34-b3a200376365
property: password
+1 -1
View File
@@ -230,7 +230,7 @@
bookmarks = [ bookmarks = [
{ {
name = "PVE1"; name = "PVE1";
url = "https://10.42.1.1:8006/"; url = "https://10.42.0.4:8006/";
} }
{ {
name = "Jeremiah"; name = "Jeremiah";
+2 -2
View File
@@ -62,12 +62,12 @@ in
if cfg.cache then if cfg.cache then
[ [
#"http://chronicles.shire-zebra.ts.net:9000/binary-cache/" #"http://chronicles.shire-zebra.ts.net:9000/binary-cache/"
"http://nas1.shire-zebra.ts.net:9000/niks3" "http://niks3.nas1.shire-zebra.ts.net:30189/"
#"http://nas1.shire-zebra.ts.net:8080/default" #"http://nas1.shire-zebra.ts.net:8080/default"
] ]
else else
[ [
"http://nas1.thehellings.lan:8080/default" "http://niks3.nas1.thehellings.lan:30189/"
] ]
) )
++ [ ++ [
+13
View File
@@ -98,6 +98,19 @@ in
inherit labels; inherit labels;
inherit (cfg) name; inherit (cfg) name;
enable = true; enable = true;
hostPackages = with pkgs; [
bash
buildah
coreutils
curl
gawk
gitMinimal
gnused
nix
nodejs
podman
wget
];
url = cfg.instanceURL; url = cfg.instanceURL;
tokenFile = config.age.secrets."gitea-runner-${host}-podman".path; tokenFile = config.age.secrets."gitea-runner-${host}-podman".path;
settings = { settings = {
-27
View File
@@ -1,7 +1,6 @@
{ {
config, config,
lib, lib,
pkgs,
... ...
}: }:
@@ -18,35 +17,9 @@ with lib;
}; };
config = mkIf cfg { config = mkIf cfg {
age.secrets.attic.file = ../../secrets/attic.age;
networking.domain = "thehellings.lan"; networking.domain = "thehellings.lan";
time.timeZone = "America/Chicago"; time.timeZone = "America/Chicago";
systemd.services.attic-client = {
enable = true;
description = "Attic client watch-store service";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "simple";
Restart = "on-failure";
RestartSec = "5s";
};
preStart = ''
set -x
mkdir -p $XDG_CONFIG_HOME/attic
cp ${config.age.secrets.attic.path} $XDG_CONFIG_HOME/attic/config.toml
'';
script = "${pkgs.attic-client}/bin/attic watch-store --ignore-upstream-cache-filter default";
environment = {
XDG_CONFIG_HOME = "/var/lib/attic-client";
};
};
systemd.tmpfiles.rules = [
"d /var/lib/attic-client 0755 root root -"
];
# Open Prometheus exporter ports on LAN-connected hosts only. # Open Prometheus exporter ports on LAN-connected hosts only.
# NOT in baseline.nix to avoid exposing these on internet-facing hosts (e.g. linode). # NOT in baseline.nix to avoid exposing these on internet-facing hosts (e.g. linode).
networking.firewall.allowedTCPPorts = [ networking.firewall.allowedTCPPorts = [
+3 -1
View File
@@ -112,7 +112,8 @@ in
keepalived = { keepalived = {
enable = true; enable = true;
openFirewall = true; openFirewall = true;
vrrpInstances.kubernetes = { vrrpInstances = {
kubernetes = {
interface = cfg.vipInterface; interface = cfg.vipInterface;
priority = cfg.priority; priority = cfg.priority;
state = if (config.networking.hostName == "isaiah") then "MASTER" else "BACKUP"; state = if (config.networking.hostName == "isaiah") then "MASTER" else "BACKUP";
@@ -128,6 +129,7 @@ in
''; '';
}; };
}; };
};
openiscsi = { openiscsi = {
enable = true; enable = true;
name = "${config.networking.hostName}-initiatorhost"; name = "${config.networking.hostName}-initiatorhost";
+13 -2
View File
@@ -23,6 +23,13 @@ with lib;
type = types.str; type = types.str;
description = "Kernel module type to install - amd, intel, etc"; description = "Kernel module type to install - amd, intel, etc";
}; };
host = mkOption {
type = types.enum [
"libvirt"
"vbox"
];
description = "Which VM hosting type to configure";
};
}; };
}; };
@@ -35,7 +42,6 @@ with lib;
nixos-generators nixos-generators
packer packer
swtpm swtpm
virt-manager
virtio-win virtio-win
xorriso xorriso
]; ];
@@ -44,7 +50,7 @@ with lib;
# Enable the virtualisation services # Enable the virtualisation services
virtualisation = { virtualisation = {
libvirtd = { libvirtd = mkIf (cfg.host == "libvirt") {
enable = true; enable = true;
onBoot = "ignore"; # Do not auto-restart VMs on boot, unless they are marked autostart onBoot = "ignore"; # Do not auto-restart VMs on boot, unless they are marked autostart
qemu = { qemu = {
@@ -54,6 +60,11 @@ with lib;
}; };
}; };
}; };
virtualbox.host = mkIf (cfg.host == "vbox") {
enable = true;
enableExtensionPack = true;
headless = true;
};
}; };
boot.extraModprobeConfig = "options kvm_${cfg.system} nested=1"; boot.extraModprobeConfig = "options kvm_${cfg.system} nested=1";
+71 -54
View File
@@ -13,13 +13,6 @@
"ip": "10.42.1.17", "ip": "10.42.1.17",
"system": "x86_64-linux" "system": "x86_64-linux"
}, },
"chronicles": {
"ip": "10.42.1.4",
"pubkey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEBecZUva9OnZuXLaBun6/1ITo5f9p0YMLPD+q0egLRS",
"external": true,
"ts": "100.119.228.115",
"aliases": ["s3"]
},
"exodus": { "exodus": {
"ip": null, "ip": null,
"pubkey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFxmnCj2E9DxcnefPW+n4yCuLShxqr0p024riogdeXA3", "pubkey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFxmnCj2E9DxcnefPW+n4yCuLShxqr0p024riogdeXA3",
@@ -35,6 +28,15 @@
"tags": ["router", "server"], "tags": ["router", "server"],
"nebulaIp": "10.157.0.2" "nebulaIp": "10.157.0.2"
}, },
"gregory.hellings-mbp": {
"external": true,
"system": "aarch64-darwin",
"user": "gregory.hellings"
},
"gregs-MacBook-Pro-16-inch-Nov-2024": {
"external": true,
"system": "aarch64-darwin"
},
"hosea": { "hosea": {
"ip": "10.42.1.7", "ip": "10.42.1.7",
"pubkey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKLIwkTTXA56sUlUjEulXXZRvZy5H4a5ZwgKWLlpkQDz", "pubkey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKLIwkTTXA56sUlUjEulXXZRvZy5H4a5ZwgKWLlpkQDz",
@@ -43,10 +45,6 @@
"tags": ["server"], "tags": ["server"],
"nebulaIp": "10.157.0.3" "nebulaIp": "10.157.0.3"
}, },
"icdm-root": {
"external": true,
"system": "x86_64-linux"
},
"isaiah": { "isaiah": {
"builder": true, "builder": true,
"ip": "10.42.1.6", "ip": "10.42.1.6",
@@ -61,12 +59,12 @@
"external": true, "external": true,
"system": "x86_64-linux" "system": "x86_64-linux"
}, },
"gregory.hellings-mbp": { "ivr": {
"external": true, "external": true,
"system": "aarch64-darwin", "system": "aarch64-darwin"
"user": "gregory.hellings"
}, },
"jeremiah": { "jeremiah": {
"aliases": ["buildbot"],
"builder": true, "builder": true,
"ip": "10.42.1.8", "ip": "10.42.1.8",
"pubkey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOjQjXq9WYU2Ki27BR9WwJ4ZruS/lJXbjC1b0Q42Adi0", "pubkey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOjQjXq9WYU2Ki27BR9WwJ4ZruS/lJXbjC1b0Q42Adi0",
@@ -76,20 +74,19 @@
"tags": ["builder", "kube", "server"], "tags": ["builder", "kube", "server"],
"nebulaIp": "10.157.0.5" "nebulaIp": "10.157.0.5"
}, },
"joel": { "kuma": {
"external": true, "ip": "10.42.1.19",
"ip": "10.42.0.4", "nebulaIp": "10.157.0.8",
"ts": null "pubkey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIhr+LmYMOk4Hixxew2FiAvL8sycgQvnhK8PBGjfnkJb",
}, "system": "x86_64-linux",
"gregs-MacBook-Pro-16-inch-Nov-2024": { "tags": ["server"]
"external": true,
"system": "aarch64-darwin"
}, },
"lithic": { "lithic": {
"external": true, "external": true,
"system": "aarch64-darwin" "system": "aarch64-darwin"
}, },
"linode": { "linode": {
"connectAddr": "thehellings.com",
"ip": null, "ip": null,
"pubkey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMv9Zud3kZOl86gtmkn+uj3D4kiXWDPtyUL02VVLNR4Q", "pubkey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMv9Zud3kZOl86gtmkn+uj3D4kiXWDPtyUL02VVLNR4Q",
"ts": "100.109.86.8", "ts": "100.109.86.8",
@@ -97,10 +94,6 @@
"tags": ["public", "server"], "tags": ["public", "server"],
"nebulaIp": "10.157.0.1" "nebulaIp": "10.157.0.1"
}, },
"ivr": {
"external": true,
"system": "aarch64-darwin"
},
"MacBook-Pro.local": { "MacBook-Pro.local": {
"external": true, "external": true,
"system": "aarch64-darwin" "system": "aarch64-darwin"
@@ -109,38 +102,10 @@
"external": true, "external": true,
"system": "aarch64-darwin" "system": "aarch64-darwin"
}, },
"nas1": {
"external": true,
"ip": "10.42.1.14",
"ts": "100.114.187.61"
},
"nixos": { "nixos": {
"external": true, "external": true,
"system": "x86_64-linux" "system": "x86_64-linux"
}, },
"printer": {
"external": true,
"ip": "10.42.1.3"
},
"proxmoxtemplate": {
"external": true,
"system": "x86_64-linux"
},
"pve2": {
"external": true,
"ip": "10.42.1.15",
"system": "x86_64-linux"
},
"pve3": {
"external": true,
"ip": "10.42.1.16",
"system": "x86_64-linux"
},
"pve4": {
"external": true,
"ip": "10.42.1.17",
"system": "x86_64-linux"
},
"wsl": { "wsl": {
"external": true, "external": true,
"system": "aarch64-linux" "system": "aarch64-linux"
@@ -155,5 +120,57 @@
"tags": ["builder", "kube", "server"], "tags": ["builder", "kube", "server"],
"nebulaIp": "10.157.0.6" "nebulaIp": "10.157.0.6"
} }
},
"external": {
"chronicles": {
"ip": "10.42.1.4",
"pubkey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEBecZUva9OnZuXLaBun6/1ITo5f9p0YMLPD+q0egLRS",
"ts": "100.119.228.115",
"aliases": ["s3"]
},
"hermes": {
"ip": "10.42.1.18",
"mac": "BC:24:11:E4:72:AB",
"nebulaIp": "10.157.0.8",
"pubkey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILFYyzz/9i5rXprCQj9IL1ulrbQ6E9BOSeOcvf4D/b0G",
"tags": ["server"]
},
"k3s": {
"aliases": ["*.k3s"],
"ip": "10.42.5.1",
"nebulaIp": "10.157.100.1"
},
"nas1": {
"aliases": ["*.nas1"],
"ip": "10.42.1.14",
"ts": "100.114.187.61"
},
"printer": {
"ip": "10.42.1.3"
},
"pve1": {
"ip": "10.42.0.4"
},
"pve2": {
"ip": "10.42.1.15"
},
"pve2bmc": {
"ip": "10.42.6.2",
"mac": "00:25:90:4b:34:e8"
},
"pve3": {
"ip": "10.42.1.16"
},
"pve3bmc": {
"ip": "10.42.6.3",
"mac": "00:25:90:4a:dc:2e"
},
"pve4": {
"ip": "10.42.1.17"
},
"pve4bmc": {
"ip": "10.42.6.4",
"mac": "00:25:90:4a:d8:2e"
}
} }
} }
+6 -2
View File
@@ -16,9 +16,12 @@ let
adblock_update = c ./adblock_update.nix { }; adblock_update = c ./adblock_update.nix { };
brew = c ./homebrew.nix { }; brew = c ./homebrew.nix { };
create_ssl = c ./create_ssl.nix { }; create_ssl = c ./create_ssl.nix { };
dockerCompat = pkgs.runCommand "docker-compat" { dockerCompat =
pkgs.runCommand "docker-compat"
{
nativeBuildInputs = [ ]; nativeBuildInputs = [ ];
} '' }
''
mkdir -p $out/bin mkdir -p $out/bin
ln -s ${pkgs.podman}/bin/podman $out/bin/docker ln -s ${pkgs.podman}/bin/podman $out/bin/docker
''; '';
@@ -29,6 +32,7 @@ let
inject = c ./inject.nix { }; inject = c ./inject.nix { };
setup-ssh = c ./setup-ssh { }; setup-ssh = c ./setup-ssh { };
upgrade-pg-cluster = c ./upgrade-pg-cluster.nix { }; upgrade-pg-cluster = c ./upgrade-pg-cluster.nix { };
zim-updater = c ./zim/updater.nix { };
}; };
x86Linux = { x86Linux = {
qemu-hook = c ./qemu-hook.nix { }; qemu-hook = c ./qemu-hook.nix { };
+28 -28
View File
@@ -2,18 +2,18 @@
"en": { "en": {
"gutenberg": { "gutenberg": {
"name": "gutenberg_en_all", "name": "gutenberg_en_all",
"version": "2023-08", "version": "2025-11",
"hash": "sha256-OXmdHdsLZcW4nCUQsy7sMpUssS8NV7ztkCgS/nsISuw=" "hash": "sha256-AWd8jVVKHKssv9AgrJnryn3Wx0084NE/JmorpgPfryg="
}, },
"phet": { "phet": {
"name": "phet_en_all", "name": "phet_en_all",
"version": "2025-03", "version": "2026-05",
"hash": "sha256-ARuUzU2o17J2/ZedHc2acXl33dtHCbQJEb72UQUEm1Y=" "hash": "sha256-zAAq/X5rjQUiYmjMpBtWP5z3J2ZHJMmIxFKnxLAhOlA="
}, },
"wikibooks": { "wikibooks": {
"name": "wikibooks_en_all_maxi", "name": "wikibooks_en_all_maxi",
"version": "2025-10", "version": "2026-04",
"hash": "sha256-ONBh/ze1Fv2Ffm5b9vDzYS/i2cWSa4pM4MLZnozr2n8=" "hash": "sha256-wt7Zr+RkfCsFrOudMCYBADacu6IvPQDkZ6Y0VG2j9hA="
}, },
"wikipedia": { "wikipedia": {
"name": "wikipedia_en_all_maxi", "name": "wikipedia_en_all_maxi",
@@ -22,40 +22,40 @@
}, },
"wikisource": { "wikisource": {
"name": "wikisource_en_all_maxi", "name": "wikisource_en_all_maxi",
"version": "2025-11", "version": "2026-05",
"hash": "sha256-p1Jio+PMTZVSLIDIOBeMG3acXJg83CwQM7zIWDUyozM=" "hash": "sha256-OA4b+U8mxpcX3fst6hrMyctucYTQOlG/b4qZDiVlcf4="
}, },
"wikiversity": { "wikiversity": {
"name": "wikiversity_en_all_maxi", "name": "wikiversity_en_all_maxi",
"version": "2025-11", "version": "2026-05",
"hash": "sha256-IG/gAUdc/vHRrIWGHhw8vMJdLWwqrNbfh+SiclQRIAI=" "hash": "sha256-8mZ1CSUcF4QnDIyN0M2KedQ4pcSUCmzHBlOm93MYpCE="
}, },
"wiktionary": { "wiktionary": {
"name": "wiktionary_en_all_nopic", "name": "wiktionary_en_all_nopic",
"version": "2025-09", "version": "2026-05",
"hash": "sha256-Ghcb60qeGaSJtTKQkJoMx/XucX7Lt1XY145lD3gHlMg=" "hash": "sha256-Dwiz+viVQt0zb077R9KQRgtUtxG9ixA/DeXAkCdD4rM="
} }
}, },
"fr": { "fr": {
"gutenberg": { "gutenberg": {
"name": "gutenberg_fr_all", "name": "gutenberg_fr_all",
"version": "2025-10", "version": "2026-01",
"hash": "sha256-gLHxLXJNwwcxM/mZHtoJ8ojbGQ1fugxgni/+RXccwhU=" "hash": "sha256-sGn1TeKwBK0+Er5YOJWq6g0itEm4gIGvKxv/PW0DIao="
}, },
"phet": { "phet": {
"name": "phet_fr_all", "name": "phet_fr_all",
"version": "2025-03", "version": "2026-05",
"hash": "sha256-CSboZNTIowLLhp1u9wkxH8xmu3LvQNx5q493AOYJRIc=" "hash": "sha256-bJmchFnaPcofE/hy3ZcRggMT9osHqXwLbwMLJ+cpF28="
}, },
"wikibooks": { "wikibooks": {
"name": "wikibooks_fr_all_maxi", "name": "wikibooks_fr_all_maxi",
"version": "2025-09", "version": "2026-07",
"hash": "sha256-KHCc/73L5Bd9iZ47SRV6vpI8fVM1v9hk1TpEvTro2uo=" "hash": "sha256-csI+E5UFGi42BLGWWHxQhVr5KSihCFc53KGKwo557Ck="
}, },
"wikipedia": { "wikipedia": {
"name": "wikipedia_fr_all_maxi", "name": "wikipedia_fr_all_maxi",
"version": "2025-06", "version": "2026-05",
"hash": "sha256-ve7Mbh96/ObNbV/KVNYZpfLN+HdWlJ7C5LItEdVkRH0=" "hash": "sha256-YUAbGzYYr+c2RQqGjHIF9XL1kNsxDgRKnHK1H7/PtDE="
}, },
"wikisource": { "wikisource": {
"name": "wikisource_fr_all_maxi", "name": "wikisource_fr_all_maxi",
@@ -64,25 +64,25 @@
}, },
"wikiversity": { "wikiversity": {
"name": "wikiversity_fr_all_maxi", "name": "wikiversity_fr_all_maxi",
"version": "2025-09", "version": "2026-05",
"hash": "sha256-55fdtw/cRezq6nkRp6wuwkukBiqsQKdwh9QWVAgFcBI=" "hash": "sha256-nVDHtkWIOJkoiGixnA1zVR1QS58thjc12FJyagK3Ec0="
}, },
"wiktionary": { "wiktionary": {
"name": "wiktionary_fr_all_nopic", "name": "wiktionary_fr_all_nopic",
"version": "2025-11", "version": "2026-05",
"hash": "sha256-P0CJptee5rDzccxyRDBzyRLuuFOcaLsJYi6DkBFUfIc=" "hash": "sha256-7UXByW2IIL0hec8RPT39jpg5IEGvRMD47hc4Y4vFkJs="
} }
}, },
"ht": { "ht": {
"phet": { "phet": {
"name": "phet_ht_all", "name": "phet_ht_all",
"version": "2025-03", "version": "2026-05",
"hash": "sha256-bHrPzE8H7ptrP6r5wPlXSsXNlTiKxJ9KatABC4kwx+s=" "hash": "sha256-GiJ1jllhioyMYidQ7+Lcbdd9JN2yf04ZQgnO8XaGAqY="
}, },
"wikipedia": { "wikipedia": {
"name": "wikipedia_ht_all_maxi", "name": "wikipedia_ht_all_maxi",
"version": "2026-04", "version": "2026-07",
"hash": "sha256-qUX0pKxIyNsWX4V6kNIsP4Z9nc6TDhwdDR0MmpDOQFs=" "hash": "sha256-InS9cMRaIv9ArlKVwKUypz56m4DgSR7Tl6XpSTMzH+o="
} }
} }
} }
+165 -110
View File
@@ -9,7 +9,7 @@ import (
"net/http" "net/http"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "reflect"
"regexp" "regexp"
"sort" "sort"
"strings" "strings"
@@ -17,27 +17,144 @@ import (
const BASE = "https://download.kiwix.org/zim" const BASE = "https://download.kiwix.org/zim"
func getTypes() []string { // ///////////////////////////////////////////////////////////////////////////
return []string{ // //////////////// THE BLOB ITSELF /////////////////////////////////////////
"phet", // ///////////////////////////////////////////////////////////////////////////
"wikipedia", type Blobs struct {
"wiktionary", En Language `json:"en"`
"wikiversity", Fr Language `json:"fr"`
"wikisource", Ht Language `json:"ht"`
"wikibooks", dirty bool
"gutenberg", }
"ted",
func (b *Blobs) Populate() {
done := make(chan bool)
waitFor := 0
// Launch self-populating efforts
blobType := reflect.Indirect(reflect.ValueOf(b)).Type()
for f := range blobType.Fields() {
if f.IsExported() {
//fmt.Printf("%s:\tBeginning population efforts\n", f.Name)
waitFor += 1
go reflect.Indirect(reflect.ValueOf(b)).
FieldByName(f.Name).
Addr().
Interface().
(*Language).
Populate(strings.ToLower(f.Name), done)
}
}
// Wait until all languages are completed
for d := range done {
waitFor -= 1
if waitFor == 0 {
fmt.Println("Completed waiting for all languages")
close(done)
break
}
b.dirty = b.dirty || d
} }
} }
func getLanguages() []string { /////////////////////////////////////////////////////////////////////////////
return []string{ //////////////////////// The Language ///////////////////////////////////////
"ht", /////////////////////////////////////////////////////////////////////////////
"en",
"fr", type Language struct {
Gutenberg *Zim `json:"gutenberg,omitempty"`
Phet *Zim `json:"phet,omitempty"`
Ted *Zim `json:"ted,omitempty"`
Wikibooks *Zim `json:"wikibooks,omitempty"`
Wikipedia *Zim `json:"wikipedia,omitempty"`
Wikisource *Zim `json:"wikisource,omitempty"`
Wikiversity *Zim `json:"wikiversity,omitempty"`
Wiktionary *Zim `json:"wiktionary,omitempty"`
dirty bool
}
func (l *Language) Populate(code string, done chan bool) {
childDone := make(chan bool)
waitFor := 0
languageType := reflect.Indirect(reflect.ValueOf(l)).Type()
l.dirty = false
for f := range languageType.Fields() {
if f.IsExported() {
ptrPtrZim := reflect.Indirect(reflect.ValueOf(l)).
FieldByName(f.Name)
if ptrPtrZim.IsValid() && !ptrPtrZim.IsNil() {
waitFor += 1
go reflect.Indirect(ptrPtrZim).
Addr().
Interface().
(*Zim).
Populate(strings.ToLower(f.Name), code, childDone)
} else {
// TODO: Figure out how to set a value over the nil pointer
// of the field, so we can auto-detect when these are available
// in the future
// waitFor += 1
//z := &Zim{Name: f.Name, Version: "1999-01-01", Hash: ""}
//ptrPtrZim.Set(reflect.ValueOf(z))
//go z.Populate(strings.ToLower(f.Name), code, childDone)
}
}
}
// Wait until children are all done
for d := range childDone {
waitFor -= 1
if waitFor == 0 {
close(childDone)
break
}
l.dirty = l.dirty || d
}
//fmt.Printf("%s\tFinished populate\n", code)
done <- l.dirty
}
// ///////////////////////////////////////////////////////////////////////////
// ////////////////////// A Single Zim ///////////////////////////////////////
// ///////////////////////////////////////////////////////////////////////////
type Zim struct {
Name string `json:"name"`
Version string `json:"version"`
Hash string `json:"hash"`
dirty bool
}
func (z *Zim) Populate(category string, language string, done chan bool) {
//fmt.Printf("%s:%s\tBeginning populate for\n", language, category)
// Look for a possible Zim file
links := getLinks(getPage(category))
link, err := getName(links, category, language)
if err != nil {
fmt.Printf("%s:%s\tNo zim found\n", language, category)
done <- false
return
}
//fmt.Printf("%s:%s\tFound link: %s\n", category, language, link)
// Extract name and version
re := regexp.MustCompilePOSIX("^([a-zA-Z_]+)_([0-9-]+)\\.zim$")
match := re.FindStringSubmatch(link)
if len(match) != 3 {
fmt.Printf("%s:%s Matches: %s", language, category, match)
os.Exit(1)
}
// Check if the name and version mismatch
if match[1] == z.Name && match[2] == z.Version {
fmt.Printf("Skipping existing hash: %s\n", link)
done <- false
} else {
z.Name = match[1]
z.Version = match[2]
// Fetch the Zim file, if it differs from what we currently have
z.UpdateHash(category)
done <- true
} }
} }
// Helper function to fetch the HTML of a given type page
func getPage(t string) string { func getPage(t string) string {
page, err := http.Get(fmt.Sprintf("%s/%s/", BASE, t)) page, err := http.Get(fmt.Sprintf("%s/%s/", BASE, t))
if err != nil { if err != nil {
@@ -48,6 +165,7 @@ func getPage(t string) string {
return string(pageBytes) return string(pageBytes)
} }
// Helper function to parse out all the links from the page
func getLinks(page string) []string { func getLinks(page string) []string {
ret := []string{} ret := []string{}
@@ -60,6 +178,7 @@ func getLinks(page string) []string {
return ret return ret
} }
// Helper function to get the most likely link for this particular entry
func getName(links []string, t, lang string) (string, error) { func getName(links []string, t, lang string) (string, error) {
candidates := []string{} candidates := []string{}
prefix := fmt.Sprintf("%s_%s_all", t, lang) prefix := fmt.Sprintf("%s_%s_all", t, lang)
@@ -79,44 +198,39 @@ func getName(links []string, t, lang string) (string, error) {
} }
} }
func getHash(ch chan result, file, category, language string) { // Helper function to get the hash value from the resulting link
// TODO: Only call this if the file doesn't already have a hash func (z *Zim) UpdateHash(category string) error {
// in the existing file file := fmt.Sprintf("%s_%s.zim", z.Name, z.Version)
fmt.Printf("Fetching hash for %s\n", file)
// First fetch the file into our local Nix store
fmt.Printf("Fetching hash: %s\n", file)
cmd := exec.Command("nix-prefetch-url", fmt.Sprintf("%s/%s/%s", BASE, category, file)) cmd := exec.Command("nix-prefetch-url", fmt.Sprintf("%s/%s/%s", BASE, category, file))
out, err := cmd.Output() out, err := cmd.Output()
if err != nil { if err != nil {
fmt.Printf("Error fetching hash for %s (category: %s, language: %s): %v\n", file, category, language, err) fmt.Printf("%s: ERROR fetching hash: %v\n", file, err)
if exitErr, ok := err.(*exec.ExitError); ok { if exitErr, ok := err.(*exec.ExitError); ok {
fmt.Printf("Command stderr: %s\n", string(exitErr.Stderr)) fmt.Printf("Command stderr: %s\n", string(exitErr.Stderr))
} }
ch <- result{category, language, ""} return errors.New("Error fetching file")
return
} }
hash := strings.TrimSpace(string(out)) hash := strings.TrimSpace(string(out))
fmt.Printf("Successfully fetched hash for %s (category: %s, language: %s)\n", file, category, language) fmt.Printf("%s: Successfully fetched raw hash\n", file)
ch <- result{category, language, hash} fmt.Printf("%s: Hash is: %s\n", file, hash)
}
func outputIsValid(o map[string]map[string]Zim) bool { // Then, convert the hash to SRI
for a := range o { cmd2 := exec.Command("nix", "hash", "convert", "--to", "sri", hash, "--hash-algo", "sha256")
for b := range o[a] { out2, err2 := cmd2.Output()
if o[a][b].Hash == "" { if err2 != nil {
return false fmt.Printf("%s: Error converting hash to SRI: %v\n", file, err)
if exitErr, ok := err.(*exec.ExitError); ok {
fmt.Printf("%s: Command stderr: %s\n", file, string(exitErr.Stderr))
} }
return errors.New("Error fetching file")
} }
} z.Hash = strings.TrimSpace(string(out2))
return true z.dirty = true
} fmt.Printf("%s: Successfully convert hash to SRI: %s", file, out2)
return nil
type result struct {
category, language, hash string
}
type Zim struct {
Name string `json:"name"`
Version string `json:"version"`
Hash string `json:"hash"`
} }
func main() { func main() {
@@ -125,90 +239,31 @@ func main() {
// Determine the output file path // Determine the output file path
var outputPath string var outputPath string
if *outputFile != "" {
outputPath = *outputFile outputPath = *outputFile
} else {
// Get the directory where updater.go is located
execPath, err := os.Executable()
if err != nil {
// Fallback to current directory if we can't determine executable path
outputPath = "blobs.json"
} else {
dir := filepath.Dir(execPath)
outputPath = filepath.Join(dir, "blobs.json")
}
}
fmt.Println("Writing file to ", outputPath) fmt.Println("Writing file to ", outputPath)
// Read existing cache if it exists // Read existing cache if it exists
cached := make(map[string]map[string]Zim) var blobs Blobs
if data, err := os.ReadFile(outputPath); err == nil { if data, err := os.ReadFile(outputPath); err == nil {
if err := json.Unmarshal(data, &cached); err != nil { if err := json.Unmarshal(data, &blobs); err != nil {
fmt.Printf("Warning: could not parse existing cache file: %v\n", err) fmt.Printf("Warning: could not parse existing cache file: %v\n", err)
} else { } else {
fmt.Printf("Loaded existing cache from %s\n", outputPath) fmt.Printf("Loaded existing cache from %s\n", outputPath)
} }
} else {
fmt.Printf("Error reading file: %s", err)
os.Exit(1)
} }
blobs.Populate()
output := make(map[string]map[string]Zim) ret, err := json.MarshalIndent(&blobs, "", " ")
comms := make(chan result)
pendingHashes := 0
for _, t := range getTypes() {
page := getPage(t)
links := getLinks(page)
for _, lang := range getLanguages() {
if file, err := getName(links, t, lang); err == nil {
if _, ok := output[lang]; !ok {
output[lang] = make(map[string]Zim)
}
// Check if this file already exists in cache with same name
if cachedLang, ok := cached[lang]; ok {
if cachedEntry, ok := cachedLang[t]; ok && cachedEntry.Name == file {
// Reuse cached hash
fmt.Printf("Using cached hash for %s (category: %s, language: %s)\n", file, t, lang)
output[lang][t] = cachedEntry
continue
}
}
// File is new or name has changed, fetch hash
output[lang][t] = Zim{file, ""}
pendingHashes++
go getHash(comms, file, t, lang)
}
}
}
// Only wait for results if we actually spawned goroutines
if pendingHashes > 0 {
hashesReceived := 0
for r := range comms {
if entry, ok := output[r.language][r.category]; ok {
entry.Hash = r.hash
output[r.language][r.category] = entry
}
hashesReceived++
if hashesReceived >= pendingHashes {
close(comms)
break
}
}
}
// Verify all hashes are present
if !outputIsValid(output) {
fmt.Println("Warning: Some hashes are missing from the output")
}
ret, err := json.MarshalIndent(output, "", " ")
if err != nil { if err != nil {
fmt.Printf("Error marshaling JSON: %v\n", err) fmt.Printf("Error marshaling JSON: %v\n", err)
os.Exit(1) os.Exit(1)
} }
err = os.WriteFile(outputPath, ret, 0644) err = os.WriteFile(outputPath, []byte(fmt.Sprintf("%s\n", ret)), 0644)
if err != nil { if err != nil {
fmt.Printf("Error writing to file %s: %v\n", outputPath, err) fmt.Printf("Error writing to file %s: %v\n", outputPath, err)
os.Exit(1) os.Exit(1)
BIN
View File
Binary file not shown.
-37
View File
@@ -1,37 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 87huqg LKhlbZI1BygDI8E4kkzhw0/Y1BfWnzekf/URa/Bma30
uT7QzE8DPX8j3us7oNRKwu6hPUFpQosbcMRmMNgS/Gw
-> ssh-ed25519 8UnW5Q dDAJI5EnPMIhs5H21wLT84GWhkROEJRXE1QVp1aOH38
qZJt4Kip5qVZl9QoIFEXgrhtrlQEpbkfLarCgaHugj8
-> ssh-ed25519 UFfTmg kbrSoge204JvRPBszhAfMewPM4oHg0HkF52BNeb9kx8
E4ASRdn0pjF//GiFCjmRlgXRS2wiJxIXDFSjldMtTdQ
-> ssh-ed25519 xNtnoA 7b9/Z/qUEmRnFCiCYzVGJVvxvV8onjZemSg6sllaDyA
bQosZIGbaSsUqFO2JuRpIhm3FJd79JyYS43A9+zr+1w
-> ssh-ed25519 aY2AXA m4gIzzAX8pkBHHzsSykIy24E6Kru/I4uNnjihKH3JHg
S18CWIY5wNcR5PVkCqbjp1FJRrGxco6fdoykQeHhyX0
-> ssh-ed25519 AQhf1g LBmvyUbKRLKtPGIEqt+NwOSrtGwlFt2zqgdmRDHu9n8
zb8OnKRsJBEkH6eJ76mlKvJmtZ8NvVwVS9/0tsZlMUk
-> ssh-ed25519 mOmPfg TuPbRMlX9eRATxSbv6v88TtzGhOKWn5FOkIg4xR6FH0
NLNzJM/9r2jZ70Y2r5Hsc36gcRTSPw40Aabn/H7OE+4
-> ssh-ed25519 YJiRbw bVMyOOgBcFFRNulym46YwKAIPlOkbQhmQAo9kl4dRx8
5W2fIxGXCXbzULOismGg4NxE+VQ8LDEbODlJ0OpFMiI
-> ssh-ed25519 Nl/5yA ydFS0bVjjDzymhQFaBJ3YqDREQDpVO6VzgS2MBtuOUo
tNzj/85BiYe6th2N6A9ZkMSPKduwAIe/qnf2NVJiHOg
-> ssh-ed25519 GdLgCQ wmfT7bCzwnkwEtn2mRnElIM75MmdRw+33MhSegSHJWk
YHrCYB1wF1njNjzpIy3hKZ9l1cj7m5yicLuj71TvKr8
-> ssh-ed25519 tOH/HQ z5/GMQOtkpMWwWdMXqxmf12MM84xkgXL/OLliq3RHh0
mVhBt+uc7z/YkoIAyXTqBgv00cJOrZ0bsBP0lD9S24c
-> ssh-ed25519 FpzvfQ D8N5JQ+3rGdSZIPmzlZqO5VpS90v6r99WMXtyUqCGiw
A2SSvI4H5TRY13R/iOa60bCdc0zR6lUAHJVHfAUR5mQ
-> ssh-ed25519 2UotMw eaM1Kkzw53Oq8lW0BFn3rqWFcTQaTz9jcDsULDg/fwU
3QVYFrhKnvwWDpIdsyTp0amontUXePko8z8PeUub9EE
-> ssh-ed25519 kdPvzQ 08LE8a24S5cvuK9DVWD2ta0GjJMNzUidmgYT4RfhQDA
cRFH8vOr2y1/C9F2wZWV2deUxUpoL34IFRyOBHPYifI
-> ssh-ed25519 onmXpg J5MKGIovNwv4FyTN4ofExlHV8qYzU/J9O3MI4tZYcTo
iagT0Ypo8gTwvGpV66XNuNPedefx2S72q9hyeB2Rz/w
-> ssh-ed25519 CnhD0g se/N4hrYxOiukByYzsIhxToceXNuBO7J7VmM4muJ3Dk
cW+WW8iWjj3eXDqDO8aEON1ZH/+6AXQGAEXkLRbL3AI
-> ssh-ed25519 4ep2UA uyjvubY39oSGeCNsX3/VIdM5CzNBlrnRpkF+YN5MBCo
xiNuksI7olV5Db392Vjz/7uDNDIssGmI9bez6vSOXTk
--- VsGbd8K7JzHe/eoYUeTMwcg/GrY9SXVzNxL4HZ23tKQ
£_÷t/¢ªØËVÎÞ}7J'%?™Á‰Å0“¤¼^õ¿-„ÏÛ„äu4¥ù‹íäóü0!®ÝîËðMÜÅ·
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+36 -36
View File
@@ -1,37 +1,37 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 87huqg CsPCBXcVp7krsPi1k0WbjKFZxUzuZNJkkpOImMDWNns -> ssh-ed25519 8UnW5Q MDrURGpcaqY6DVIURK6dJs7xKCGLtFS8+hH0UCRT7G4
h6evECCNa5VGBe1dtbVwOBFBPkzwUKPFyVdQsTNMUXo qsqMoWCrssVlJ2kP1cvP9+Fj+c07iFvbFs3Cs+RYVLM
-> ssh-ed25519 8UnW5Q 1pioLo4kA+RJ6r35H9FNCQ5LZqmYUmxZTVyTdD0o92Q -> ssh-ed25519 UFfTmg lTHOOV5/G7IPaYWqrAwM9Nb75//N9O1wMDFSUtyo1gI
4r/sOb3IcQElEJnKAgmYeHtubm1Hk/cdiY6gUI1GkHg kEWctDmQRHNzxMIwONsZo9EEIc/wkPxqX851BO6ohYo
-> ssh-ed25519 UFfTmg ruMzDG9lKKSHo2I1L/2wigVZs1Jhi6aTNmrr4zAyEiI -> ssh-ed25519 xNtnoA lm6OHoKNa8wB1ML5lA/xl13Xp8WUSF2UY89bP8BZP0E
3gsAmzM6fE8RL/fLL63pPIH75P9TW954nw11/JpU77M iPDWUaoViQ7faVkUf2V1MQxrklAw8lJ2KXfJZTYN2X4
-> ssh-ed25519 xNtnoA eTZoJFu1SqUoUGPcdVDw/2wW82xvRiSCnAmQSZPQT2w -> ssh-ed25519 aY2AXA 4E8FsRsfsEKsLNVvBRTAoxghfex8omAQcy8NKzJ17kw
Y9Cf+/h80vn2w6G9n+V4uNV7bj3tpOT1KWRKajM7d5k uzZQp9nVfyVH3dz0UinqZjsZ0Kft7tPVSk1EkE6NvA8
-> ssh-ed25519 aY2AXA c4MkdSio2FFkulOBKDSAG3Iq71ghRdw8/SQF0B98chY -> ssh-ed25519 AQhf1g rgcA2UeG0s75kSpok9+VR4ixNyZUqD+8ye1TJsMMA3Q
lvT+m2ey5+HqipuC7MrPQIKu8KrSsLHM0XRK8c0iS8w rfM5/54WWHrnG1qfex57tGH97lbvKM+J6TGztYOrU+c
-> ssh-ed25519 AQhf1g vLig+8a5jPo3cQhdmQw/C/P1hgzKHiVkVwUTkMBNmTk -> ssh-ed25519 r/3ipA 7pNJRvOFO5v2nlMPbXP9oad6jp1pPAsByfiEhdCTAWI
N5ROr2EtHpTwti7NByDiR8R3pOQ/STwlIuNeY1pDA20 Vh+iyg2P6fvNWyCS+V4087zRf+pCIBj0jsPX0DtPp0c
-> ssh-ed25519 mOmPfg WcbxDQfraXfxkN1+IGaArpIHOmlUlhGjBijQt5ZYSxE -> ssh-ed25519 mOmPfg 9WuzH4QasTe0NNcIf+XSremq5GuBZoKP+7t4MJNAFA0
6KHLewxXWwo8fVIuaTuY/T/igsI6CKqEl2tyM/gkn6g 5E1Rbupw8IUnTuicTubXWmwkJ2xVg5K4BpkZCsUj5UU
-> ssh-ed25519 YJiRbw IblKWpY9DeDSWDfvlEmNeWSV1lGdz9aHcv2oQVmKQFI -> ssh-ed25519 YJiRbw msPFM69Tuy/luxASGVA8ey77vqtvXNy7ytf2VxQWNi8
qPcdGcA6Z7YaLL5umR8ZOKzOyNIUJVHRBpV5HyAJeqw oD5vRs439A/YT5FxkSltl1Qf56NNhiKt17++vlFvwPA
-> ssh-ed25519 Nl/5yA wr0Q96yztc+Rf88q6ooiDHlKqpVdWPkRWApfJsc7uQc -> ssh-ed25519 Nl/5yA C3zn641k6eFQePbp2q7dwlIu7Iiw2aU5dmSrH2HCai4
hQZTwZ36mkajMcSbxDsL+TtAezJIY+H+J7VaU1QOqEo v1/XJRKIrIgHWfFtSDaFCvOKtcIR84abUZHPjaxP5bw
-> ssh-ed25519 GdLgCQ LiwfxrAh9dLjMeo6FglQzvUQ3hfWRAZr2naADkB5/WM -> ssh-ed25519 GdLgCQ ZztOWiw1ao1pvJ9REB/wBuxq00uyO+JAkIWjLUMueSc
Bn4fnoqTvKPd73qi28NAgAN8AZl4EWcr9e/uhuUwVgI zXSv3MauG2E2el+Yv5oocTgDQjQ1fKXLpm6y2OTyIvw
-> ssh-ed25519 tOH/HQ x35ypXVDI9C1wpquWxDUFYXYHxEsD2NJ0VIDosRONyE -> ssh-ed25519 tOH/HQ /eEgAf2KH1Zgd4yQf+kzyESkvPI8GKJC0MAJl+8+WD4
Aa5eZt98GQQZmKlBDzRC9KRyMCy2z1htSAsjKNGCuFw H35T+ulGSCrWAuIsZs8ISRJRj2wqpRrOGlaoq9fnN5o
-> ssh-ed25519 FpzvfQ jlAbIzsWi8eX+PTKn100NaiSoezN1kXzZ3gWUOKfQVg -> ssh-ed25519 FpzvfQ dRq/NtT/TxJ/k9WlaMl/PrLTvPzkhV8LpF/LxjqjGmM
NQARp2qsxIdSG3OLJyP33A97r6cBRaMSaneT8NBnhDI LJN8xxnNF3EcMmXKdLhc70b2Y6n9qS3A5wdFXY6hUjw
-> ssh-ed25519 2UotMw 53sXK937St2F3MzVIhmsjH6WeCSRdkpv4oFa2ZBaelI -> ssh-ed25519 2UotMw I+kJsu4GAflSfMjzE/8+vp6AZb88OpiCREuxfAnQPis
lNsjlQzS8Szj0FcAvrQno9rDO17iKDjMN7VwMLvIleE hRu7IbLMdc3U+NQo1PDhc+O9uyd/wJZyPtfTv9z9TvI
-> ssh-ed25519 kdPvzQ YdeMlv40jR9bFnXVjPJDpvCnqn091dCKAB60m4Obwgo -> ssh-ed25519 kdPvzQ uOLSQFzsGSNg1HsiJLCYi2Lp8pasc7H/jhUBlf6b0zg
vgPAO0evfCXQUX7Tu/G9ERUhLO3KiWXqpxIqATDl5vw KbUOl2WOsc6VuAC33SjEJS3tM3o82A3QO0bA9wd0rbA
-> ssh-ed25519 onmXpg mrDB6F061SjeYOZuUJVvZP8SzOVrFdpAAEfgPOzp608 -> ssh-ed25519 onmXpg NKdAvcN3TStWYtQeLW1oEn7+shQuuNBndHaQRAU4f1o
AzAEEHK6Q71YxPfiljl7ZCy0b3YBdSBMKORJd7Opkck vCuDnPc3tayIwDbHJneLQNoENyfA6GRpQi6+OZ34Jjc
-> ssh-ed25519 CnhD0g Ov3v97PyY79WoXUDAdvXEZvTE7ruIgDeXVz3jD5O1HY -> ssh-ed25519 CnhD0g Co6fy3fm8BUi2qn+xBY1X33N2m40jEM7CJhSQcLokR0
+0rSmiqdxP6PgplxLkim4AJtKPcjn7OlkXpcu0BsI4s kwrOzTRiVe1aQH/P+ua3xZNgNRZh2pfQrQl2k2Y727Q
-> ssh-ed25519 4ep2UA bDGTw6Msbh9sOp66l1VKGrT53AlrPv+QG2T6ZJv1pDk -> ssh-ed25519 4ep2UA /f1HxU62FqhDJyJ9fPMKiqJdw1m/UjASKuYhY5Aq8D8
WvHFJ3LIlpiuVhHUxY6egKifWNepzIB7Ls2R4Kx1Kng tckIOvPq3Qid9Z5ud2v9syaed/h+3GrackXKZonDYEg
--- Ec6/6bQEn4GQOedrSzE+Yw1xRjQA34sj29Tr3zLFgZo --- FHj/yA6RDV1VYPsi84z5Y3NrbfVUthwdtuRWqiKC57Q
NïP¢uGc!Wcݼ¯£ \¼ìæ—K-©;]Ðu¹!,ó$#nŒ¶dZ‹«­¦yž“-kX’BÕÙƒ°·ªc'‡Lò¯Flݪš6L‚n˸n’Ý£f$ƒðÀ´ê Õ=Â7T÷Ü`6¦K./ ¾¿àO Ö¼‰R•Pá€K…2NYqWÖ¹£®ê0v{±µi'¢žÖVûÆ!+‘|ÎÕ0¿ŽšÆ¼ú´Ìi ½†Ä?QŽq¢2Ô5ÖÀéŽ gÜ/c_
Binary file not shown.
+36 -36
View File
@@ -1,37 +1,37 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 87huqg OP0JAd66/SUS9oBMmOAUdDc+zLgKJ90OUrfO5fhf/zk -> ssh-ed25519 8UnW5Q /cVdlKHdFUszYMCldfAZVCCHSt15HjcWFtz2TkiXyjY
YUlZvlaZF8o7BBPEYbxDeqiMmOnV3HdUUX3aUdhnPKk DWQdhHSYXFTHJG21uhDMlljeSqCKSriFtDW3LptRtK8
-> ssh-ed25519 8UnW5Q VD5yOGQB6wS7ChQwaLFCEYEF5Yt6bCA7mHrytolI8WU -> ssh-ed25519 UFfTmg 4ezUQ1CrfVmPvm/B4twGSqbYgN5aOKe7TfOzJCwzJXQ
Jphq2HxVsMJD79yZM1SlxpD5RuJnE05OfuH0aOIGPvk MiEugBcdP9lcO/nP1mpuf7lhPXKbUUd9zVu0gmeXasU
-> ssh-ed25519 UFfTmg 1s7VkQEbq1L9BCAOVlCQ4NfPfwYjcqItN4PMatuSTjE -> ssh-ed25519 xNtnoA I/664KfHWJsCcRxQC47dccXgl31HoxnUlt697f5cID4
EOj0rFqARHPeBRKP0chH5BJcr8lyLCFEBZ6wfAhYbbc DwENqVKt4GxU+ynL99K0kIj/qeT+krZvPXZefbij11A
-> ssh-ed25519 xNtnoA CKFIZ8blJvm+vT2xJxBz5xzp4afsIU56Z5gP6cxba3Q -> ssh-ed25519 aY2AXA 6VlRolPP+GvsEzSNDtY6NtqsV/fCLwkKX2frsVx/e34
scD+SuipcZkWT2WERFEnjwGdbA9XrXfsmIZ7r8bmM8U tBlkTlDE/iEOhO0zfgto98hiJzS4pEzr29iuZXL9nnM
-> ssh-ed25519 aY2AXA f6Mt6J6Iqdex7SP0ngYwFrQFOObwNx/kLp7QVsJkFVE -> ssh-ed25519 AQhf1g rjIeZ1pT0WmkWTxA27HfHLJRWNOSJXH1hWEFQaTWKk4
KtF/G7BBmgg0eonne52KN/hRSfc7muRg+aqllcaGZTU 4nPriRa628dVznIoL2Wqu7rC0h/34OCNgkrbqfewiZs
-> ssh-ed25519 AQhf1g sKGPNRD/rgVQj0/wModKct9dFOr1Nm20GJV44HLn7Es -> ssh-ed25519 r/3ipA UsT9khxY0QbCgjsjVq6C8w1sAc14ldHA47QIZ/z2i1M
rr4SInqIn8tUamEBACummSzUvq6TK/Nnz4M2zHY6dRQ DHf6CipFevIS+12XXO4hU8uFC9RtpDe8MZoTrdjM264
-> ssh-ed25519 mOmPfg sGlYKhIISYka5/5mVBGoCwEUk2j+6tcYRiDBtvKosVI -> ssh-ed25519 mOmPfg uVhT1cO1hfr9FF1vX01AVMfcuL4Fne8K21llW6MKAgc
938SaOYsIjFpJZJAfRV9JWUoCQZ2nm6NGn0AE5RtlM4 QJWSUgpSKCM8MionIw2uFM7sz0zrNhwPZUftDMQWfaU
-> ssh-ed25519 YJiRbw D58sw+Z+YuSoTg4pZeGOJcFCuRDVqA45R/r9MntQWB4 -> ssh-ed25519 YJiRbw Helxk3oufur9cbJSc5PLN6/LmIRCBQgD7WZqNyd292I
fpV33ShLgn3XuPxD2EZ3CQ2WdSdqmCQyfVOmMCPl9zs +9IKaKUkrJr/hWSq/+xIzYqbOqnxBBfVfBV6A+TEz/o
-> ssh-ed25519 Nl/5yA 7QHmS3lFG+cU8+Ik9iRvaXyf/vBPe7wa9sAYekQKB1c -> ssh-ed25519 Nl/5yA QDrpal6sH+qykRk9RbmNJVuQZnq1fU2KD2DfADBQFQM
dHsGrtXNbt0+reajFztW8SlGuz+0PTMsWbtUMcTaF2U XLPBHeipZz2TiS28SmQGsPikGyfhvCJCFPaFyMXtFz8
-> ssh-ed25519 GdLgCQ c+IZuoQzLMbn6N44w/SsCGaeL9KxwIe1Yj1iHLj0TQw -> ssh-ed25519 GdLgCQ EIEU+UNtsnnIDg9Cz/aUoCuLpgGysnpjMuzeWTHsMCM
KzWUk7/C1xDxZXSu5YKFiwctg0k6Vee6PmudFUPoEq8 +d6a83uoBqes28e0KTjxOulwhVPwdJ4K5dsBXAGSrDI
-> ssh-ed25519 tOH/HQ 0W8zyXYP6RzIBFfFZl3Z/b5IphG0OUZgJDgjvDC0FG0 -> ssh-ed25519 tOH/HQ ttYI97W+nqSunHhEHhaHrGPxIRmhKKyyHDgoFF6R5U4
WojVazNzk2mlfUCsNnJFC+74nYCEjO1fp0pvsq7FHLA +sf4VdWrsOTWfi7OUKET/OucniwkvctcyqP3eCqCI7E
-> ssh-ed25519 FpzvfQ mMziPqzzRrQDf0cYJS028icRScECfi8aCxPz3Xe/w1I -> ssh-ed25519 FpzvfQ hJigNhU18mMxIlIx/NvuZc9bi45PplnROyyDRzEknSk
1TzjHZYunhMmZCPMjam7LpvGtvw40hRuk0IlUUe45f0 b0aFC/vUi1CgRO3Dttodv3R/VBI5HJXk5eAb1PXY6rY
-> ssh-ed25519 2UotMw v8kYr544AHHIv1C5HJb47sFYAhLLPANZ0r1nWLjYYmo -> ssh-ed25519 2UotMw 8IEuY5An4B2NPjSyawKN6YpRlutsOjZdYpmr3Zed6EQ
Yr8QHe/V0LQJroyJncVabqS8m4YtF8mrMBMIaiZO7r0 R2PhWVN+HL+Cpa5UCeZnYDhUCDn+8wbvvHgWDyRWR4A
-> ssh-ed25519 kdPvzQ 7Uv+ltj/EOX/jseUjGXAryi9r1w6uO39ao3yeH3z0V4 -> ssh-ed25519 kdPvzQ xBmYNmttCwRBMQCyfvb16p2wuHrHwqtUo98RSRWiUCE
oVp5cJCiDi/Lb6cH708QanulTNI7386GalxHfYiZQWY oapGMLXigHx/anDaV2s9SZZosccqP1a8/2t/4yMLodM
-> ssh-ed25519 onmXpg nFhA0zvOJYDK8C7DNNIbJSi56UrjgHaXyhzQH+pNkmY -> ssh-ed25519 onmXpg hH0VAFzTN3CezRdY9KhLkYlHnrlvCo/eHlvnuTzVtWQ
Mrl7Urw2EJ/SIF+fnf4fqNMJ9QsF1YzKQLRIc4kPNPI vIyTINNw/pHL1gEl7MA4J7GvtL+8/oPjG86uDvET/jk
-> ssh-ed25519 CnhD0g slBtQIp3uM2x2NhUz+yt9z+4Y5IoGeohW03j/B0VSUU -> ssh-ed25519 CnhD0g XBpQYVj4CX7Bv64cFxR3YevKKW5Oelt1uFoQCZVR4kQ
yY1IRFJEgtNuKG6nP05XOiwPUZXTFxOgttT1gXBMBcc prmdbQuuTNMikogdkdhED8g9oWUXPP5u3Jn3qbqq6Pg
-> ssh-ed25519 4ep2UA Xe+tcFe77241jAAyj96ShjVsdCIA2ECNp72rJdefSj0 -> ssh-ed25519 4ep2UA S2PhUuDTrNBtZDdLUnnl6Ck0jAq+duWdhzAKtRNpuhQ
ruNsQAjf3dGmIxV7qNYPQAPRTWi18UDNOAETfMBAd4s dsEv7lSU0G6RAUBtqv7zg7nYt9vfTXzqvKjtTCgF0nk
--- FoB0CBe8heDBXHuPn056QFz6+RTC+AFPyRBewoI0cwo --- mNxL6onhO2/m3dfTuAosml1qIMtfUkNlucKPmG0t0so
.(\û*0›U݆P€{CˆL9Ö„ÕGèχ±£9e!‹–5)!¶j¸bÞ‘nmðÅ–b1_¨Ocþ–ÝsW¥¹6«Ðˆ Î†‹šÀ©è ˆŸÉ]tÇSìngç-ž„È`ò‘_ágÇœc$ÐH¾&úñwo[lăcßÐrz½u{€öÌ<÷åDƒgç>8<# ï*Ò\¾©w+=)É2@ú?&M—w^;{G*?¹À­÷n/™*ñ‚ð?×óÝ*¬ß1?Z8(ld:3óß¾•|ìÀßK½eû g^Ðä{âFPš€òídCŒIHÔBé¢Mg¡¶Þ®¿K•" ¤w%ìW1Góǧ<HK␍qfxt¯1„/
+37 -36
View File
@@ -1,37 +1,38 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 87huqg ua9lzblqM2d0AmRbEj9c6p8LVBxNkYYr/vH5+HFoDEI -> ssh-ed25519 8UnW5Q UlSvWFtyzP1itr1QuvrEQYhvw1oMjOgXyR1H8Geyc30
Y08ot6KWTZdHXjYUsc2hcKnQlJBtcmE1oD5+OX86J80 m7GOH/FvAh35dmtU8SrQUcHre3QjrHZ/rvbSzq+DJFI
-> ssh-ed25519 8UnW5Q QW+RWL8RfOoPfZEb+m2XHNgvlUoLZqPSDjx6riMCXDk -> ssh-ed25519 UFfTmg 4ifiDuC+WyaZCJEWLkUogxEFz/3CnwlMbBojSznie1A
DyJSnhbUWRCMUWlHYnz/jbqBxazGXEaxe6/T6CNtvsc qgeDtFVdt2+WGGlYJL43iIdu3+nmtHZJEh5R1PdwL/g
-> ssh-ed25519 UFfTmg XcNVYggkFQmj591cbFEpz0ishJgp90W1Eu1OWphmj1g -> ssh-ed25519 xNtnoA g73KMG80Xe8DP3ou9YllkmG4f5RtTu70md3WG6XVkzE
3/GL+Q2euyXgcapUXDt8Mw5Q2+bbk2C2voQgGuTtiUU gUylPhlmUwx2y4Ld2ibDFdIQHHPYGkbI9ghT/YBYuME
-> ssh-ed25519 xNtnoA CYfNyaWgYlM4oe/G2sI99gvldiKY9ScDsi7XPLnDTjU -> ssh-ed25519 aY2AXA VHCrb4MI+LIY169KZIOqlRoRHl7qeqeweI5/Q6IFq24
h07PCdnOUF4o6YggrJ27Cdc/Gb9cu5CE0cZegyqLiKc hA1eiydZmy+A8FtX8kPP9biAzI7SUPRzaJAMvayBXvE
-> ssh-ed25519 aY2AXA NxBftj7RM1QeZ5Np3Mt/xsxZ12XMtgHh/foWN2uyyT8 -> ssh-ed25519 AQhf1g Ht0O8KwIzi4FSjj3Gsx3d6tR9L1VWDssNw4MI0JH0GE
nXUQI/tjhtPSYH6GFDxw5oIQnrLrQHYfNpriXXqH5fg 6xWDy+DXY3etU3QSNs+6nS2vQ/zO6tBUcMKlpyCnWlA
-> ssh-ed25519 AQhf1g 8BTUwRGn9xPBIO+Ez2viFtp1B0LzWR69Aer0B/OfhS0 -> ssh-ed25519 r/3ipA CkosmEHp1uLBUzMTWkQLLT/2HicXU6QNQhbe2hyK3xo
uKAkoOTpuyLFnqKPXgTPYBriaNCQZz/hwSLkUKypBwo rHAaWdoqLtK7awKgXixVudFkzvvuJLqW0esFFJRTxOY
-> ssh-ed25519 mOmPfg FNLltRffV5bNxipVpxAOkfviS/RKJfrZ1TBWIVSspHM -> ssh-ed25519 mOmPfg z/D9xXbXsI2O4kOtHnaB9uqA7pAB6q2mpNzkQInNxRU
ML0HeuZwms//wyIBfXspWQPLh/DSbl5YkcyHHJ4vZ/8 ELp9idvf6ytjUlwXcwjDskx/nNxWzZBAu3z/35H2raA
-> ssh-ed25519 YJiRbw rgJDr6qSeN679l+aIfDuhonxcoGw1h5C+nVGS0ce3nE -> ssh-ed25519 YJiRbw PuTysdLGmt/N0K3HirjfBRv1v+rvnfXOl5EOZDyKOWU
c5xynEMZNtHuPb3wc9d8QADay6Pgf5dhSw9jLw5jkjw XQitNgPuduUQ0/kYD2oKgDaDAkM+eUsRDtJimxulE2E
-> ssh-ed25519 Nl/5yA /5IxJynZ+oP2iBZikH1dePktiwHrjYMSSeEn0wR4ywc -> ssh-ed25519 Nl/5yA F8xymke/81LlgOQq4IZtpUL8zAYIZLDU7/hYPbDW+UQ
My8esaXF11AgCEOeyNX+JRgLGuMlSPYGHqJIbxG3XWk BL5pks4vXzbM2Obzmb3vEUdYe/dEP5cm6490o1MjpMY
-> ssh-ed25519 GdLgCQ zKBABsXQE98vU0BgEj5onnfHs/Ta9qWwMgKKPFI//n4 -> ssh-ed25519 GdLgCQ J7fDZ4MEt/A8jhfCM8Qq2++v/bwhpSvykKefrp0R2Dk
h0cMTFqCZ3pON8JwZBfJz1E2HPWVEqH9fRc2ry59HaM E8BrcouvDsBTcAITuhUyENKTR2U3SlyUFgHThBkZ5NU
-> ssh-ed25519 tOH/HQ oPtW9p3QZzva2unDORMZURJAl7VVbuGF91HCe+wbTzo -> ssh-ed25519 tOH/HQ 5pbs0Qpugt2Z4GnERpgG7V1E+u/PqQZ8jmdhxiGAKmY
9bTm0B3q1tFNVepL20MIU5hWUFK6uUn3781NDqhWkv8 B6HXWpicDrESt1NcCrpjTTmWla11zRGInKpe5EqRKK8
-> ssh-ed25519 FpzvfQ R4ZCZsgf2tlN4h07M6mzgR/lhaZnP7uyUxajO+oC+UE -> ssh-ed25519 FpzvfQ ErKw/iWsCByk10H1SRr0771IsOF5kuKZYYynOI4NIhk
iJnJWKYrushgkegJPxw7M2aimtQ/dqOB31BHnMaFTm8 DXo1XN6lRhGcbZ0wOn4FKK+k3Qx8jp5jY2GYJ+5S/Oo
-> ssh-ed25519 2UotMw eIow72TygjpYbhJLCqt2vm2X7bu3NjY6MFTOWjl+pgI -> ssh-ed25519 2UotMw JvfWHcMKFS/FNr6dpLso8xDEmtKrd+bf6W4FSU+9vys
2EgimzYzga4FW5c79N3ppEMVvREAmh5wx3lI8gh0/BU MSHnO/7jZUAo/7FKWOYzaRWbLAC1Sn7JfSyN0Shoo7U
-> ssh-ed25519 kdPvzQ 5XbOccIDpMFKcCaBWFRWWCaUh3p1LBJ0ayolQroZeA4 -> ssh-ed25519 kdPvzQ TqAXhvp06kZR6czrD0ZKWRlyqU6kUYoZfP8gakziS2U
Jb+n0HeR3gDYizA0kta1TBvEiZryKlDwbuoa2u8PyKM ad0/vG0CRQ7sHiHvzedRAkdWarR+vHfgPMAjvXHBk7M
-> ssh-ed25519 onmXpg PZR1T8ylkM55nGIBYiCroNWNTwBcEA5PZU1YWH3tsWA -> ssh-ed25519 onmXpg ndkl5ubOnF20q+1Cd5d8b5Zy6KZ88EjWlmhGzy8+70c
LsOHqiryBJkA7b463zyg3IToKy1Teo/miyPfENewGnQ 18mzoHrH0VHlDfia5ch2+pLy/EA6PejcVEkV1+cWQnI
-> ssh-ed25519 CnhD0g j8T3e67+tDXJFRsX/gC9qqQn6YGFxgAMwWsQ9vlDsGg -> ssh-ed25519 CnhD0g JJ20jASeobaaiVJvg2m/JYp57UeCs9P0ddDJbE0I5E4
KAOrCxfTTo4uB0EjrV6VwAx71hbrNiJuP6G8F9lOr2Q uxGbgcL7CA+Gk8p0jRtc/1uXMM6fflOJKKvCCscsYMw
-> ssh-ed25519 4ep2UA wC0BaXPYM2iRPRBhQlOo2QRM0nX084cDp6brzKWjkzo -> ssh-ed25519 4ep2UA Gt5+6tALjGgyLYln/5GME6/cyX6zBIIoKEbfU3k5XVo
wNBztDXiPi6K9q+HJRXsr56/nf6k/aQJQIEpVCjQjQE 8+jhXYNZqIGP9gxYPTEUAeclc2yOoi1iPc0Wlsb2Fw4
--- IsVY/KsFoTGubmdpOdoTI64+O40RJplehy026aS1RJc --- C93ywGKoxGqj+uUh7M8VrRr9+6/sl4jbUWvIUlwOack
]̃R…ÊYá½²1ù\½LœÙkœ”­“¡Q:ÙŸý6 š¶¥b»Ø*ÙI­ÝZ3ýAóQÆ%HÑ4Êða0,ìvÇåÙ÷Ä­Äþ7ð- 8ÕXÛêÐÞQŸà¡•$Œ¬G¹„Ön.
2sÏÞ›n®ê®‘&­›XÙßü«?‡!Ñþ`g7Ó §DÕ‘ôëMìÓæŽiÍŒáé±è*ú 
Binary file not shown.
+36 -36
View File
@@ -1,37 +1,37 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 87huqg 0BPWYqZmhRyvis9uvGwUUSW+ele+l8IeF800BDyGSzg -> ssh-ed25519 8UnW5Q E0Cdhbg4mRNzzHLghvg/dgtXcgt/1kuQagBhFjDdfnQ
5VjgpSd1sFRNREuv1C3MYCWhDs1a9xiXc/PhvesR22g gEByb0FlQRO3RvqS7uop6kvyHCK8lkkdApI7KKDiLLo
-> ssh-ed25519 8UnW5Q PbSyI0V2Yi2zGhgHhi7bFQzN8nGw3YTJaDCltysRJmI -> ssh-ed25519 UFfTmg eCt3JllYLv+BIRrfHTNvOVY2bOmvU7Vn9dgdSETLxWg
m3o81t3eHybGoyid9mCulXu2TiCXoYZgEJkeMTVOIGE RYr//nOKClYqf6wT2ZfaUdWUvhZwdnAd9KuQRIAog/o
-> ssh-ed25519 UFfTmg EefXcU4i8wJ7Zxf3tFkjcZhnAuJRl2yvx3+tmUZiJQQ -> ssh-ed25519 xNtnoA ZD2sNDXV39GdAm0H5PDB1glXHjNTwgpmy03B/tX1G3A
XSsgWWZvEdyEZMluvbPr5WkGBCPmyQDMejtzwf8DNI4 v4HNBA77JAAOjgOqIEmgvM9TaTcX1Pgsh4mA8FJbDJ0
-> ssh-ed25519 xNtnoA 30K1t7yvl8xp+r3G048X4dTBBt7yuIJpSsirj4TuhT0 -> ssh-ed25519 aY2AXA Pgw8zantkYPSIlEVtApmrv6FANvJMScFlGn7XuVINnQ
TowyK2GWXSO4k1Y/eYA3jrQow1j8Ti3JGNj+KGEHs7s F55HvsAjccLCDXwsnLtiCTzqjCykI1LgNvrBPo/9Hhg
-> ssh-ed25519 aY2AXA 0CcV1pMMlaQpvuba3YVvOAmGKQbMNn3pciGhUsU9rGg -> ssh-ed25519 AQhf1g ocWSVOtSSwziSbHLpfzt9onAo+f20CnD92HDmHuvjms
BBsUSmzFL4nlyHeoDGCplOCNcgCGVXyw8ZcdY1V8UU0 +RfduLd2K1PXzXbjfBUsvSlErh1a7HcWq1uEmYccwOQ
-> ssh-ed25519 AQhf1g w7CyGajIHe+QtVcxd7LkmAfoViCGlETXUzmdfwAnfUg -> ssh-ed25519 r/3ipA GHKAUd/EJW/fhYqlZcoMJvDN0JnxOSnJ85zaWHCoEj8
k3pttObVlS9U+k3AaSmr5RdteuV7KS4FoD+jKP+ohjw VPBMtl/vSBUuQka53xmUtmcZ7Ug09rmVLr0zz4J7qa0
-> ssh-ed25519 mOmPfg TdZUGOwl8iLES+lLOOUS5z2vrmzn0UszNTAsoY0KtQw -> ssh-ed25519 mOmPfg H5wv8RYDXisyIbKDEfmy5qYofko73JLPEdwqW527q1o
jEV5asKniZYCzdbALXyIcF/leiaV1e0Xo50Qq1ni5VM gzykZnqY4Rxvnol4k24zrcSrX+Rhb5I5ueGSsHM2do0
-> ssh-ed25519 YJiRbw SQsOrXQaFPTKUWSKIjluoWbd5Sg0wP1ZVMOOiVilN04 -> ssh-ed25519 YJiRbw TANfFv+VCX835WeB4xwzE+7bSzOlNcUiiWeTc7ZSVWw
2Sl9esKTW0hAI2QITOM7tCXmU//86i9qIHqbzmT1LQw W4IJ3e6KMPEu4LGpPYNedPpd7yYM2WDwpO8cFOKCO8g
-> ssh-ed25519 Nl/5yA Y+rlhRD1PNIUEZhdfgZTcWe8qY0SQe8V9OavljXjxQ8 -> ssh-ed25519 Nl/5yA 5A04J8hrMgo+Zc1kueTxjEWOiLhXS2Z61Bt1Ykz1+0Y
oEbfC1+We251iuRBzQOFS0mb0QrPuP1184sqEq6J+As iGHr1oYbfYjuyrpgMBZSg8O/GGlx4fsBZGI3xb/8010
-> ssh-ed25519 GdLgCQ 7s9Jz+QDMx/VCpauGudchhYmdozHi+Drk1FTJkCZIlQ -> ssh-ed25519 GdLgCQ rqmXK9UWq6h8LYNhwzZv2JVEpO9pTWPOEZ07NEdftB8
JpNnTmbMZuAq1t19usJeaFk/XWIvI/E6O2XYW9xk1lo Pow3I9bqgjbaWzq+HPoliD2ZWe4xp4YROGQsv9WPxy8
-> ssh-ed25519 tOH/HQ bQjSTr7z9m0FnCwcwVNvXb6q7b7N8waWzDz2ext7xQc -> ssh-ed25519 tOH/HQ VJSZ0038Bq3VtvV9fG0rpNp33dozSAYUE7ILBG0KjGQ
fkGOxszYZbvfEgKCf8h1bSFDdhTQudWahW5GaoRvKwU dSwc/Kf7sC0qah7UKmXgbvKah3CiIABSS9e3SwVnf4g
-> ssh-ed25519 FpzvfQ WA8BXVcevPVZHqAQkcMuPygLD8qqFtNWU3tJYpwHMHo -> ssh-ed25519 FpzvfQ d3qVUKv1cKsoeuXK0KcDyViMExlsF4z9Zod6T6v5eCM
BMemxjA6UjegYD2DK0wmOc0ULYukqyDsRBAFYDeG7lA UyYVI9cPFMr5XRETLWcO/eqSpch7zKJElwuBU8CNGwY
-> ssh-ed25519 2UotMw KYrj8o6902OrxXaJf1RFG8H5HIVeRKwaTBiL/aXbWlU -> ssh-ed25519 2UotMw AiFjRIE+vsMZP1oF7jSlXK2VNRthzXyUuBvbhZIcAV0
J3xUYx69EUnyZUbzeN7X/Eh/J2Spva/3hlemM5171j4 xyZ79tTLJ+1QpEVfQ+un5Sz3CTKq0T7wuF/Qka/NBE4
-> ssh-ed25519 kdPvzQ 4mJ/cUrhX8UQa9+tStk81pxyJZiKKEv8nA1S3YIWbxc -> ssh-ed25519 kdPvzQ IRv2zsdpO0axmwXMBicAAgN8ebqBPgCmCK177xwU6Qc
JAhwjDcn63KA56ArrgCfb8ImF4+gdYb2t37RDHzREC0 v4HbNhr9Ma4f5UIkNqgdXLylmOyg42sa2NOLz9Sisgw
-> ssh-ed25519 onmXpg BaBbFKcLHhk2HmvWuC8oCv19H/gGplhQrYI3jhJSiC8 -> ssh-ed25519 onmXpg 4TlZ050M+oJdS88xGgMjSYjIP4tcekkxKYBrs59FVzs
DffAJpgSSISvUe+fGjiV/0ZD7ilpRjVfylbBgmzvwu0 yH8FE7Jg1r/vxNYXYlZ688A3tKdFuner17OvZNTZv0g
-> ssh-ed25519 CnhD0g 2pIX282qmM1TjcenouThl+EVDe7liSf48Xty52ryjzU -> ssh-ed25519 CnhD0g EkUxGQbJ9/B8KkXYnhSniZUhCIkuauilRhpC+N1HTBk
AdRqyALk3xZoG6Q26y3ueB6HgGBvojUfBmVVkI+/GoY rf0m3TU0xg9ch/0KEJcE2NGFqW3Aumt1NbnxCtAEjHo
-> ssh-ed25519 4ep2UA xWUwvjYFMJhMtg4hS4D0FOpfs/yPFZkNdVv8xhQgGEE -> ssh-ed25519 4ep2UA /1we2B4B3jY/ADtXPYxNe5bRoRbFHeSDzIR7qu3BA30
tBCKF5X+gYNbCik4j9YVXKkPA8BVb/pywmmVPEByUDg f0wku5YBXpggzWRsYs1rs1EHwOjWygyjLIM2xSYo1MY
--- 38S1jD1FbeM20/LKFLWepHbatAh6Kyy+wKS+Ptz5qtw --- vhT0oAaUS7BzF6k2pSvO08EILvWQcl0h3X8IBtnrUrc
Öþ­c$Kf”æ£ßr%Vù]U¥Šä#Þ¡2m$c …ï÷ áév2Ü< 6LÖƒÏ- nteºPöđԳ۪ðn„¢”Ý+¤3 O0T :LÇoV|âžezÔ~Pôòšü­ÔÁ鑯9Qà\ÞÇ¢p‚ºg'jëf;ÕjŽ{Ã{લþTE¸dÏ;*› 0¸k€¼O
+37 -36
View File
@@ -1,37 +1,38 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 87huqg iZk0mtBXNJEHptCG6sm5Bre86Ittrbshc7mgBg8lHwA -> ssh-ed25519 8UnW5Q FRrvjiuNlnu4/DkwfY2K5p3MdQ5bDF3+u+JKrYiHzGw
YgWizpWE1BvU8p4A2nnVM+KEW+pP/VQfeXNyn2C+RkY 9dGLw4PT4OapoTW2GnoJ85GEWgO3Aepj7hl0LpPZylk
-> ssh-ed25519 8UnW5Q rWJlpARVcYaUwReRg3WP0Lo5EK1WHXnDF281NfRCTh0 -> ssh-ed25519 UFfTmg uMTPiCPPoVqt/3SOr+y5oKGTxpFq2UNGrwaRVmnZT1Q
6JMBB4BVRxh4irXU5jR7NEtGgHUKEnATl05kPLkIJVk Rn7dRYCGZwYN7sCmAsne6kAuKmD6CFlGXR130ELiJCA
-> ssh-ed25519 UFfTmg r5QfXMP2yX1sT5/NSZOk81uKuUD2gHKCJ00OUfMstxg -> ssh-ed25519 xNtnoA FW0dLFehc2yVvpxIDEcVWD1zHspZuvwrn2qgYltdp1Y
9vQme3i/ip6BdyWXSqKf9KtBciD/xWnlTfU5bF9n6KM 1zYm+LF/8lvfEhQVr4cbyDF5CfhPu/fNBYZMQLtTrqw
-> ssh-ed25519 xNtnoA kiD+2ao6nBdkn3Us43lwCK4FMTWUX83AXZTdNS2ct1k -> ssh-ed25519 aY2AXA aNRD8OIqKluKhHQZCGkW+kS71vlU2N8K6k590eLO7HM
BQaO2/DuYW42uSRu9XLz8A3N7H1H3LZk8kz1Za12qTk PZHX6fqbX0U+55MtJ2iSur7TSHFEgQBiAgpXiGlHbuU
-> ssh-ed25519 aY2AXA cG0+CVmbBoR3El6TwvwrJhHbuLKpO0FNLMQQuAMU5XA -> ssh-ed25519 AQhf1g cIhfdle1UsPx86LETXhB46evMenWtypO4GmL2/oLbXs
uedc7XXzPp1q877M4Kb2AfGAafp2unNIB8Hz/15hSbg ezwVMUSz5KbBymwnZlKuLD7RbNBJigfkb4sOpHAAnBk
-> ssh-ed25519 AQhf1g ZIT944IUaACBEPFVv0/Q3Era9425gfYPDHTKQDFj0TA -> ssh-ed25519 r/3ipA Gt94r1I1CUMKrGQKBVgq/FLlOa7V3weD6N1rv/dVIV0
nJsuyOXfhNqejnljvd07tiGAH/6cVebb8N9op+yUkaQ UsBIZfHiU17IjzhcKc1kvSEIMIk7I/DizSdBGhXNwqA
-> ssh-ed25519 mOmPfg O+i/JqV2MSpDtjq2fGYsZk4cGe4mY1IMxfFiVsZX8FE -> ssh-ed25519 mOmPfg b3/Gwqh1kik/AuBzcpqsuSuFcK0Pko3hRu32wFB/yks
mqjMKCEPYrP9T5QvrPgrqpuQj90syD5Nly3xcZzlu+s X9AXKVJ3d0IV7wkV2ZibScIV9En9uJNyUIPIk7WFKb0
-> ssh-ed25519 YJiRbw cww2VvvXfFmWdspOqp0fYNizYF5gOJoWo2z0cmc2Q3E -> ssh-ed25519 YJiRbw yDkwCFtGXgS18DwqMCBied8+Jt8u2GBWuFQSrajij1s
t746Geby8GdPXb4G6PSnYWxAYHhwEygAy2kWOTNlQSE eSeFTNbeOT/tDb9iQo/YzThtQeMgNYmEK61o8hjG43k
-> ssh-ed25519 Nl/5yA /sbUMK+/aNe604RdYYGhC76NUAUV0zWC/d/BOFUMdDE -> ssh-ed25519 Nl/5yA ee68eLzrRi35az65YmfA/WF9VliRmnlPEbGQAet91nw
UYGmy1Cq4aZCJ6XghmqJVgCI+Q50NXKzVTbDV0cwCVo 2KdTnyBTyJu8q03eH5s4oRyvhTQ6f/qvwrLabvk3C3o
-> ssh-ed25519 GdLgCQ 7DVn9soiWBMSoWH8s0vJh9CxTnOGqwT1kCD2kKJffXo -> ssh-ed25519 GdLgCQ DAlJqI0uIBSrFpPMfl4FkrpjCO5qkzvJU/PBOWFh+XQ
1S3yC99Gp7im+ntDy5BF6Gbja0qI1iAcbBnUGBOdG2U S5tkvMrTrYbOK3U3wWxLn3MuJTfrP8vUIYe6nBpixQo
-> ssh-ed25519 tOH/HQ HjMJb09INVPg9p6eFWDq0x6aXxtv3e9WHns/b9dRq1w -> ssh-ed25519 tOH/HQ zQMhFkG/vkqosDn3VvzuKt4xagkUWoqE/DW6AsYtBGE
rol+78bs1kWGNNT9uGgpyhLo8Qg2KFZOZNV40o9ngjI MGQA/Jxv/YTny5CyqfQBorfwIUVPZFf/hAcUTFrX9vk
-> ssh-ed25519 FpzvfQ DYtu2GOhQMVefKgpFzGsUwQE93AABG7o7zlYBx4Sax0 -> ssh-ed25519 FpzvfQ d4cgnsFfo5xGDUFyT65HJ6S6vtzLmvB0eugwq6t0nGg
p9aaahOTOcwTwJh887brzzAz0K9eM1Q2okGwS6wcPWA 0hEFjipS1Jbp6xycUsZYHzcjQVJ22JlGMUsjPCkDfbI
-> ssh-ed25519 2UotMw XrenSoEXsC9g8pF+nIYu3/mEEE92h9NsjQlMHWf9RVo -> ssh-ed25519 2UotMw C8ukSysPTKrwKCVnqjBzspXLLyJyhn2YCHcr1n0ulRg
c3GnMhYdVXnTZ4zBpp+ZOL47i4iQ7PKKreWCrLz1JC4 NErsgu49C3ElHmpsz4q+zR/0Oj+9jBPnC0BErB/48Fc
-> ssh-ed25519 kdPvzQ wKe++MlxxvHTN1fogMxxO/Ek8ytLnUY4rS3/TGwYun0 -> ssh-ed25519 kdPvzQ oreOkf0nFgkgm5KuEjP28nbbqRZTA/b+bj7SSBmAslc
yERY9pzUSb7/YSkVPuhX9fJ6SHFZhgBztvx42wRU9i0 OrQ99MlWePEk5IVeoC/X4UYLhK10oTLFrS4KqzoVOE0
-> ssh-ed25519 onmXpg fccql4vrSXq2rmGNJAwNmnXXj/6rMp9rQL2/T19AeAs -> ssh-ed25519 onmXpg v8MQUHZj5sSu2XqiUH+8wcvEJmrGWQqs0e9evQKkzHw
41pFfrrmas1ttzD/wpQjJIbzgi27p80hJtuyXhpwE+4 ffZTIoH8stR+ZLhoz8GjvGG61xVbv4+VkHbd25Jyc/w
-> ssh-ed25519 CnhD0g cgwxIxMn6IFqHIaFhTrN1ycr9d4B+sSVcLZeiHaVn28 -> ssh-ed25519 CnhD0g Ja9KftQBH93zJAl8nOMQZXHbXIFIs9W4UqXwYr9gdDI
WFaOrcE8RuxatVGWCU+EAYTOZmks9bfKTme7s7VrDpM StRE03gMP6QQ+fCuhE1Q5ptCpBrUxrWINgCrWzwSqxo
-> ssh-ed25519 4ep2UA zStnhLrVw1+BNhOd+LQ1euusmCQnyQx7/ukUSgEs10w -> ssh-ed25519 4ep2UA fbcuNM4FWkTOVSNSJGAwncdkjLN1K2Uv3dxFsnC60VU
NDzx2fwKDs+of+62Gj9dE3l1+Wh0aVQAfjXPjYFjVc8 uVbHhoO/IXfakiYFJ4yrtReK9uvYLsj4BTILRBqbRgk
--- 63bVjaHZOWE+1hpG5yDQN8vMspyOOfw3NnXLCYSL3eE --- dYPR49CT7omcJ7jDRNUAoc4t7az/pEg00aqPF00OlA4
Ú![„•j-C3[äæª0µj gÄ Ñ³ª‚È(Lv¹•Õ¬›Øþá2Eý+qæ%ªѹP­ÃŒíËÑLs;3˜ù,³7]\¯– „Ï¿Ÿ ðç(C›Ø
I'ð^¿mc¶bßH…¹«CûK␍0ýĉwé¯;lú¿P<üH㛬õI¿{àÈ|øª·ý Páy(Oì«81åÐß
+36 -37
View File
@@ -1,38 +1,37 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 87huqg 9bSltGjltla8XkrCzhfU6yqy/Kb73jHmaaxpgE/mYjc -> ssh-ed25519 8UnW5Q mCwgPdwCWzi8QXME7vc1nncnCjUdhXJfHgz5CI2ppWI
q+UwMDloa3ud2r09prz5/nsIF98LI9xDqnxW12GPx0k rnBpIQ9WYgFs65Rh4eMICoesrg76o46AjmtY9fTbCl4
-> ssh-ed25519 8UnW5Q MjKIEX54pROJm4wMTQFP9vc1uhz/gN81zyy69zQA2A8 -> ssh-ed25519 UFfTmg EW1P9WRcH6esoNH098Vj4E+udGzKWYw+HkxaHcRpF3M
B71KLdMEXUgyD1lg1nyJPXnZXxDSKyvRb0BBOMN/y6E t3AsT1kOCeDbpYotmYAFQA5/k0NA9KJ+R1DRnbLX63c
-> ssh-ed25519 UFfTmg fk/DRRcki6qQf/TnwBA+FIgLVdrYdktLR9yf9r/82Uc -> ssh-ed25519 xNtnoA shOVkNxHyvKcLRYAAIW1C6UPAGiwxZl0Y7i73DkA3j0
PUpzNkavVk/VfO8X+mb2IfKrseA1yJJ6xNnap9W+FUM MgFo9Gy+24rWvIkqQKDogakf4q1nE+MTdmXg2nYMNR0
-> ssh-ed25519 xNtnoA 8wXxop/HSkpNJe2W+Lq6J1dPLk8P1w75xHKUxUjv918 -> ssh-ed25519 aY2AXA dXi7BYpOVSGbbxI5KOQkElq0GQj3vmbU8AA9rzqGIE0
may0BdqkiYxgaUGxv80Udz+UVCI/+pFgzlCZetEzLoY GlpXrUk11XX6zirXrTK3uIhLBwlTKwn4/cyCWjPBVTE
-> ssh-ed25519 aY2AXA /GeX9PATA0svXJ2cq7IIoWAx+Jap36OYFFw52mbtZ3A -> ssh-ed25519 AQhf1g qV41Qx3onxW0Z91xCiUwse51OoEU7tBAi9t6MrwF8Fw
BEOqSa4F8PVxGkVT4lSsP8FiloINw4mEjtZ+Dq6u9Kw rFXGO8JG1HE916LMS8xMLACVqHuQzP/SAgM5Ngi9tLQ
-> ssh-ed25519 AQhf1g URV4/G7uUPxZNpP09qyS6Tok7KlcfjYCGqEGftwkM3o -> ssh-ed25519 r/3ipA u1cHvRRt6JrScsmCY6PtybjU80VuU7NuRwtBW+Omc28
+l4j3tVMj8TcCE7KobympPIv3fRlLu7UGnZFeNZP4xY ztXCVbWHTMBY/x6dDdSSPQmTWfLCGNG7xkYBtupKRQ0
-> ssh-ed25519 mOmPfg NoIRVRE3P4/nnerdYsAw+S9csK6NB+AhnjYQj7NZZk0 -> ssh-ed25519 mOmPfg jCT547k33Dxx8nTS/WVe+Peo1eViKVSjLumucXempBc
GUuYluAhGcuiIfB6oh9rvfcd1Trhb/Jeyb7FAz4Plcs X2SCtafedtleUTQoYtKN/85uUnWS3kuY9Bb90xHXXBM
-> ssh-ed25519 YJiRbw n3/TMqijUG2LdAsqrq13Jelw4hEenbjMu70YknGrtCE -> ssh-ed25519 YJiRbw j16MQ20JnMktKiREpNRx5qed8jXXKCAq+8b5AvkW0gM
LCfUQDnpe2a7dD5YOKcteXQ4K8FyZNQ1gZi1GPkuCYs KovMsW55OvGyjSJuAN5M0Ga7ln0TOQoQEQKvCkODJJs
-> ssh-ed25519 Nl/5yA W0IMc+9Mpjehqib77k1LLeUoKSp8QwJkz0aEfAttMTo -> ssh-ed25519 Nl/5yA oYGAT0greb0CHjptVKt1vPBhBX1KXsJAVlU4WoV0vjo
0yrHlLQR3g5JGAuICMYQ8UBQ1SEdkPCiVq/j4PBLm+I SI4ZXY4pHqYEn2AKEX7MpcYT71LsVUGiZQd0LmwGywY
-> ssh-ed25519 GdLgCQ W1evgMNEDrmT5cgqRPK7NsTde8igIIiYbjRPBu38WSw -> ssh-ed25519 GdLgCQ rEB3gHJ+MovVDQsQd3X4pGI03itwoUGeHg7aCQ9oUms
5gDQVJxEcChyAGak31Qh70eFjOu3z4iLXZejBRXjUwo mAVXvwQqslqP4sm7uG9LXfNvD0XtnaB5W37esGyRsgU
-> ssh-ed25519 tOH/HQ iGA0Bf0Moa6UsXC484hFHp+4by41o8QhjsrCtnlnjDw -> ssh-ed25519 tOH/HQ XPExYlY9j8DKCZwviAAgSvJ2+xpx3lUBsktfMPwo8U4
YELtzO3zBhul4CCPdSaOm5KctPAoU1y27Jgfrs1H7KU v2PV6wtTTQINJ2XfCcA/0OpNkOHr4AER3lG73CJL7J8
-> ssh-ed25519 FpzvfQ LcehUBu0dDyGfYKqbdfxS7d6aTtYTgpokG+GWHnjtzI -> ssh-ed25519 FpzvfQ RRpPZ5GIdzvRimAXe1ybhxs+lV+SSigyyvEn3qmkOUg
6Rcos5SJmbUXXtMFqge/CRUb4RVYaHrt/H9V9tprBxQ z7QV/M3zO3tnOO3XiabL62w7Uphs9OxARpGbND1tm1I
-> ssh-ed25519 2UotMw Az0wVK6RPjD6Mm5H+gvCZDRuNbHFmuVXRGMKBgL1SAY -> ssh-ed25519 2UotMw JfTnR9wed+1B9Hung4FdV3Zvx8eQ+lrweFiFrhX8B2g
hf/DmLzyPoMQIYoV1A7CEifAdKQD8nOy7kWfpiJnuN0 k2KYxpsSoTBaHuXCCl5fBgn/jyi4KDKvg2QShU0Awpc
-> ssh-ed25519 kdPvzQ mP9FISgXfkj1Vflxun3bgnlwwqLFhL/RI7knX+Qpml4 -> ssh-ed25519 kdPvzQ GrUGPXTVNTMafGGfn2xA5pTIBEnEfSKmDtQ+W/QYpUU
ax99X2ePfqnYIsA3knPz19lcEv35pTF3YgEAI7FI/Xo eDNGzwGWhnZ2kLXzDLVWJNvl6F6vZBTFZ16zrh87bxY
-> ssh-ed25519 onmXpg 1Hg7Hf+HW28fBH4fMvrNUAd1XwiLOFGDQ7Tscqn7UzM -> ssh-ed25519 onmXpg LiArSCT2VCCbEE02Q9n6fsWP1VtYL7OcahnM7CJyywU
Cr1Y/Z60BwLm9b7GA94QnlNBwgmUqe8X8ksAZMHcgCk LUKTMk2IAFpg7mPpHjBBw8NbpbgpDGnH9FCvjuF9qBw
-> ssh-ed25519 CnhD0g TR6lw5KiTVLkgoErQMMTbgDAhV/Vdka35izHR5SJIjI -> ssh-ed25519 CnhD0g H2M/9h954AS4ROeJFDfOpwU2DsACwQ/20OdGVaeGxxE
EJs5EOZlprrfpQfpJgE4//VI3bAWE/OPV6bNOF7O3s4 tSMsZUT079DdPhW1yvFbk4DBlNd6Lvhk4SAarFjYfpY
-> ssh-ed25519 4ep2UA pSDKM7BZFXY+6BAfJYTar/eZ2eE2U18iFGdfmb7xPzo -> ssh-ed25519 4ep2UA /FZ8+q7M90Iug7/qUkpmyL3uhUz2WTBSoc2O719JhBs
0Og+gnsiBQcoCJzLIDSfTLRbnPf9ZqF62HKbtNcknrI y0dpaERxrnygXbDhp6v/rIZsoKx7kv/aQI667jt+/t8
--- 8adV1z73QFaTnpZABU9wkK/QfvnFdsVamSgndB6aGx4 --- K04yLmYsJIXBing2v+tijM5K1vOLQy0hWu7TItk3xCM
\!Ïç>ín;¥.\¿±¹üÆBsC Ò#é!)D}ÆPx ï` ‡t Hëw’÷ìgn$c\ÑØG >T¤b Ã,z¿ì|~u§Dhs±KP©íÜ0c‹ªŒ–÷ÙþÔ{™­w`ZªPODmüxOägƒ+FäCH
O±zøCÙFB¾tèÞÝnë½ßÇxÊŸ÷صÿ @²8
Binary file not shown.

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