Compare commits

...

38 Commits

Author SHA1 Message Date
02795a6ee4 nixos/nvme: Specify Host NQN on command line
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 2h24m47s
2025-09-06 18:02:18 +01:00
8fa4a7ee60 "Release" 25.09 Giving
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 31m46s
2025-09-06 17:14:09 +01:00
773674d879 nixos/chatterbox: Add adzerq to Instagram bridge
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 29m47s
2025-07-23 19:42:35 +01:00
12c5ca126d nixos/middleman: kinkcraft Bluemap
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 30m2s
2025-06-07 23:28:20 +01:00
b38a2a07e2 nixos/estuary: Update FrysIX BGP config to new /23
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 30m16s
2025-06-03 11:06:58 +01:00
0dc474887f Add kinkcraft Minecraft server
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 30m20s
2025-05-29 20:51:56 +01:00
c8bd63ec3e nixos: Add nixlight static IP and WLED hass integration
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 29m45s
2025-05-26 23:25:05 +01:00
d7522f3f97 nixos/whale2: Op kev in kevcraft
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 30m31s
2025-04-24 22:04:45 +01:00
58c76f822f home-manager/gui: Use tmux kill-session in brainrot screensavers
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 29m19s
2025-04-14 13:27:01 +01:00
31bcde23b8 nixos/gui: Enable udisks2
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 5m13s
2025-04-07 23:18:29 +01:00
fc2fa0666e nixos/middleman: Increase worker_processes
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 5m10s
2025-03-28 16:42:54 +00:00
854cc48479 home-manager/gui: Add Brainrot story mode screensaver
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 29m6s
2025-03-28 11:01:46 +00:00
85a4b124e5 pkgs: Remove own terminaltexteffects
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 5m7s
2025-03-27 11:58:36 +00:00
f322f3ebac home-manager/gui: Longer and looping brainrot screensavers
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 29m7s
2025-03-25 10:56:08 +00:00
bc74fb4968 home-manager/gui: Add brainrot screensavers
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 30m15s
2025-03-24 15:09:46 +00:00
584abd4991 nixos/home/hass: Add USB webcam
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 1h12m19s
2025-03-15 01:43:44 +00:00
05074a1fd9 nixos/home/hass: Basic Reolink camera setup
Some checks failed
CI / Check, build and cache nixfiles (push) Has been cancelled
2025-03-15 01:07:12 +00:00
69060dfbff nixos/home/routing-common: Add static lease for hass-panel 2025-03-14 22:53:36 +00:00
8e288a9e2a nixos/home/hass: Include scenes.yaml
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 1h17m11s
2025-03-14 17:48:18 +00:00
bb03b6fa76 nixos/home/hass: Add HEOS
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 1h0m24s
2025-03-12 01:55:46 +00:00
fd92cfae6e nixos/home/hass: Include scripts.yaml
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 1h1m12s
2025-03-11 14:35:10 +00:00
25267d09a2 nixos/home/hass: Add androidtv_remote and alarmo
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 59m46s
2025-03-11 02:12:16 +00:00
f02f538ab2 nixos/home/routing-common: Add media DHCP reservations 2025-03-10 22:33:48 +00:00
d319657680 nixos/netboot: Use older iPXE with patch
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 1h3m31s
2025-03-10 22:23:08 +00:00
dff5a4e6d8 nixos/home/hass: Add Irish Rail integration
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 1h9m21s
2025-03-10 14:04:22 +00:00
2a8ced0fec nixos/home/routing-common: Add DNS blocklist
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 1h6m52s
2025-03-10 10:46:21 +00:00
36c7096120 nixos/home/hass: Home Assistant CLI and automation fix
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 2h47m3s
2025-03-10 01:28:14 +00:00
adfcf2f848 nixos/home/hass: Initial Home Assistant setup
Some checks failed
CI / Check, build and cache nixfiles (push) Has been cancelled
2025-03-09 22:59:59 +00:00
a3870a4293 nixos/home/sfh: Introduce hass container
Some checks failed
CI / Check, build and cache nixfiles (push) Has been cancelled
2025-03-09 20:07:28 +00:00
8f4b61fc2b Update inputs 2025-03-09 20:00:35 +00:00
44e3a3011a nixos/stream: Disable octoprint for now
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 3m16s
2025-03-02 14:21:31 +00:00
45c972cca9 lib: Update public IPs 2025-03-02 13:40:22 +00:00
7bd5b8cbdf nixos/whale2: Add kevcraft
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 2m33s
2025-02-18 17:15:03 +00:00
d1eb9cc981 nixos/toot: Add BlueSky PDS
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 3m4s
2025-01-31 14:54:40 +00:00
7a2ebf6872 nixos: Add ADB stuff
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 1h3m46s
2025-01-26 18:33:04 +00:00
72b8bd089c nixos/uk: Add WireGuard VPN for access
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 1h15m33s
2025-01-22 19:19:03 +00:00
cff229f487 nixos: Add britway
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 1h3m58s
2025-01-19 23:58:51 +00:00
f3ac3cd67f nixos/middleman: Add pubkey and HTTP access to p.nul.ie
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 51m34s
2025-01-16 15:20:57 +00:00
61 changed files with 2732 additions and 1877 deletions

347
flake.lock generated
View File

@@ -8,7 +8,7 @@
"ragenix",
"nixpkgs"
],
"systems": "systems_7"
"systems": "systems_6"
},
"locked": {
"lastModified": 1723293904,
@@ -31,29 +31,27 @@
"nixpkgs": [
"nixpkgs-unstable"
],
"poetry2nix": "poetry2nix"
"pyproject-nix": "pyproject-nix"
},
"locked": {
"lastModified": 1718746012,
"narHash": "sha256-sp9vGl3vWXvD/C2JeMDi5nbW6CkKIC3Q2JMGKwexYEs=",
"ref": "refs/heads/master",
"rev": "ea24100bd4a914b9e044a2085a3785a6bd3a3833",
"revCount": 5,
"type": "git",
"url": "https://git.nul.ie/dev/boardie"
"lastModified": 1757170758,
"narHash": "sha256-FyO+Brz5eInmdAkG8B2rJAfrNGMCsDQ8BPflKV2+r5g=",
"owner": "devplayer0",
"repo": "boardie",
"rev": "ed5fd520d5bf122871b5508dd3c1eda28d6e515d",
"type": "github"
},
"original": {
"type": "git",
"url": "https://git.nul.ie/dev/boardie"
"owner": "devplayer0",
"repo": "boardie",
"type": "github"
}
},
"borgthin": {
"inputs": {
"devshell": "devshell_2",
"flake-utils": "flake-utils_5",
"nixpkgs": [
"nixpkgs-mine"
]
"flake-utils": "flake-utils_4",
"nixpkgs": "nixpkgs_3"
},
"locked": {
"lastModified": 1732994213,
@@ -116,11 +114,11 @@
"utils": "utils"
},
"locked": {
"lastModified": 1727447169,
"narHash": "sha256-3KyjMPUKHkiWhwR91J1YchF6zb6gvckCAY1jOE+ne0U=",
"lastModified": 1756719547,
"narHash": "sha256-N9gBKUmjwRKPxAafXEk1EGadfk2qDZPBQp4vXWPHINQ=",
"owner": "serokell",
"repo": "deploy-rs",
"rev": "aa07eb05537d4cd025e2310397a6adcedfe72c76",
"rev": "125ae9e3ecf62fb2c0fd4f2d894eb971f1ecaed2",
"type": "github"
},
"original": {
@@ -150,7 +148,7 @@
},
"devshell-tools": {
"inputs": {
"flake-utils": "flake-utils_9",
"flake-utils": "flake-utils_8",
"nixpkgs": "nixpkgs_4"
},
"locked": {
@@ -169,8 +167,8 @@
},
"devshell_2": {
"inputs": {
"flake-utils": "flake-utils_4",
"nixpkgs": "nixpkgs_3"
"flake-utils": "flake-utils_3",
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1671489820,
@@ -193,11 +191,11 @@
]
},
"locked": {
"lastModified": 1728330715,
"narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=",
"lastModified": 1741473158,
"narHash": "sha256-kWNaq6wQUbUMlPgw8Y+9/9wP0F8SHkjy24/mN3UAppg=",
"owner": "numtide",
"repo": "devshell",
"rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef",
"rev": "7c9e793ebe66bcba8292989a68c0419b737a22a0",
"type": "github"
},
"original": {
@@ -209,11 +207,11 @@
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"lastModified": 1733328505,
"narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
"type": "github"
},
"original": {
@@ -241,24 +239,6 @@
}
},
"flake-utils_10": {
"inputs": {
"systems": "systems_10"
},
"locked": {
"lastModified": 1705309234,
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_11": {
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
@@ -292,24 +272,6 @@
}
},
"flake-utils_3": {
"inputs": {
"systems": "systems_3"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_4": {
"locked": {
"lastModified": 1642700792,
"narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=",
@@ -324,7 +286,7 @@
"type": "github"
}
},
"flake-utils_5": {
"flake-utils_4": {
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
@@ -339,9 +301,27 @@
"type": "github"
}
},
"flake-utils_5": {
"inputs": {
"systems": "systems_4"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_6": {
"inputs": {
"systems": "systems_6"
"systems": "systems_5"
},
"locked": {
"lastModified": 1731533236,
@@ -358,23 +338,8 @@
}
},
"flake-utils_7": {
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_8": {
"inputs": {
"systems": "systems_8"
"systems": "systems_7"
},
"locked": {
"lastModified": 1710146030,
@@ -390,9 +355,9 @@
"type": "github"
}
},
"flake-utils_9": {
"flake-utils_8": {
"inputs": {
"systems": "systems_9"
"systems": "systems_8"
},
"locked": {
"lastModified": 1709126324,
@@ -408,6 +373,24 @@
"type": "github"
}
},
"flake-utils_9": {
"inputs": {
"systems": "systems_9"
},
"locked": {
"lastModified": 1705309234,
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
@@ -437,16 +420,16 @@
]
},
"locked": {
"lastModified": 1732466619,
"narHash": "sha256-T1e5oceypZu3Q8vzICjv1X/sGs9XfJRMW5OuXHgpB3c=",
"lastModified": 1756679287,
"narHash": "sha256-Xd1vOeY9ccDf5VtVK12yM0FS6qqvfUop8UQlxEB+gTQ=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "f3111f62a23451114433888902a55cf0692b408d",
"rev": "07fc025fe10487dd80f2ec694f1cd790e752d0e8",
"type": "github"
},
"original": {
"id": "home-manager",
"ref": "release-24.11",
"ref": "release-25.05",
"type": "indirect"
}
},
@@ -457,11 +440,11 @@
]
},
"locked": {
"lastModified": 1732884235,
"narHash": "sha256-r8j6R3nrvwbT1aUp4EPQ1KC7gm0pu9VcV1aNaB+XG6Q=",
"lastModified": 1757075491,
"narHash": "sha256-a+NMGl5tcvm+hyfSG2DlVPa8nZLpsumuRj1FfcKb2mQ=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "819f682269f4e002884702b87e445c82840c68f2",
"rev": "f56bf065f9abedc7bc15e1f2454aa5c8edabaacf",
"type": "github"
},
"original": {
@@ -471,11 +454,11 @@
},
"impermanence": {
"locked": {
"lastModified": 1731242966,
"narHash": "sha256-B3C3JLbGw0FtLSWCjBxU961gLNv+BOOBC6WvstKLYMw=",
"lastModified": 1737831083,
"narHash": "sha256-LJggUHbpyeDvNagTUrdhe/pRVp4pnS6wVKALS782gRI=",
"owner": "nix-community",
"repo": "impermanence",
"rev": "3ed3f0eaae9fcc0a8331e77e9319c8a4abd8a71a",
"rev": "4b3e914cdf97a5b536a889e939fb2fd2b043a170",
"type": "github"
},
"original": {
@@ -484,41 +467,35 @@
"type": "github"
}
},
"nix-github-actions": {
"inputs": {
"nixpkgs": [
"boardie",
"poetry2nix",
"nixpkgs"
]
},
"libnetRepo": {
"flake": false,
"locked": {
"lastModified": 1703863825,
"narHash": "sha256-rXwqjtwiGKJheXB43ybM8NwWB8rO2dSRrEqes0S7F5Y=",
"owner": "nix-community",
"repo": "nix-github-actions",
"rev": "5163432afc817cf8bd1f031418d1869e4c9d5547",
"lastModified": 1745053097,
"narHash": "sha256-BEW57utyWCqP4U+MzCXFqbvEC8LE3iZv5dsPMrmTJ9Q=",
"owner": "oddlama",
"repo": "nixos-extra-modules",
"rev": "7565d8554b0fc9d621851150e7939d34a3a8cd6c",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-github-actions",
"owner": "oddlama",
"repo": "nixos-extra-modules",
"type": "github"
}
},
"nixGL": {
"inputs": {
"flake-utils": "flake-utils_7",
"flake-utils": "flake-utils_6",
"nixpkgs": [
"nixpkgs-unstable"
]
},
"locked": {
"lastModified": 1713543440,
"narHash": "sha256-lnzZQYG0+EXl/6NkGpyIz+FEOc/DSEG57AP1VsdeNrM=",
"lastModified": 1752054764,
"narHash": "sha256-Ob/HuUhANoDs+nvYqyTKrkcPXf4ZgXoqMTQoCK0RFgQ=",
"owner": "nix-community",
"repo": "nixGL",
"rev": "310f8e49a149e4c9ea52f1adf70cdc768ec53f8a",
"rev": "a8e1ce7d49a149ed70df676785b07f63288f53c5",
"type": "github"
},
"original": {
@@ -545,11 +522,11 @@
},
"nixpkgs-mine": {
"locked": {
"lastModified": 1732985787,
"narHash": "sha256-6rSJ9L4QywpHLi/xvpOHdTuPm6/eOJcXxnYzDbP3U1k=",
"lastModified": 1757173087,
"narHash": "sha256-NYXuC8xUUbvtwbaC1aLdpQKHzQtQ2XB3VkK0hfYTPd8=",
"owner": "devplayer0",
"repo": "nixpkgs",
"rev": "a28c46933ef5038fb7a2dd483b85152a539c7969",
"rev": "06e4c8cd503ed73806744b39368393df38b36bb7",
"type": "github"
},
"original": {
@@ -561,11 +538,11 @@
},
"nixpkgs-mine-stable": {
"locked": {
"lastModified": 1732985894,
"narHash": "sha256-YYuQQCcSF6KjgtAenZJiBmqt5jqP3UvYgC424VQ+22s=",
"lastModified": 1757173155,
"narHash": "sha256-aDNAiQQsrgS/coVOqLbtILpOUouE6jp/wqAsO8Dta/o=",
"owner": "devplayer0",
"repo": "nixpkgs",
"rev": "e0a3f4e2bbc5f7b681e344b389dcbab23f2e92a8",
"rev": "8a1a03f2d17918a6d51746371031a8fe4014c549",
"type": "github"
},
"original": {
@@ -577,26 +554,26 @@
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1732824227,
"narHash": "sha256-fYNXgpu1AEeLyd3fQt4Ym0tcVP7cdJ8wRoqJ+CtTRyY=",
"lastModified": 1757020766,
"narHash": "sha256-PLoSjHRa2bUbi1x9HoXgTx2AiuzNXs54c8omhadyvp0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c71ad5c34d51dcbda4c15f44ea4e4aa6bb6ac1e9",
"rev": "fe83bbdde2ccdc2cb9573aa846abe8363f79a97a",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-24.11",
"ref": "nixos-25.05",
"type": "indirect"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1732758367,
"narHash": "sha256-RzaI1RO0UXqLjydtz3GAXSTzHkpb/lLD1JD8a0W4Wpo=",
"lastModified": 1756787288,
"narHash": "sha256-rw/PHa1cqiePdBxhF66V7R+WAP8WekQ0mCDG4CFqT8Y=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "fa42b5a5f401aab8a32bd33c9a4de0738180dc59",
"rev": "d0fc30899600b9b3466ddb260fd83deb486c32f1",
"type": "github"
},
"original": {
@@ -606,22 +583,6 @@
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1718632497,
"narHash": "sha256-YtlyfqOdYMuu7gumZtK0Kg7jr4OKfHUhJkZfNUryw68=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c58b4a9118498c1055c5908a5bbe666e56abe949",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable-small",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1643381941,
"narHash": "sha256-pHTwvnN4tTsEKkWlXQ8JMY423epos8wUOhthpwJjtpc=",
@@ -637,6 +598,20 @@
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1673606088,
"narHash": "sha256-wdYD41UwNwPhTdMaG0AIe7fE1bAdyHe6bB4HLUqUvck=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "37b97ae3dd714de9a17923d004a2c5b5543dfa6d",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1709309926,
@@ -669,25 +644,24 @@
"type": "github"
}
},
"poetry2nix": {
"pyproject-nix": {
"inputs": {
"flake-utils": "flake-utils_3",
"nix-github-actions": "nix-github-actions",
"nixpkgs": "nixpkgs_2",
"systems": "systems_4",
"treefmt-nix": "treefmt-nix"
"nixpkgs": [
"boardie",
"nixpkgs"
]
},
"locked": {
"lastModified": 1718726452,
"narHash": "sha256-w4hJSYvACz0i5XHtxc6XNyHwbxpisN13M2kA2Y7937o=",
"owner": "nix-community",
"repo": "poetry2nix",
"rev": "53e534a08c0cd2a9fa7587ed1c3e7f6aeb804a2c",
"lastModified": 1756395552,
"narHash": "sha256-5aJM14MpoLk2cdZAetu60OkLQrtFLWTICAyn1EP7ZpM=",
"owner": "pyproject-nix",
"repo": "pyproject.nix",
"rev": "030dffc235dcf240d918c651c78dc5f158067b51",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "poetry2nix",
"owner": "pyproject-nix",
"repo": "pyproject.nix",
"type": "github"
}
},
@@ -695,7 +669,7 @@
"inputs": {
"agenix": "agenix",
"crane": "crane",
"flake-utils": "flake-utils_8",
"flake-utils": "flake-utils_7",
"nixpkgs": [
"nixpkgs-unstable"
],
@@ -722,10 +696,11 @@
"borgthin": "borgthin",
"deploy-rs": "deploy-rs",
"devshell": "devshell_3",
"flake-utils": "flake-utils_6",
"flake-utils": "flake-utils_5",
"home-manager-stable": "home-manager-stable",
"home-manager-unstable": "home-manager-unstable",
"impermanence": "impermanence",
"libnetRepo": "libnetRepo",
"nixGL": "nixGL",
"nixpkgs-mine": "nixpkgs-mine",
"nixpkgs-mine-stable": "nixpkgs-mine-stable",
@@ -758,7 +733,7 @@
},
"sbt": {
"inputs": {
"flake-utils": "flake-utils_11",
"flake-utils": "flake-utils_10",
"nixpkgs": "nixpkgs_5"
},
"locked": {
@@ -778,18 +753,18 @@
"sharry": {
"inputs": {
"devshell-tools": "devshell-tools",
"flake-utils": "flake-utils_10",
"flake-utils": "flake-utils_9",
"nixpkgs": [
"nixpkgs-unstable"
],
"sbt": "sbt"
},
"locked": {
"lastModified": 1720592125,
"narHash": "sha256-vR89LefkY8mBPWxDTQ8SNg6Z7/J6Yga80T4kSb6MNdk=",
"lastModified": 1741328331,
"narHash": "sha256-OtsHm9ykxfAOMRcgFDsqFBBy5Wu0ag7eq1qmTIluVcw=",
"owner": "eikek",
"repo": "sharry",
"rev": "604b20517150599cb05dbe178cd35cd10659aa4c",
"rev": "6203b90f9a76357d75c108a27ad00f323d45c1d0",
"type": "github"
},
"original": {
@@ -813,21 +788,6 @@
"type": "github"
}
},
"systems_10": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
@@ -868,8 +828,9 @@
"type": "github"
},
"original": {
"id": "systems",
"type": "indirect"
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_5": {
@@ -947,38 +908,16 @@
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"boardie",
"poetry2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1718522839,
"narHash": "sha256-ULzoKzEaBOiLRtjeY3YoGFJMwWSKRYOic6VNw2UyTls=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "68eb1dc333ce82d0ab0c0357363ea17c31ea1f81",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"utils": {
"inputs": {
"systems": "systems_5"
"systems": "systems_3"
},
"locked": {
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {

View File

@@ -3,17 +3,22 @@
inputs = {
flake-utils.url = "github:numtide/flake-utils";
# libnet.url = "github:reo101/nix-lib-net";
libnetRepo = {
url = "github:oddlama/nixos-extra-modules";
flake = false;
};
devshell.url = "github:numtide/devshell";
devshell.inputs.nixpkgs.follows = "nixpkgs-unstable";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
nixpkgs-stable.url = "nixpkgs/nixos-24.11";
nixpkgs-stable.url = "nixpkgs/nixos-25.05";
nixpkgs-mine.url = "github:devplayer0/nixpkgs/devplayer0";
nixpkgs-mine-stable.url = "github:devplayer0/nixpkgs/devplayer0-stable";
home-manager-unstable.url = "home-manager";
home-manager-unstable.inputs.nixpkgs.follows = "nixpkgs-unstable";
home-manager-stable.url = "home-manager/release-24.11";
home-manager-stable.url = "home-manager/release-25.05";
home-manager-stable.inputs.nixpkgs.follows = "nixpkgs-stable";
# Stuff used by the flake for build / deployment
@@ -25,7 +30,7 @@
# Stuff used by systems
impermanence.url = "github:nix-community/impermanence";
boardie.url = "git+https://git.nul.ie/dev/boardie";
boardie.url = "github:devplayer0/boardie";
boardie.inputs.nixpkgs.follows = "nixpkgs-unstable";
nixGL.url = "github:nix-community/nixGL";
nixGL.inputs.nixpkgs.follows = "nixpkgs-unstable";
@@ -34,7 +39,8 @@
sharry.url = "github:eikek/sharry";
sharry.inputs.nixpkgs.follows = "nixpkgs-unstable";
borgthin.url = "github:devplayer0/borg";
borgthin.inputs.nixpkgs.follows = "nixpkgs-mine";
# TODO: Update borgthin so this works
# borgthin.inputs.nixpkgs.follows = "nixpkgs-mine";
};
outputs =
@@ -57,7 +63,7 @@
# Extend a lib with extras that _must not_ internally reference private nixpkgs. flake-utils doesn't, but many
# other flakes (e.g. home-manager) probably do internally.
libOverlay = final: prev: {
my = import ./lib { lib = final; };
my = import ./lib { inherit inputs; lib = final; };
flake = flake-utils.lib;
};
pkgsLibOverlay = final: prev: { lib = prev.lib.extend libOverlay; };
@@ -88,10 +94,11 @@
(_: path: mkDefaultSystemsPkgs path (system: {
overlays = [
pkgsLibOverlay
myPkgsOverlay
inputs.devshell.overlays.default
inputs.ragenix.overlays.default
inputs.deploy-rs.overlay
inputs.deploy-rs.overlays.default
(flakePackageOverlay inputs.home-manager-unstable system)
];
}))
@@ -102,6 +109,7 @@
(_: path: mkDefaultSystemsPkgs path (_: {
overlays = [
pkgsLibOverlay
myPkgsOverlay
];
@@ -126,6 +134,7 @@
nixos/boxes/home/palace
nixos/boxes/home/castle
nixos/boxes/britway
nixos/boxes/britnet.nix
nixos/boxes/kelder
# Homes
@@ -156,7 +165,7 @@
# Platform independent stuff
{
nixpkgs = pkgs';
inherit lib nixfiles;
inherit inputs lib nixfiles;
overlays.default = myPkgsOverlay;

View File

@@ -66,7 +66,7 @@ in
lsd = {
enable = mkDefault true;
enableAliases = mkDefault true;
enableFishIntegration = mkDefault true;
};
starship = {
@@ -132,6 +132,8 @@ in
ssh = {
enable = mkDefault true;
# TODO: Set after 25.11 releases
# enableDefaultConfig = false;
matchBlocks = {
nix-dev-vm = {
user = "dev";
@@ -226,6 +228,8 @@ in
# Note: If globalPkgs mode is on, then these will be overridden by the NixOS equivalents of these options
nixpkgs = {
overlays = [
inputs.libnet.overlays.default
inputs.deploy-rs.overlay
inputs.boardie.overlays.default
inputs.nixGL.overlays.default

View File

@@ -1,7 +1,8 @@
{ lib, pkgs', pkgs, config, ... }:
let
inherit (lib) genAttrs mkIf mkMerge mkForce mapAttrs mkOptionDefault;
inherit (lib.my) mkBoolOpt';
inherit (lib.my) mkOpt' mkBoolOpt';
inherit (lib.my.c) pubDomain;
cfg = config.my.gui;
@@ -15,24 +16,42 @@ let
url = "https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad";
hash = "sha256-HX1DvlAeZ9kn5BXguPPinDvzMHXoWXIYFvZSpSbKx3E=";
};
subwaySurfers = pkgs.fetchurl {
url = "https://p.${pubDomain}/video/subway-surfers-smol.mkv";
hash = "sha256-fMe7TDRNTymRHIJOi7qG3trzu4GP8a3gCDz+FMkX1dY=";
};
minecraftParkour = pkgs.fetchurl {
url = "https://p.${pubDomain}/video/minecraft-parkour-smol.mkv";
hash = "sha256-723pRm4AsIjY/WFUyAHzTJp+JvH4Pn5hvzF9wHTnOPA=";
};
doomsaver = pkgs.runCommand "doomsaver" {
inherit (pkgs) windowtolayer;
genLipsum = pkgs.writeScript "lipsum" ''
#!${pkgs.python3.withPackages (ps: [ ps.python-lorem ])}/bin/python
import lorem
print(lorem.get_paragraph(count=5, sep='\n\n'))
'';
doomsaver' = brainrotTextCommand: pkgs.runCommand "doomsaver" {
inherit (pkgs) windowtolayer tmux terminaltexteffects;
chocoDoom = pkgs.chocolate-doom2xx;
ffmpeg = pkgs.ffmpeg-full;
python = pkgs.python3.withPackages (ps: [ ps.filelock ]);
inherit doomWad;
enojy = ./enojy.jpg;
inherit brainrotTextCommand subwaySurfers minecraftParkour;
} ''
mkdir -p "$out"/bin
substituteAll ${./screensaver.py} "$out"/bin/doomsaver
chmod +x "$out"/bin/doomsaver
'';
doomsaver = doomsaver' cfg.screensaver.brainrotTextCommand;
in
{
options.my.gui = {
options.my.gui = with lib.types; {
enable = mkBoolOpt' true "Enable settings and packages meant for graphical systems";
manageGraphical = mkBoolOpt' false "Configure the graphical session";
standalone = mkBoolOpt' false "Enable settings for fully Nix managed systems";
screensaver.brainrotTextCommand = mkOpt' (either path str) genLipsum "Command to generate brainrot text.";
};
config = mkIf cfg.enable (mkMerge [

View File

@@ -73,7 +73,7 @@ class TTESaver(Screensaver):
def wait(self):
while self.running:
effect_cmd = ['tte', random.choice(self.effects)]
effect_cmd = ['@terminaltexteffects@/bin/tte', random.choice(self.effects)]
print(f"$ {self.cmd} | {' '.join(effect_cmd)}")
content = subprocess.check_output(self.cmd, shell=True, env=self.env, stderr=subprocess.DEVNULL)
@@ -86,6 +86,51 @@ class TTESaver(Screensaver):
self.running = False
self.proc.terminate()
class FFmpegCACASaver(Screensaver):
@staticmethod
def command(video, size):
return ['@ffmpeg@/bin/ffmpeg', '-hide_banner', '-loglevel', 'error',
'-stream_loop', '-1', '-i', video,
'-pix_fmt', 'rgb24', '-window_size', f'{size}x{size}',
'-f', 'caca', '-']
def __init__(self, video, weight=2):
cols, lines = os.get_terminal_size()
# IDK if it's reasonable to do this as "1:1"
size = lines - 4
super().__init__(
self.command(video, size),
env={'CACA_DRIVER': 'ncurses'},
weight=weight,
)
def stop(self):
super().stop(kill=True)
class BrainrotStorySaver(Screensaver):
def __init__(self, video, text_command, weight=2):
cols, lines = os.get_terminal_size()
video_size = lines - 1
video_command = ' '.join(FFmpegCACASaver.command(video, video_size))
text_command = (
f'while true; do {text_command} | '
f'@terminaltexteffects@/bin/tte --wrap-text --canvas-width=80 --canvas-height={video_size//2} --anchor-canvas=c '
'print --final-gradient-stops=ffffff; clear; done' )
self.tmux_session = f'screensaver-{os.urandom(4).hex()}'
super().__init__(
['@tmux@/bin/tmux', 'new-session', '-s', self.tmux_session, '-n', 'brainrot',
text_command, ';', 'split-window', '-hbl', str(lines), video_command],
# ['sh', '-c', text_command],
env={
'CACA_DRIVER': 'ncurses',
'SHELL': '/bin/sh',
},
weight=weight,
)
def stop(self):
subprocess.check_call(['@tmux@/bin/tmux', 'kill-session', '-t', self.tmux_session])
class MultiSaver:
savers = [
DoomSaver(0),
@@ -100,6 +145,9 @@ class MultiSaver:
TTESaver('ss -nltu'),
TTESaver('ss -ntu'),
TTESaver('jp2a --width=100 @enojy@'),
BrainrotStorySaver('@subwaySurfers@', '@brainrotTextCommand@'),
BrainrotStorySaver('@minecraftParkour@', '@brainrotTextCommand@'),
]
state_filename = 'screensaver.json'

View File

@@ -22,12 +22,13 @@ rec {
kea = 404;
keepalived_script = 405;
photoprism = 406;
adbusers = 407;
};
};
kernel = {
lts = pkgs: pkgs.linuxKernel.packages.linux_6_6;
latest = pkgs: pkgs.linuxKernel.packages.linux_6_12;
lts = pkgs: pkgs.linuxKernel.packages.linux_6_12;
latest = pkgs: pkgs.linuxKernel.packages.linux_6_16;
};
nginx = rec {
@@ -199,11 +200,20 @@ rec {
port = 25566;
dst = aa.simpcraft-staging-oci.internal.ipv4.address;
}
{
port = 25575;
dst = aa.simpcraft-oci.internal.ipv4.address;
port = 25567;
dst = aa.kevcraft-oci.internal.ipv4.address;
}
{
port = 25568;
dst = aa.kinkcraft-oci.internal.ipv4.address;
}
# RCON... unsafe?
# {
# port = 25575;
# dst = aa.simpcraft-oci.internal.ipv4.address;
# }
{
port = 2456;
@@ -227,6 +237,16 @@ rec {
dst = aa.simpcraft-oci.internal.ipv4.address;
proto = "udp";
}
{
port = 25567;
dst = aa.kevcraft-oci.internal.ipv4.address;
proto = "udp";
}
{
port = 25568;
dst = aa.kinkcraft-oci.internal.ipv4.address;
proto = "udp";
}
{
port = 15636;
@@ -267,8 +287,8 @@ rec {
"stream"
];
routersPubV4 = [
"109.255.31.155"
"109.255.252.63"
"109.255.108.88"
"109.255.108.121"
];
prefixes = with lib.my.net.cidr; rec {
@@ -334,6 +354,20 @@ rec {
assignedV6 = "2001:19f0:7402:128b:5400:04ff:feac:6e06";
};
britnet = {
domain = "bhx1.int.${pubDomain}";
pubV4 = "77.74.199.67";
vpn = {
port = 51820;
};
prefixes = with lib.my.net.cidr; rec {
vpn = {
v4 = "10.200.0.0/24";
v6 = "fdfb:5ebf:6e84::/64";
};
};
};
tailscale = {
prefix = {
v4 = "100.64.0.0/10";

View File

@@ -1,11 +1,11 @@
{ lib }:
{ inputs, lib }:
let
inherit (builtins) length match elemAt filter replaceStrings substring;
inherit (lib)
genAttrs mapAttrsToList filterAttrsRecursive nameValuePair types
mkOption mkOverride mkForce mkIf mergeEqualOption optional
showWarnings concatStringsSep flatten unique optionalAttrs
mkBefore toLower;
mkBefore toLower splitString last;
inherit (lib.flake) defaultSystems;
in
rec {
@@ -23,7 +23,7 @@ rec {
attrsToNVList = mapAttrsToList nameValuePair;
inherit (import ./net.nix { inherit lib; }) net;
inherit ((import "${inputs.libnetRepo}/lib/netu.nix" { inherit lib; }).lib) net;
dns = import ./dns.nix { inherit lib; };
c = import ./constants.nix { inherit lib; };
@@ -53,7 +53,7 @@ rec {
in mkApp "${app}/bin/${app.meta.mainProgram}";
flakePackageOverlay' = flake: pkg: system: (final: prev:
let
pkg' = if pkg != null then flake.packages.${system}.${pkg} else flake.defaultPackage.${system};
pkg' = if pkg != null then flake.packages.${system}.${pkg} else flake.packages.${system}.default;
name = if pkg != null then pkg else pkg'.name;
in
{
@@ -248,12 +248,13 @@ rec {
in
{
trivial = prev.trivial // {
release = "24.12:u-${prev.trivial.release}";
codeName = "Epic";
release = "25.09:u-${prev.trivial.release}";
codeName = "Giving";
revisionWithDefault = default: self.rev or default;
versionSuffix = ".${date}.${revCode self}:u-${revCode pkgsFlake}";
};
};
upstreamRelease = last (splitString "-" lib.trivial.release);
netbootKeaClientClasses = { tftpIP, hostname, systems }:
let

File diff suppressed because it is too large Load Diff

191
nixos/boxes/britnet.nix Normal file
View File

@@ -0,0 +1,191 @@
{ lib, ... }:
let
inherit (lib.my) net;
inherit (lib.my.c) pubDomain;
inherit (lib.my.c.britnet) domain pubV4 prefixes;
in
{
nixos.systems.britnet = {
system = "x86_64-linux";
nixpkgs = "mine";
assignments = {
allhost = {
inherit domain;
ipv4 = {
address = pubV4;
mask = 24;
gateway = "77.74.199.1";
};
ipv6 = {
address = "2a12:ab46:5344:99::a";
gateway = "2a12:ab46:5344::1";
};
};
vpn = {
ipv4 = {
address = net.cidr.host 1 prefixes.vpn.v4;
gateway = null;
};
ipv6.address = net.cidr.host 1 prefixes.vpn.v6;
};
};
configuration = { lib, pkgs, modulesPath, config, assignments, allAssignments, ... }:
let
inherit (lib) mkMerge mkForce;
inherit (lib.my) networkdAssignment;
in
{
imports = [
"${modulesPath}/profiles/qemu-guest.nix"
];
config = mkMerge [
{
boot = {
initrd.availableKernelModules = [
"ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "ahci" "sr_mod" "virtio_blk"
];
loader = {
systemd-boot.enable = false;
grub = {
enable = true;
device = "/dev/vda";
};
};
};
fileSystems = {
"/boot" = {
device = "/dev/disk/by-uuid/457444a1-81dd-4934-960c-650ad16c92b5";
fsType = "ext4";
};
"/nix" = {
device = "/dev/disk/by-uuid/992c0c79-5be6-45b6-bc30-dc82e3ec082a";
fsType = "ext4";
};
"/persist" = {
device = "/dev/disk/by-uuid/f020a955-54d5-4098-98ba-d3615781d96a";
fsType = "ext4";
neededForBoot = true;
};
};
environment = {
systemPackages = with pkgs; [
wireguard-tools
];
};
services = {
iperf3 = {
enable = true;
openFirewall = true;
};
tailscale = {
enable = true;
authKeyFile = config.age.secrets."tailscale-auth.key".path;
openFirewall = true;
interfaceName = "tailscale0";
extraUpFlags = [
"--operator=${config.my.user.config.name}"
"--login-server=https://hs.nul.ie"
"--netfilter-mode=off"
"--advertise-exit-node"
"--accept-routes=false"
];
};
};
networking = { inherit domain; };
systemd.network = {
netdevs = {
"30-wg0" = {
netdevConfig = {
Name = "wg0";
Kind = "wireguard";
};
wireguardConfig = {
PrivateKeyFile = config.age.secrets."britnet/wg.key".path;
ListenPort = lib.my.c.britnet.vpn.port;
};
wireguardPeers = [
{
PublicKey = "EfPwREfZ/q3ogHXBIqFZh4k/1NRJRyq4gBkBXtegNkE=";
AllowedIPs = [
(net.cidr.host 10 prefixes.vpn.v4)
(net.cidr.host 10 prefixes.vpn.v6)
];
}
];
};
};
links = {
"10-veth0" = {
matchConfig.PermanentMACAddress = "00:db:d9:62:68:1a";
linkConfig.Name = "veth0";
};
};
networks = {
"20-veth0" = mkMerge [
(networkdAssignment "veth0" assignments.allhost)
{
dns = [ "1.1.1.1" "1.0.0.1" ];
routes = [
{
# Gateway is on a different network for some reason...
Destination = "2a12:ab46:5344::1";
Scope = "link";
}
];
}
];
"30-wg0" = mkMerge [
(networkdAssignment "wg0" assignments.vpn)
{
networkConfig.IPv6AcceptRA = mkForce false;
}
];
};
};
my = {
server.enable = true;
secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJIEx+1EC/lN6WKIaOB+O5LJgVHRK962YpZEPQg/m78O";
files = {
"tailscale-auth.key" = {};
"britnet/wg.key" = {
owner = "systemd-network";
};
};
};
firewall = {
udp.allowed = [ lib.my.c.britnet.vpn.port ];
trustedInterfaces = [ "tailscale0" ];
extraRules = ''
table inet filter {
chain forward {
iifname wg0 oifname veth0 accept
}
}
table inet nat {
chain postrouting {
iifname { tailscale0, wg0 } oifname veth0 snat ip to ${assignments.allhost.ipv4.address}
iifname { tailscale0, wg0 } oifname veth0 snat ip6 to ${assignments.allhost.ipv6.address}
}
}
'';
};
};
}
];
};
};
}

View File

@@ -11,23 +11,24 @@ in
config = {
my = {
secrets.files."britway/bgp-password-vultr.conf" = {
owner = "bird2";
group = "bird2";
owner = "bird";
group = "bird";
};
};
environment.etc."bird/vultr-password.conf".source = config.age.secrets."britway/bgp-password-vultr.conf".path;
systemd = {
services.bird2.after = [ "systemd-networkd-wait-online@veth0.service" ];
services.bird.after = [ "systemd-networkd-wait-online@veth0.service" ];
network = {
config.networkConfig.ManageForeignRoutes = false;
};
};
services = {
bird2 = {
bird = {
enable = true;
package = pkgs.bird2;
preCheckConfig = ''
echo '"dummy"' > vultr-password.conf
'';

View File

@@ -8,8 +8,9 @@ in
{
config = {
services = {
bird2 = {
bird = {
enable = true;
package = pkgs.bird2;
# TODO: Clean up and modularise
config = ''
define OWNAS = 211024;
@@ -250,42 +251,88 @@ in
neighbor 2001:7f8:10f::dc49:254 as 56393;
}
protocol bgp ixp4_frysix_rs3 from ixp_bgp4 {
description "Frys-IX route server 3 (IPv4)";
neighbor 185.1.160.255 as 56393;
}
protocol bgp ixp6_frysix_rs3 from ixp_bgp6 {
description "Frys-IX route server 3 (IPv6)";
neighbor 2001:7f8:10f::dc49:1 as 56393;
}
protocol bgp ixp4_frysix_rs4 from ixp_bgp4 {
description "Frys-IX route server 4 (IPv4)";
neighbor 185.1.161.0 as 56393;
}
protocol bgp ixp6_frysix_rs4 from ixp_bgp6 {
description "Frys-IX route server 4 (IPv6)";
neighbor 2001:7f8:10f::dc49:2 as 56393;
}
protocol bgp peer4_frysix_luje from peer_bgp4 {
description "LUJE.net (on Frys-IX, IPv4)";
neighbor 185.1.203.152 as 212855;
neighbor 185.1.160.152 as 212855;
}
protocol bgp peer6_frysix_luje from peer_bgp6 {
description "LUJE.net (on Frys-IX, IPv6)";
neighbor 2001:7f8:10f::3:3f95:152 as 212855;
}
protocol bgp peer4_frysix_he from peer_bgp4 {
description "Hurricane Electric (on Frys-IX, IPv4)";
neighbor 185.1.203.154 as 6939;
neighbor 185.1.160.154 as 6939;
}
protocol bgp peer4_frysix_cloudflare from peer_bgp4 {
description "Cloudflare (on Frys-IX, IPv4)";
protocol bgp peer4_frysix_cloudflare1_old from peer_bgp4 {
description "Cloudflare 1 (on Frys-IX, IPv4)";
neighbor 185.1.203.217 as 13335;
}
protocol bgp peer6_frysix_cloudflare from peer_bgp6 {
description "Cloudflare (on Frys-IX, IPv6)";
protocol bgp peer4_frysix_cloudflare2_old from peer_bgp4 {
description "Cloudflare 2 (on Frys-IX, IPv4)";
neighbor 185.1.203.109 as 13335;
}
protocol bgp peer4_frysix_cloudflare1 from peer_bgp4 {
description "Cloudflare 1 (on Frys-IX, IPv4)";
neighbor 185.1.160.217 as 13335;
}
protocol bgp peer4_frysix_cloudflare2 from peer_bgp4 {
description "Cloudflare 2 (on Frys-IX, IPv4)";
neighbor 185.1.160.109 as 13335;
}
protocol bgp peer6_frysix_cloudflare1 from peer_bgp6 {
description "Cloudflare 1 (on Frys-IX, IPv6)";
neighbor 2001:7f8:10f::3417:217 as 13335;
}
protocol bgp peer6_frysix_cloudflare2 from peer_bgp6 {
description "Cloudflare 2 (on Frys-IX, IPv6)";
neighbor 2001:7f8:10f::3417:109 as 13335;
}
protocol bgp peer4_frysix_jurrian from peer_bgp4 {
description "AS212635 aka jurrian (on Frys-IX, IPv4)";
neighbor 185.1.203.134 as 212635;
neighbor 185.1.160.134 as 212635;
}
protocol bgp peer6_frysix_jurrian from peer_bgp6 {
description "AS212635 aka jurrian (on Frys-IX, IPv6)";
neighbor 2001:7f8:10f::3:3e9b:134 as 212635;
}
protocol bgp peer4_frysix_meta1 from peer_bgp4 {
protocol bgp peer4_frysix_meta1_old from peer_bgp4 {
description "Meta 1 (on Frys-IX, IPv4)";
neighbor 185.1.203.225 as 32934;
}
protocol bgp peer4_frysix_meta2 from peer_bgp4 {
protocol bgp peer4_frysix_meta2_old from peer_bgp4 {
description "Meta 2 (on Frys-IX, IPv4)";
neighbor 185.1.203.226 as 32934;
}
protocol bgp peer4_frysix_meta1 from peer_bgp4 {
description "Meta 1 (on Frys-IX, IPv4)";
neighbor 185.1.160.225 as 32934;
}
protocol bgp peer4_frysix_meta2 from peer_bgp4 {
description "Meta 2 (on Frys-IX, IPv4)";
neighbor 185.1.160.226 as 32934;
}
protocol bgp peer6_frysix_meta1 from peer_bgp6 {
description "Meta 1 (on Frys-IX, IPv6)";
neighbor 2001:7f8:10f::80a6:225 as 32934;
@@ -317,36 +364,36 @@ in
ipv6 { preference (PREFIXP-1); };
}
protocol bgp peer4_nlix_cloudflare1 from peer_bgp4 {
description "Cloudflare NL-ix 1 (IPv4)";
neighbor 193.239.117.14 as 13335;
ipv4 { preference (PREFPEER-1); };
}
protocol bgp peer4_nlix_cloudflare2 from peer_bgp4 {
description "Cloudflare NL-ix 2 (IPv4)";
neighbor 193.239.117.114 as 13335;
ipv4 { preference (PREFPEER-1); };
}
protocol bgp peer4_nlix_cloudflare3 from peer_bgp4 {
description "Cloudflare NL-ix 3 (IPv4)";
neighbor 193.239.118.138 as 13335;
ipv4 { preference (PREFPEER-1); };
}
protocol bgp peer6_nlix_cloudflare1 from peer_bgp6 {
description "Cloudflare NL-ix 1 (IPv6)";
neighbor 2001:7f8:13::a501:3335:1 as 13335;
ipv6 { preference (PREFPEER-1); };
}
protocol bgp peer6_nlix_cloudflare2 from peer_bgp6 {
description "Cloudflare NL-ix 2 (IPv6)";
neighbor 2001:7f8:13::a501:3335:2 as 13335;
ipv6 { preference (PREFPEER-1); };
}
protocol bgp peer6_nlix_cloudflare3 from peer_bgp6 {
description "Cloudflare NL-ix 3 (IPv6)";
neighbor 2001:7f8:13::a501:3335:3 as 13335;
ipv6 { preference (PREFPEER-1); };
}
# protocol bgp peer4_nlix_cloudflare1 from peer_bgp4 {
# description "Cloudflare NL-ix 1 (IPv4)";
# neighbor 193.239.117.14 as 13335;
# ipv4 { preference (PREFPEER-1); };
# }
# protocol bgp peer4_nlix_cloudflare2 from peer_bgp4 {
# description "Cloudflare NL-ix 2 (IPv4)";
# neighbor 193.239.117.114 as 13335;
# ipv4 { preference (PREFPEER-1); };
# }
# protocol bgp peer4_nlix_cloudflare3 from peer_bgp4 {
# description "Cloudflare NL-ix 3 (IPv4)";
# neighbor 193.239.118.138 as 13335;
# ipv4 { preference (PREFPEER-1); };
# }
# protocol bgp peer6_nlix_cloudflare1 from peer_bgp6 {
# description "Cloudflare NL-ix 1 (IPv6)";
# neighbor 2001:7f8:13::a501:3335:1 as 13335;
# ipv6 { preference (PREFPEER-1); };
# }
# protocol bgp peer6_nlix_cloudflare2 from peer_bgp6 {
# description "Cloudflare NL-ix 2 (IPv6)";
# neighbor 2001:7f8:13::a501:3335:2 as 13335;
# ipv6 { preference (PREFPEER-1); };
# }
# protocol bgp peer6_nlix_cloudflare3 from peer_bgp6 {
# description "Cloudflare NL-ix 3 (IPv6)";
# neighbor 2001:7f8:13::a501:3335:3 as 13335;
# ipv6 { preference (PREFPEER-1); };
# }
protocol bgp peer4_nlix_jurrian from peer_bgp4 {
description "AS212635 aka jurrian (on NL-ix, IPv4)";
neighbor 193.239.117.55 as 212635;

View File

@@ -219,6 +219,9 @@ in
mkMerge
[
(mkIXPConfig "frys-ix" "185.1.203.196/24" "2001:7f8:10f::3:3850:196/64")
# FrysIX is migrating to a /23
{ "85-frys-ix".address = [ "185.1.160.196/23" ]; }
(mkIXPConfig "nl-ix" "193.239.116.145/22" "2001:7f8:13::a521:1024:1/64")
(mkIXPConfig "fogixp" "185.1.147.159/24" "2001:7f8:ca:1::159/64")
{
@@ -399,8 +402,10 @@ in
ip6 daddr ${aa.middleman.internal.ipv6.address} tcp dport { http, https, 8448 } accept
${matchInet "tcp dport { http, https } accept" "git"}
ip6 daddr ${aa.simpcraft-oci.internal.ipv6.address} tcp dport { 25565, 25575 } accept
ip6 daddr ${aa.simpcraft-oci.internal.ipv6.address} tcp dport 25565 accept
ip6 daddr ${aa.simpcraft-staging-oci.internal.ipv6.address} tcp dport 25565 accept
ip6 daddr ${aa.kevcraft-oci.internal.ipv6.address} tcp dport 25567 accept
ip6 daddr ${aa.kinkcraft-oci.internal.ipv6.address} tcp dport 25568 accept
return
}
chain routing-udp {
@@ -408,6 +413,8 @@ in
ip6 daddr ${aa.waffletail.internal.ipv6.address} udp dport 41641 accept
ip6 daddr ${aa.simpcraft-oci.internal.ipv6.address} udp dport 25565 accept
ip6 daddr ${aa.enshrouded-oci.internal.ipv6.address} udp dport { 15636-15637 } accept
ip6 daddr ${aa.kevcraft-oci.internal.ipv6.address} udp dport 25567 accept
ip6 daddr ${aa.kinkcraft-oci.internal.ipv6.address} udp dport 25568 accept
return
}
chain filter-routing {

View File

@@ -14,7 +14,7 @@ in
owner = "pdns";
group = "pdns";
};
"estuary/pdns/recursor.conf" = {
"estuary/pdns/recursor.yml" = {
owner = "pdns-recursor";
group = "pdns-recursor";
};
@@ -31,7 +31,7 @@ in
pdns.recursor = {
enable = true;
extraSettingsFile = config.age.secrets."estuary/pdns/recursor.conf".path;
extraSettingsFile = config.age.secrets."estuary/pdns/recursor.yml".path;
};
};
@@ -44,45 +44,55 @@ in
};
pdns-recursor = {
dns = {
address = [
"127.0.0.1" "::1"
assignments.base.ipv4.address assignments.base.ipv6.address
];
allowFrom = [
"127.0.0.0/8" "::1/128"
prefixes.all.v4 prefixes.all.v6
] ++ (with lib.my.c.tailscale.prefix; [ v4 v6 ]);
};
yaml-settings = {
incoming = {
listen = [
"127.0.0.1" "::1"
assignments.base.ipv4.address assignments.base.ipv6.address
];
allow_from = [
"127.0.0.0/8" "::1/128"
prefixes.all.v4 prefixes.all.v6
] ++ (with lib.my.c.tailscale.prefix; [ v4 v6 ]);
settings = {
query-local-address = [
assignments.internal.ipv4.address
assignments.internal.ipv6.address
assignments.base.ipv6.address
];
forward-zones = map (z: "${z}=127.0.0.1:5353") authZones;
# DNS NOTIFY messages override TTL
allow_notify_for = authZones;
allow_notify_from = [ "127.0.0.0/8" "::1/128" ];
};
# DNS NOTIFY messages override TTL
allow-notify-for = authZones;
allow-notify-from = [ "127.0.0.0/8" "::1/128" ];
outgoing = {
source_address = [
assignments.internal.ipv4.address
assignments.internal.ipv6.address
assignments.base.ipv6.address
];
};
webserver = true;
webserver-address = "::";
webserver-allow-from = [ "127.0.0.1" "::1" ];
recursor = {
forward_zones = map (z: {
zone = z;
forwarders = [ "127.0.0.1:5353" ];
}) authZones;
lua-dns-script = pkgs.writeText "pdns-script.lua" ''
function preresolve(dq)
if dq.qname:equal("nix-cache.nul.ie") then
dq:addAnswer(pdns.CNAME, "http.${config.networking.domain}.")
dq.rcode = 0
dq.followupFunction = "followCNAMERecords"
return true
lua_dns_script = pkgs.writeText "pdns-script.lua" ''
function preresolve(dq)
if dq.qname:equal("nix-cache.nul.ie") then
dq:addAnswer(pdns.CNAME, "http.${config.networking.domain}.")
dq.rcode = 0
dq.followupFunction = "followCNAMERecords"
return true
end
return false
end
'';
};
return false
end
'';
webservice = {
webserver = true;
address = "::";
allow_from = [ "127.0.0.1" "::1" ];
};
};
};
};
@@ -154,6 +164,10 @@ in
simpcraft-staging IN A ${assignments.internal.ipv4.address}
simpcraft-staging IN AAAA ${allAssignments.simpcraft-staging-oci.internal.ipv6.address}
enshrouded IN A ${assignments.internal.ipv4.address}
kevcraft IN A ${assignments.internal.ipv4.address}
kevcraft IN AAAA ${allAssignments.kevcraft-oci.internal.ipv6.address}
kinkcraft IN A ${assignments.internal.ipv4.address}
kinkcraft IN AAAA ${allAssignments.kinkcraft-oci.internal.ipv6.address}
mail-vm IN A ${net.cidr.host 0 prefixes.mail.v4}
mail-vm IN AAAA ${net.cidr.host 1 prefixes.mail.v6}

View File

@@ -328,6 +328,7 @@ in
};
permissions = {
"@dev:nul.ie" = "admin";
"@adzerq:nul.ie" = "user";
};
};
};

View File

@@ -251,6 +251,9 @@ in
proxyResolveWhileRunning = true;
sslDhparam = config.age.secrets."dhparams.pem".path;
appendConfig = ''
worker_processes auto;
'';
# Based on recommended*Settings, but probably better to be explicit about these
appendHttpConfig = ''
${baseHttpConfig}

View File

@@ -49,6 +49,7 @@ let
"/.well-known/webfinger".return = "301 https://toot.nul.ie$request_uri";
"/.well-known/nodeinfo".return = "301 https://toot.nul.ie$request_uri";
"/.well-known/host-meta".return = "301 https://toot.nul.ie$request_uri";
"/.well-known/atproto-did".return = "301 https://pds.nul.ie$request_uri";
};
in
{
@@ -79,6 +80,10 @@ in
sha256 = "018wh6ps19n7323fi44njzj9yd4wqslc90dykbwfyscv7bgxhlar";
};
}
{
name = "ssh.pub";
path = lib.my.c.sshKeyFiles.me;
}
];
}
wellKnown
@@ -322,6 +327,15 @@ in
useACMEHost = pubDomain;
};
"pds.nul.ie" = {
locations."/" = {
proxyPass = "http://toot-ctr.${domain}:3000";
proxyWebsockets = true;
extraConfig = proxyHeaders;
};
useACMEHost = pubDomain;
};
"share.${pubDomain}" = {
locations."/" = {
proxyPass = "http://object-ctr.${domain}:9090";
@@ -343,6 +357,8 @@ in
useACMEHost = pubDomain;
};
"public.${pubDomain}" = {
onlySSL = false;
addSSL = true;
serverAliases = [ "p.${pubDomain}" ];
locations."/" = {
root = "/mnt/media/public";
@@ -363,6 +379,11 @@ in
useACMEHost = pubDomain;
};
"mc-map-kink.${pubDomain}" = {
locations."/".proxyPass = "http://kinkcraft-oci.${domain}:8100";
useACMEHost = pubDomain;
};
"librespeed.${domain}" = {
locations."/".proxyPass = "http://localhost:8989";
};
@@ -413,6 +434,14 @@ in
}
(ssoServer "generic")
];
"hass.${pubDomain}" = {
locations."/" = {
proxyPass = "http://hass-ctr.${home.domain}:8123";
proxyWebsockets = true;
extraConfig = proxyHeaders;
};
useACMEHost = pubDomain;
};
};
minio =

View File

@@ -26,6 +26,8 @@ in
let
inherit (lib) mkMerge mkIf genAttrs;
inherit (lib.my) networkdAssignment systemdAwaitPostgres;
pdsPort = 3000;
in
{
config = mkMerge [
@@ -36,7 +38,7 @@ in
secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILSslLkDe54AKYzxdtKD70zcU72W0EpYsfbdJ6UFq0QK";
files = genAttrs
files = (genAttrs
(map (f: "toot/${f}") [
"postgres-password.txt"
"secret-key.txt"
@@ -48,7 +50,12 @@ in
(_: with config.services.mastodon; {
owner = user;
inherit group;
});
})) // {
"toot/pds.env" = {
owner = "pds";
group = "pds";
};
};
};
firewall = {
@@ -56,6 +63,7 @@ in
19999
"http"
pdsPort
];
};
};
@@ -79,7 +87,7 @@ in
netdata.enable = true;
mastodon = mkMerge [
rec {
enable = true;
enable = false;
localDomain = extraConfig.WEB_DOMAIN; # for nginx config
extraConfig = {
LOCAL_DOMAIN = "nul.ie";
@@ -87,7 +95,9 @@ in
};
secretKeyBaseFile = config.age.secrets."toot/secret-key.txt".path;
otpSecretFile = config.age.secrets."toot/otp-secret.txt".path;
# TODO: This was removed at some point.
# If we want to bring Mastodon back, this will probably need to be addressd.
# otpSecretFile = config.age.secrets."toot/otp-secret.txt".path;
vapidPrivateKeyFile = config.age.secrets."toot/vapid-key.txt".path;
vapidPublicKeyFile = toString (pkgs.writeText
"vapid-pubkey.txt"
@@ -155,6 +165,32 @@ in
};
};
};
bluesky-pds = {
enable = true;
environmentFiles = [ config.age.secrets."toot/pds.env".path ];
settings = {
PDS_HOSTNAME = "pds.nul.ie";
PDS_PORT = pdsPort;
PDS_BLOBSTORE_DISK_LOCATION = null;
PDS_BLOBSTORE_S3_BUCKET = "pds";
PDS_BLOBSTORE_S3_ENDPOINT = "https://s3.nul.ie/";
PDS_BLOBSTORE_S3_REGION = "eu-central-1";
PDS_BLOBSTORE_S3_ACCESS_KEY_ID = "pds";
PDS_BLOB_UPLOAD_LIMIT = "52428800";
PDS_EMAIL_FROM_ADDRESS = "pds@nul.ie";
PDS_DID_PLC_URL = "https://plc.directory";
PDS_INVITE_REQUIRED = 1;
PDS_BSKY_APP_VIEW_URL = "https://api.bsky.app";
PDS_BSKY_APP_VIEW_DID = "did:web:api.bsky.app";
PDS_REPORT_SERVICE_URL = "https://mod.bsky.app";
PDS_REPORT_SERVICE_DID = "did:plc:ar7c4by46qjdydhdevvrndac";
PDS_CRAWLERS = "https://bsky.network";
};
};
};
}
(mkIf config.my.build.isDevVM {

View File

@@ -53,6 +53,8 @@ in
simpcraft-oci = 3;
simpcraft-staging-oci = 4;
enshrouded-oci = 5;
kevcraft-oci = 6;
kinkcraft-oci = 7;
};
configuration = { lib, pkgs, modulesPath, config, assignments, allAssignments, ... }:

View File

@@ -5,12 +5,13 @@ let
# devplayer0
op = "6d7d971b-ce10-435b-85c5-c99c0d8d288c";
kev = "703b378a-09f9-4c1d-9876-1c9305728c49";
whitelist = concatStringsSep "," [
op
"dcd2ecb9-2b5e-49cb-9d4f-f5a76162df56" # Elderlypug
"fcb26db2-c3ce-41aa-b588-efec79d37a8a" # Jesthral_
"1d366062-12c0-4e29-aba7-6ab5d8c6bb05" # shr3kas0ras
"703b378a-09f9-4c1d-9876-1c9305728c49" # OROURKEIRE
kev
"f105bbe6-eda6-4a13-a8cf-894e77cab77b" # Adzerq
"1fc94979-41fb-497a-81e9-34ae24ca537a" # johnnyscrims
"d53c91df-b6e6-4463-b106-e8427d7a8d01" # BossLonus
@@ -104,6 +105,87 @@ in
# ''--network=colony:${dockerNetAssignment allAssignments "simpcraft-staging-oci"}''
# ];
# };
kevcraft = {
# 2025.2.1-java21-alpine
image = "itzg/minecraft-server@sha256:57e319c15e9fee63f61029a65a33acc3de85118b21a2b4bb29f351cf4a915027";
environment = {
TYPE = "VANILLA";
VERSION = "1.20.1";
SERVER_PORT = "25567";
QUERY_PORT = "25567";
EULA = "true";
ENABLE_QUERY = "true";
ENABLE_RCON = "true";
MOTD = "§4§k----- §9K§ae§bv§cc§dr§ea§ff§6t §4§k-----";
ICON = "/ext/icon.png";
EXISTING_WHITELIST_FILE = "SYNCHRONIZE";
WHITELIST = whitelist;
EXISTING_OPS_FILE = "SYNCHRONIZE";
OPS = concatStringsSep "," [ op kev ];
DIFFICULTY = "normal";
SPAWN_PROTECTION = "0";
# VIEW_DISTANCE = "20";
MAX_MEMORY = "4G";
TZ = "Europe/Dublin";
};
environmentFiles = [ config.age.secrets."whale2/simpcraft.env".path ];
volumes = [
"kevcraft_data:/data"
"${./kev.png}:/ext/icon.png:ro"
];
extraOptions = [
''--network=colony:${dockerNetAssignment allAssignments "kevcraft-oci"}''
];
};
kinkcraft = {
# 2025.5.1-java21-alpine
image = "itzg/minecraft-server@sha256:de26c7128e3935f3be48fd30283f0b5a6da1b3d9f1a10c9f92502ee1ba072f7b";
environment = {
TYPE = "MODRINTH";
SERVER_PORT = "25568";
QUERY_PORT = "25568";
EULA = "true";
ENABLE_QUERY = "true";
ENABLE_RCON = "true";
MOTD = "§4§k----- §9K§ai§bn§ck§dc§er§fa§6f§5t §4§k-----";
ICON = "/ext/icon.png";
EXISTING_WHITELIST_FILE = "SYNCHRONIZE";
WHITELIST = whitelist;
EXISTING_OPS_FILE = "SYNCHRONIZE";
OPS = op;
DIFFICULTY = "normal";
SPAWN_PROTECTION = "0";
VIEW_DISTANCE = "20";
MAX_MEMORY = "6G";
MODRINTH_MODPACK = "https://cdn.modrinth.com/data/CIYf3Hk8/versions/NGutsQSd/Simpcraft-0.2.1.mrpack";
TZ = "Europe/Dublin";
};
environmentFiles = [ config.age.secrets."whale2/simpcraft.env".path ];
volumes = [
"kinkcraft_data:/data"
"${./icon.png}:/ext/icon.png:ro"
];
extraOptions = [
''--network=colony:${dockerNetAssignment allAssignments "kinkcraft-oci"}''
];
};
};
services = {

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -150,6 +150,7 @@ in
mstflint
qperf
ethtool
android-tools
];
nix = {

View File

@@ -188,6 +188,13 @@
hostBDF = "44:00.4";
};
};
qemuFlags = [
"device qemu-xhci,id=xhci"
# Front-right port?
"device usb-host,hostbus=1,hostport=4"
# Front-left port
"device usb-host,hostbus=1,hostport=3"
];
};
};
};

View File

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

View File

@@ -0,0 +1,262 @@
{ lib, ... }:
let
inherit (lib.my) net;
inherit (lib.my.c) pubDomain;
inherit (lib.my.c.home) domain prefixes vips hiMTU;
in
{
nixos.systems.hass = { config, ... }: {
system = "x86_64-linux";
nixpkgs = "mine";
rendered = config.configuration.config.my.asContainer;
assignments = {
hi = {
name = "hass-ctr";
altNames = [ "frigate" ];
inherit domain;
mtu = hiMTU;
ipv4 = {
address = net.cidr.host 103 prefixes.hi.v4;
mask = 22;
gateway = vips.hi.v4;
};
ipv6 = {
iid = "::5:3";
address = net.cidr.host (65536*5+3) prefixes.hi.v6;
};
};
lo = {
name = "hass-ctr-lo";
inherit domain;
mtu = 1500;
ipv4 = {
address = net.cidr.host 103 prefixes.lo.v4;
mask = 21;
gateway = null;
};
ipv6 = {
iid = "::5:3";
address = net.cidr.host (65536*5+3) prefixes.lo.v6;
};
};
};
configuration = { lib, config, pkgs, assignments, allAssignments, ... }:
let
inherit (lib) mkMerge mkIf mkForce;
inherit (lib.my) networkdAssignment;
hassCli = pkgs.writeShellScriptBin "hass-cli" ''
export HASS_SERVER="http://localhost:${toString config.services.home-assistant.config.http.server_port}"
export HASS_TOKEN="$(< ${config.age.secrets."hass/cli-token.txt".path})"
exec ${pkgs.home-assistant-cli}/bin/hass-cli "$@"
'';
in
{
config = {
my = {
deploy.enable = false;
server.enable = true;
secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGpYX2WbYwUqHp8bFFf0eHFrqrR8xp8IheguA054F8V4";
files = {
"hass/cli-token.txt" = {
owner = config.my.user.config.name;
};
};
};
firewall = {
tcp.allowed = [ "http" 1883 ];
};
};
environment = {
systemPackages = with pkgs; [
usbutils
hassCli
];
};
systemd = {
network.networks = {
"80-container-host0" = networkdAssignment "host0" assignments.hi;
"80-container-lan-lo" = networkdAssignment "lan-lo" assignments.lo;
};
};
services = {
mosquitto = {
enable = true;
listeners = [
{
omitPasswordAuth = true;
settings = {
allow_anonymous = true;
};
}
];
};
go2rtc = {
enable = true;
settings = {
streams = {
reolink_living_room = [
# "http://reolink-living-room.${domain}/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=admin#video=copy#audio=copy#audio=opus"
"rtsp://admin:@reolink-living-room:554/h264Preview_01_main"
];
webcam_office = [
"ffmpeg:device?video=/dev/video0&video_size=1024x576#video=h264"
];
};
};
};
frigate = {
enable = true;
hostname = "frigate.${domain}";
settings = {
mqtt = {
enabled = true;
host = "localhost";
topic_prefix = "frigate";
};
cameras = {
reolink_living_room = {
ffmpeg.inputs = [
{
path = "rtsp://127.0.0.1:8554/reolink_living_room";
input_args = "preset-rtsp-restream";
roles = [ "record" "detect" ];
}
];
detect = {
enabled = false;
};
record = {
enabled = true;
retain.days = 1;
};
};
webcam_office = {
ffmpeg.inputs = [
{
path = "rtsp://127.0.0.1:8554/webcam_office";
input_args = "preset-rtsp-restream";
roles = [ "record" "detect" ];
}
];
detect.enabled = false;
record = {
enabled = true;
retain.days = 1;
};
};
};
};
};
home-assistant =
let
cfg = config.services.home-assistant;
pyirishrail = ps: ps.buildPythonPackage rec {
pname = "pyirishrail";
version = "0.0.2";
src = pkgs.fetchFromGitHub {
owner = "ttroy50";
repo = "pyirishrail";
tag = version;
hash = "sha256-NgARqhcXP0lgGpgBRiNtQaSn9JcRNtCcZPljcL7t3Xc=";
};
dependencies = with ps; [
requests
];
pyproject = true;
build-system = [ ps.setuptools ];
};
in
{
enable = true;
extraComponents = [
"default_config"
"esphome"
"google_translate"
"met"
"zha"
"denonavr"
"webostv"
"androidtv_remote"
"heos"
"mqtt"
"wled"
];
extraPackages = python3Packages: with python3Packages; [
zlib-ng
isal
gtts
(pyirishrail python3Packages)
];
customComponents = with pkgs.home-assistant-custom-components; [
alarmo
frigate
];
configWritable = false;
openFirewall = true;
config = {
default_config = {};
homeassistant = {
name = "Home";
unit_system = "metric";
currency = "EUR";
country = "IE";
time_zone = "Europe/Dublin";
external_url = "https://hass.${pubDomain}";
internal_url = "http://hass-ctr.${domain}:${toString cfg.config.http.server_port}";
};
http = {
use_x_forwarded_for = true;
trusted_proxies = with allAssignments.middleman.internal; [
ipv4.address
ipv6.address
];
ip_ban_enabled = false;
};
automation = "!include automations.yaml";
script = "!include scripts.yaml";
scene = "!include scenes.yaml";
sensor = [
{
platform = "irish_rail_transport";
name = "To Work from Home";
station = "Glenageary";
stops_at = "Dublin Connolly";
direction = "Northbound";
}
{
platform = "irish_rail_transport";
name = "To Home from Work";
station = "Dublin Connolly";
stops_at = "Glenageary";
direction = "Southbound";
}
];
};
};
};
};
};
};
}

View File

@@ -55,8 +55,8 @@ in
unifi = {
enable = true;
openFirewall = true;
unifiPackage = pkgs.unifi8;
mongodbPackage = pkgs.mongodb-6_0;
unifiPackage = pkgs.unifi;
mongodbPackage = pkgs.mongodb-7_0;
};
};
};

View File

@@ -29,7 +29,7 @@ in
configuration = { lib, modulesPath, pkgs, config, assignments, allAssignments, ... }:
let
inherit (lib) mapAttrs mkMerge;
inherit (lib) mapAttrs mkMerge mkForce;
inherit (lib.my) networkdAssignment;
inherit (lib.my.c) networkd;
inherit (lib.my.c.home) domain;
@@ -83,6 +83,12 @@ in
};
};
environment = {
systemPackages = with pkgs; [
usbutils
];
};
systemd.network = {
links = {
"10-lan-hi" = {
@@ -105,6 +111,13 @@ in
MTUBytes = toString lib.my.c.home.hiMTU;
};
};
"10-lan-lo-ctrs" = {
matchConfig = {
Driver = "virtio_net";
PermanentMACAddress = "52:54:00:a5:7e:93";
};
linkConfig.Name = "lan-lo-ctrs";
};
};
networks = {
@@ -118,9 +131,29 @@ in
linkConfig.RequiredForOnline = "no";
networkConfig = networkd.noL3;
};
"30-lan-lo-ctrs" = {
matchConfig.Name = "lan-lo-ctrs";
linkConfig.RequiredForOnline = "no";
networkConfig = networkd.noL3;
};
};
};
systemd.nspawn = {
hass = {
networkConfig = {
MACVLAN = mkForce "lan-hi-ctrs:host0 lan-lo-ctrs:lan-lo";
};
};
};
systemd.services = {
"systemd-nspawn@hass".serviceConfig.DeviceAllow = [
"char-ttyUSB rw"
"char-video4linux rw"
];
};
my = {
secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAAaav5Se1E/AbqEXmADryVszYfNDscyP6jrWioN57R7";
@@ -141,7 +174,17 @@ in
containers.instances =
let
instances = {
unifi = {};
# unifi = {};
hass = {
bindMounts = {
"/dev/bus/usb/001/002".readOnly = false;
"/dev/video0".readOnly = false;
"/dev/serial/by-id/usb-Nabu_Casa_Home_Assistant_Connect_ZBT-1_ce549704fe38ef11a2c2e5d154516304-if00-port0" = {
readOnly = false;
mountPoint = "/dev/ttyUSB0";
};
};
};
};
in
mkMerge [

View File

@@ -141,8 +141,8 @@ in
onState = [ "configured" ];
script = ''
#!${pkgs.runtimeShell}
if [ $IFACE = "wan-ifb" ]; then
${pkgs.iproute2}/bin/tc filter add dev wan parent ffff: matchall action mirred egress redirect dev $IFACE
if [ "$IFACE" = "wan-ifb" ]; then
${pkgs.iproute2}/bin/tc filter add dev wan parent ffff: matchall action mirred egress redirect dev "$IFACE"
fi
'';
};

View File

@@ -0,0 +1,74 @@
# Blocklist for LG WebOS Services (US)
ad.lgappstv.com
ibis.lgappstv.com
info.lgsmartad.com
lgtvsdp.com
ngfts.lge.com
rdx2.lgtvsdp.com
smartshare.lgtvsdp.com
lgappstv.com
us.ad.lgsmartad.com
us.ibs.lgappstv.com
us.info.lgsmartad.com
us.lgtvsdp.com
# Community Contributions
lgad.cjpowercast.com
edgesuite.net
yumenetworks.com
smartclip.net
smartclip.com
# Non-US Entries
rdx2.lgtvsdp.com
info.lgsmartad.com
ibs.lgappstv.com
lgtvsdp.com
lgappstv.com
smartshare.lgtvsdp.com
# Full Block for Europe and Other Regions
de.ad.lgsmartad.com
de.emp.lgsmartplatform.com
de.ibs.lgappstv.com
de.info.lgsmartad.com
de.lgeapi.com
de.lgtvsdp.com
de.rdx2.lgtvsdp.com
eu.ad.lgsmartad.com
eu.ibs.lgappstv.com
eu.info.lgsmartad.com
app-lgwebos.pluto.tv
it.lgtvsdp.com
it.lgeapi.com
it.emp.lgsmartplatform.com
# LG ThinQ Services
eic.common.lgthinq.com
eic.iotservice.lgthinq.com
eic.service.lgthinq.com
eic.ngfts.lge.com
eic.svc-lgthinq-com.aws-thinq-prd.net
eic.cdpsvc.lgtvcommon.com
eic.cdpbeacon.lgtvcommon.com
eic.cdplauncher.lgtvcommon.com
eic.homeprv.lgtvcommon.com
eic.lgtviot.com
eic.nudge.lgtvcommon.com
eic.rdl.lgtvcommon.com
eic.recommend.lgtvcommon.com
eic.service.lgtvcommon.com
gb-lgeapi-com.esi-prd.net
gb.lgeapi.com
lgtvonline.lge.com
lg-channelplus-de-beacons.xumo.com
lg-channelplus-de-mds.xumo.com
lg-channelplus-eu-beacons.xumo.com
lg-channelplus-eu-mds.xumo.com
kr-op-v2.lgthinqhome.com
ngfts.lge.com
noti.lgthinq.com
objectcontent.lgthinq.com
# Update Server Block
#snu.lge.com

View File

@@ -19,7 +19,7 @@ in
owner = "pdns";
group = "pdns";
};
"home/pdns/recursor.conf" = {
"home/pdns/recursor.yml" = {
owner = "pdns-recursor";
group = "pdns-recursor";
};
@@ -28,52 +28,78 @@ in
pdns.recursor = {
enable = true;
extraSettingsFile = config.age.secrets."home/pdns/recursor.conf".path;
extraSettingsFile = config.age.secrets."home/pdns/recursor.yml".path;
};
};
services = {
pdns-recursor = {
dns = {
address = [
"127.0.0.1" "::1"
assignments.hi.ipv4.address assignments.hi.ipv6.address
assignments.lo.ipv4.address assignments.lo.ipv6.address
];
allowFrom = [
"127.0.0.0/8" "::1/128"
prefixes.hi.v4 prefixes.hi.v6
prefixes.lo.v4 prefixes.lo.v6
] ++ (with lib.my.c.tailscale.prefix; [ v4 v6 ]);
};
yaml-settings = {
incoming = {
listen = [
"127.0.0.1" "::1"
assignments.hi.ipv4.address assignments.hi.ipv6.address
assignments.lo.ipv4.address assignments.lo.ipv6.address
];
allow_from = [
"127.0.0.0/8" "::1/128"
prefixes.hi.v4 prefixes.hi.v6
prefixes.lo.v4 prefixes.lo.v6
] ++ (with lib.my.c.tailscale.prefix; [ v4 v6 ]);
settings = {
query-local-address = [
"0.0.0.0"
"::"
];
forward-zones = map (z: "${z}=127.0.0.1:5353") authZones;
# DNS NOTIFY messages override TTL
allow_notify_for = authZones;
allow_notify_from = [ "127.0.0.0/8" "::1/128" ];
};
# DNS NOTIFY messages override TTL
allow-notify-for = authZones;
allow-notify-from = [ "127.0.0.0/8" "::1/128" ];
outgoing = {
source_address = [ "0.0.0.0" "::" ];
};
webserver = true;
webserver-address = "::";
webserver-allow-from = [ "127.0.0.1" "::1" ];
recursor = {
forward_zones = map (z: {
zone = z;
forwarders = [ "127.0.0.1:5353" ];
}) authZones;
lua-dns-script = pkgs.writeText "pdns-script.lua" ''
-- Disney+ doesn't like our IP space...
function preresolve(dq)
local name = dq.qname:toString()
if dq.qtype == pdns.AAAA and (string.find(name, "disneyplus") or string.find(name, "disney-plus") or string.find(name , "disney.api")) then
dq.rcode = 0
return true
lua_dns_script = pkgs.writeText "pdns-script.lua" ''
blocklist = newDS()
function preresolve(dq)
local name = dq.qname:toString()
-- Disney+ doesn't like our IP space...
if dq.qtype == pdns.AAAA and (string.find(name, "disneyplus") or string.find(name, "disney-plus") or string.find(name , "disney.api")) then
dq.rcode = 0
return true
end
if blocklist:check(dq.qname) then
if dq.qtype == pdns.A then
dq:addAnswer(dq.qtype, "127.0.0.1")
elseif dq.qtype == pdns.AAAA then
dq:addAnswer(dq.qtype, "::1")
end
return true
end
return false
end
return false
end
'';
for line in io.lines("${./dns-blocklist.txt}") do
entry = line:gsub("%s+", "")
if entry ~= "" and string.sub(entry, 1, 1) ~= "#" then
blocklist:add(entry)
end
end
'';
};
webservice = {
webserver = true;
address = "::";
allow_from = [ "127.0.0.1" "::1" ];
};
};
};
};
@@ -206,6 +232,9 @@ in
ups IN A ${net.cidr.host 20 prefixes.lo.v4}
palace-kvm IN A ${net.cidr.host 21 prefixes.lo.v4}
reolink-living-room IN A ${net.cidr.host 45 prefixes.lo.v4}
nixlight IN A ${net.cidr.host 46 prefixes.lo.v4}
${lib.my.dns.fwdRecords {
inherit allAssignments names;
domain = config.networking.domain;

View File

@@ -2,7 +2,7 @@
import argparse
import subprocess
import CloudFlare
import cloudflare
def main():
parser = argparse.ArgumentParser(description='Cloudflare DNS update script')
@@ -19,17 +19,22 @@ def main():
if args.api_token_file:
with open(args.api_token_file) as f:
cf_token = f.readline().strip()
cf = cloudflare.Cloudflare(api_token=cf_token)
cf = CloudFlare.CloudFlare(token=cf_token)
zones = cf.zones.get(params={'name': args.zone})
zones = list(cf.zones.list(name=args.zone))
assert zones, f'Zone {args.zone} not found'
records = cf.zones.dns_records.get(zones[0]['id'], params={'name': args.record})
assert len(zones) == 1, f'More than one zone found for {args.zone}'
zone = zones[0]
records = list(cf.dns.records.list(zone_id=zone.id, name=args.record, type='A'))
assert records, f'Record {args.record} not found in zone {args.zone}'
assert len(records) == 1, f'More than one record found for {args.record}'
record = records[0]
print(f'Updating {args.record} -> {address}')
cf.zones.dns_records.patch(
zones[0]['id'], records[0]['id'],
data={'type': 'A', 'name': args.record, 'content': address})
cf.dns.records.edit(
zone_id=zone.id, dns_record_id=record.id,
type='A', content=address)
if __name__ == '__main__':
main()

View File

@@ -132,6 +132,37 @@ in
hw-address = "24:8a:07:a8:fe:3a";
ip-address = net.cidr.host 40 prefixes.lo.v4;
}
{
# avr
hw-address = "8c:a9:6f:30:03:6b";
ip-address = net.cidr.host 41 prefixes.lo.v4;
}
{
# tv
hw-address = "00:a1:59:b8:4d:86";
ip-address = net.cidr.host 42 prefixes.lo.v4;
}
{
# android tv
hw-address = "b8:7b:d4:95:c6:74";
ip-address = net.cidr.host 43 prefixes.lo.v4;
}
{
# hass-panel
hw-address = "80:30:49:cd:d7:51";
ip-address = net.cidr.host 44 prefixes.lo.v4;
}
{
# reolink-living-room
hw-address = "ec:71:db:30:69:a4";
ip-address = net.cidr.host 45 prefixes.lo.v4;
}
{
# nixlight
hw-address = "00:4b:12:3b:d3:14";
ip-address = net.cidr.host 46 prefixes.lo.v4;
}
];
}
];

View File

@@ -45,12 +45,12 @@
services = {
mjpg-streamer = {
enable = true;
enable = false;
inputPlugin = "input_uvc.so";
outputPlugin = "output_http.so -w @www@ -n -p 5050";
};
octoprint = {
enable = true;
enable = false;
host = "::";
extraConfig = {
plugins = {

View File

@@ -92,12 +92,14 @@ in
nextcloud = {
enable = true;
package = pkgs.nextcloud29;
# TODO: Might need to do some bullshit to go from Nextcloud 28 (?) to 30
package = pkgs.nextcloud30;
datadir = "/mnt/storage/nextcloud";
hostName = "cloud.${domain}";
https = true;
config = {
adminpassFile = config.age.secrets."kelder/nextcloud-root.txt".path;
dbtype = "sqlite";
};
settings = {
updatechecker = false;

View File

@@ -23,7 +23,7 @@ let
pkgs = pkgs'.${config'.nixpkgs}.${config'.system};
allPkgs = mapAttrs (_: p: p.${config'.system}) pkgs';
modules' = [ hmFlakes.${config'.home-manager}.nixosModule ] ++ (attrValues cfg.modules);
modules' = [ hmFlakes.${config'.home-manager}.nixosModules.default ] ++ (attrValues cfg.modules);
in
# Import eval-config ourselves since the flake now force-sets lib
import "${pkgsFlake}/nixos/lib/eval-config.nix" {

View File

@@ -31,8 +31,10 @@
server.enable = true;
};
image = {
baseName = "jackos-installer";
};
isoImage = {
isoBaseName = "jackos-installer";
volumeID = "jackos-${config.system.nixos.release}-${pkgs.stdenv.hostPlatform.uname.processor}";
edition = "devplayer0";
appendToMenuLabel = " /dev/player0 Installer";

View File

@@ -14,7 +14,7 @@
network = ./network.nix;
pdns = ./pdns.nix;
nginx-sso = ./nginx-sso.nix;
gui = ./gui.nix;
gui = ./gui;
l2mesh = ./l2mesh.nix;
borgthin = ./borgthin.nix;
nvme = ./nvme;

View File

@@ -1,4 +1,4 @@
{ lib, pkgs, config, ... }:
{ inputs, lib, pkgs, config, ... }:
let
inherit (builtins) substring match;
inherit (lib)
@@ -127,7 +127,9 @@ in
enable = mkBoolOpt' false "Whether to enable borgthin jobs";
lvmPackage = mkOpt' package pkgs.lvm2 "Packge containing LVM tools";
thinToolsPackage = mkOpt' package pkgs.thin-provisioning-tools "Package containing thin-provisioning-tools";
package = mkOpt' package pkgs.borgthin "borgthin package";
# Really we should use the version from the overlay, but the package is quite far behind...
# Not bothering to update until Borg 2.0 releases
package = mkOpt' package inputs.borgthin.packages.${config.nixpkgs.system}.borgthin "borgthin package";
jobs = mkOpt' (attrsOf jobType) { } "borgthin jobs";
};

View File

@@ -221,8 +221,8 @@ in
memorySize = dummyOption;
qemu.options = dummyOption;
};
image.baseName = dummyOption;
isoImage = {
isoBaseName = dummyOption;
volumeID = dummyOption;
edition = dummyOption;
appendToMenuLabel = dummyOption;

View File

@@ -65,9 +65,10 @@ in
};
nixpkgs = {
overlays = [
inputs.deploy-rs.overlay
inputs.deploy-rs.overlays.default
inputs.sharry.overlays.default
inputs.borgthin.overlays.default
# TODO: Re-enable when borgthin is updated
# inputs.borgthin.overlays.default
inputs.boardie.overlays.default
];
config = {

View File

@@ -15,6 +15,7 @@ let
passAsFile = [ "code" ];
code = ''
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <systemd/sd-daemon.h>

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,12 @@ let
inherit (lib.my) mkBoolOpt';
cfg = config.my.gui;
androidUdevRules = pkgs.runCommand "udev-rules-android" {
rulesFile = ./android-udev.rules;
} ''
install -D "$rulesFile" "$out"/lib/udev/rules.d/51-android.rules
'';
in
{
options.my.gui = with lib.types; {
@@ -26,6 +32,12 @@ in
pam.services.swaylock-plugin = {};
};
users = {
groups = {
adbusers.gid = lib.my.c.ids.gids.adbusers;
};
};
environment.systemPackages = with pkgs; [
# for pw-jack
pipewire.jack
@@ -44,8 +56,12 @@ in
gnome = {
gnome-keyring.enable = true;
};
udisks2.enable = true;
udev = {
packages = [
androidUdevRules
];
extraRules = ''
# Nvidia
SUBSYSTEM=="usb", ATTR{idVendor}=="0955", MODE="0664", GROUP="wheel"
@@ -88,5 +104,13 @@ in
];
};
};
my = {
user = {
config = {
extraGroups = [ "adbusers" ];
};
};
};
};
}

View File

@@ -5,6 +5,7 @@ let
cfg = config.my.netboot;
# Newer releases don't boot on desktop?
ipxe = pkgs.ipxe.overrideAttrs (o: rec {
version = "1.21.1-unstable-2024-06-27";
src = pkgs.fetchFromGitHub {
@@ -13,6 +14,9 @@ let
rev = "b66e27d9b29a172a097c737ab4d378d60fe01b05";
hash = "sha256-TKZ4WjNV2oZIYNefch7E7m1JpeoC/d7O1kofoNv8G40=";
};
# This upstream patch (in newer versions) is needed for newer GCC
patches = (if (o ? patches) then o.patches else []) ++ [ ./fix-uninitialised-var.patch ];
});
tftpRoot = pkgs.linkFarm "tftp-root" [
{
@@ -26,23 +30,25 @@ let
substituteAll ${./menu.ipxe} "$out"
'';
bootBuilder = pkgs.substituteAll {
bootBuilder = pkgs.replaceVarsWith {
src = ./netboot-loader-builder.py;
isExecutable = true;
inherit (pkgs) python3;
bootspecTools = pkgs.bootspec;
nix = config.nix.package.out;
replacements = {
inherit (pkgs) python3;
bootspecTools = pkgs.bootspec;
nix = config.nix.package.out;
inherit (config.system.nixos) distroName;
systemName = config.system.name;
inherit (cfg.client) configurationLimit;
checkMountpoints = pkgs.writeShellScript "check-mountpoints" ''
if ! ${pkgs.util-linuxMinimal}/bin/findmnt /boot > /dev/null; then
echo "/boot is not a mounted partition. Is the path configured correctly?" >&2
exit 1
fi
'';
inherit (config.system.nixos) distroName;
systemName = config.system.name;
inherit (cfg.client) configurationLimit;
checkMountpoints = pkgs.writeShellScript "check-mountpoints" ''
if ! ${pkgs.util-linuxMinimal}/bin/findmnt /boot > /dev/null; then
echo "/boot is not a mounted partition. Is the path configured correctly?" >&2
exit 1
fi
'';
};
};
in
{

View File

@@ -0,0 +1,48 @@
From 7f75d320f6d8ac7ec5185b2145da87f698aec273 Mon Sep 17 00:00:00 2001
From: Michael Brown <mcb30@ipxe.org>
Date: Mon, 2 Sep 2024 12:24:57 +0100
Subject: [PATCH] [etherfabric] Fix use of uninitialised variable in
falcon_xaui_link_ok()
The link status check in falcon_xaui_link_ok() reads from the
FCN_XX_CORE_STAT_REG_MAC register only on production hardware (where
the FPGA version reads as zero), but modifies the value and writes
back to this register unconditionally. This triggers an uninitialised
variable warning on newer versions of gcc.
Fix by assuming that the register exists only on production hardware,
and so moving the "modify-write" portion of the "read-modify-write"
operation to also be covered by the same conditional check.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
---
src/drivers/net/etherfabric.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/src/drivers/net/etherfabric.c b/src/drivers/net/etherfabric.c
index b40596beae7..be30b71f79f 100644
--- a/src/drivers/net/etherfabric.c
+++ b/src/drivers/net/etherfabric.c
@@ -2225,13 +2225,16 @@ falcon_xaui_link_ok ( struct efab_nic *efab )
sync = ( sync == FCN_XX_SYNC_STAT_DECODE_SYNCED );
link_ok = align_done && sync;
- }
- /* Clear link status ready for next read */
- EFAB_SET_DWORD_FIELD ( reg, FCN_XX_COMMA_DET, FCN_XX_COMMA_DET_RESET );
- EFAB_SET_DWORD_FIELD ( reg, FCN_XX_CHARERR, FCN_XX_CHARERR_RESET);
- EFAB_SET_DWORD_FIELD ( reg, FCN_XX_DISPERR, FCN_XX_DISPERR_RESET);
- falcon_xmac_writel ( efab, &reg, FCN_XX_CORE_STAT_REG_MAC );
+ /* Clear link status ready for next read */
+ EFAB_SET_DWORD_FIELD ( reg, FCN_XX_COMMA_DET,
+ FCN_XX_COMMA_DET_RESET );
+ EFAB_SET_DWORD_FIELD ( reg, FCN_XX_CHARERR,
+ FCN_XX_CHARERR_RESET );
+ EFAB_SET_DWORD_FIELD ( reg, FCN_XX_DISPERR,
+ FCN_XX_DISPERR_RESET );
+ falcon_xmac_writel ( efab, &reg, FCN_XX_CORE_STAT_REG_MAC );
+ }
has_phyxs = ( efab->phy_op->mmds & ( 1 << MDIO_MMD_PHYXS ) );
if ( link_ok && has_phyxs ) {

View File

@@ -1,6 +1,6 @@
{ lib, pkgs, config, ... }:
let
inherit (lib) flatten optional mkIf mkDefault mkMerge;
inherit (lib) flatten optional mkIf mkDefault mkMerge versionAtLeast;
in
{
config = mkMerge [
@@ -12,14 +12,6 @@ in
useNetworkd = mkDefault true;
};
systemd = {
additionalUpstreamSystemUnits = [
# TODO: NixOS has its own version of this, but with `network` instead of `networkd`. Is this just a typo? It
# hasn't been updated in 2 years...
"systemd-networkd-wait-online@.service"
];
};
services.resolved = {
domains = [ config.networking.domain ];
# Explicitly unset fallback DNS (Nix module will not allow for a blank config)

View File

@@ -4,19 +4,6 @@ let
inherit (lib.my) mkOpt';
cfg = config.my.nvme;
nvme-cli = pkgs.nvme-cli.override {
libnvme = pkgs.libnvme.overrideAttrs (o: rec {
# TODO: Remove when 1.11.1 releases (see https://github.com/linux-nvme/libnvme/pull/914)
version = "1.11.1";
src = pkgs.fetchFromGitHub {
owner = "linux-nvme";
repo = "libnvme";
rev = "v${version}";
hash = "sha256-CEGr7PDOVRi210XvICH8iLYDKn8S9bGruBO4tycvsT8=";
};
patches = (if (o ? patches) then o.patches else [ ]) ++ [ ./libnvme-hostconf.patch ];
});
};
hostNQN = "nqn.2014-08.org.nvmexpress:uuid:${cfg.uuid}";
etc = prefix: {
@@ -36,7 +23,7 @@ in
config = mkIf (cfg.uuid != null) {
environment = {
systemPackages = [
nvme-cli
pkgs.nvme-cli
];
etc = etc "";
};
@@ -52,10 +39,6 @@ in
ip = "${iproute2}/bin/ip";
nvme = "${nvme-cli}/bin/nvme";
};
extraConfig = ''
DefaultTimeoutStartSec=20
DefaultDeviceTimeoutSec=20
'';
network = {
enable = true;
@@ -70,14 +53,25 @@ in
serviceConfig = {
Type = "oneshot";
ExecStart = "${nvme-cli}/bin/nvme connect -t rdma -a ${cfg.boot.address} -n ${cfg.boot.nqn}";
ExecStart = "${pkgs.nvme-cli}/bin/nvme connect -t rdma -a ${cfg.boot.address} -n ${cfg.boot.nqn} -q ${hostNQN}";
Restart = "on-failure";
RestartSec = 10;
};
wantedBy = [ "initrd-root-device.target" ];
};
};
# TODO: Remove when 25.11 releases
} // (if (lib.versionAtLeast lib.my.upstreamRelease "25.11") then {
settings.Manager = {
DefaultTimeoutStartSec = 20;
DefaultDeviceTimeoutSec = 20;
};
} else {
extraConfig = ''
DefaultTimeoutStartSec=20
DefaultDeviceTimeoutSec=20
'';
});
};
};
};

View File

@@ -1,7 +1,7 @@
{ lib, pkgs, config, ... }:
let
inherit (builtins) isList;
inherit (lib) mkMerge mkIf mkDefault mapAttrsToList concatMapStringsSep concatStringsSep;
inherit (lib) mkMerge mkIf mkDefault mapAttrsToList concatMapStringsSep concatStringsSep getExe;
inherit (lib.my) mkBoolOpt' mkOpt';
# Yoinked from nixos/modules/services/networking/pdns-recursor.nix
@@ -165,7 +165,7 @@ let
extraSettingsOpt = with lib.types; mkOpt' (nullOr str) null "Path to extra settings (e.g. for secrets).";
baseAuthSettings = pkgs.writeText "pdns.conf" (settingsToLines cfg.auth.settings);
baseRecursorSettings = pkgs.writeText "pdns-recursor.conf" (settingsToLines config.services.pdns-recursor.settings);
baseRecursorSettings = (pkgs.formats.yaml { }).generate "pdns-recursor.yaml" config.services.pdns-recursor.yaml-settings;
generateSettings = type: base: dst: if (cfg."${type}".extraSettingsFile != null) then ''
oldUmask="$(umask)"
umask 006
@@ -174,6 +174,14 @@ let
'' else ''
cp "${base}" "${dst}"
'';
generateYamlSettings = type: base: dst: if (cfg."${type}".extraSettingsFile != null) then ''
oldUmask="$(umask)"
umask 006
${getExe pkgs.yaml-merge} "${base}" "${cfg."${type}".extraSettingsFile}" > "${dst}"
umask "$oldUmask"
'' else ''
cp "${base}" "${dst}"
'';
namedConf = pkgs.writeText "pdns-named.conf" ''
options {
@@ -315,9 +323,9 @@ in
(mkIf cfg.recursor.enable {
systemd.services.pdns-recursor = {
preStart = ''
${generateSettings "recursor" baseRecursorSettings "/run/pdns-recursor/recursor.conf"}
${generateYamlSettings "recursor" baseRecursorSettings "/run/pdns-recursor/recursor.yml"}
'';
serviceConfig.ExecStart = [ "" "${pkgs.pdns-recursor}/bin/pdns_recursor --config-dir=/run/pdns-recursor" ];
serviceConfig.ExecStart = [ "" "${pkgs.pdns-recursor}/bin/pdns_recursor --config-dir=/run/pdns-recursor --daemon=no --write-pid=no --disable-syslog --log-timestamp=no" ];
};
services.pdns-recursor = {

View File

@@ -551,6 +551,42 @@ in
];
});
})
(mkIf (config.services ? "bluesky-pds" && config.services.bluesky-pds.enable) {
my.tmproot.persistence.config.directories = [
{
directory = "/var/lib/pds";
mode = "0750";
user = "pds";
group = "pds";
}
];
})
(mkIf config.services.home-assistant.enable {
my.tmproot.persistence.config.directories = [
{
directory = config.services.home-assistant.configDir;
mode = "0750";
user = "hass";
group = "hass";
}
];
})
(mkIf config.services.frigate.enable {
my.tmproot.persistence.config.directories = [
{
directory = "/var/lib/frigate";
mode = "0755";
user = "frigate";
group = "frigate";
}
{
directory = "/var/cache/frigate";
mode = "0755";
user = "frigate";
group = "frigate";
}
];
})
]))
]);

View File

@@ -1,4 +1,4 @@
{ lib, stdenv, autoreconfHook, pkg-config, SDL, SDL_mixer, SDL_net
{ lib, stdenv, autoreconfHook, pkg-config, SDL1, SDL_mixer, SDL_net
, fetchFromGitHub, fetchpatch, python3 }:
stdenv.mkDerivation rec {
@@ -35,7 +35,7 @@ stdenv.mkDerivation rec {
# for documentation
python3
];
buildInputs = [ (SDL.override { cacaSupport = true; }) SDL_mixer SDL_net ];
buildInputs = [ (SDL1.override { cacaSupport = true; }) SDL_mixer SDL_net ];
enableParallelBuilding = true;
meta = {

View File

@@ -11,5 +11,4 @@ in
chocolate-doom2xx = callPackage ./chocolate-doom2xx { };
windowtolayer = callPackage ./windowtolayer.nix { };
swaylock-plugin = callPackage ./swaylock-plugin.nix { };
terminaltexteffects = callPackage ./terminaltexteffects.nix { };
}

View File

@@ -1,19 +0,0 @@
{ lib
, python3Packages
, fetchPypi
}:
python3Packages.buildPythonApplication rec {
pname = "terminaltexteffects";
version = "0.10.1";
pyproject = true;
src = fetchPypi {
inherit pname version;
hash = "sha256-NyWPfdgLeXAxKPJOzB7j4aT+zjrURN59CGcv0Vt99y0=";
};
build-system = with python3Packages; [
poetry-core
];
}

View File

@@ -1,18 +1,25 @@
{ lib
, fetchFromGitLab
, rustPlatform
, python3
, rustfmt
}:
rustPlatform.buildRustPackage rec {
pname = "windowtolayer";
version = "a5b89c3c";
version = "97ebd079";
nativeBuildInputs = [
python3
rustfmt
];
src = fetchFromGitLab {
domain = "gitlab.freedesktop.org";
owner = "mstoeckl";
repo = pname;
rev = "a5b89c3c047297fd574932860a6c89e9ea02ba5d";
hash = "sha256-rssL2XkbTqUvJqfUFhzULeE4/VBzjeBC5iZWSJ8MJ+M=";
rev = "97ebd0790b13bf00afb0c53a768397882fd2e831";
hash = "sha256-XjbhZEoE5NPBofyJe7OSsE7MWgzjyRjBqiEzaQEuRrU=";
};
cargoHash = "sha256-XHmLsx9qdjlBz4xJFFiO24bR9CMw1o5368K+YMpMIBA=";
cargoHash = "sha256-M0BVSUEFGvjgX+vSpwzvaEGs0i80XOTCzvbV4SzYpLc=";
}

View File

@@ -0,0 +1,13 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IHNqUFR5ZyBVVkI0
dE5YN1pJWExzLzltcmhna2tJUmdRNjZ1Y1hwbzdtRE0wa2hReTNBCk4ydmNFK0FF
b0RUdVl3a3d4amhKSEVhZWZPeHZDenBiTXpkVVFiNXFXNGsKLT4gWDI1NTE5IG9i
K0ZrNEc5SVlyWU1EbXdlbWppRG1DdjFRbTBCREY2OUxrMmVqNHhSazQKVnRaVmVn
MFBRL1dWeFNOaEwyU2szb1lOVzF1enQwdmVZZWRJcHd5MHdFbwotPiB2Wy1gUV8/
LWdyZWFzZSBdSDFebHsgKkBkVzl+KnggJTEKdlhrdzVpMHYxUUliQnhaYXNaVWNR
S3NxbjhFMEFGamZkRU1RNURhcmwzOGxFbGxXelhOdDBWTHBSY1hBcGFtUwpkampi
WnhzMDcxTk1seWZ6VURZb1l1QU1GdwotLS0gRFNpcXpDUFZLTXFJN3Z0bEJQd280
WGROWUVvdSt3ZUdBbmRNcGFhRE9BWQoDDlPEY/t2eapa4Xbv8FcW6gdLzQn7Y2cH
5UwD+0CTF3JdUpxWUIx9RWFleHekkt8j1+2/oO+m7+24yCg5mdqTJ3ZIwu9uk1eI
0As8IA==
-----END AGE ENCRYPTED FILE-----

View File

@@ -1,12 +0,0 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IG44Q3BVdyA4bGQr
dzJZbU4reWI1Sk45QTR3UkRoc0NvaDBFcUwrVWlCYWUrcWtYZGpNCm1PWjVzRVlt
UDFKY2ZSZTg4S2pVZ0pDNzR1WklYQ3pEclJZLy9kKzdGTGsKLT4gWDI1NTE5IHFO
TXVRK2d3azg2cHpRanhUNXp6YnRsZW1MUDJqc3l1bnNYNUhHaTIzMVkKWXp1M09H
TnJIazRmb0tOSnE1Q0E1dERiaHZCQkh2YzE1cS9zRUhwaEovMAotPiBzPj5nLWdy
ZWFzZQozSThRWnJCcVFFRHpoSi9tZnZMdnJoRlFud2VISHBHSThMem9qZVVWdS9C
VFBDVEVzbUVCdFU2Qy9PaGdyc0FaCmk3UFZma2ZiR3hmWG1sa053bDBnY04yZ1VZ
TW9jZwotLS0gMDVSaE5aakxHenFPVXpXa1JxczlWQ2x2VGNuQzdwaWZFTTFTaUp6
cnRmZwoomylfwjD5A3N21/mk1Wtt8f4bsK747iZz7KT34kqmoX597rbGYxyip5lg
VLZV6CY4LLRjnnSKoC2hIXU0dgudAmvxhztuaQ42fOc=
-----END AGE ENCRYPTED FILE-----

View File

@@ -0,0 +1,12 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IG44Q3BVdyB0RnVq
RUpSZy9qZ29DemdnWjdscHMvelRYUGF0YVZlNDFtdzFRdVljbGpZCjdWcE50ck44
NVBsbVk3SmR6cHhHdkJ0TWI2S2ppOUtnK3pMK28xeTc0KzgKLT4gWDI1NTE5IHIy
SEUxOCtjK3VFMEozblB1T00yRTE3c3dRSXIydmJHdmEvL25yMStOUVEKbE1XdU4z
L1lLcEJWY2w2WXRWbmVIN0ZBRVl1R1dhNk10MWtheTRCYjloZwotPiBXXXRKcS1n
cmVhc2UgRUBEWyBwamZsOVQKZ09pVGdWUG02WmxUcGNBN3RnbE42V05xRDE2azMr
WHd3VEt0NmwvZnI1dXdiSjNvaStsNTZmUEhwbUp5cVlieQpSYmhUVm1GbEJVdXo3
ZwotLS0gSkFZMFdiRHBjWFJsR3pqcytYZkEza3dsZ0ZyaDkxdmliZ3RUOFErUXlt
cwq9gj+Fg4p2D1548J+bhvJ0re9uVm9TZ9lJSqmj5tMxWRS9aN1j9BlhmK/RnEG9
KcodvBiyqibzauS4KC18xLLu986hK2gn3857waXn/AIp+p8BIA2J9M2M
-----END AGE ENCRYPTED FILE-----

View File

@@ -0,0 +1,16 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFQrc2JHQSBmTlVp
RnlKNE9ySGo4L2h3VXBXRzIyZGdqU0RtUWk4ZmJVcGNKZ3BqTmpjCjJtQjUyTmJN
dkpsbVI3M01mQlNPSEI0U1lVeUJTMVlXUlpheGxVblhUbUkKLT4gWDI1NTE5IG5K
K0F3QWxJaW5CbW5TZElEVklIeUJxS0JCc2IxaFI5dVZrbDc3NDZGV2MKOVR6M0k5
eW5HWDQrT3Rtb0tIM1EyajI1V0dKbHBLb0tVNU9nb21OUjcxYwotPiA5anw6bk56
dC1ncmVhc2UgPCVeLiZyIH4KTGFRWHBGZFBJUElONUZLb3pJeXNZeXhoakYwT3BM
TW9kUXBhOGhNbHh1Q1RPRTlCRnhSckg5NEUxWk5MVHJucQp4YlFDcVRzK2V5bWVT
V0xLQjN1SjVTaWNJajJaTjRrQTd2VHlMRy82TExXbAotLS0gVE5YZVhTWXl4VUN2
WUpidkJLV1JDU0R2QkdHZE5ZbCt2K2FlbGNjK0ZlNApzDh+kgAy4SBqC51mJi+VX
ON8wbwLVTQRs1H30eyWNzt/3MO++eS4AoZUKQZUxURwXfhV0t0zd5/MlByBsqaHR
+W6O/9Dp8e/8GYSX3D892r1LKN0AYHgcKeKwEtJojt5CTNJS2IgU6UxZhTliqAEc
NkfxvcoAEHhGhPOudEIX2SgjrgVGJA8MYm6/46zAolZws3TWim3NEgJpb9tWXpvi
1f/MXuxiowplF+PqCsd1EGzpXKsvADq6Rwyxpo6CbJzrq+GhFrTHF+LRkzjWx6JE
LUsZwDqOZUY=
-----END AGE ENCRYPTED FILE-----

View File

@@ -1,14 +0,0 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpOcUlvZyBlODZr
RHpJcFdFaVNYM0x1d3QxVmhKTFBkMndrakFYS3FxWk00YWxXejNzCkFqWFlCWUt2
cGluRGtxODQzbElhRWt1TGFVeTE1UU5SSkdZejJzNVdhZ3cKLT4gc3NoLWVkMjU1
MTkgcytxUmZnIFRpeVNsT2Jqc2I4dzB3cEFWK2ZEZlpJQklWSnhJM3o0Ukhsc1lz
REZ0VFkKWWJPckVSNlZHREJIVVgwNVNBSkpSbHRPcUxIWVo4ZTlyVkovTGRpZThL
MAotPiBYMjU1MTkgUGxhR2d3TVh1dnJwQjNoY0pjV09halZKZFhybVk3Vjk3Tmwr
bDd5ckp6MApBcW8zbUl1SnhmOXZwOFRNUG1EZUNacDlXdXJSbWFUeG5GNjM3eXJo
RmR3Ci0+IDstZ3JlYXNlICRoICVbfmU2fQpFYzNyZXBxVU5jT3JSY1NFMGEzUnVF
WFQ2MmR2SGQ0Vnd6V0VxQlp5bE5LZ2NML2hyd09LOEVPL2lGREdLR3FMCmVGN09J
OUNscVh1d0VSdwotLS0gbTB1NnZ4Q3B6WE1KVzJjbmVwL2dEVjc4WnRXZTlYbFBG
T3htUHBWang2awr0OgkUO6XPZji5ZBNpqGwOlwpa605t38QCmFSXvPQhvT4Gj/0+
rUvg7zWf5Yb4c86EDD05CsqGEUQTOKEz08z0lewN5kuFfZmrYQY=
-----END AGE ENCRYPTED FILE-----

View File

@@ -0,0 +1,14 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpOcUlvZyBJSU1V
M1QyaWcvcFJlUlJEcDVvblJGcXJDWk11RDhCZzBkY2Qyc2lDQW5jCjJVRVBWMTZy
SHNTZG9ZSnZ3RjRqUE9Ub3JKZERkcTZpeEhSUlppTmVsZm8KLT4gc3NoLWVkMjU1
MTkgcytxUmZnIFFsbm1oNk1jNndoU0J3SkdFSkNhSGNVRjdQb2JSUFBnczVwdlF0
bDVhaVUKaFBzSHF3THNiL09Ib2ZhOFlyNVY0Q1ZwOUMwczZiQW9jVlNwanRYek1P
WQotPiBYMjU1MTkgcEppMVBpbmRGS1h5RUgwNkZPZ0dXWVpkdXlZcFc5S3dQaDA4
THdhUm9oTQpLbUpTaVVuQ29Zc3FuQ2MyaFcvTkxVK1l1T3V0L3FZSXZBS2dlY2hM
VUNVCi0+IENcLWdyZWFzZSAnNGJjfiB1IHB3QDpUIHsoQi57Ilw9CnkxdFRqWVZi
ZFdHQXJwNGZuNDg2Q3cKLS0tIDJSNmthczc1U2xxSlVKZDBLc1BHNnFMV3MwK3Qr
ckJDL204d210NW1Pb2sKCC+sa8uPupC3Rv+o12XT/wTmLsKhtaE/bbshPCDIHUFn
cpTwpY96JsCShAjSb6n7Xt6FgTKTFt2iDsGQ6+sLp0AJ2quxRaoxmqaFVsz4p8BL
gF0On7LgZg==
-----END AGE ENCRYPTED FILE-----

View File

@@ -1,14 +1,18 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyByYlJn
aERLcEhadS9jVUlyUmgxWEk5K0U2cE9WUlhCc0ZXbzhDRnZLTERvCmo2Vy9XeFhq
NTcwdG5PZjlDb1JIM3BYWEVzMlBFWHFmRWt2dkF2OEQ2TDQKLT4gc3NoLWVkMjU1
MTkgT0VxTXNnIHROaUlGUExERTZFaU5QL3dBcFpQVWNobGQwSEZ1YTU3NXJkekRi
c0RUMGsKUHg4V0hIdFJ0aGxwOTFhaVB6MUdVWE0wUFgrMjI2am5uZlhWL09ObjhB
VQotPiBYMjU1MTkgTWwyQjZjcUFYQ01KUHpoajRrVkpZd0czSzVrMTZxdjVHaHRh
bERCSjBqSQpYOXJibDZPM2Z6bkNCSGpMRExZT21UTzU0N0RiT2FNM0l3N1pnRkl6
WUJBCi0+IE0qLWdyZWFzZSB6TDVwIGRiQm0gajFFIEVqUXcKU3pEOFBqRVQ0dDZi
REszS1h0T2FnOFF6cHBrN2xtOHdEQkIrCi0tLSBTM3EwNHhDaEo1eldDOTN5dzQz
Q3Rpeno1K25KRU15L01wU21tczNmdlVJCqHBdFLovtLJGH9IY86pvc3xhpoLnfI/
OVAF5RdpR9T2oNCr3oAiVURkPocYXLHnbjZhLKoj3uDoSZAE52VN9l05jhyX1wwY
/Vfnp48kP8xfbQ==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IHNqUFR5ZyArUnBS
MCtjZERmK2IwTm16eGcrZFF5QlpYZU9VbUNzbHZ2VDBoZkJkam0wCndDdmhHc2pu
TFFiT3MzcU13YklrdFpiRW1ZSU4zUGFQbXF3ellUU3U3bUkKLT4gc3NoLWVkMjU1
MTkgRExNZUZnIE9EbUtYRFg0Z0xuVGNRM2pad3FFVGRDVTA3ZE50SHlvT1ZrU1NW
b3VYREkKL0dPV3RGMHYyUW9jSlJhTU5yTnR3L0pHVjZTNWpoaGJiSmlPVWlDYlFv
RQotPiBzc2gtZWQyNTUxOSBPRXFNc2cgRkwrZEY4RjAxYzhpbEE2eU0ya2N4emE5
T0NlUnJwUi8vdVlJWlVOWEZESQo0OFdldUdML0hoR0NENHp2UktCTFhOYkxUZyti
OGlhS3V1RnFUdHhVT0JvCi0+IFgyNTUxOSBOcnEzanBFWnltMUwwd3VBd3Jablk1
Z3hDU283RVJxSlkzKy9JQW1adVVVCmtnSjVTTSsxblpsczMzR2NldlFlTFk0S210
T1AxV1RQRjhDSU1CQ2p6M1UKLT4gVnNOLWdyZWFzZSB1fDAgYy1xRSBESjoyIDJz
CkdRcWxTa1NHVkJDcUVmeDlIVEZTcW13N0I4ek5jTjliQ2t6Zk9nRkloQmhSY3hG
TUdJekhXdlRzUGJ6WU8zRXgKZXFGUGgrTndSQmVyMFcyL2J0bEdKY09paTkzRHd0
R1ZWVVVuaDljWE4zK00rdllOdGRVTzVZTnFtT1p0WlZOYgpGdwotLS0gd3dvU08x
SzJkdjAvQys5Mnp0dDZQUWp1dzZ3U2tuYUpqR09xeTJnSzVDTQooXx8cndfMYlmf
7eCLssPnHKj7KKgUfiihj91X8pokJR/++wQSarMdRtFB0S0MpDs/khwgG0HkmrKp
XB1jureGwJs7gmJ6gafKCKSkBv9Jkaw=
-----END AGE ENCRYPTED FILE-----

18
secrets/toot/pds.env.age Normal file
View File

@@ -0,0 +1,18 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IDYySmNjQSBONnFw
QVduaWJac2hVVDl0bHY5dXFQSkFUNGlWaTNUbGkxN3d1RWpSZGdRCmpBZ2pLZHZ0
V21EenE0U3lYblp3dTFyRlRrMGVjWGpxdVVRWW5pcnpCVlUKLT4gWDI1NTE5IEx0
QUM0aEVsbCtLd3ZmS0kyb0Q3d2RuVW1oc2pHSFpMbUZHY2VXYlhYR28KSHhraW9K
RXArS1lia0NsMWkvRFhTVEduM1M0c2JnYmduY0ZmSjhCN1M1YwotPiAlL1lJLWdy
ZWFzZSAhVCpkTAplMU5KckU1K2diWnBreG9LbERtbGJZQjZwK0lOZjJHcEJyMWZp
c1lxL1UvbTE5QzRIMm9wSXFmY2xUSzhBMEJiCmgxUQotLS0gOUhYVERseXJlVksr
SEZtby92YUIrTG4ra0hneklheFBERHhqSlFlT0YwVQr5gAYwgdPqUqW2XEtN7+ZR
VblX1NFXjMLljiGcW+ZlMXHIaKMxizPr+S/6U183e4wiUUqcpipnznnslhm/Zkny
iHmW37pnNC0T9kctqOXeEjqsQxAMo2YKFroxo1iK0YvN+VyoIDSYMDKu8uDe1Cna
rabi42KfdZNDjtPLrJyHSo2cCdnDUeWalAjQ3eQqn4y85gfPZq8kZcwvK6SmurDN
GkwxXpZpSd6MdY4fIaaBEwe7WY9hq4fE7WgcQaz5yG47F+ArCwWauAz38+309XHj
omsDSzj1jrN7T4kr2gjtUX227NrCw3REHYRNN6IQK/6fDNyPF1wbLFpXU4dnANLT
OdMRnsDRPafNLAOYn0pgCVcVs0KLpaJvy3KLevVt2MZEtSZe/S+ys28H3JJCB8qz
igaX3gw9+W8by4ET864fpFgufJrpufVvdz/MZ1207YHz1URQACWRtFKwnwfzP45+
l47Y4s+xy34V+IXLJduEQdQ0ZHqKmTv02BjEjqksBwZswjI0EbTvD3Nsiw==
-----END AGE ENCRYPTED FILE-----

View File

@@ -1,72 +1,74 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyBVUDR4
Um1XS00yUDFIRnYyZzg2KzYzanBIMWFNTmV1MVF6ei8rZDBiTXowCnBBRFEyQU14
ZU5MdSt0NnRJdUMyMyt6dVlOWHBqUnkvRWNmMjNRUENKeTgKLT4gc3NoLWVkMjU1
MTkgM2JCM1pnIHFyc2laWnBTQU0rcThOamJTcEtlUGNsSW8reTc2eTJjbVBkZlJu
cXEzbUUKcmFrTEVjaXY2a0lJNEtCWXNjTUsxNENkSWZmZUJhRm5ydWZ6WlJ1aDdR
RQotPiBzc2gtZWQyNTUxOSBxKzBYY3cgRVBuOEJ4K0NRVjdLdFhIU2Y3ZGQwL3F4
clFjMVNsOWNvTU8wVlRoNG5CZwpycFRlMzFjZ0drN0t5QXpoMkJ4aERMYkxVSFhU
STJTdUNzeWtkUmFMTHVBCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBBRUhnNlNzbDVX
Q1ArRENrZzBrNkhhSUd5dEZnM2oxRUtmYWx2L1NtbG53ClZIalNsaUNBUUtKWGpT
dTM3VExldm0xRXJoSWZ0SU4vdWk5SDlZTEFPczQKLT4gc3NoLWVkMjU1MTkgajY3
RlhRIGR0VkhtNWxCK2xSYUNlS2hhdzRldEVZRDQwNmVnN0dtRTdOamFSM1Jqek0K
YS9uWGMyY3JzeUZCWkhLTzk4d1dxT0NkbEQ3UnlWOStCdUh0bkg3K2N3TQotPiBz
c2gtZWQyNTUxOSBjMFROYVEgYXJhZUdOeEphOGxkMTZmamJxdmMrTElkYkFScVA3
alExSC9TVTJzeUFqNApsZXo1cC9wdnp3Zml4bG52ekFHMEUyU29acFFJeU1VN3Mr
ZlorWC9VWDZzCi0+IHNzaC1lZDI1NTE5IG44Q3BVdyBTenhVdjNncGxudDJ2Y3lw
K0JIOFJDd2VVQzFkWGc1STROdFZqbnUrYlJnCk5MTWxRYVRPcUFjMmdySEJ5Rndy
TzdnNGErNnBRa1dTSFVFekxQUitOYTAKLT4gc3NoLWVkMjU1MTkgakk4UkFnIGtL
c1psRWRRN1hNZUNiVHFmR3JGVm1jUWJtdm91ZVR6M01zNmhGdW9pRTAKNGpwek8w
QkRnSkZXUjhEMEpPaUdkeGwxZDRGbTRSMjg1Z1pMdEVSaTJEdwotPiBzc2gtZWQy
NTUxOSBoTWE0bncgYmRqR1FRaDdQQ09ZZHQwWmQxVUJ2QWdLYjdoRlNLU09GYUNi
ajJhMWx5QQo3ZWFNWjMvTzNxSXJjeTY5cTNMWmk0K0IzZ053Mmd6T1hhaVFTVVBj
NHBrCi0+IHNzaC1lZDI1NTE5IGV5cTNkZyBXbUdJKzdMZDF1NW1pTi94aUtjNGpo
aGVLbno0RzE1MXlURTJJQ3hRb1dVClg5K2FwRHBvcXIwVUl1U21GSnJsSmJmMGZN
cmdBcmRiRERzcjJmZzV4Q2sKLT4gc3NoLWVkMjU1MTkgN1dROVBBIEIrays1YUJN
TkRMS01oVzQyZEJuSjFPTTV4YkZSMDdTV0UvZE4rZ1U3SFEKWEZSL0g0dmFnelJC
S3VGZDlaTHhJQ3NaaEc2aUsvRmdKdjRNZ1VXMExmQQotPiBzc2gtZWQyNTUxOSBn
U3hQMFEgODNUUEg4M0hLL3RSUXk4M3dGV0tZNjJXQWxabmxLanF0Slc0WWMyUkNo
bwpCMGlaZDdodk4zeDROczVFc0FxM25qMFdicWZZSVpjb2tiT081bUVUTGFzCi0+
IHNzaC1lZDI1NTE5IFZGY3c1ZyBKanVnSDI0bUhvS3RVbzdSc0s2TmQzSVdEczRF
eU1CazZPM094eEt1ZGp3Cm1HWGluLzhoRUtNRDZOcVJDVUR1R3dneHNHa1M1VGpH
YWF3TDQ5cS9saFUKLT4gc3NoLWVkMjU1MTkgaGtidHZnIHJLN2dJQnA4eGo5SnU3
SkttSlM2YXNERXJOYjc1Tlo4NnhFakdYT0dqUWMKQllrZm83NHJrYmtWaytCc1VI
aVhESUtYeHpoT0JmdStSRURMZ0JldlQwYwotPiBzc2gtZWQyNTUxOSBldDJ6cFEg
d3NnSXpMRzU0QjBBL0c4SGw5Znl6d3hRdWxvbHdXZCtIeVdnU1F6MFVVQQpiQjVX
TSsycGZqMVNWajZHcFkyN2JwY2RqcGRlNitRWXgxWnN5TzlpU1lRCi0+IHNzaC1l
ZDI1NTE5IFpiTEpXQSB3VmFwR2ZqR2p4OXlpSnQrbExqTktkaEJ4emxLM2ZZbGdx
U0drOWtxUGprClgyYnd1M1NQem1rZkxwUk5tVXBLNGVDMFVjNjc5Lys4N0RsajZN
eG9LeEEKLT4gc3NoLWVkMjU1MTkgWk5xSW9nIFl3QUlPNnVHNXNwQ2sxRUEycFda
TkJsUmx0dCtRdnRVRVAzY3pPbm1LM0EKbVZDMHBSOFBiMFVQbkxHOGpkQjhrbDRJ
YUN0M2JPOW1PbjVtQURaUnVFbwotPiBzc2gtZWQyNTUxOSBxTGpxeVEgUXc5TUxn
YXk2ai9EbHdVeFVsUk96bHZIRFdlcDFqYkxLQ3FJaFBQVG93bwpTSFJ5dmJiN2tt
TVlLUlBhb3VmSG8zVHNYdC9HVjcwN3JUVVVWN3BFUkhvCi0+IHNzaC1lZDI1NTE5
IEJhUWxSZyAxYkNsekljV0s1ZWR2eVZnSk9Oc2QvWjE2a2dMaldDYzJRU0FWUVE0
Z0FvCnk5UlhrT0ZaK3FXTThVY0RKZlE0d0FTajJLRCtSNWdvWjd5V3hZNEg4dUkK
LT4gc3NoLWVkMjU1MTkgcytxUmZnIHA5cGpXWlMvTlVreDNremhCa1FDUlFVYk45
OHhjaUhYTWZVa3dySzNLeW8KNXZnZzFPNC8zMExuMG4yUTJFMDgxTFdGdDZ6VVl1
WEFGUC9zNVgrd2RRdwotPiBzc2gtZWQyNTUxOSA2MkpjY0EgMG51elJWRWRDNzRM
SERza2RiNFBoOHc1eCt0SWtmUy90dGl0VEd6QTJENApodnNBM1FkUlZ2ZjB6b1Np
QWNXdjVoNFlsa0NOQWp6TUw2TVQrU3VNRlVZCi0+IHNzaC1lZDI1NTE5IC9oeC9k
QSBxdlhXM3Rqb3J4YjVDUzdhUUVYQlFvSTJjZXA5MHBYY0NXWVR0VzllR2hzCkU2
K2xCY2tGeEJjK1dMYkhCZ29pR3EzYndWUXF4bWorNC83d1E3U3luMFUKLT4gc3No
LWVkMjU1MTkgV3pMR0hBIGg1MjIydFM3YlM3aWVFR0h4TytwRWxYWTVkTXN4VkdW
TnJ0bXQ0WTduQUEKemtad2lsTTlPUEtUaVpFLzNPVFhqd3VpeWJWbDFyayt2VVhy
Q0FSb01rRQotPiBzc2gtZWQyNTUxOSBISi9KN0EgTkdKZUx2U1NTODZzTlpJb2xT
VFptQ3hWOS9BMCsyZXdsM3ErMXhtaHlFQQoyUnp3RW81VUh6OVRQcGhJOXYxNXRR
NHNGT3ZIU2ZQb2c5aEg0UmhRcG13Ci0+IHNzaC1lZDI1NTE5IE9FcU1zZyBLMi9r
bmFyTnBCU1lsdUpDWTJsd3ltRzAxZmw5eDNqVUtjMkR0OGF1dVRjCndrNmVHcmYy
c0lQOFM5SjBjN1ZqZXk1Vkk3RzA0b3JtaWZrdDBmdmFrYXcKLT4gc3NoLWVkMjU1
MTkgL0VKWHZnIEV6eVNrNEZvVWhPMXppeFpmSEt1Y2NqcmtUOXAxQ1lOWVdtcnlm
R3B3VFEKVXJJRWlmOFVHZ3hyWWhLZE03VlNlM0M4ejFDYjM1b1c0YWhMMVcrRXlH
bwotPiBYMjU1MTkgUkRPY2JrSGZYeGNVWldVbTAzbkdtbHdUS1hoZXg2R2JEOGtC
ckZSOWV3TQpGejNQOUlxb05oWE9hRWdjbzI2a0NKVkpHMG1PMWlMWVZpYkVQNlpx
c2xRCi0+ICwlLDsrbWYtZ3JlYXNlIE8mcz1jaywgeiJbOE9FeyAjXFl4Ugo1c2VM
THdsOFlhODVMV3JsYzY3QU5Hb1BJTHBWNFEvalRHN3lXQlBBZFVvQXRIdXpXYVpU
b0NLRG40WWhMQ2hDCnZyS1d6SGxGekIzWUs2Uk5XSFRscTIrTTEwNzJKMExGcG5m
UWR0MWtBNnk4bDBYYStVQzFwZDlWRzRDNXJVZm0KajVrCi0tLSBkQ044Z3A5R0dt
S0htaUZaSzdPOTNCcXZrSWFVVHlTZk0zejBuT21yQzFBCo6rc9fznstf3eXBRUA8
73MZAYqSnJ5wVMrYrwGfT9lXvKbHCOvkgjUI6Ieo0nuw+aZpXoV3t9HfZv62UEll
ZZVu+ieRCZqOOqZKKZ3TCP24vdXun8Tu+3YK8fyn88QSRH/0ZMnqI9FXbtsUhsF8
2o7m7Fn48B0nVKy16HZyBsksknAuZCkfS/JOkgI=
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IHNqUFR5ZyBlbHl0
S0lQbXBKVGpNNnJOUS9TSlp0U0EvYWFVanN3N0RMb1JudEdwYVQ4CnJGdklzeEFy
RmxjamNyUWszYjFGb0ZZbk9EQVdERERtckpqczVscjdmUE0KLT4gc3NoLWVkMjU1
MTkgRExNZUZnIGR4czhRYjUyU29JbnFnRk5IeXliNzZzMVMya1ZuS2tkUlFVTkxU
aFd0VWsKenprWWQ0UEdaUGhvRlJUbnU1T2h1czZBK1dpOGwwcjJxc2p6ejV1RnM0
RQotPiBzc2gtZWQyNTUxOSAzYkIzWmcgMHB6dzVFQ3FtaWErVWNyRXo3WnNhT2NF
eldUVWtOaVlWOTVwcVVaOUlGMApJUDUzNmhKbUxleTV6SjV0Zmk3dno0STVIRDIv
SUkyd1M2Z21mdUtMUXIwCi0+IHNzaC1lZDI1NTE5IHErMFhjdyBnRFBPRnNSa0Nn
UTlpR1Y4OU1UQmNLRnRWaGxzU3RBV0c1bG90K2I5QUQ0CjArUFlGS1B2RkVKSEtP
ajRpUUNlMkRPN3pxaEkrZ1M3RndxRDZ6U09Wc2cKLT4gc3NoLWVkMjU1MTkgWkIz
ZTZRIFRPdXRTeEVvUTM1dlQzMll2VDFkUlY2eEFRcnRrc1lNeDZDbFE1a3BjaDgK
MytBM0Y2Mmo2M1JOWExLQy8xTm9SR05WcmxrV2xBZ0RpeXQxeGVkZ1VZcwotPiBz
c2gtZWQyNTUxOSBqNjdGWFEgYUw5cnJabnhhdU9lN0NPVXVUazRnVWpzcUVtM3VR
bWQxNVVSQTN5N3hXRQp0blhXUC94TlRPbS9Ba2N1eVM0QkNNblJBa1hJYjZ1Y1lM
UDhWbUd5bWNVCi0+IHNzaC1lZDI1NTE5IGMwVE5hUSA0TXowVjA0N2FvcER6OEts
VTVwa0UzUEtsY005WDhmaU8zZ3VLaXQvaVRJCjB4cjJiMHVGM3hyWlg0OHhaT0lu
K2NJQWVndzYrSDAyK25NMklSVUI4S28KLT4gc3NoLWVkMjU1MTkgbjhDcFV3IFNE
Q1NZbnpqUkdiaktnYkxZdzZrYUVqWDEvYnMvOTJqSUpybERTNk9uQ0kKYlMzZkVu
SXVtaWk2WEtDMEpwZFM3ZVIyWHQwUWNOZjVRS0I0ZjN5MklHYwotPiBzc2gtZWQy
NTUxOSBqSThSQWcgWTZIMCtNMCtzTFpROHpBMnA3b2s2UFE2dDZGbnlxU2VxMlkz
aGJFUzV6awpKNDhobHQrTCs4cUVpNE5wblJMako3bU5tVldjVDBjVlJOOHhkUTNk
NFdrCi0+IHNzaC1lZDI1NTE5IFQrc2JHQSBTbVlBTXIzQ09SOHRJakZXK3NkT1Uy
RFgrUTZncSsyK3p5WlVDSFNwM2lFClErRHk4Qmp2VlIvZW8rV2lNME53ZFlIUmVC
bXF5RlVvV2FUM3ZmeWpaQzgKLT4gc3NoLWVkMjU1MTkgaE1hNG53IDBINGhyMDBy
bkp0RWpTU0F6Uk1kaXllRHBHbXF2QWUwNkN1U0tEWE53VGsKdi9QRlhwRCtyQkRq
cng1Wk1rZkx2NnJTMUxGajN3b2Z3SG0zd0ptcklCZwotPiBzc2gtZWQyNTUxOSBl
eXEzZGcgcnQ4WUFMcGRtL1BvYTkxWU12WTdkT1lLRmJlZXZ4cWtHNG54QVo0dDYw
RQp2NkMwbTROZTBuRUVLNEs3L3BmOTZ2S3dDL0hUbm5OaHZXbjVCRG15bExnCi0+
IHNzaC1lZDI1NTE5IDdXUTlQQSBPL0t1ZWptTm5YQXIwc3ZNUGhkaVM5QU1DMkNL
NU1WSFlTT05KOWR3dGhJCmdTTEIrNEZma3E0UzArMndqVEgzWnVLNzl0TjhsbG9P
OE9aRVk1Ung1cEkKLT4gc3NoLWVkMjU1MTkgZ1N4UDBRIGJNazFtRThSVVVvb3dP
RHV5WGxCbktDK3c5aEhiYkphNU4zUnVNUVNNV2sKbWZJYkNSZFMvTDI1WVg5SnJV
bUFSY2JsNDJBc253dlN5Y2Nqdm9TbU9IawotPiBzc2gtZWQyNTUxOSBWRmN3NWcg
eEo0dmRNWVpuVGdxRHpXc09tUDZldFRKcTBIMVVWcXdmVFRhZnZmenBETQpJWHVp
NWJNRWhacHlMbHlQcjEzdEZWdUVpbGg0N2pqMjcvTk92UDJpNUlvCi0+IHNzaC1l
ZDI1NTE5IGhrYnR2ZyB0SFJGRE03T3lnTUJZakVCcnQxVklPNXhzak94eU5KUzNX
L216SCtUWEVzCmRrS2Rlc1JiNEg1KzExaUsrNHJuSDlTcU5Oa0J4QVZKVmNBRGFP
ZWlqUjAKLT4gc3NoLWVkMjU1MTkgZXQyenBRIEFhMFVxZ3RRbk4za2t5cWtwVjVi
Qm9ucVdMekVsSHEwSWlML0JIdmQ2SFkKWW5mWnQvRWlaT3hJLzJyTE5RdTNUMWNM
SDB4TjVKZCtDN0tCR1NhdnRqbwotPiBzc2gtZWQyNTUxOSBaYkxKV0EgV1loMWZx
OHhKelNvNzErMDc4cUE5amgycTFTem5lVmlGYTk5bUM2T2dEUQpkMVQ0VS80Y3Jt
QTZUVnNZV0daczM0Titvc3Q1T2JiTVZYV2tXOW4xV0VRCi0+IHNzaC1lZDI1NTE5
IFpOcUlvZyAzMnZ2NjR1R2R2UlJNZjNvOU9RckR0MEtnbllyYVJPSUZtUDNWSU5k
U3c4Ckgza2txalJhOW14c1dGZ0VTc3EzK2NpOUJaVWhqN2lMWU9HL3hMSWlJUVkK
LT4gc3NoLWVkMjU1MTkgcUxqcXlRIHMxNStVTnY1TUZJaHlXQnNTSFhXditsWnVF
Y2ZKRWZ5UXVPZUVKY2VjakEKV1N3ODVFYXROTzFReWE5Y1A5MkpXUjJVc00wVVd3
ZUpzTC9rRGdOWUpxWQotPiBzc2gtZWQyNTUxOSBCYVFsUmcganpkWlpaWlRVQ3Vp
Y2hvbkpld2kzdzVtdERHajBNUTEyM0NOWlp0WkxtRQp1MEJUKzFUSW9tWjluVU9Y
clBzNFpzdU83MXdGN2dJSGducnplbEd4M1JNCi0+IHNzaC1lZDI1NTE5IHMrcVJm
ZyBSRW1pZWFhQkpQRTFYTG9IZnVmWmx6S2pNUll4MGhtRFd1Y0ZhS25JNFZVCjhU
UDhoOTlTUEtqbytZMjZ2NlozcnZTNXVNcVA3cU1TRmtsL1g4bEhKUzgKLT4gc3No
LWVkMjU1MTkgNjJKY2NBIElSSXZjc3J5cWNwOHFNV281YzBrVzc2TlVwMnRwb0NJ
dEdST0s4MEhmQnMKaTNEdkFjRktCZHNCY3FsWE5UbFo1R3lXSlI2NE5MR25neWJ4
NTlsSllxWQotPiBzc2gtZWQyNTUxOSAvaHgvZEEgOExaRjJiNTJkUGFxZllSK1Uz
eWxQTmtxOVFPZkVFb2w2Z0tmZVpwTndDWQpuRFlqZWdaQjZaT1BZSmllVzB5NWhY
MmhHaWtZOXFERzhSRWRXWk5TR1RRCi0+IHNzaC1lZDI1NTE5IFd6TEdIQSBtZW04
eWlNWU9JOXYvcVlsb1JXM2JKRlREeXJXNHd6MlkvazZrSzdscG5BCnZzWUFwb3lK
dUhkcDZNakFPN0RMRG5LQzdqU1UzNlJ6eGRGSGlhYUx0YXMKLT4gc3NoLWVkMjU1
MTkgSEovSjdBIDBaNzZGVkdaVWlWNk4yVW5UdnFCZ2xWUEtIc2QzQmJTMnlINVF1
V093UmsKcXNhSnlnWHQrRzVSU296NENDN29aMUN5VlRIcittdGNySGhvMHZlT0xl
NAotPiBzc2gtZWQyNTUxOSBPRXFNc2cgNUFSc045eUVqQWI3MXB4Tkd2RndDS2Na
VGJrblFLaENPVlZucFdGRGFDTQp6dlRHTnRLSFkxb1RFdmxGS09Jenh2Q25VZ2ha
QWQ4YUNjdVNJbW8vVGVrCi0+IHNzaC1lZDI1NTE5IC9FSlh2ZyBGM2lrUG1DWUx3
YndZWWdobVo3TjZHTDNabmdsa3ZHcndwUXVZSVg5T0VZCjNYdlFYSHBsWjBTWXlS
V0lSZkpwVE05eU1LcFBEbWdXWEZ0U0tSTkthQnMKLT4gWDI1NTE5IDF5SmczUWpo
bkdmWS9SamxtTTF1eVJnc1QxUGJiUjQwR1VSTmdxMEtqQzAKeTF0NWp6dG1CWGNy
VVVXVGFLV3dkWWo2YTVkZmtXcHRZai9FSDVBSmJhbwotPiAmJC1ncmVhc2UgaWU3
YGkpVSBNV0ZfIDM1fltQdzBcCmZYRXB1NEVMNkVqWVF3Ci0tLSB2RVRFYmVGVklB
bGFiUTBKYlMrRitvN2NnUkhScTMvWml6ZzRKU3ZIeEtvChoKB2c5roTC97pdDOi6
aPFIaTyOu9NZ4ESwwRjpEgB0D6GP2r7YR3CnxVyXa4sCFUnTF8dLUkABFnSeNeQZ
M64tM6J+tZAyJa9IKaTgSqvQaGYHHYinygNvf6BShCK4nPUJu0cV6gFtqFle0MWA
Rez5eRMFH/M2aubhwBeDyHG4WRelkt7oMVXyY6U=
-----END AGE ENCRYPTED FILE-----