Compare commits

..

1 Commits

Author SHA1 Message Date
ab25c07f69 An attempt was made 2024-01-09 21:56:10 +00:00
136 changed files with 1457 additions and 3790 deletions

View File

@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: cachix/install-nix-action@v27 - uses: cachix/install-nix-action@v23
with: with:
# Gitea will supply a token in GITHUB_TOKEN, which this action will # Gitea will supply a token in GITHUB_TOKEN, which this action will
# try to pass to Nix when downloading from GitHub # try to pass to Nix when downloading from GitHub
@@ -18,8 +18,6 @@ jobs:
extra_nix_config: | extra_nix_config: |
# Make sure we're using sandbox # Make sure we're using sandbox
sandbox-fallback = false sandbox-fallback = false
# Big C++ projects fill up memory...
cores = 6
extra-substituters = https://nix-cache.nul.ie/main extra-substituters = https://nix-cache.nul.ie/main
extra-trusted-public-keys = main:mMChkG8LwXrFirVfudqjSHasK1jV31OVElYD3eImYl8= extra-trusted-public-keys = main:mMChkG8LwXrFirVfudqjSHasK1jV31OVElYD3eImYl8=

View File

@@ -14,7 +14,7 @@ jobs:
uses: https://github.com/actions/setup-go@v4 uses: https://github.com/actions/setup-go@v4
with: with:
go-version: '>=1.20.1' go-version: '>=1.20.1'
- uses: cachix/install-nix-action@v27 - uses: cachix/install-nix-action@v23
with: with:
github_access_token: ${{ secrets.GH_PULL_TOKEN }} github_access_token: ${{ secrets.GH_PULL_TOKEN }}
extra_nix_config: | extra_nix_config: |
@@ -39,13 +39,12 @@ jobs:
run: | run: |
nix build .#nixfiles.config.nixos.systems.installer.configuration.config.my.buildAs.netbootArchive nix build .#nixfiles.config.nixos.systems.installer.configuration.config.my.buildAs.netbootArchive
ln -s "$(readlink result)" \ ln -s "$(readlink result)" \
jackos-installer-netboot-${{ steps.setup.outputs.short_rev }}.tar.zst jackos-installer-netboot-${{ steps.setup.outputs.short_rev }}.tar
- name: Create release - name: Create release
uses: https://gitea.com/actions/release-action@main uses: https://gitea.com/actions/release-action@main
with: with:
title: Latest installer title: Latest installer
api_key: '${{ secrets.RELEASE_TOKEN }}'
files: | files: |
jackos-installer-${{ steps.setup.outputs.short_rev }}.iso jackos-installer-${{ steps.setup.outputs.short_rev }}.iso
jackos-installer-netboot-${{ steps.setup.outputs.short_rev }}.tar.zst jackos-installer-netboot-${{ steps.setup.outputs.short_rev }}.tar

View File

@@ -20,7 +20,7 @@ in
[ -e "${homeFlake}" ] && echo "${homeFlake} already exists" && exit 1 [ -e "${homeFlake}" ] && echo "${homeFlake} already exists" && exit 1
mkdir -p "$(dirname "${homeFlake}")" mkdir -p "$(dirname "${homeFlake}")"
ln -sf "$(pwd)/flake.nix" "${homeFlake}" ln -s "$(pwd)/flake.nix" "${homeFlake}"
echo "Installed link to $(pwd)/flake.nix at ${homeFlake}" echo "Installed link to $(pwd)/flake.nix at ${homeFlake}"
''; '';
} }
@@ -52,7 +52,7 @@ in
name = "json2nix"; name = "json2nix";
category = "utilities"; category = "utilities";
help = "Convert JSON to formatted Nix"; help = "Convert JSON to formatted Nix";
command = "nix eval --impure --expr 'builtins.fromJSON (builtins.readFile /dev/stdin)' | ${pkgs.nixfmt-rfc-style}/bin/nixfmt"; command = "nix eval --impure --expr 'builtins.fromJSON (builtins.readFile /dev/stdin)' | ${pkgs.nixfmt}/bin/nixfmt";
} }
{ {
@@ -106,8 +106,8 @@ in
{ {
name = "build-netboot"; name = "build-netboot";
category = "tasks"; category = "tasks";
help = "Build NixOS configuration as netboot tree"; help = "Build NixOS configuration as netboot archive";
command = ''nix build "''${@:2}" ".#nixfiles.config.nixos.systems.\"$1\".configuration.config.my.buildAs.netbootTree"''; command = ''nix build "''${@:2}" ".#nixfiles.config.nixos.systems.\"$1\".configuration.config.my.buildAs.netbootArchive"'';
} }
{ {
name = "build-home"; name = "build-home";

518
flake.lock generated
View File

@@ -3,19 +3,17 @@
"agenix": { "agenix": {
"inputs": { "inputs": {
"darwin": "darwin", "darwin": "darwin",
"home-manager": "home-manager",
"nixpkgs": [ "nixpkgs": [
"ragenix", "ragenix",
"nixpkgs" "nixpkgs"
], ]
"systems": "systems_8"
}, },
"locked": { "locked": {
"lastModified": 1707830867, "lastModified": 1682101079,
"narHash": "sha256-PAdwm5QqdlwIqGrfzzvzZubM+FXtilekQ/FA0cI49/o=", "narHash": "sha256-MdAhtjrLKnk2uiqun1FWABbKpLH090oeqCSiWemtuck=",
"owner": "ryantm", "owner": "ryantm",
"repo": "agenix", "repo": "agenix",
"rev": "8cb01a0e717311680e0cbca06a76cbceba6f3ed6", "rev": "2994d002dcff5353ca1ac48ec584c7f6589fe447",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -37,11 +35,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1720542474, "lastModified": 1702969472,
"narHash": "sha256-aKjJ/4l2I9+wNGTaOGRsuS3M1+IoTibqgEMPDikXm04=", "narHash": "sha256-IJP9sC+/gLUdWhm6TsnWpw6A1zQWUfn53ym63KeLXvU=",
"owner": "zhaofengli", "owner": "zhaofengli",
"repo": "attic", "repo": "attic",
"rev": "6139576a3ce6bb992e0f6c3022528ec233e45f00", "rev": "bdafd64910bb2b861cf90fa15f1fc93318b6fbf6",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -60,17 +58,17 @@
"poetry2nix": "poetry2nix" "poetry2nix": "poetry2nix"
}, },
"locked": { "locked": {
"lastModified": 1718746012, "lastModified": 1682289679,
"narHash": "sha256-sp9vGl3vWXvD/C2JeMDi5nbW6CkKIC3Q2JMGKwexYEs=", "narHash": "sha256-DbhSJ6y62VAO2VsJwoz3VsxCEP/4KMeFVs0wIz6Im04=",
"ref": "refs/heads/master", "owner": "devplayer0",
"rev": "ea24100bd4a914b9e044a2085a3785a6bd3a3833", "repo": "boardie",
"revCount": 5, "rev": "e4b977f75bf7b4f656a691efca492ae057672a77",
"type": "git", "type": "github"
"url": "https://git.nul.ie/dev/boardie"
}, },
"original": { "original": {
"type": "git", "owner": "devplayer0",
"url": "https://git.nul.ie/dev/boardie" "repo": "boardie",
"type": "github"
} }
}, },
"borgthin": { "borgthin": {
@@ -103,11 +101,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1717025063, "lastModified": 1702918879,
"narHash": "sha256-dIubLa56W9sNNz0e8jGxrX3CAkPXsq7snuFA/Ie6dn8=", "narHash": "sha256-tWJqzajIvYcaRWxn+cLUB9L9Pv4dQ3Bfit/YjU5ze3g=",
"owner": "ipetkov", "owner": "ipetkov",
"repo": "crane", "repo": "crane",
"rev": "480dff0be03dac0e51a8dfc26e882b0d123a450e", "rev": "7195c00c272fdd92fc74e7d5a0a2844b9fadb2fb",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -118,17 +116,26 @@
}, },
"crane_2": { "crane_2": {
"inputs": { "inputs": {
"flake-compat": "flake-compat_3",
"flake-utils": [
"ragenix",
"flake-utils"
],
"nixpkgs": [ "nixpkgs": [
"ragenix", "ragenix",
"nixpkgs" "nixpkgs"
],
"rust-overlay": [
"ragenix",
"rust-overlay"
] ]
}, },
"locked": { "locked": {
"lastModified": 1708794349, "lastModified": 1681680516,
"narHash": "sha256-jX+B1VGHT0ruHHL5RwS8L21R6miBn4B6s9iVyUJsJJY=", "narHash": "sha256-EB8Adaeg4zgcYDJn9sR6UMjN/OHdIiMMK19+3LmmXQY=",
"owner": "ipetkov", "owner": "ipetkov",
"repo": "crane", "repo": "crane",
"rev": "2c94ff9a6fbeb9f3ea0107f28688edbe9c81deaa", "rev": "54b63c8eae4c50172cb50b612946ff1d2bc1c75c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -146,11 +153,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1700795494, "lastModified": 1673295039,
"narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=", "narHash": "sha256-AsdYgE8/GPwcelGgrntlijMg4t3hLFJFCRF3tL5WVjA=",
"owner": "lnl7", "owner": "lnl7",
"repo": "nix-darwin", "repo": "nix-darwin",
"rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d", "rev": "87b9d090ad39b25b2400029c64825fc2a8868943",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -169,11 +176,11 @@
"utils": "utils" "utils": "utils"
}, },
"locked": { "locked": {
"lastModified": 1718194053, "lastModified": 1703087360,
"narHash": "sha256-FaGrf7qwZ99ehPJCAwgvNY5sLCqQ3GDiE/6uLhxxwSY=", "narHash": "sha256-0VUbWBW8VyiDRuimMuLsEO4elGuUw/nc2WDeuO1eN1M=",
"owner": "serokell", "owner": "serokell",
"repo": "deploy-rs", "repo": "deploy-rs",
"rev": "3867348fa92bc892eba5d9ddb2d7a97b9e127a8a", "rev": "b709d63debafce9f5645a5ba550c9e0983b3d1f7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -188,11 +195,11 @@
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
}, },
"locked": { "locked": {
"lastModified": 1717408969, "lastModified": 1678957337,
"narHash": "sha256-Q0OEFqe35fZbbRPPRdrjTUUChKVhhWXz3T9ZSKmaoVY=", "narHash": "sha256-Gw4nVbuKRdTwPngeOZQOzH/IFowmz4LryMPDiJN/ah4=",
"owner": "numtide", "owner": "numtide",
"repo": "devshell", "repo": "devshell",
"rev": "1ebbe68d57457c8cae98145410b164b5477761f4", "rev": "3e0e60ab37cd0bf7ab59888f5c32499d851edb47",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -201,25 +208,6 @@
"type": "github" "type": "github"
} }
}, },
"devshell-tools": {
"inputs": {
"flake-utils": "flake-utils_11",
"nixpkgs": "nixpkgs_4"
},
"locked": {
"lastModified": 1710099997,
"narHash": "sha256-WmBKTLdth6I/D+0//9enbIXohGsBjepbjIAm9pCYj0U=",
"owner": "eikek",
"repo": "devshell-tools",
"rev": "e82faf976d318b3829f6f7f6785db6f3c7b65267",
"type": "github"
},
"original": {
"owner": "eikek",
"repo": "devshell-tools",
"type": "github"
}
},
"devshell_2": { "devshell_2": {
"inputs": { "inputs": {
"flake-utils": "flake-utils_5", "flake-utils": "flake-utils_5",
@@ -241,17 +229,17 @@
}, },
"devshell_3": { "devshell_3": {
"inputs": { "inputs": {
"flake-utils": "flake-utils_7",
"nixpkgs": [ "nixpkgs": [
"nixpkgs-unstable" "nixpkgs-unstable"
] ],
"systems": "systems_4"
}, },
"locked": { "locked": {
"lastModified": 1713532798, "lastModified": 1701787589,
"narHash": "sha256-wtBhsdMJA3Wa32Wtm1eeo84GejtI43pMrFrmwLXrsEc=", "narHash": "sha256-ce+oQR4Zq9VOsLoh9bZT8Ip9PaMLcjjBUHVPzW5d7Cw=",
"owner": "numtide", "owner": "numtide",
"repo": "devshell", "repo": "devshell",
"rev": "12e914740a25ea1891ec619bb53cf5e6ca922e40", "rev": "44ddedcbcfc2d52a76b64fb6122f209881bd3e1e",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -292,6 +280,22 @@
"type": "github" "type": "github"
} }
}, },
"flake-compat_3": {
"flake": false,
"locked": {
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": { "flake-utils": {
"locked": { "locked": {
"lastModified": 1667395993, "lastModified": 1667395993,
@@ -308,60 +312,6 @@
} }
}, },
"flake-utils_10": { "flake-utils_10": {
"inputs": {
"systems": "systems_9"
},
"locked": {
"lastModified": 1705309234,
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_11": {
"inputs": {
"systems": "systems_10"
},
"locked": {
"lastModified": 1709126324,
"narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "d465f4819400de7c8d874d50b982301f28a84605",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_12": {
"inputs": {
"systems": "systems_11"
},
"locked": {
"lastModified": 1705309234,
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_13": {
"locked": { "locked": {
"lastModified": 1667395993, "lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
@@ -377,15 +327,12 @@
} }
}, },
"flake-utils_2": { "flake-utils_2": {
"inputs": {
"systems": "systems"
},
"locked": { "locked": {
"lastModified": 1701680307, "lastModified": 1642700792,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", "narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725", "rev": "846b2ae0fc4cc943637d3d1def4454213e203cba",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -396,14 +343,14 @@
}, },
"flake-utils_3": { "flake-utils_3": {
"inputs": { "inputs": {
"systems": "systems_2" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1710146030, "lastModified": 1681202837,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -414,14 +361,14 @@
}, },
"flake-utils_4": { "flake-utils_4": {
"inputs": { "inputs": {
"systems": "systems_3" "systems": "systems_2"
}, },
"locked": { "locked": {
"lastModified": 1710146030, "lastModified": 1681202837,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -462,7 +409,7 @@
}, },
"flake-utils_7": { "flake-utils_7": {
"inputs": { "inputs": {
"systems": "systems_6" "systems": "systems_5"
}, },
"locked": { "locked": {
"lastModified": 1701680307, "lastModified": 1701680307,
@@ -479,24 +426,6 @@
} }
}, },
"flake-utils_8": { "flake-utils_8": {
"inputs": {
"systems": "systems_7"
},
"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_9": {
"locked": { "locked": {
"lastModified": 1659877975, "lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
@@ -511,25 +440,21 @@
"type": "github" "type": "github"
} }
}, },
"home-manager": { "flake-utils_9": {
"inputs": { "inputs": {
"nixpkgs": [ "systems": "systems_6"
"ragenix",
"agenix",
"nixpkgs"
]
}, },
"locked": { "locked": {
"lastModified": 1703113217, "lastModified": 1681202837,
"narHash": "sha256-7ulcXOk63TIT2lVDSExj7XzFx09LpdSAPtvgtM7yQPE=", "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "nix-community", "owner": "numtide",
"repo": "home-manager", "repo": "flake-utils",
"rev": "3bfaacf46133c037bb356193bd2f1765d9dc82c1", "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nix-community", "owner": "numtide",
"repo": "home-manager", "repo": "flake-utils",
"type": "github" "type": "github"
} }
}, },
@@ -540,11 +465,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1719827415, "lastModified": 1703367386,
"narHash": "sha256-pvh+1hStXXAZf0sZ1xIJbWGx4u+OGBC1rVx6Wsw0fBw=", "narHash": "sha256-FMbm48UGrBfOWGt8+opuS+uLBLQlRfhiYXhHNcYMS5k=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "f2e3c19867262dbe84fdfab42467fc8dd83a2005", "rev": "d5824a76bc6bb93d1dce9ebbbcb09a9b6abcc224",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -560,11 +485,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1720734513, "lastModified": 1703754036,
"narHash": "sha256-neWQ8eNtLTd+YMesb7WjKl1SVCbDyCm46LUgP/g/hdo=", "narHash": "sha256-JpJdcj9Tg4lMuYikXDpajA8wOp+rHyn9RD2rKBEM4cQ=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "90ae324e2c56af10f20549ab72014804a3064c7f", "rev": "c24c298562fe41b39909f632c5a7151bbf6b4628",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -574,11 +499,11 @@
}, },
"impermanence": { "impermanence": {
"locked": { "locked": {
"lastModified": 1719091691, "lastModified": 1703656108,
"narHash": "sha256-AxaLX5cBEcGtE02PeGsfscSb/fWMnyS7zMWBXQWDKbE=", "narHash": "sha256-hCSUqdFJKHHbER8Cenf5JRzjMlBjIdwdftGQsO0xoJs=",
"owner": "nix-community", "owner": "nix-community",
"repo": "impermanence", "repo": "impermanence",
"rev": "23c1f06316b67cb5dabdfe2973da3785cfe9c34a", "rev": "033643a45a4a920660ef91caa391fbffb14da466",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -587,41 +512,19 @@
"type": "github" "type": "github"
} }
}, },
"nix-github-actions": {
"inputs": {
"nixpkgs": [
"boardie",
"poetry2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1703863825,
"narHash": "sha256-rXwqjtwiGKJheXB43ybM8NwWB8rO2dSRrEqes0S7F5Y=",
"owner": "nix-community",
"repo": "nix-github-actions",
"rev": "5163432afc817cf8bd1f031418d1869e4c9d5547",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-github-actions",
"type": "github"
}
},
"nixGL": { "nixGL": {
"inputs": { "inputs": {
"flake-utils": "flake-utils_9", "flake-utils": "flake-utils_8",
"nixpkgs": [ "nixpkgs": [
"nixpkgs-unstable" "nixpkgs-unstable"
] ]
}, },
"locked": { "locked": {
"lastModified": 1713543440, "lastModified": 1685908677,
"narHash": "sha256-lnzZQYG0+EXl/6NkGpyIz+FEOc/DSEG57AP1VsdeNrM=", "narHash": "sha256-E4zUPEUFyVWjVm45zICaHRpfGepfkE9Z2OECV9HXfA4=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nixGL", "repo": "nixGL",
"rev": "310f8e49a149e4c9ea52f1adf70cdc768ec53f8a", "rev": "489d6b095ab9d289fe11af0219a9ff00fe87c7c5",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -632,11 +535,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1704161960, "lastModified": 1677383253,
"narHash": "sha256-QGua89Pmq+FBAro8NriTuoO/wNaUtugt29/qqA8zeeM=", "narHash": "sha256-UfpzWfSxkfXHnb4boXZNaKsAcUrZT9Hw+tao1oZxd08=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "63143ac2c9186be6d9da6035fa22620018c85932", "rev": "9952d6bc395f5841262b006fbace8dd7e143b634",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -648,11 +551,11 @@
}, },
"nixpkgs-mine": { "nixpkgs-mine": {
"locked": { "locked": {
"lastModified": 1720115894, "lastModified": 1703756459,
"narHash": "sha256-oWiGxG2JRchzTYP11jSCHOnbom5tOwbZofV2IjbTdnk=", "narHash": "sha256-ztEMyPQZh3Pb+LOoWl5lbIK2LenP59sOUBC86CDmLio=",
"owner": "devplayer0", "owner": "devplayer0",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "f05b4fdd5610255bd674ce75faaf573a614bdb60", "rev": "e80160eb2ac3a7111d07cc43a15c16b9edca01ea",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -664,11 +567,11 @@
}, },
"nixpkgs-mine-stable": { "nixpkgs-mine-stable": {
"locked": { "locked": {
"lastModified": 1720116136, "lastModified": 1703756491,
"narHash": "sha256-cUfR+WCV5xz3nga7uGPdAMvlYaITpP7qEcVbEdoMRXU=", "narHash": "sha256-9VL34e0gzomwqRnryRn23V2ImYcaZIQdp7CsWg5TmlE=",
"owner": "devplayer0", "owner": "devplayer0",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "281333a642d6f8156554e0d8457083d8a0d435c2", "rev": "36611f5f7cfd401f51ad4ca76fd6ee85a714bb74",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -680,11 +583,11 @@
}, },
"nixpkgs-stable": { "nixpkgs-stable": {
"locked": { "locked": {
"lastModified": 1720535198, "lastModified": 1703467016,
"narHash": "sha256-zwVvxrdIzralnSbcpghA92tWu2DV2lwv89xZc8MTrbg=", "narHash": "sha256-/5A/dNPhbQx/Oa2d+Get174eNI3LERQ7u6WTWOlR1eQ=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "205fd4226592cc83fd4c0885a3e4c9c400efabb5", "rev": "d02d818f22c777aa4e854efc3242ec451e5d462a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -695,11 +598,11 @@
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1720768451, "lastModified": 1703438236,
"narHash": "sha256-EYekUHJE2gxeo2pM/zM9Wlqw1Uw2XTJXOSAO79ksc4Y=", "narHash": "sha256-aqVBq1u09yFhL7bj1/xyUeJjzr92fXVvQSSEx6AdB1M=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "7e7c39ea35c5cdd002cd4588b03a3fb9ece6fad9", "rev": "5f64a12a728902226210bf01d25ec6cbb9d9265b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -710,16 +613,15 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1718632497, "lastModified": 1681756206,
"narHash": "sha256-YtlyfqOdYMuu7gumZtK0Kg7jr4OKfHUhJkZfNUryw68=", "narHash": "sha256-7B2Jc1zosXvZJKlxTPBlGew0LeX/7cxguG/d3syc1JI=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "c58b4a9118498c1055c5908a5bbe666e56abe949", "rev": "6eceb07c28016ec50dd683fda94995702b67e855",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixos-unstable-small",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@@ -740,52 +642,17 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_4": {
"locked": {
"lastModified": 1709309926,
"narHash": "sha256-VZFBtXGVD9LWTecGi6eXrE0hJ/mVB3zGUlHImUs2Qak=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "79baff8812a0d68e24a836df0a364c678089e2c7",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-23.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_5": {
"locked": {
"lastModified": 1674990008,
"narHash": "sha256-4zOyp+hFW2Y7imxIpZqZGT8CEqKmDjwgfD6BzRUE0mQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d2bbcbe6c626d339b25a4995711f07625b508214",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"poetry2nix": { "poetry2nix": {
"inputs": { "inputs": {
"flake-utils": "flake-utils_4", "flake-utils": "flake-utils_4",
"nix-github-actions": "nix-github-actions", "nixpkgs": "nixpkgs_2"
"nixpkgs": "nixpkgs_2",
"systems": "systems_4",
"treefmt-nix": "treefmt-nix"
}, },
"locked": { "locked": {
"lastModified": 1718726452, "lastModified": 1681532901,
"narHash": "sha256-w4hJSYvACz0i5XHtxc6XNyHwbxpisN13M2kA2Y7937o=", "narHash": "sha256-9ZN/gaCOlkx53km4J2QkLQh4bS+6UCBsjdi87kw6+jc=",
"owner": "nix-community", "owner": "nix-community",
"repo": "poetry2nix", "repo": "poetry2nix",
"rev": "53e534a08c0cd2a9fa7587ed1c3e7f6aeb804a2c", "rev": "2e66fd2623eccb3086e52929c2cefd882faac8a8",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -798,18 +665,18 @@
"inputs": { "inputs": {
"agenix": "agenix", "agenix": "agenix",
"crane": "crane_2", "crane": "crane_2",
"flake-utils": "flake-utils_10", "flake-utils": "flake-utils_9",
"nixpkgs": [ "nixpkgs": [
"nixpkgs-unstable" "nixpkgs-unstable"
], ],
"rust-overlay": "rust-overlay" "rust-overlay": "rust-overlay"
}, },
"locked": { "locked": {
"lastModified": 1718869541, "lastModified": 1682237245,
"narHash": "sha256-smhpGh1x/8mNl+sFL8SbeWnx0bK4HWjmdRA3mIwGjPU=", "narHash": "sha256-xbBR7LNK+d5Yi/D6FXQGc1R6u2VV2nwr/Df5iaEbOEQ=",
"owner": "yaxitech", "owner": "yaxitech",
"repo": "ragenix", "repo": "ragenix",
"rev": "8a254bbaa93fbd38e16f70fa81af6782794e046e", "rev": "281f68c3d477904f79ff1cd5807a8c226cd80a50",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -825,7 +692,7 @@
"borgthin": "borgthin", "borgthin": "borgthin",
"deploy-rs": "deploy-rs", "deploy-rs": "deploy-rs",
"devshell": "devshell_3", "devshell": "devshell_3",
"flake-utils": "flake-utils_8", "flake-utils": "flake-utils_7",
"home-manager-stable": "home-manager-stable", "home-manager-stable": "home-manager-stable",
"home-manager-unstable": "home-manager-unstable", "home-manager-unstable": "home-manager-unstable",
"impermanence": "impermanence", "impermanence": "impermanence",
@@ -850,11 +717,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1708740535, "lastModified": 1682129965,
"narHash": "sha256-NCTw235XwSDbeTAtAwg/hOeNOgwYhVq7JjDdbkOgBeA=", "narHash": "sha256-1KRPIorEL6pLpJR04FwAqqnt4Tzcm4MqD84yhlD+XSk=",
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "9b24383d77f598716fa0cbb8b48c97249f5ee1af", "rev": "2c417c0460b788328220120c698630947547ee83",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -863,40 +730,19 @@
"type": "github" "type": "github"
} }
}, },
"sbt": {
"inputs": {
"flake-utils": "flake-utils_13",
"nixpkgs": "nixpkgs_5"
},
"locked": {
"lastModified": 1698464090,
"narHash": "sha256-Pnej7WZIPomYWg8f/CZ65sfW85IfIUjYhphMMg7/LT0=",
"owner": "zaninime",
"repo": "sbt-derivation",
"rev": "6762cf2c31de50efd9ff905cbcc87239995a4ef9",
"type": "github"
},
"original": {
"owner": "zaninime",
"repo": "sbt-derivation",
"type": "github"
}
},
"sharry": { "sharry": {
"inputs": { "inputs": {
"devshell-tools": "devshell-tools", "flake-utils": "flake-utils_10",
"flake-utils": "flake-utils_12",
"nixpkgs": [ "nixpkgs": [
"nixpkgs-unstable" "nixpkgs-unstable"
], ]
"sbt": "sbt"
}, },
"locked": { "locked": {
"lastModified": 1720592125, "lastModified": 1687587666,
"narHash": "sha256-vR89LefkY8mBPWxDTQ8SNg6Z7/J6Yga80T4kSb6MNdk=", "narHash": "sha256-t1VNvdQdDUFTEKTFP2fc7Fb3buQBmP+h9WUeO8b2Bus=",
"owner": "eikek", "owner": "eikek",
"repo": "sharry", "repo": "sharry",
"rev": "604b20517150599cb05dbe178cd35cd10659aa4c", "rev": "a9b3371aa6c7b92088b20fd6e479c251a5556b86",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -920,36 +766,6 @@
"type": "github" "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_11": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": { "systems_2": {
"locked": { "locked": {
"lastModified": 1681028828, "lastModified": 1681028828,
@@ -990,8 +806,9 @@
"type": "github" "type": "github"
}, },
"original": { "original": {
"id": "systems", "owner": "nix-systems",
"type": "indirect" "repo": "default",
"type": "github"
} }
}, },
"systems_5": { "systems_5": {
@@ -1024,76 +841,9 @@
"type": "github" "type": "github"
} }
}, },
"systems_7": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_8": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_9": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"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": { "utils": {
"inputs": { "inputs": {
"systems": "systems_5" "systems": "systems_3"
}, },
"locked": { "locked": {
"lastModified": 1701680307, "lastModified": 1701680307,

View File

@@ -24,7 +24,7 @@
# Stuff used by systems # Stuff used by systems
impermanence.url = "github:nix-community/impermanence"; 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"; boardie.inputs.nixpkgs.follows = "nixpkgs-unstable";
nixGL.url = "github:nix-community/nixGL"; nixGL.url = "github:nix-community/nixGL";
nixGL.inputs.nixpkgs.follows = "nixpkgs-unstable"; nixGL.inputs.nixpkgs.follows = "nixpkgs-unstable";
@@ -115,9 +115,9 @@
nixos/installer.nix nixos/installer.nix
nixos/boxes/colony nixos/boxes/colony
nixos/boxes/tower nixos/boxes/tower
nixos/boxes/castle
nixos/boxes/home/stream.nix nixos/boxes/home/stream.nix
nixos/boxes/home/palace nixos/boxes/home/palace
nixos/boxes/home/castle
nixos/boxes/britway nixos/boxes/britway
nixos/boxes/kelder nixos/boxes/kelder

View File

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

View File

@@ -1,28 +0,0 @@
# XTerm's default colors
# Default colors
[colors.primary]
background = '#000000'
foreground = '#ffffff'
# Normal colors
[colors.normal]
black = '#000000'
red = '#cd0000'
green = '#00cd00'
yellow = '#cdcd00'
blue = '#0000ee'
magenta = '#cd00cd'
cyan = '#00cdcd'
white = '#e5e5e5'
# Bright colors
[colors.bright]
black = '#7f7f7f'
red = '#ff0000'
green = '#00ff00'
yellow = '#ffff00'
blue = '#5c5cff'
magenta = '#ff00ff'
cyan = '#00ffff'
white = '#ffffff'

View File

@@ -10,23 +10,6 @@ let
name = "Monocraft"; name = "Monocraft";
size = 10; size = 10;
}; };
doomWad = pkgs.fetchurl {
url = "https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad";
hash = "sha256-HX1DvlAeZ9kn5BXguPPinDvzMHXoWXIYFvZSpSbKx3E=";
};
doomsaver = pkgs.runCommand "doomsaver" {
inherit (pkgs) windowtolayer;
chocoDoom = pkgs.chocolate-doom2xx;
python = pkgs.python3.withPackages (ps: [ ps.filelock ]);
inherit doomWad;
enojy = ./enojy.jpg;
} ''
mkdir -p "$out"/bin
substituteAll ${./screensaver.py} "$out"/bin/doomsaver
chmod +x "$out"/bin/doomsaver
'';
in in
{ {
options.my.gui = { options.my.gui = {
@@ -49,19 +32,11 @@ in
slurp slurp
swappy swappy
python3Packages.python-lsp-server python310Packages.python-lsp-server
nil # nix language server nil # nix language server
zls # zig language server zls # zig language server
rust-analyzer rust-analyzer
cowsay
fortune
jp2a
terminaltexteffects
screenfetch
neofetch neofetch
cmatrix
doomsaver
]; ];
}; };
@@ -76,15 +51,7 @@ in
alacritty = { alacritty = {
enable = true; enable = true;
settings = { settings = {
import = [ ./alacritty-xterm.toml ]; font.normal.family = font.name;
font = {
size = font.size;
normal = {
family = font.name;
style = "Regular";
};
};
}; };
}; };
@@ -92,31 +59,12 @@ in
enable = true; enable = true;
inherit font; inherit font;
settings = { settings = {
background_opacity = "0.65"; background_opacity = "0.8";
tab_bar_edge = "top"; tab_bar_edge = "top";
shell_integration = "no-sudo"; shell_integration = "no-sudo";
}; };
}; };
termite = {
enable = true;
font = "${font.name} ${toString font.size}";
backgroundColor = "rgba(0, 0, 0, 0.8)";
};
foot = {
enable = true;
settings = {
main = {
font = "${font.name}:size=${toString font.size}";
};
colors = {
alpha = 0.8;
background = "000000";
};
};
};
helix = { helix = {
enable = true; enable = true;
settings = { settings = {
@@ -178,11 +126,10 @@ in
]; ];
pointerCursor = { pointerCursor = {
package = pkgs.posy-cursors; package = pkgs.vanilla-dmz;
name = "Posy_Cursor"; name = "Vanilla-DMZ";
size = 32; size = 16;
gtk.enable = true; gtk.enable = true;
x11.enable = true;
}; };
}; };
@@ -215,7 +162,7 @@ in
in in
lib.mkOptionDefault { lib.mkOptionDefault {
"${mod}+d" = null; "${mod}+d" = null;
"${mod}+l" = "exec ${doomsaver}/bin/doomsaver"; "${mod}+l" = "exec swaylock -i ${./lock.png} -s stretch";
"${mod}+x" = "exec ${cfg.menu}"; "${mod}+x" = "exec ${cfg.menu}";
"${mod}+Shift+x" = "exec rofi -show drun"; "${mod}+Shift+x" = "exec rofi -show drun";
"${mod}+q" = "kill"; "${mod}+q" = "kill";
@@ -263,10 +210,17 @@ in
}; };
qt = { qt = {
enable = true; enable = true;
platformTheme.name = "gtk"; platformTheme = "gtk";
}; };
services = { services = {
swaync = {
enable = true;
settings = {
widgets = [ "title" "dnd" "mpris" "notifications" ];
};
};
playerctld.enable = true; playerctld.enable = true;
spotifyd = { spotifyd = {
enable = false; enable = false;
@@ -343,15 +297,6 @@ in
] (_: "chromium-browser.desktop"); ] (_: "chromium-browser.desktop");
}; };
}; };
my = {
swaync = {
enable = true;
settings = {
widgets = [ "title" "dnd" "mpris" "notifications" ];
};
};
};
}) })
(mkIf (cfg.standalone && !pkgs.stdenv.isDarwin) { (mkIf (cfg.standalone && !pkgs.stdenv.isDarwin) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

View File

@@ -1,209 +0,0 @@
#!@python@/bin/python
import argparse
import json
import os
import random
import signal
import subprocess
import sys
import filelock
class Screensaver:
def __init__(self, cmd, env=None, weight=1):
self.cmd = cmd
self.weight = weight
if env is not None:
self.env = os.environ.copy()
for k, v in env.items():
self.env[k] = v
else:
self.env = None
self.proc = None
def start(self):
assert self.proc is None
self.proc = subprocess.Popen(self.cmd, env=self.env)
def wait(self):
assert self.proc is not None
self.proc.wait()
def stop(self, kill=False):
assert self.proc is not None
if kill:
self.proc.kill()
else:
self.proc.terminate()
class DoomSaver(Screensaver):
wad = '@doomWad@'
def __init__(self, demo_index, weight=1.5):
super().__init__(
['@chocoDoom@/bin/chocolate-doom',
'-iwad', self.wad,
'-demoloopi', str(demo_index)],
env={
'SDL_AUDIODRIVER': 'null',
'SDL_VIDEODRIVER': 'caca',
'CACA_DRIVER': 'ncurses',
},
weight=weight,
)
def stop(self):
super().stop(kill=True)
class TTESaver(Screensaver):
effects = (
'beams,binarypath,blackhole,bouncyballs,bubbles,burn,colorshift,crumble,'
'decrypt,errorcorrect,expand,fireworks,middleout,orbittingvolley,overflow,'
'pour,print,rain,randomsequence,rings,scattered,slice,slide,spotlights,'
'spray,swarm,synthgrid,unstable,vhstape,waves,wipe'
).split(',')
def __init__(self, cmd, env=None, weight=1):
super().__init__(cmd, env=env, weight=weight)
self.running = False
def start(self):
self.running = True
def wait(self):
while self.running:
effect_cmd = ['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)
self.proc = subprocess.Popen(effect_cmd, stdin=subprocess.PIPE)
self.proc.stdin.write(content)
self.proc.stdin.close()
self.proc.wait()
def stop(self):
self.running = False
self.proc.terminate()
class MultiSaver:
savers = [
DoomSaver(0),
DoomSaver(1),
DoomSaver(2),
Screensaver(['cmatrix']),
TTESaver('screenfetch -N'),
TTESaver('fortune | cowsay'),
TTESaver('top -bn1 | head -n50'),
TTESaver('ss -nltu'),
TTESaver('ss -ntu'),
TTESaver('jp2a --width=100 @enojy@'),
]
state_filename = 'screensaver.json'
def __init__(self, select=None):
self.state_path = os.path.join(f'/run/user/{os.geteuid()}', self.state_filename)
self.lock = filelock.FileLock(f'{self.state_path}.lock')
if select is not None:
assert select >= 0 and select < len(self.savers), 'Invalid screensaver index'
self.selected = self.savers[select]
else:
self.selected = None
self.cleaned_up = False
def select(self):
with self.lock:
if not os.path.exists(self.state_path):
state = {'instances': []}
else:
with open(self.state_path) as f:
state = json.load(f)
if self.selected is None:
available = set(range(len(self.savers)))
new_instances = []
for instance in state['instances']:
if not os.path.exists(f"/proc/{instance['pid']}"):
continue
new_instances.append(instance)
i = instance['saver']
assert i in available
available.remove(i)
assert available, 'No screensavers left'
available = list(available)
weights = []
for i in available:
weights.append(self.savers[i].weight)
selected_i = random.choices(available, weights=weights)[0]
new_instances.append({'pid': os.getpid(), 'saver': selected_i})
state['instances'] = new_instances
# print(f'Selected saver {selected_i}')
self.selected = self.savers[selected_i]
with open(self.state_path, 'w') as f:
json.dump(state, f)
def cleanup(self):
if self.cleaned_up:
return
self.cleaned_up = True
with self.lock:
with open(self.state_path) as f:
state = json.load(f)
for i, instance in enumerate(state['instances']):
if instance['pid'] == os.getpid():
del state['instances'][i]
with open(self.state_path, 'w') as f:
json.dump(state, f)
def run(self):
assert self.selected is not None
self.selected.start()
signal.signal(signal.SIGINT, self._sighandler)
signal.signal(signal.SIGTERM, self._sighandler)
signal.signal(signal.SIGHUP, self._sighandler)
self.selected.wait()
self.cleanup()
def stop(self):
assert self.selected is not None
print('Shutting down')
self.selected.stop()
self.cleanup()
def _sighandler(self, signum, frame):
self.stop()
def main():
parser = argparse.ArgumentParser(description='Wayland terminal-based lock screen')
parser.add_argument('-l', '--locker-cmd', default='swaylock-plugin', help='swaylock-plugin command to use')
parser.add_argument('-t', '--terminal', default='alacritty', help='Terminal emulator to use')
parser.add_argument('-i', '--instance', action='store_true', help='Run as instance')
parser.add_argument('-s', '--screensaver', type=int, help='Force use of specific screensaver')
args = parser.parse_args()
if not args.instance:
cmd = [
args.locker_cmd, '--command-each',
f'@windowtolayer@/bin/windowtolayer -- {args.terminal} -e {sys.argv[0]} --instance']
if args.screensaver is not None:
cmd[-1] += f' --screensaver {args.screensaver}'
subprocess.check_call(cmd)
return
ms = MultiSaver(select=args.screensaver)
ms.select()
ms.run()
if __name__ == '__main__':
main()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 KiB

After

Width:  |  Height:  |  Size: 249 KiB

View File

@@ -146,9 +146,9 @@ in
dnd-none = ""; dnd-none = "";
}; };
return-type = "json"; return-type = "json";
exec = "${config.my.swaync.package}/bin/swaync-client -swb"; exec = "${config.services.swaync.package}/bin/swaync-client -swb";
on-click = "${config.my.swaync.package}/bin/swaync-client -t -sw"; on-click = "${config.services.swaync.package}/bin/swaync-client -t -sw";
on-click-right = "${config.my.swaync.package}/bin/swaync-client -d -sw"; on-click-right = "${config.services.swaync.package}/bin/swaync-client -d -sw";
escape = true; escape = true;
}; };
}; };

View File

@@ -19,10 +19,10 @@ let
}; };
}; };
cfg = config.my.swaync; cfg = config.services.swaync;
in in
{ {
options.my.swaync = with lib.types; { options.services.swaync = with lib.types; {
enable = mkEnableOption "Sway Notification Center"; enable = mkEnableOption "Sway Notification Center";
package = mkOption { package = mkOption {
type = package; type = package;

View File

@@ -11,8 +11,6 @@ rec {
jellyseerr = 402; jellyseerr = 402;
atticd = 403; atticd = 403;
kea = 404; kea = 404;
keepalived_script = 405;
photoprism = 406;
}; };
gids = { gids = {
matrix-syncv3 = 400; matrix-syncv3 = 400;
@@ -20,14 +18,12 @@ rec {
jellyseerr = 402; jellyseerr = 402;
atticd = 403; atticd = 403;
kea = 404; kea = 404;
keepalived_script = 405;
photoprism = 406;
}; };
}; };
kernel = { kernel = {
lts = pkgs: pkgs.linuxKernel.packages.linux_6_6; lts = pkgs: pkgs.linuxKernel.packages.linux_6_1;
latest = pkgs: pkgs.linuxKernel.packages.linux_6_9; latest = pkgs: pkgs.linuxKernel.packages.linux_6_6;
}; };
nginx = rec { nginx = rec {
@@ -111,7 +107,7 @@ rec {
}; };
pubDomain = "nul.ie"; pubDomain = "nul.ie";
colony = rec { colony = {
domain = "ams1.int.${pubDomain}"; domain = "ams1.int.${pubDomain}";
pubV4 = "94.142.240.44"; pubV4 = "94.142.240.44";
prefixes = with lib.my.net.cidr; rec { prefixes = with lib.my.net.cidr; rec {
@@ -148,10 +144,6 @@ rec {
v4 = "94.142.242.255/32"; v4 = "94.142.242.255/32";
v6 = subnet 8 1 cust.v6; v6 = subnet 8 1 cust.v6;
}; };
jam = {
v4 = subnet 8 4 cust.v4;
v6 = subnet 8 2 cust.v6;
};
vip1 = "94.142.241.224/30"; vip1 = "94.142.241.224/30";
vip2 = "94.142.242.254/31"; vip2 = "94.142.242.254/31";
@@ -164,12 +156,6 @@ rec {
home.v6 = "2a0e:97c0:4d0::/48"; home.v6 = "2a0e:97c0:4d0::/48";
}; };
custRouting = with lib.my.net.cidr; {
mail-vm = host 1 prefixes.cust.v4;
darts-vm = host 2 prefixes.cust.v4;
jam-ctr = host 3 prefixes.cust.v4;
};
firewallForwards = aa: [ firewallForwards = aa: [
{ {
port = "http"; port = "http";
@@ -183,7 +169,6 @@ rec {
port = 8448; port = 8448;
dst = aa.middleman.internal.ipv4.address; dst = aa.middleman.internal.ipv4.address;
} }
{ {
port = 25565; port = 25565;
dst = aa.simpcraft-oci.internal.ipv4.address; dst = aa.simpcraft-oci.internal.ipv4.address;
@@ -192,7 +177,6 @@ rec {
port = 25566; port = 25566;
dst = aa.simpcraft-staging-oci.internal.ipv4.address; dst = aa.simpcraft-staging-oci.internal.ipv4.address;
} }
{ {
port = 25575; port = 25575;
dst = aa.simpcraft-oci.internal.ipv4.address; dst = aa.simpcraft-oci.internal.ipv4.address;
@@ -243,7 +227,7 @@ rec {
"stream" "stream"
]; ];
routersPubV4 = [ routersPubV4 = [
"80.111.122.16" "109.255.1.246"
"109.255.252.63" "109.255.252.63"
]; ];
@@ -293,8 +277,6 @@ rec {
v6 = host ((1*65536*65536*65536) + 65535) prefixes.as211024.v6; v6 = host ((1*65536*65536*65536) + 65535) prefixes.as211024.v6;
}; };
}; };
roceBootModules = [ "ib_core" "ib_uverbs" "mlx5_core" "mlx5_ib" ];
}; };
britway = { britway = {
@@ -345,7 +327,6 @@ rec {
}; };
domain = "hentai.engineer"; domain = "hentai.engineer";
ipv4MTU = 1460;
vpn = { vpn = {
port = 51820; port = 51820;
}; };

View File

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

View File

@@ -5,20 +5,18 @@ let
inherit (lib.my.c.britway) prefixes domain; inherit (lib.my.c.britway) prefixes domain;
# Can't use overrideAttrs because we need to override `vendorHash` within `buildGoModule` # Can't use overrideAttrs because we need to override `vendorHash` within `buildGoModule`
headscale = (pkgs.headscale.override { headscale = pkgs.headscale.override {
buildGoModule = args: pkgs.buildGoModule (args // rec { buildGoModule = args: pkgs.buildGoModule (args // rec {
version = "0.23.0-alpha12"; version = "0.23.0-alpha2";
src = pkgs.fetchFromGitHub { src = pkgs.fetchFromGitHub {
owner = "juanfont"; owner = "juanfont";
repo = "headscale"; repo = "headscale";
rev = "v${version}"; rev = "v${version}";
hash = "sha256-kZZK0cXnFARxblSMz01TDcBbTorkHGAwGpR+a4/mYfU="; hash = "sha256-sz+uQyyq/5YYDe5I44x5x2nvd48swAhNlInB8KZYvDo=";
}; };
patches = []; vendorHash = "sha256-u9AmJguQ5dnJpfhOeLN43apvMHuraOrJhvlEIp9RoIc=";
vendorHash = "sha256-EorT2AVwA3usly/LcNor6r5UIhLCdj3L4O4ilgTIC2o=";
doCheck = false;
}); });
}); };
advRoutes = concatStringsSep "," [ advRoutes = concatStringsSep "," [
lib.my.c.home.prefixes.all.v4 lib.my.c.home.prefixes.all.v4

View File

@@ -1,8 +1,7 @@
{ lib, ... }: { lib, ... }:
let let
inherit (lib.my) net; inherit (lib.my) net;
inherit (lib.my.c) networkd; inherit (lib.my.c.home) domain vlans prefixes;
inherit (lib.my.c.home) domain vlans prefixes vips roceBootModules;
in in
{ {
nixos.systems.castle = { nixos.systems.castle = {
@@ -16,7 +15,7 @@ in
ipv4 = { ipv4 = {
address = net.cidr.host 40 prefixes.hi.v4; address = net.cidr.host 40 prefixes.hi.v4;
mask = 22; mask = 22;
gateway = vips.hi.v4; gateway = null;
}; };
ipv6 = { ipv6 = {
iid = "::3:1"; iid = "::3:1";
@@ -48,7 +47,7 @@ in
timeout = 10; timeout = 10;
}; };
kernelPackages = lib.my.c.kernel.latest pkgs; kernelPackages = lib.my.c.kernel.latest pkgs;
kernelModules = [ "kvm-amd" "dm-snapshot" ]; kernelModules = [ "kvm-amd" ];
kernelParams = [ "amd_iommu=on" "amd_pstate=passive" ]; kernelParams = [ "amd_iommu=on" "amd_pstate=passive" ];
kernelPatches = [ kernelPatches = [
# { # {
@@ -58,38 +57,27 @@ in
# } # }
]; ];
initrd = { initrd = {
availableKernelModules = [ availableKernelModules = [ "thunderbolt" "xhci_pci" "nvme" "ahci" "usbhid" "usb_storage" "sd_mod" ];
"thunderbolt" "xhci_pci" "nvme" "ahci" "usbhid" "usb_storage" "sd_mod"
"8021q"
] ++ roceBootModules;
systemd.network = {
netdevs = mkVLAN "lan-hi" vlans.hi;
networks = {
"10-et100g" = {
matchConfig.Name = "et100g";
vlan = [ "lan-hi" ];
linkConfig.RequiredForOnline = "no";
networkConfig = networkd.noL3;
};
"20-lan-hi" = networkdAssignment "lan-hi" assignments.hi;
};
};
}; };
}; };
fileSystems = { fileSystems = {
"/boot" = {
device = "/dev/disk/by-partuuid/8ce4248a-3ee4-f44f-801f-064a628b4d6e";
fsType = "vfat";
};
"/nix" = { "/nix" = {
device = "/dev/nvmeof/nix"; device = "/dev/disk/by-partuuid/2da23a1d-2daf-d943-b91e-fc175f3dad07";
fsType = "ext4"; fsType = "ext4";
}; };
"/persist" = { "/persist" = {
device = "/dev/nvmeof/persist"; device = "/dev/disk/by-partuuid/f4c80d4f-a022-e941-b5d1-fe2e65e444b9";
fsType = "ext4"; fsType = "ext4";
neededForBoot = true; neededForBoot = true;
}; };
"/home" = { "/home" = {
device = "/dev/nvmeof/home"; device = "/dev/disk/by-partuuid/992a93cf-6c9c-324b-b0ce-f8eb2d1ce10d";
fsType = "ext4"; fsType = "ext4";
}; };
}; };
@@ -113,12 +101,6 @@ in
dnssec = "false"; dnssec = "false";
}; };
pipewire.extraConfig.pipewire = {
"10-buffer"."context.properties" = {
"default.clock.quantum" = 128;
"default.clock.max-quantum" = 128;
};
};
blueman.enable = true; blueman.enable = true;
}; };
@@ -132,7 +114,7 @@ in
virtualisation.libvirtd.enable = true; virtualisation.libvirtd.enable = true;
networking = { networking = {
inherit domain; domain = "h.${lib.my.c.pubDomain}";
firewall.enable = false; firewall.enable = false;
}; };
@@ -149,6 +131,14 @@ in
qperf qperf
ethtool ethtool
]; ];
environment.etc = {
"pipewire/pipewire.conf.d/sample-size.conf".text = ''
context.properties = {
default.clock.quantum = 128
default.clock.max-quantum = 128
}
'';
};
nix = { nix = {
gc.automatic = false; gc.automatic = false;
@@ -156,6 +146,7 @@ in
systemd = { systemd = {
network = { network = {
wait-online.enable = false;
netdevs = mkMerge [ netdevs = mkMerge [
(mkVLAN "lan-hi" vlans.hi) (mkVLAN "lan-hi" vlans.hi)
]; ];
@@ -172,20 +163,29 @@ in
matchConfig.PermanentMACAddress = "24:8a:07:a8:fe:3a"; matchConfig.PermanentMACAddress = "24:8a:07:a8:fe:3a";
linkConfig = { linkConfig = {
Name = "et100g"; Name = "et100g";
MTUBytes = toString lib.my.c.home.hiMTU; MTUBytes = "9000";
}; };
}; };
}; };
networks = { networks = {
"30-et100g" = { "50-lan" = {
matchConfig.Name = "et2.5g";
DHCP = "no";
address = [ "10.16.7.1/16" ];
};
"50-et100g" = {
matchConfig.Name = "et100g"; matchConfig.Name = "et100g";
vlan = [ "lan-hi" ]; vlan = [ "lan-hi" ];
networkConfig.IPv6AcceptRA = false; networkConfig.IPv6AcceptRA = false;
}; };
"40-lan-hi" = mkMerge [ "60-lan-hi" = mkMerge [
(networkdAssignment "lan-hi" assignments.hi) (networkdAssignment "lan-hi" assignments.hi)
# So we don't drop the IP we use to connect to NVMe-oF! {
{ networkConfig.KeepConfiguration = "static"; } DHCP = "yes";
matchConfig.Name = "lan-hi";
linkConfig.MTUBytes = "9000";
}
]; ];
}; };
}; };
@@ -205,7 +205,10 @@ in
packages = with pkgs; [ packages = with pkgs; [
jacktrip jacktrip
qpwgraph qpwgraph
boardie # TODO: seems to be borked (infinite recursion???)
# (writeShellScriptBin "boardie" ''
# exec pw-jack ${boardie}/bin/boardie "$@"
# '')
]; ];
}; };
@@ -219,7 +222,6 @@ in
HDMI-A-1 = { HDMI-A-1 = {
transform = "270"; transform = "270";
position = "0 0"; position = "0 0";
bg = "${./his-team-player.jpg} fill";
}; };
DP-1 = { DP-1 = {
mode = "2560x1440@170Hz"; mode = "2560x1440@170Hz";
@@ -241,19 +243,11 @@ in
}; };
#deploy.generate.system.mode = "boot"; #deploy.generate.system.mode = "boot";
deploy.node.hostname = "castle.box.${config.networking.domain}";
secrets = { secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMlVuTzKObeaUuPocCF41IO/8X+443lzUJLuCIclt2vr"; key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMlVuTzKObeaUuPocCF41IO/8X+443lzUJLuCIclt2vr";
}; };
netboot.client = { nvme.uuid = "2230b066-a674-4f45-a1dc-f7727b3a9e7b";
enable = true;
};
nvme = {
uuid = "2230b066-a674-4f45-a1dc-f7727b3a9e7b";
boot = {
nqn = "nqn.2016-06.io.spdk:castle";
address = "192.168.68.80";
};
};
firewall = { firewall = {
enable = false; enable = false;

View File

@@ -1,7 +1,7 @@
{ lib, ... }: { lib, ... }:
let let
inherit (lib.my) net; inherit (lib.my) net;
inherit (lib.my.c.colony) domain prefixes custRouting firewallForwards; inherit (lib.my.c.colony) domain prefixes firewallForwards;
in in
{ {
imports = [ ./vms ]; imports = [ ./vms ];
@@ -60,8 +60,8 @@ in
kernelPackages = (lib.my.c.kernel.lts pkgs).extend (self: super: { kernelPackages = (lib.my.c.kernel.lts pkgs).extend (self: super: {
kernel = super.kernel.override { kernel = super.kernel.override {
structuredExtraConfig = with lib.kernel; { structuredExtraConfig = with lib.kernel; {
ACPI_APEI_PCIEAER = yes; #SOME_OPT = yes;
PCIEAER = yes; #A_MOD = module;
}; };
}; };
}); });
@@ -150,12 +150,12 @@ in
"serial-getty@ttyS1".enable = true; "serial-getty@ttyS1".enable = true;
lvm-activate-main = { lvm-activate-main = {
description = "Activate remaining LVs"; description = "Activate remaining LVs";
unitConfig.DefaultDependencies = false; before = [ "local-fs-pre.target" ];
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
ExecStart = "${pkgs.lvm2.bin}/bin/vgchange -aay main"; ExecStart = "${pkgs.lvm2.bin}/bin/vgchange -aay main";
}; };
wantedBy = [ "local-fs-pre.target" ]; wantedBy = [ "sysinit.target" ];
}; };
rsync-lvm-meta = { rsync-lvm-meta = {
@@ -276,10 +276,6 @@ in
Destination = lib.my.c.tailscale.prefix.v6; Destination = lib.my.c.tailscale.prefix.v6;
Gateway = allAssignments.shill.internal.ipv6.address; Gateway = allAssignments.shill.internal.ipv6.address;
} }
{
Destination = prefixes.jam.v6;
Gateway = allAssignments.shill.internal.ipv6.address;
}
{ {
Destination = prefixes.oci.v4; Destination = prefixes.oci.v4;
@@ -311,7 +307,7 @@ in
"90-vm-mail" = { "90-vm-mail" = {
matchConfig.Name = "vm-mail"; matchConfig.Name = "vm-mail";
address = [ address = [
"${custRouting.mail-vm}/32" (net.cidr.subnet 8 1 prefixes.cust.v4)
prefixes.mail.v6 prefixes.mail.v6
]; ];
networkConfig = { networkConfig = {
@@ -334,7 +330,7 @@ in
"90-vm-darts" = { "90-vm-darts" = {
matchConfig.Name = "vm-darts"; matchConfig.Name = "vm-darts";
address = [ address = [
"${custRouting.darts-vm}/32" (net.cidr.subnet 8 2 prefixes.cust.v4)
prefixes.darts.v6 prefixes.darts.v6
]; ];
networkConfig = { networkConfig = {

View File

@@ -29,9 +29,6 @@
}; };
in in
{ {
# Kernel Same-Page Merging to attempt memory usage reduction
hardware.ksm.enable = false;
systemd = { systemd = {
network = { network = {
links = { links = {
@@ -134,7 +131,6 @@
(vm.lvmDisk "media") (vm.lvmDisk "media")
(vm.lvmDisk "minio") (vm.lvmDisk "minio")
(vm.lvmDisk "nix-atticd") (vm.lvmDisk "nix-atticd")
(vm.lvmDisk "jam")
]); ]);
}; };
@@ -213,7 +209,6 @@
drives = [ drives = [
(mkMerge [ (vm.disk "darts" "root") { frontendOpts.bootindex = 0; } ]) (mkMerge [ (vm.disk "darts" "root") { frontendOpts.bootindex = 0; } ])
(vm.lvmDisk' "media" "darts-media") (vm.lvmDisk' "media" "darts-media")
(vm.lvmDisk' "ext" "darts-ext")
]; ];
}; };
}; };

View File

@@ -9,7 +9,6 @@ in
vpns = { vpns = {
l2 = { l2 = {
as211024 = { as211024 = {
udpEncapsulation = true;
vni = 211024; vni = 211024;
security.enable = true; security.enable = true;
peers = { peers = {
@@ -394,9 +393,6 @@ in
# Safe enough to allow all SSH # Safe enough to allow all SSH
tcp dport ssh accept tcp dport ssh accept
# jam-ctr forwards
ip daddr ${aa.shill.internal.ipv4.address} tcp dport 60022 accept
ip6 daddr ${aa.middleman.internal.ipv6.address} tcp dport { http, https, 8448 } accept ip6 daddr ${aa.middleman.internal.ipv6.address} tcp dport { http, https, 8448 } accept
${matchInet "tcp dport { http, https } accept" "git"} ${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, 25575 } accept

View File

@@ -2,7 +2,7 @@
let let
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.my) net; inherit (lib.my) net;
inherit (lib.my.c.colony) prefixes custRouting; inherit (lib.my.c.colony) prefixes;
authZones = attrNames config.my.pdns.auth.bind.zones; authZones = attrNames config.my.pdns.auth.bind.zones;
in in
@@ -162,10 +162,6 @@ in
andrey-cust IN A ${allAssignments.kelder.estuary.ipv4.address} andrey-cust IN A ${allAssignments.kelder.estuary.ipv4.address}
jam-cust IN A ${net.cidr.host 0 prefixes.jam.v4}
jam-fwd IN A ${allAssignments.shill.internal.ipv4.address}
jam-cust IN AAAA ${net.cidr.host 1 prefixes.jam.v6}
$TTL 3 $TTL 3
_acme-challenge IN LUA TXT @@FILE@@ _acme-challenge IN LUA TXT @@FILE@@

View File

@@ -102,6 +102,34 @@ in
services = { services = {
fstrim = lib.my.c.colony.fstrimConfig; fstrim = lib.my.c.colony.fstrimConfig;
# Hacks for Jsch (Minecraft FastBack) to work
openssh = {
hostKeys = [
{
bits = 4096;
path = "/etc/ssh/ssh_host_rsa_key";
type = "rsa";
}
{
path = "/etc/ssh/ssh_host_ed25519_key";
type = "ed25519";
}
{
type = "ecdsa-sha2-nistp256";
path = "/etc/ssh/ssh_host_ecdsa_key";
}
];
settings = {
Macs = [
"hmac-sha2-512-etm@openssh.com"
"hmac-sha2-256-etm@openssh.com"
"umac-128-etm@openssh.com"
"hmac-sha2-256"
];
};
};
netdata.enable = true; netdata.enable = true;
nginx = { nginx = {
enable = true; enable = true;

View File

@@ -1,105 +0,0 @@
{ lib, pkgs, assignments, ... }:
let
inherit (lib.my) net;
inherit (lib.my.c.colony) prefixes custRouting;
in
{
fileSystems = {
"/mnt/jam" = {
device = "/dev/disk/by-label/jam";
fsType = "ext4";
};
"/var/lib/machines/jam" = {
device = "/mnt/jam";
options = [ "bind" ];
};
};
systemd = {
nspawn = {
jam = {
enable = true;
execConfig = {
Boot = true;
PrivateUsers = "pick";
LinkJournal = false;
};
networkConfig = {
Private = true;
VirtualEthernet = true;
};
};
};
network.networks = {
"50-ve-jam" = {
matchConfig = {
Kind = "veth";
Name = "ve-jam";
};
address = [
custRouting.jam-ctr
prefixes.jam.v6
];
networkConfig = {
IPv6AcceptRA = false;
IPv6SendRA = true;
};
ipv6Prefixes = [
{
ipv6PrefixConfig.Prefix = prefixes.jam.v6;
}
];
routes = map (r: { routeConfig = r; }) [
{
Destination = prefixes.jam.v4;
Scope = "link";
}
];
};
};
services = {
"systemd-nspawn@jam" = {
overrideStrategy = "asDropin";
serviceConfig = {
CPUQuota = "400%";
MemoryHigh = "infinity";
MemoryMax = "4G";
};
wantedBy = [ "machines.target" ];
};
};
};
my = {
firewall =
let
jamIP = net.cidr.host 0 prefixes.jam.v4;
in
{
nat.forwardPorts."${assignments.internal.ipv4.address}" = [
{
port = 60022;
dst = jamIP;
dstPort = "ssh";
}
];
extraRules = ''
table inet filter {
chain forward {
iifname { ve-jam } oifname vms accept
iifname vms oifname { ve-jam } accept
}
}
table inet nat {
chain postrouting {
ip saddr ${jamIP} snat to ${assignments.internal.ipv4.address}
}
}
'';
};
};
}

View File

@@ -24,7 +24,7 @@ in
configuration = { lib, pkgs, config, assignments, allAssignments, ... }: configuration = { lib, pkgs, config, assignments, allAssignments, ... }:
let let
inherit (lib) genAttrs mkMerge mkIf mkForce; inherit (lib) mkMerge mkIf mkForce;
inherit (lib.my) networkdAssignment; inherit (lib.my) networkdAssignment;
in in
{ {
@@ -45,28 +45,10 @@ in
owner = "matrix-synapse"; owner = "matrix-synapse";
group = "matrix-synapse"; group = "matrix-synapse";
}; };
"chatterbox/doublepuppet.yaml" = {
owner = "matrix-synapse";
group = "matrix-synapse";
};
"chatterbox/syncv3.env" = { "chatterbox/syncv3.env" = {
owner = "matrix-syncv3"; owner = "matrix-syncv3";
group = "matrix-syncv3"; group = "matrix-syncv3";
}; };
"chatterbox/mautrix-whatsapp.env" = {
owner = "mautrix-whatsapp";
group = "mautrix-whatsapp";
};
"chatterbox/mautrix-messenger.env" = {
owner = "mautrix-meta-messenger";
group = "mautrix-meta";
};
"chatterbox/mautrix-instagram.env" = {
owner = "mautrix-meta-instagram";
group = "mautrix-meta";
};
}; };
}; };
@@ -77,9 +59,6 @@ in
users = with lib.my.c.ids; { users = with lib.my.c.ids; {
users = { users = {
matrix-synapse.extraGroups = [
"mautrix-whatsapp"
];
matrix-syncv3 = { matrix-syncv3 = {
isSystemUser = true; isSystemUser = true;
uid = uids.matrix-syncv3; uid = uids.matrix-syncv3;
@@ -100,10 +79,7 @@ in
User = "matrix-syncv3"; User = "matrix-syncv3";
Group = "matrix-syncv3"; Group = "matrix-syncv3";
}; };
} // (genAttrs [ "mautrix-whatsapp" "mautrix-meta-messenger" "mautrix-meta-instagram" ] (_: { };
# ffmpeg needed to convert GIFs to video
path = with pkgs; [ ffmpeg ];
}));
}; };
services = { services = {
@@ -192,19 +168,17 @@ in
app_service_config_files = [ app_service_config_files = [
"/var/lib/heisenbridge/registration.yml" "/var/lib/heisenbridge/registration.yml"
config.age.secrets."chatterbox/doublepuppet.yaml".path
"/var/lib/mautrix-whatsapp/whatsapp-registration.yaml"
]; ];
}; };
}; sliding-sync = {
matrix-sliding-sync = { enable = true;
enable = true; createDatabase = false;
createDatabase = false; environmentFile = config.age.secrets."chatterbox/syncv3.env".path;
environmentFile = config.age.secrets."chatterbox/syncv3.env".path; settings = {
settings = { SYNCV3_BINDADDR = "[::]:8009";
SYNCV3_BINDADDR = "[::]:8009"; SYNCV3_SERVER = "http://localhost:8008";
SYNCV3_SERVER = "http://localhost:8008"; };
}; };
}; };
@@ -221,140 +195,6 @@ in
]; ];
}; };
}; };
mautrix-whatsapp = {
enable = true;
environmentFile = config.age.secrets."chatterbox/mautrix-whatsapp.env".path;
settings = {
homeserver = {
address = "http://localhost:8008";
domain = "nul.ie";
};
appservice = {
database = {
type = "postgres";
uri = "$MAU_WAPP_PSQL_URI";
};
id = "whatsapp2";
bot = {
username = "whatsapp2";
displayname = "WhatsApp Bridge Bot";
};
};
bridge = {
username_template = "wapp2_{{.}}";
displayname_template = "{{or .BusinessName .PushName .JID}} (WA)";
personal_filtering_spaces = true;
delivery_receipts = true;
allow_user_invite = true;
url_previews = true;
command_prefix = "!wa";
login_shared_secret_map."nul.ie" = "$MAU_WAPP_DOUBLE_PUPPET_TOKEN";
encryption = {
allow = true;
default = true;
require = true;
};
permissions = {
"@dev:nul.ie" = "admin";
};
};
};
};
mautrix-meta.instances = {
messenger = {
enable = true;
registerToSynapse = true;
dataDir = "mautrix-messenger";
environmentFile = config.age.secrets."chatterbox/mautrix-messenger.env".path;
settings = {
homeserver = {
address = "http://localhost:8008";
domain = "nul.ie";
};
appservice = {
database = {
type = "postgres";
uri = "$MAU_FBM_PSQL_URI";
};
id = "fbm2";
bot = {
username = "messenger2";
displayname = "Messenger Bridge Bot";
avatar = "mxc://maunium.net/ygtkteZsXnGJLJHRchUwYWak";
};
};
meta.mode = "messenger";
bridge = {
username_template = "fbm2_{{.}}";
displayname_template = ''{{or .DisplayName .Username "Unknown user"}} (FBM)'';
personal_filtering_spaces = true;
delivery_receipts = true;
management_room_text.welcome = "Hello, I'm a Messenger bridge bot.";
command_prefix = "!fbm";
login_shared_secret_map."nul.ie" = "$MAU_FBM_DOUBLE_PUPPET_TOKEN";
backfill = {
history_fetch_pages = 5;
};
encryption = {
allow = true;
default = true;
require = true;
};
permissions = {
"@dev:nul.ie" = "admin";
};
};
};
};
instagram = {
enable = true;
registerToSynapse = true;
dataDir = "mautrix-instagram";
environmentFile = config.age.secrets."chatterbox/mautrix-instagram.env".path;
settings = {
homeserver = {
address = "http://localhost:8008";
domain = "nul.ie";
};
appservice = {
database = {
type = "postgres";
uri = "$MAU_IG_PSQL_URI";
};
id = "instagram";
bot = {
username = "instagram";
displayname = "Instagram Bridge Bot";
avatar = "mxc://maunium.net/JxjlbZUlCPULEeHZSwleUXQv";
};
};
meta.mode = "instagram";
bridge = {
username_template = "ig_{{.}}";
displayname_template = ''{{or .DisplayName .Username "Unknown user"}} (IG)'';
personal_filtering_spaces = true;
delivery_receipts = true;
management_room_text.welcome = "Hello, I'm an Instagram bridge bot.";
command_prefix = "!ig";
login_shared_secret_map."nul.ie" = "$MAU_IG_DOUBLE_PUPPET_TOKEN";
backfill = {
history_fetch_pages = 5;
};
encryption = {
allow = true;
default = true;
require = true;
};
permissions = {
"@dev:nul.ie" = "admin";
};
};
};
};
};
}; };
} }
(mkIf config.my.build.isDevVM { (mkIf config.my.build.isDevVM {

View File

@@ -1,8 +1,6 @@
{ lib, ... }: { lib, ... }:
let let
inherit (lib) concatStringsSep;
inherit (lib.my) net; inherit (lib.my) net;
inherit (lib.my.c) pubDomain;
inherit (lib.my.c.colony) domain prefixes; inherit (lib.my.c.colony) domain prefixes;
in in
{ {
@@ -37,9 +35,6 @@ in
secrets = { secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPUv1ntVrZv5ripsKpcOAnyDQX2PHjowzyhqWK10Ml53"; key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPUv1ntVrZv5ripsKpcOAnyDQX2PHjowzyhqWK10Ml53";
files = {
"jackflix/photoprism-pass.txt" = {};
};
}; };
}; };
@@ -55,16 +50,10 @@ in
uid = uids.jellyseerr; uid = uids.jellyseerr;
group = "jellyseerr"; group = "jellyseerr";
}; };
photoprism = {
isSystemUser = true;
uid = uids.photoprism;
group = "photoprism";
};
}; };
groups = { groups = {
media.gid = 2000; media.gid = 2000;
jellyseerr.gid = gids.jellyseerr; jellyseerr.gid = gids.jellyseerr;
photoprism.gid = gids.photoprism;
}; };
}; };
@@ -87,10 +76,6 @@ in
RootDirectoryStartOnly = lib.mkForce false; RootDirectoryStartOnly = lib.mkForce false;
RootDirectory = lib.mkForce ""; RootDirectory = lib.mkForce "";
}; };
photoprism.serviceConfig = {
# Needs to be able to access its data
DynamicUser = mkForce false;
};
}; };
}; };
@@ -132,24 +117,6 @@ in
}; };
jellyfin.enable = true; jellyfin.enable = true;
photoprism = {
enable = true;
address = "[::]";
port = 2342;
originalsPath = "/mnt/media/photoprism/originals";
importPath = "/mnt/media/photoprism/import";
passwordFile = config.age.secrets."jackflix/photoprism-pass.txt".path;
settings = {
PHOTOPRISM_AUTH_MODE = "password";
PHOTOPRISM_ADMIN_USER = "dev";
PHOTOPRISM_APP_NAME = "/dev/player0 Photos";
PHOTOPRISM_SITE_URL = "https://photos.${pubDomain}/";
PHOTOPRISM_SITE_TITLE = "/dev/player0 Photos";
PHOTOPRISM_TRUSTED_PROXY = concatStringsSep "," (with prefixes.ctrs; [ v4 v6 ]);
PHOTOPRISM_DATABASE_DRIVER = "sqlite";
};
};
}; };
}; };
}; };

View File

@@ -37,7 +37,7 @@ in
tcp dport ${toString transmissionPeerPort} accept tcp dport ${toString transmissionPeerPort} accept
iifname vpn return iifname vpn return
tcp dport { 19999, 9091, 9117, 7878, 8989, 8096, 2342 } accept tcp dport { 19999, 9091, 9117, 7878, 8989, 8096 } accept
return return
} }
chain input { chain input {

View File

@@ -206,8 +206,7 @@ in
# Currently it seems like single quotes aren't escaped like they should be... # Currently it seems like single quotes aren't escaped like they should be...
conf = { conf = {
brand = "/dev/player0 Matrix"; brand = "/dev/player0 Matrix";
show_labs_settings = true; showLabsSettings = true;
default_country_code = "IE";
disable_guests = true; disable_guests = true;
default_server_config = { default_server_config = {
"m.homeserver" = { "m.homeserver" = {
@@ -215,8 +214,9 @@ in
server_name = "nul.ie"; server_name = "nul.ie";
}; };
}; };
room_directory.servers = [ roomDirectory.servers = [
"nul.ie" "nul.ie"
"netsoc.ie"
"matrix.org" "matrix.org"
]; ];
}; };
@@ -364,7 +364,7 @@ in
useACMEHost = pubDomain; useACMEHost = pubDomain;
}; };
"mc-rail.${pubDomain}" = { "mc-rail.${pubDomain}" = {
locations."/".proxyPass = "http://simpcraft-oci.${domain}:3876"; locations."/".proxyPass = "http://simpcraft-staging-oci.${domain}:3876";
useACMEHost = pubDomain; useACMEHost = pubDomain;
}; };
@@ -384,18 +384,6 @@ in
}; };
useACMEHost = pubDomain; useACMEHost = pubDomain;
}; };
"pb.${pubDomain}" = {
locations."/".proxyPass = "http://object-ctr.${domain}:8088";
useACMEHost = pubDomain;
};
"photos.${pubDomain}" = {
locations."/" = {
proxyPass = "http://jackflix-ctr.${domain}:2342";
proxyWebsockets = true;
extraConfig = proxyHeaders;
};
useACMEHost = pubDomain;
};
}; };
minio = minio =

View File

@@ -49,7 +49,6 @@ in
}; };
"object/atticd.env" = {}; "object/atticd.env" = {};
"object/hedgedoc.env" = {}; "object/hedgedoc.env" = {};
"object/wastebin.env" = {};
}; };
}; };
@@ -59,7 +58,6 @@ in
config.services.sharry.config.bind.port config.services.sharry.config.bind.port
8069 8069
config.services.hedgedoc.settings.port config.services.hedgedoc.settings.port
8088
]; ];
}; };
@@ -222,15 +220,6 @@ in
allowEmailRegister = false; allowEmailRegister = false;
}; };
}; };
wastebin = {
enable = true;
settings = {
WASTEBIN_MAX_BODY_SIZE = 67108864; # 16 MiB
WASTEBIN_PASSWORD_SALT = "TeGhaemeer0Siez3";
};
secretFile = config.age.secrets."object/wastebin.env".path;
};
}; };
} }
(mkIf config.my.build.isDevVM { (mkIf config.my.build.isDevVM {

View File

@@ -49,11 +49,7 @@ in
inherit (lib.my) networkdAssignment; inherit (lib.my) networkdAssignment;
in in
{ {
imports = [ imports = [ "${modulesPath}/profiles/qemu-guest.nix" ];
"${modulesPath}/profiles/qemu-guest.nix"
./containers-ext.nix
];
config = mkMerge [ config = mkMerge [
{ {

View File

@@ -108,30 +108,45 @@ in
oci-containers = { oci-containers = {
backend = "podman"; backend = "podman";
}; };
containers.containersConf.settings.network = { # NixOS has switched to using netavark, which is native to podman. It's currently missing an option to
network_backend = "netavark"; # disable iptables rules generation, which is very annoying.
firewall_driver = "none"; containers.containersConf.settings.network.network_backend = mkForce "cni";
};
}; };
environment = { environment = {
etc = { etc = {
"containers/networks/colony.json".text = toJSON { "cni/net.d/90-colony.conflist".text = toJSON {
cniVersion = "0.4.0";
name = "colony"; name = "colony";
id = "0000000000000000000000000000000000000000000000000000000000000001"; plugins = [
driver = "bridge";
network_interface = "oci";
ipv6_enabled = true;
internal = false;
dns_enabled = false;
subnets = [
{ {
subnet = prefixes.oci.v4; type = "bridge";
gateway = net.cidr.host 1 prefixes.oci.v4; bridge = "oci";
} isGateway = true;
{ ipMasq = false;
subnet = prefixes.oci.v6; hairpinMode = true;
gateway = net.cidr.host 1 prefixes.oci.v6; ipam = {
type = "host-local";
routes = [
{ dst = "0.0.0.0/0"; }
{ dst = "::/0"; }
];
ranges = [
[
{
subnet = prefixes.oci.v4;
gateway = net.cidr.host 1 prefixes.oci.v4;
}
]
[
{
subnet = prefixes.oci.v6;
gateway = net.cidr.host 1 prefixes.oci.v6;
}
]
];
};
capabilities.ips = true;
} }
]; ];
}; };

View File

@@ -25,20 +25,22 @@ let
email = "simpcraft@nul.ie" email = "simpcraft@nul.ie"
name = "Simpcraft bot" name = "Simpcraft bot"
''; '';
knownHosts = pkgs.writeText "known_hosts" ''
git.nul.ie ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBD023ECzYmLeXIpcGVaciPjq6UN/Sjmsys5HP/Nei5GkrUZqPa3OJ2uSXKLUSKGYdeNhxaFTPJe8Yx3TsZxMme8=
'';
}; };
in in
{ {
config = { config = {
virtualisation.oci-containers.containers = { virtualisation.oci-containers.containers = {
simpcraft = { simpcraft = {
image = "git.nul.ie/dev/craftblock:2024.1.0-java17-alpine"; image = "ghcr.io/itzg/minecraft-server:2023.12.2-java17-alpine";
environment = { environment = {
TYPE = "MODRINTH"; TYPE = "MODRINTH";
EULA = "true"; EULA = "true";
ENABLE_QUERY = "true"; ENABLE_QUERY = "true";
ENABLE_RCON = "true";
MOTD = "§4§k----- §9S§ai§bm§cp§dc§er§fa§6f§5t §4§k-----"; MOTD = "§4§k----- §9S§ai§bm§cp§dc§er§fa§6f§5t §4§k-----";
ICON = "/ext/icon.png"; ICON = "/ext/icon.png";
@@ -50,17 +52,15 @@ in
SPAWN_PROTECTION = "0"; SPAWN_PROTECTION = "0";
VIEW_DISTANCE = "20"; VIEW_DISTANCE = "20";
MAX_MEMORY = "8G"; MAX_MEMORY = "6G";
MODRINTH_MODPACK = "https://cdn.modrinth.com/data/CIYf3Hk8/versions/NGutsQSd/Simpcraft-0.2.1.mrpack"; MODRINTH_MODPACK = "https://cdn.modrinth.com/data/CIYf3Hk8/versions/cdj2bSKg/Simpcraft-0.1.2.mrpack";
TZ = "Europe/Dublin"; TZ = "Europe/Dublin";
}; };
environmentFiles = [ config.age.secrets."whale2/simpcraft.env".path ];
volumes = [ volumes = [
"minecraft_data:/data" "minecraft_data:/data"
"${./icon.png}:/ext/icon.png:ro" "${./icon.png}:/ext/icon.png:ro"
"${fastback.gitConfig}:/data/.config/git/config:ro"
]; ];
extraOptions = [ extraOptions = [
@@ -68,77 +68,53 @@ in
]; ];
}; };
# simpcraft-staging = { simpcraft-staging = {
# image = "git.nul.ie/dev/craftblock:2024.1.0-java17-alpine"; image = "git.nul.ie/dev/craftblock:2024.1.0-java17-alpine";
# environment = { environment = {
# TYPE = "MODRINTH"; TYPE = "MODRINTH";
# EULA = "true"; EULA = "true";
# ENABLE_QUERY = "true"; ENABLE_QUERY = "true";
# ENABLE_RCON = "true"; ENABLE_RCON = "true";
# MOTD = "§4§k----- §9S§ai§bm§cp§dc§er§fa§6f§5t [staging] §4§k-----"; MOTD = "§4§k----- §9S§ai§bm§cp§dc§er§fa§6f§5t [staging] §4§k-----";
# ICON = "/ext/icon.png"; ICON = "/ext/icon.png";
# EXISTING_WHITELIST_FILE = "SYNCHRONIZE"; EXISTING_WHITELIST_FILE = "SYNCHRONIZE";
# WHITELIST = whitelist; WHITELIST = whitelist;
# EXISTING_OPS_FILE = "SYNCHRONIZE"; EXISTING_OPS_FILE = "SYNCHRONIZE";
# OPS = op; OPS = op;
# DIFFICULTY = "normal"; DIFFICULTY = "normal";
# SPAWN_PROTECTION = "0"; SPAWN_PROTECTION = "0";
# VIEW_DISTANCE = "20"; VIEW_DISTANCE = "20";
# MAX_MEMORY = "4G"; MAX_MEMORY = "4G";
# MODRINTH_MODPACK = "https://cdn.modrinth.com/data/CIYf3Hk8/versions/Ym3sIi6H/Simpcraft-0.2.0.mrpack"; MODRINTH_MODPACK = "https://cdn.modrinth.com/data/CIYf3Hk8/versions/Ym3sIi6H/Simpcraft-0.2.0.mrpack";
# TZ = "Europe/Dublin"; TZ = "Europe/Dublin";
# };
# environmentFiles = [ config.age.secrets."whale2/simpcraft.env".path ];
# volumes = [
# "minecraft_staging_data:/data"
# "${./icon.png}:/ext/icon.png:ro"
# ];
# extraOptions = [
# ''--network=colony:${dockerNetAssignment allAssignments "simpcraft-staging-oci"}''
# ];
# };
};
services = {
borgbackup.jobs.simpcraft =
let
rconCommand = cmd: ''${pkgs.mcrcon}/bin/mcrcon -H simpcraft-oci -p "$RCON_PASSWORD" "${cmd}"'';
in
{
paths = [ "/var/lib/containers/storage/volumes/minecraft_data/_data/world" ];
repo = "/var/lib/containers/backup/simpcraft";
doInit = true;
encryption.mode = "none";
compression = "zstd,10";
# every ~15 minutes offset from 5 minute intervals (Minecraft seems to save at precise times?)
startAt = "*:03,17,33,47";
prune.keep = {
within = "12H";
hourly = 48;
}; };
environmentFiles = [ config.age.secrets."whale2/simpcraft.env".path ];
# Avoid Minecraft poking the files while we back up volumes = [
preHook = rconCommand "save-off"; "minecraft_staging_data:/data"
postHook = rconCommand "save-on"; "${./icon.png}:/ext/icon.png:ro"
}; "${fastback.gitConfig}:/data/.config/git/config:ro"
}; "${fastback.knownHosts}:/data/.ssh/known_hosts:ro"
"${config.age.secrets."whale2/simpcraft-git.key".path}:/data/.ssh/id_rsa"
];
systemd = { extraOptions = [
services = { ''--network=colony:${dockerNetAssignment allAssignments "simpcraft-staging-oci"}''
borgbackup-job-simpcraft.serviceConfig.EnvironmentFile = [ config.age.secrets."whale2/simpcraft.env".path ]; ];
}; };
}; };
my = { my = {
secrets.files = { secrets.files = {
"whale2/simpcraft.env" = {}; "whale2/simpcraft.env" = {};
"whale2/simpcraft-git.key" = {
owner = "1000";
};
}; };
}; };
}; };

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 MiB

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -148,33 +148,19 @@ in
}; };
}; };
}; };
nginx.enable = true;
}; };
networking = { inherit domain; }; networking.domain = "h.${pubDomain}";
systemd.services = systemd.services = {
let ipsec =
waitOnline = "systemd-networkd-wait-online@wan.service"; let
in waitOnline = "systemd-networkd-wait-online@wan.service";
{ in
ipsec = { {
after = [ waitOnline ]; after = [ waitOnline ];
requires = [ waitOnline ]; requires = [ waitOnline ];
}; };
ipv6-clear-default-route = {
description = "Clear IPv6 RA default route";
after = [ waitOnline ];
requires = [ waitOnline ];
script = ''
# Seems like we can sometimes pick up a default route somehow...
${pkgs.iproute2}/bin/ip -6 route del default via fe80::1 || true
'';
serviceConfig.Type = "oneshot";
wantedBy = [ "multi-user.target" ];
};
}; };
systemd.network = { systemd.network = {
@@ -228,7 +214,7 @@ in
extraConfig = '' extraConfig = ''
[CAKE] [CAKE]
Bandwidth=235M Bandwidth=235M
RTTSec=50ms RTTSec=10ms
PriorityQueueingPreset=besteffort PriorityQueueingPreset=besteffort
# DOCSIS preset # DOCSIS preset
OverheadBytes=18 OverheadBytes=18
@@ -252,7 +238,7 @@ in
[CAKE] [CAKE]
Parent=root Parent=root
Bandwidth=24M Bandwidth=24M
RTTSec=50ms RTTSec=1ms
''; '';
} }
]; ];
@@ -372,16 +358,6 @@ in
return return
} }
chain forward-early {
type filter hook forward priority -1; policy accept;
# MSS clamping to workaround IPv6 PMTUD being broken...
tcp flags syn tcp option maxseg size set rt mtu counter
# More Disney+ discrimination...
# TODO: This prefix could change (random AWS block)
ip6 daddr 2600:9000:2245::/48 drop
}
chain forward { chain forward {
${lib.my.c.as211024.nftTrust} ${lib.my.c.as211024.nftTrust}
iifname lan-untrusted jump filter-untrusted iifname lan-untrusted jump filter-untrusted

View File

@@ -61,19 +61,6 @@ in
webserver = true; webserver = true;
webserver-address = "::"; webserver-address = "::";
webserver-allow-from = [ "127.0.0.1" "::1" ]; webserver-allow-from = [ "127.0.0.1" "::1" ];
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
end
return false
end
'';
}; };
}; };
}; };
@@ -172,7 +159,6 @@ in
}} }}
${elemAt routers 0} IN AAAA ${net.cidr.host 1 prefixes.hi.v6} ${elemAt routers 0} IN AAAA ${net.cidr.host 1 prefixes.hi.v6}
${elemAt routers 1} IN AAAA ${net.cidr.host 2 prefixes.hi.v6} ${elemAt routers 1} IN AAAA ${net.cidr.host 2 prefixes.hi.v6}
boot IN CNAME river-hi.${config.networking.domain}.
@ IN NS ns1 @ IN NS ns1
@ IN NS ns2 @ IN NS ns2
@@ -196,10 +182,8 @@ in
dave-lo IN A ${net.cidr.host 11 prefixes.lo.v4} dave-lo IN A ${net.cidr.host 11 prefixes.lo.v4}
dave-lo IN AAAA ${net.cidr.host (65536+2) prefixes.lo.v6} dave-lo IN AAAA ${net.cidr.host (65536+2) prefixes.lo.v6}
shytzel IN A ${net.cidr.host 12 prefixes.core.v4} ;ap0 IN A ${net.cidr.host 12 prefixes.hi.v4}
;ap0 IN AAAA ${net.cidr.host (65536+3) prefixes.hi.v6}
wave IN A ${net.cidr.host 12 prefixes.hi.v4}
; wave IN AAAA ${net.cidr.host (65536+3) prefixes.hi.v6}
vibe IN A ${net.cidr.host 13 prefixes.hi.v4} vibe IN A ${net.cidr.host 13 prefixes.hi.v4}
vibe IN AAAA ${net.cidr.host (65536+4) prefixes.hi.v6} vibe IN AAAA ${net.cidr.host (65536+4) prefixes.hi.v6}

View File

@@ -1,7 +1,7 @@
index: { lib, pkgs, config, assignments, allAssignments, ... }: index: { lib, pkgs, assignments, ... }:
let let
inherit (lib) mkForce; inherit (lib) mkForce;
inherit (lib.my) net netbootKeaClientClasses; inherit (lib.my) net;
inherit (lib.my.c.home) domain prefixes vips hiMTU; inherit (lib.my.c.home) domain prefixes vips hiMTU;
dns-servers = [ dns-servers = [
@@ -26,11 +26,7 @@ in
}; };
systemd.services = { systemd.services = {
kea-dhcp4-server.serviceConfig = { kea-dhcp4-server.serviceConfig.DynamicUser = mkForce false;
# Sometimes interfaces might not be ready in time and Kea doesn't like that
Restart = "on-failure";
DynamicUser = mkForce false;
};
kea-dhcp-ddns-server.serviceConfig.DynamicUser = mkForce false; kea-dhcp-ddns-server.serviceConfig.DynamicUser = mkForce false;
}; };
@@ -63,14 +59,6 @@ in
always-send = true; always-send = true;
} }
]; ];
client-classes = netbootKeaClientClasses {
tftpIP = allAssignments.river.lo.ipv4.address;
hostname = "boot.${domain}";
systems = {
sfh = "52:54:00:a5:7e:93";
castle = "c8:7f:54:6e:17:0f";
};
};
subnet4 = [ subnet4 = [
{ {
id = 1; id = 1;

View File

@@ -1,83 +1,52 @@
index: { lib, pkgs, config, ... }: index: { lib, pkgs, config, ... }:
let let
inherit (builtins) attrNames concatMap length; inherit (builtins) attrNames concatMap;
inherit (lib) optional concatMapStringsSep; inherit (lib) optional;
inherit (lib.my) net; inherit (lib.my) net;
inherit (lib.my.c.home) prefixes vips; inherit (lib.my.c.home) prefixes vips;
pingScriptFor = name: ips:
let
script' = pkgs.writeShellScript
"keepalived-ping-${name}"
(concatMapStringsSep " || " (ip: "${pkgs.iputils}/bin/ping -qnc 1 -W 1 ${ip}") ips);
in
{
script = toString script';
interval = 1;
timeout = (length ips) + 1;
rise = 3;
fall = 3;
};
vlanIface = vlan: if vlan == "as211024" then vlan else "lan-${vlan}"; vlanIface = vlan: if vlan == "as211024" then vlan else "lan-${vlan}";
vrrpIPs = family: concatMap (vlan: (optional (family == "v6") { vrrpIPs = family: concatMap (vlan: [
addr = "fe80::1/64";
dev = vlanIface vlan;
}) ++ [
{ {
addr = "${vips.${vlan}.${family}}/${toString (net.cidr.length prefixes.${vlan}.${family})}"; addr = "${vips.${vlan}.${family}}/${toString (net.cidr.length prefixes.${vlan}.${family})}";
dev = vlanIface vlan; dev = vlanIface vlan;
} }
]) (attrNames vips); ] ++ (optional (family == "v6") {
addr = "fe80::1/64";
dev = vlanIface vlan;
})) (attrNames vips);
mkVRRP = family: routerId: { mkVRRP = family: routerId: {
state = if index == 0 then "MASTER" else "BACKUP"; state = if index == 0 then "MASTER" else "BACKUP";
interface = "lan-core"; interface = "lan-core";
priority = 255 - index; priority = 255 - index;
virtualRouterId = routerId; virtualRouterId = routerId;
virtualIps = vrrpIPs family; virtualIps = vrrpIPs family;
trackScripts = [ "${family}Alive" ]; extraConfig = ''
notify_master "${config.systemd.package}/bin/systemctl start radvd.service"
notify_backup "${config.systemd.package}/bin/systemctl stop radvd.service"
'';
}; };
in in
{ {
users = with lib.my.c.ids; {
users.keepalived_script = {
uid = uids.keepalived_script;
isSystemUser = true;
group = "keepalived_script";
};
groups.keepalived_script.gid = gids.keepalived_script;
};
services = { services = {
keepalived = { keepalived = {
enable = true; enable = true;
enableScriptSecurity = true;
extraGlobalDefs = '' extraGlobalDefs = ''
vrrp_version 3 vrrp_version 3
nftables keepalived nftables keepalived
''; '';
vrrpScripts = {
v4Alive = pingScriptFor "v4" [ "1.1.1.1" "8.8.8.8" "216.218.236.2" ];
v6Alive = pingScriptFor "v6" [ "2606:4700:4700::1111" "2001:4860:4860::8888" "2600::" ];
};
vrrpInstances = { vrrpInstances = {
v4 = mkVRRP "v4" 51; v4 = mkVRRP "v4" 51;
v6 = (mkVRRP "v6" 52) // { v6 = mkVRRP "v6" 52;
extraConfig = ''
notify_master "${config.systemd.package}/bin/systemctl start radvd.service" root
notify_backup "${config.systemd.package}/bin/systemctl stop radvd.service" root
'';
};
}; };
# Actually disable this for now, don't want to fault IPv4 just because IPv6 is broken... extraConfig = ''
# extraConfig = '' vrrp_sync_group main {
# vrrp_sync_group main { group {
# group { v4
# v4 v6
# v6 }
# } }
# } '';
# '';
}; };
}; };
} }

View File

@@ -123,7 +123,7 @@
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPYTB4zeAqotrEJ8M+AiGm/s9PFsWlAodz3hYSROGuDb"; key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPYTB4zeAqotrEJ8M+AiGm/s9PFsWlAodz3hYSROGuDb";
}; };
server.enable = true; server.enable = true;
# deploy.node.hostname = "192.168.68.2"; deploy.node.hostname = "192.168.68.2";
}; };
}; };
}; };

View File

@@ -65,13 +65,7 @@ in
systemd = { systemd = {
services = { services = {
jackett.bindsTo = [ "systemd-networkd-wait-online@vpn.service" ]; jackett.bindsTo = [ "systemd-networkd-wait-online@vpn.service" ];
transmission.bindsTo = [ "systemd-networkd-wait-online@vpn.service" ]; transmission.bindsTo = [ "systemd-networkd-wait-online@vpn.service" ];
# https://github.com/NixOS/nixpkgs/issues/258793#issuecomment-1748168206
transmission.serviceConfig = {
RootDirectoryStartOnly = lib.mkForce false;
RootDirectory = lib.mkForce "";
};
radarr.serviceConfig.UMask = "0002"; radarr.serviceConfig.UMask = "0002";
sonarr.serviceConfig.UMask = "0002"; sonarr.serviceConfig.UMask = "0002";

View File

@@ -2,7 +2,6 @@
let let
inherit (lib) mkMerge mkIf; inherit (lib) mkMerge mkIf;
inherit (lib.my) networkdAssignment; inherit (lib.my) networkdAssignment;
inherit (lib.my.c.kelder) ipv4MTU;
wg = { wg = {
keyFile = "kelder/acquisition/airvpn-privkey"; keyFile = "kelder/acquisition/airvpn-privkey";
@@ -90,7 +89,6 @@ in
(networkdAssignment "host0" assignments.internal) (networkdAssignment "host0" assignments.internal)
{ {
networkConfig.DNSDefaultRoute = false; networkConfig.DNSDefaultRoute = false;
linkConfig.MTUBytes = toString ipv4MTU;
} }
]; ];
"90-vpn" = with wg; { "90-vpn" = with wg; {

View File

@@ -92,17 +92,17 @@ in
nextcloud = { nextcloud = {
enable = true; enable = true;
package = pkgs.nextcloud29; package = pkgs.nextcloud28;
datadir = "/mnt/storage/nextcloud"; datadir = "/mnt/storage/nextcloud";
hostName = "cloud.${domain}"; hostName = "cloud.${domain}";
https = true; https = true;
config = { config = {
extraTrustedDomains = [ "cloud-local.${domain}" ];
adminpassFile = config.age.secrets."kelder/nextcloud-root.txt".path; adminpassFile = config.age.secrets."kelder/nextcloud-root.txt".path;
defaultPhoneRegion = "IE";
}; };
settings = { extraOptions = {
updatechecker = false; updatechecker = false;
trusted_domains = [ "cloud-local.${domain}" ];
default_phone_region = "IE";
}; };
}; };
}; };

View File

@@ -84,7 +84,6 @@ in
c c
]; ];
acquisition = "http://${allAssignments.kelder-acquisition.internal.ipv4.address}"; acquisition = "http://${allAssignments.kelder-acquisition.internal.ipv4.address}";
# This is kinda borked because Virgin Media filters DNS responses with local IPs...
localRedirect = to: '' localRedirect = to: ''
rewrite_by_lua_block { rewrite_by_lua_block {
if ngx.var.remote_addr == pub_ip then if ngx.var.remote_addr == pub_ip then
@@ -104,7 +103,7 @@ in
"monitor.${domain}" = withAuth { "monitor.${domain}" = withAuth {
serverAliases = [ "monitor-local.${domain}" ]; serverAliases = [ "monitor-local.${domain}" ];
# extraConfig = localRedirect "monitor-local.${domain}"; extraConfig = localRedirect "monitor-local.${domain}";
locations = { locations = {
"/" = { "/" = {
proxyPass = "http://${allAssignments.kelder.ctrs.ipv4.address}:19999"; proxyPass = "http://${allAssignments.kelder.ctrs.ipv4.address}:19999";
@@ -137,17 +136,17 @@ in
}; };
"torrents.${domain}" = withAuth { "torrents.${domain}" = withAuth {
serverAliases = [ "torrents-local.${domain}" ]; serverAliases = [ "torrents-local.${domain}" ];
# extraConfig = localRedirect "torrents-local.${domain}"; extraConfig = localRedirect "torrents-local.${domain}";
locations."/".proxyPass = "${acquisition}:9091"; locations."/".proxyPass = "${acquisition}:9091";
}; };
"jackett.${domain}" = withAuth { "jackett.${domain}" = withAuth {
serverAliases = [ "jackett-local.${domain}" ]; serverAliases = [ "jackett-local.${domain}" ];
# extraConfig = localRedirect "jackett-local.${domain}"; extraConfig = localRedirect "jackett-local.${domain}";
locations."/".proxyPass = "${acquisition}:9117"; locations."/".proxyPass = "${acquisition}:9117";
}; };
"radarr.${domain}" = withAuth { "radarr.${domain}" = withAuth {
serverAliases = [ "radarr-local.${domain}" ]; serverAliases = [ "radarr-local.${domain}" ];
# extraConfig = localRedirect "radarr-local.${domain}"; extraConfig = localRedirect "radarr-local.${domain}";
locations."/" = { locations."/" = {
proxyPass = "${acquisition}:7878"; proxyPass = "${acquisition}:7878";
proxyWebsockets = true; proxyWebsockets = true;
@@ -156,7 +155,7 @@ in
}; };
"sonarr.${domain}" = withAuth { "sonarr.${domain}" = withAuth {
serverAliases = [ "sonarr-local.${domain}" ]; serverAliases = [ "sonarr-local.${domain}" ];
# extraConfig = localRedirect "sonarr-local.${domain}"; extraConfig = localRedirect "sonarr-local.${domain}";
locations."/" = { locations."/" = {
proxyPass = "${acquisition}:8989"; proxyPass = "${acquisition}:8989";
proxyWebsockets = true; proxyWebsockets = true;

View File

@@ -1,7 +1,7 @@
{ lib, ... }: { lib, ... }:
let let
inherit (lib.my) net; inherit (lib.my) net;
inherit (lib.my.c.kelder) domain prefixes ipv4MTU; inherit (lib.my.c.kelder) domain prefixes;
in in
{ {
imports = [ ./containers ]; imports = [ ./containers ];
@@ -182,7 +182,7 @@ in
{ {
wireguardPeerConfig = { wireguardPeerConfig = {
PublicKey = "bP1XUNxp9i8NLOXhgPaIaRzRwi5APbam44/xjvYcyjU="; PublicKey = "bP1XUNxp9i8NLOXhgPaIaRzRwi5APbam44/xjvYcyjU=";
Endpoint = "${allAssignments.estuary.internal.ipv4.address}:${toString lib.my.c.kelder.vpn.port}"; Endpoint = "estuary-vm.${lib.my.c.colony.domain}:${toString lib.my.c.kelder.vpn.port}";
AllowedIPs = [ "0.0.0.0/0" ]; AllowedIPs = [ "0.0.0.0/0" ];
PersistentKeepalive = 25; PersistentKeepalive = 25;
}; };
@@ -200,7 +200,6 @@ in
"50-lan" = { "50-lan" = {
matchConfig.Name = "et1g0"; matchConfig.Name = "et1g0";
DHCP = "yes"; DHCP = "yes";
linkConfig.MTUBytes = toString ipv4MTU;
}; };
"80-ctrs" = mkMerge [ "80-ctrs" = mkMerge [
(networkdAssignment "ctrs" assignments.ctrs) (networkdAssignment "ctrs" assignments.ctrs)
@@ -273,7 +272,7 @@ in
config.name = "kontent"; config.name = "kontent";
}; };
# deploy.node.hostname = "192.168.0.69"; #deploy.node.hostname = "10.16.9.21";
secrets = { secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOFvUdJshXkqmchEgkZDn5rgtZ1NO9vbd6Px+S6YioWi"; key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOFvUdJshXkqmchEgkZDn5rgtZ1NO9vbd6Px+S6YioWi";
files = { files = {

View File

@@ -129,9 +129,10 @@
wifi = { wifi = {
backend = "wpa_supplicant"; backend = "wpa_supplicant";
}; };
settings = { extraConfig = ''
main.no-auto-default = "*"; [main]
}; no-auto-default=*
'';
}; };
}; };

View File

@@ -135,7 +135,6 @@ let
ipv6 = mkBoolOpt' false "Whether this mesh's underlay operates over IPv6."; ipv6 = mkBoolOpt' false "Whether this mesh's underlay operates over IPv6.";
baseMTU = mkOpt' ints.unsigned 1500 "Base MTU to calculate VXLAN MTU with."; baseMTU = mkOpt' ints.unsigned 1500 "Base MTU to calculate VXLAN MTU with.";
l3Overhead = mkOpt' ints.unsigned 40 "Overhead of L3 header (to calculate MTU)."; l3Overhead = mkOpt' ints.unsigned 40 "Overhead of L3 header (to calculate MTU).";
udpEncapsulation = mkBoolOpt' false "Whether to encapsulate ESP frames in UDP.";
firewall = mkBoolOpt' true "Whether to generate firewall rules."; firewall = mkBoolOpt' true "Whether to generate firewall rules.";
vni = mkOpt' ints.unsigned 1 "VXLAN VNI."; vni = mkOpt' ints.unsigned 1 "VXLAN VNI.";
peers = mkOpt' (attrsOf (submodule l2PeerOpts)) { } "Peers."; peers = mkOpt' (attrsOf (submodule l2PeerOpts)) { } "Peers.";

View File

@@ -1,7 +1,7 @@
{ {
nixos.systems.installer = { config, ... }: { nixos.systems.installer = { config, ... }: {
system = "x86_64-linux"; system = "x86_64-linux";
nixpkgs = "mine"; nixpkgs = "unstable";
docCustom = false; docCustom = false;
rendered = config.configuration.config.my.asISO; rendered = config.configuration.config.my.asISO;
@@ -52,8 +52,6 @@
home.shellAliases = { home.shellAliases = {
show-hw-config = "nixos-generate-config --show-hardware-config --root $INSTALL_ROOT"; show-hw-config = "nixos-generate-config --show-hardware-config --root $INSTALL_ROOT";
}; };
my.gui.enable = false;
}; };
services = { services = {
@@ -82,8 +80,6 @@
${pkgs.gawk}/bin/awk '{ print $1 }')" ${pkgs.gawk}/bin/awk '{ print $1 }')"
''; '';
boot.supportedFilesystems.nfs = true;
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
dhcpcd dhcpcd
lm_sensors lm_sensors

View File

@@ -20,6 +20,5 @@
nvme = ./nvme; nvme = ./nvme;
spdk = ./spdk.nix; spdk = ./spdk.nix;
librespeed = ./librespeed; librespeed = ./librespeed;
netboot = ./netboot;
}; };
} }

View File

@@ -1,6 +1,6 @@
{ lib, pkgs, extendModules, modulesPath, options, config, ... }: { lib, pkgs, extendModules, modulesPath, options, config, ... }:
let let
inherit (lib) recursiveUpdate mkOption mkDefault mkIf mkMerge mkForce flatten optional; inherit (lib) recursiveUpdate mkOption mkDefault mkIf mkMerge flatten optional;
inherit (lib.my) mkBoolOpt' dummyOption; inherit (lib.my) mkBoolOpt' dummyOption;
cfg = config.my.build; cfg = config.my.build;
@@ -43,145 +43,15 @@ let
modules = flatten [ modules = flatten [
"${modulesPath}/installer/netboot/netboot.nix" "${modulesPath}/installer/netboot/netboot.nix"
allHardware allHardware
];
};
asNetboot = extendModules {
modules = flatten [
allHardware
({ pkgs, config, ... }: { ({ pkgs, config, ... }: {
boot = { system.build.netbootArchive = pkgs.runCommand "netboot-${config.system.name}-archive.tar" { } ''
loader.grub.enable = false; ${pkgs.gnutar}/bin/tar -rvC "${config.system.build.kernel}" \
initrd = { -f "$out" "${config.system.boot.loader.kernelFile}"
kernelModules = [ "nbd" ]; ${pkgs.gnutar}/bin/tar -rvC "${config.system.build.netbootRamdisk}" \
availableKernelModules = [ "igb" "igc" ]; -f "$out" initrd
${pkgs.gnutar}/bin/tar -rvC "${config.system.build.netbootIpxeScript}" \
systemd = { -f "$out" netboot.ipxe
storePaths = with pkgs; [ '';
gnused
nbd
netcat
];
extraBin = with pkgs; {
dmesg = "${util-linux}/bin/dmesg";
ip = "${iproute2}/bin/ip";
nbd-client = "${nbd}/bin/nbd-client";
};
extraConfig = ''
DefaultTimeoutStartSec=20
DefaultDeviceTimeoutSec=20
'';
network = {
enable = true;
wait-online.enable = true;
networks."10-netboot" = {
matchConfig.Name = "et-boot";
DHCP = "yes";
};
};
services = {
nbd = {
description = "NBD Root FS";
script = ''
get_cmdline() {
${pkgs.gnused}/bin/sed -rn "s/^.*$1=(\\S+).*\$/\\1/p" < /proc/cmdline
}
s="$(get_cmdline nbd_server)"
until ${pkgs.netcat}/bin/nc -zv "$s" 22; do
sleep 0.1
done
exec ${pkgs.nbd}/bin/nbd-client -systemd-mark -N "$(get_cmdline nbd_export)" "$s" /dev/nbd0
'';
unitConfig = {
IgnoreOnIsolate = "yes";
DefaultDependencies = "no";
};
serviceConfig = {
Type = "forking";
Restart = "on-failure";
RestartSec = 10;
};
wantedBy = [ "initrd-root-device.target" ];
};
};
};
};
postBootCommands = ''
# After booting, register the contents of the Nix store
# in the Nix database in the COW root.
${config.nix.package}/bin/nix-store --load-db < /nix-path-registration
# nixos-rebuild also requires a "system" profile and an
# /etc/NIXOS tag.
touch /etc/NIXOS
${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
'';
};
programs.nbd.enable = true;
fileSystems = {
"/" = {
fsType = "ext4";
device = "/dev/nbd0";
noCheck = true;
autoResize = true;
};
};
networking.useNetworkd = mkForce true;
systemd = {
network.networks."10-boot" = {
matchConfig.Name = "et-boot";
DHCP = "yes";
networkConfig.KeepConfiguration = "yes";
};
};
system.build = {
rootImage = pkgs.callPackage "${modulesPath}/../lib/make-ext4-fs.nix" {
storePaths = [ config.system.build.toplevel ];
volumeLabel = "netboot-root";
};
netbootScript = pkgs.writeText "boot.ipxe" ''
#!ipxe
kernel ${pkgs.stdenv.hostPlatform.linux-kernel.target} init=${config.system.build.toplevel}/init initrd=initrd ifname=et-boot:''${mac} nbd_server=''${next-server} ${toString config.boot.kernelParams} ''${cmdline}
initrd initrd
boot
'';
netbootTree = pkgs.linkFarm "netboot-${config.system.name}" [
{
name = config.system.boot.loader.kernelFile;
path = "${config.system.build.kernel}/${config.system.boot.loader.kernelFile}";
}
{
name = "initrd";
path = "${config.system.build.initialRamdisk}/initrd";
}
{
name = "rootfs.ext4";
path = config.system.build.rootImage;
}
{
name = "boot.ipxe";
path = config.system.build.netbootScript;
}
];
netbootArchive = pkgs.runCommand "netboot-${config.system.name}.tar.zst" { } ''
export PATH=${pkgs.zstd}/bin:$PATH
${pkgs.gnutar}/bin/tar --dereference --zstd -cvC ${config.system.build.netbootTree} -f "$out" .
'';
};
}) })
]; ];
}; };
@@ -207,7 +77,6 @@ in
asISO = mkAsOpt asISO "a bootable .iso image"; asISO = mkAsOpt asISO "a bootable .iso image";
asContainer = mkAsOpt asContainer "a container"; asContainer = mkAsOpt asContainer "a container";
asKexecTree = mkAsOpt asKexecTree "a kexec-able kernel and initrd"; asKexecTree = mkAsOpt asKexecTree "a kexec-able kernel and initrd";
asNetboot = mkAsOpt asNetboot "a netboot-able kernel initrd, and iPXE script";
buildAs = options.system.build; buildAs = options.system.build;
}; };
@@ -241,8 +110,7 @@ in
iso = config.my.asISO.config.system.build.isoImage; iso = config.my.asISO.config.system.build.isoImage;
container = config.my.asContainer.config.system.build.toplevel; container = config.my.asContainer.config.system.build.toplevel;
kexecTree = config.my.asKexecTree.config.system.build.kexecTree; kexecTree = config.my.asKexecTree.config.system.build.kexecTree;
netbootTree = config.my.asNetboot.config.system.build.netbootTree; netbootArchive = config.my.asKexecTree.config.system.build.netbootArchive;
netbootArchive = config.my.asNetboot.config.system.build.netbootArchive;
}; };
}; };
}; };

View File

@@ -1,4 +1,4 @@
{ lib, pkgsFlake, pkgs, pkgs', inputs, config, ... }: { lib, pkgs, pkgs', inputs, config, ... }:
let let
inherit (lib) mkIf mkDefault mkMerge; inherit (lib) mkIf mkDefault mkMerge;
inherit (lib.my) mkDefault'; inherit (lib.my) mkDefault';
@@ -53,7 +53,7 @@ in
pkgs = { pkgs = {
to = { to = {
type = "path"; type = "path";
path = "${pkgsFlake}"; path = "${pkgs.path}";
}; };
exact = true; exact = true;
}; };

View File

@@ -1,6 +1,6 @@
{ lib, pkgs, options, config, systems, ... }: { lib, pkgs, options, config, systems, ... }:
let let
inherit (builtins) attrNames attrValues all hashString toJSON any; inherit (builtins) attrNames attrValues all hashString toJSON;
inherit (lib) inherit (lib)
groupBy' mapAttrsToList optionalString optional concatMapStringsSep filterAttrs mkOption mkDefault mkIf mkMerge; groupBy' mapAttrsToList optionalString optional concatMapStringsSep filterAttrs mkOption mkDefault mkIf mkMerge;
inherit (lib.my) mkOpt' mkBoolOpt'; inherit (lib.my) mkOpt' mkBoolOpt';
@@ -98,7 +98,6 @@ let
}; };
networking = { networking = {
bridge = mkOpt' (nullOr str) null "Network bridge to connect to."; bridge = mkOpt' (nullOr str) null "Network bridge to connect to.";
macVLAN = mkOpt' (nullOr str) null "Network interface to make MACVLAN interface from.";
}; };
}; };
}; };
@@ -116,19 +115,26 @@ in
assertion = config.systemd.network.enable; assertion = config.systemd.network.enable;
message = "Containers currently require systemd-networkd!"; message = "Containers currently require systemd-networkd!";
} }
{
assertion = all (i: i.networking.bridge == null || i.networking.macVLAN == null) (attrValues cfg.instances);
message = "Only bridge OR MACVLAN can be set";
}
]; ];
# TODO: Better security # TODO: Better security
my.firewall.trustedInterfaces = my.firewall.trustedInterfaces =
mapAttrsToList mapAttrsToList
(n: _: "ve-${n}") (n: _: "ve-${n}")
(filterAttrs (_: c: c.networking.bridge == null && c.networking.macVLAN == null) cfg.instances); (filterAttrs (_: c: c.networking.bridge == null) cfg.instances);
systemd = mkMerge (mapAttrsToList (n: c: { systemd = mkMerge ([
{
# By symlinking to the original systemd-nspawn@.service for every instance we force the unit generator to
# create overrides instead of replacing the unit entirely
packages = [
(pkgs.linkFarm "systemd-nspawn-containers" (map (n: {
name = "etc/systemd/system/systemd-nspawn@${n}.service";
path = "${pkgs.systemd}/example/systemd/system/systemd-nspawn@.service";
}) (attrNames cfg.instances)))
];
}
] ++ (mapAttrsToList (n: c: {
nspawn."${n}" = { nspawn."${n}" = {
execConfig = { execConfig = {
Boot = true; Boot = true;
@@ -159,8 +165,6 @@ in
}; };
networkConfig = if (c.networking.bridge != null) then { networkConfig = if (c.networking.bridge != null) then {
Bridge = c.networking.bridge; Bridge = c.networking.bridge;
} else if (c.networking.macVLAN != null) then {
MACVLAN = "${c.networking.macVLAN}:host0";
} else { } else {
VirtualEthernet = true; VirtualEthernet = true;
}; };
@@ -178,9 +182,6 @@ in
c.containerSystem; c.containerSystem;
in in
{ {
# To prevent creating a whole new unit file
overrideStrategy = "asDropin";
environment = { environment = {
# systemd.nspawn units can't set the root directory directly, but /run/machines/${n} is one of the search paths # systemd.nspawn units can't set the root directory directly, but /run/machines/${n} is one of the search paths
root = "/run/machines/${n}"; root = "/run/machines/${n}";
@@ -246,7 +247,7 @@ in
Bridge = c.networking.bridge; Bridge = c.networking.bridge;
}; };
}; };
}) cfg.instances); }) cfg.instances));
}) })
# Inside container # Inside container

View File

@@ -23,13 +23,13 @@ in
security = { security = {
polkit.enable = true; polkit.enable = true;
pam.services.swaylock-plugin = {}; pam.services.swaylock = {};
}; };
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
# for pw-jack # for pw-jack
pipewire.jack pipewire.jack
swaylock-plugin swaylock
]; ];
services = { services = {
pipewire = { pipewire = {
@@ -51,8 +51,6 @@ in
SUBSYSTEM=="usb", ATTR{idVendor}=="0955", MODE="0664", GROUP="wheel" SUBSYSTEM=="usb", ATTR{idVendor}=="0955", MODE="0664", GROUP="wheel"
# Nintendo # Nintendo
SUBSYSTEM=="usb", ATTR{idVendor}=="057e", MODE="0664", GROUP="wheel" SUBSYSTEM=="usb", ATTR{idVendor}=="057e", MODE="0664", GROUP="wheel"
# FT
SUBSYSTEM=="usb", ATTR{idVendor}=="0403", MODE="0664", GROUP="wheel"
''; '';
}; };
}; };

View File

@@ -36,8 +36,8 @@ let
espOverhead = espOverhead =
if (!mesh.security.enable) then 0 if (!mesh.security.enable) then 0
else else
# UDP encap + SPI + seq + IV + pad / header + ICV # SPI + seq + IV + pad / header + ICV
(if mesh.udpEncapsulation then 8 else 0) + 4 + 4 + (if mesh.security.encrypt then 8 else 0) + 2 + 16; 4 + 4 + (if mesh.security.encrypt then 8 else 0) + 2 + 16;
# UDP + VXLAN + Ethernet + L3 (IPv4/IPv6) # UDP + VXLAN + Ethernet + L3 (IPv4/IPv6)
overhead = espOverhead + 8 + 8 + 14 + mesh.l3Overhead; overhead = espOverhead + 8 + 8 + 14 + mesh.l3Overhead;
in in
@@ -62,11 +62,7 @@ let
chain l2mesh-${name} { chain l2mesh-${name} {
${optionalString mesh.security.enable '' ${optionalString mesh.security.enable ''
udp dport isakmp accept udp dport isakmp accept
${if mesh.udpEncapsulation then '' meta l4proto esp accept
udp dport ipsec-nat-t accept
'' else ''
meta l4proto esp accept
''}
''} ''}
${optionalString (!mesh.security.enable) (vxlanAllow mesh.vni)} ${optionalString (!mesh.security.enable) (vxlanAllow mesh.vni)}
return return
@@ -98,7 +94,6 @@ let
esp=${if mesh.security.encrypt then "aes_gcm256" else "null-sha256"} esp=${if mesh.security.encrypt then "aes_gcm256" else "null-sha256"}
ikev2=yes ikev2=yes
modecfgpull=no modecfgpull=no
encapsulation=${if mesh.udpEncapsulation then "yes" else "no"}
''; '';
}) })
otherPeers); otherPeers);

View File

@@ -1,223 +0,0 @@
{ lib, pkgs, config, ... }:
let
inherit (lib) mkMerge mkIf mkForce genAttrs concatMapStringsSep;
inherit (lib.my) mkOpt' mkBoolOpt';
cfg = config.my.netboot;
tftpRoot = pkgs.linkFarm "tftp-root" [
{
name = "ipxe-x86_64.efi";
path = "${pkgs.ipxe}/ipxe.efi";
}
];
menuFile = pkgs.runCommand "menu.ipxe" {
bootHost = cfg.server.host;
} ''
substituteAll ${./menu.ipxe} "$out"
'';
bootBuilder = pkgs.substituteAll {
src = ./netboot-loader-builder.py;
isExecutable = true;
inherit (pkgs) python3;
bootspecTools = pkgs.bootspec;
nix = config.nix.package.out;
inherit (config.system.nixos) distroName;
systemName = config.system.name;
inherit (cfg.client) configurationLimit;
checkMountpoints = pkgs.writeShellScript "check-mountpoints" ''
if ! ${pkgs.util-linuxMinimal}/bin/findmnt /boot > /dev/null; then
echo "/boot is not a mounted partition. Is the path configured correctly?" >&2
exit 1
fi
'';
};
in
{
options.my.netboot = with lib.types; {
client = {
enable = mkBoolOpt' false "Whether network booting should be enabled.";
configurationLimit = mkOpt' ints.unsigned 10 "Max generations to show in boot menu.";
};
server = {
enable = mkBoolOpt' false "Whether a netboot server should be enabled.";
ip = mkOpt' str null "IP clients should connect to via TFTP.";
host = mkOpt' str config.networking.fqdn "Hostname clients should connect to over HTTP / NFS.";
allowedPrefixes = mkOpt' (listOf str) null "Prefixes clients should be allowed to connect from (NFS).";
installer = {
storeSize = mkOpt' str "16GiB" "Total allowed writable size of store.";
};
instances = mkOpt' (listOf str) [ ] "Systems to hold boot files for.";
};
};
config = mkMerge [
(mkIf cfg.client.enable {
systemd = {
services = {
mount-boot = {
description = "Mount /boot";
after = [ "systemd-networkd-wait-online.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = with pkgs; [ gnused ldns nfs-utils ];
script = ''
get_cmdline() {
sed -rn "s/^.*$1=(\\S+).*\$/\\1/p" < /proc/cmdline
}
host="$(get_cmdline boothost)"
if [ -z "$host" ]; then
echo "boothost kernel parameter not found!" >&2
exit 1
fi
until [ -n "$(drill -Q $host)" ]; do
sleep 0.1
done
mkdir -p /boot
mount.nfs $host:/srv/netboot/systems/${config.system.name} /boot
'';
wantedBy = [ "remote-fs.target" ];
};
};
};
boot.supportedFilesystems.nfs = true;
boot.loader = {
grub.enable = false;
systemd-boot.enable = false;
};
system = {
build.installBootLoader = bootBuilder;
boot.loader.id = "ipxe-netboot";
};
})
(mkIf cfg.server.enable {
environment = {
etc = {
"netboot/menu.ipxe".source = menuFile;
"netboot/shell.efi".source = "${pkgs.edk2-uefi-shell}/shell.efi";
};
};
systemd = {
tmpfiles.settings."10-netboot" = genAttrs
(map (i: "/srv/netboot/systems/${i}") cfg.server.instances)
(p: {
d = {
user = "root";
group = "root";
mode = "0777";
};
});
services = {
netboot-update = {
description = "Update netboot images";
after = [ "systemd-networkd-wait-online.service" ];
serviceConfig.Type = "oneshot";
path = with pkgs; [
coreutils curl jq zstd gnutar
];
script = ''
update_nixos() {
latestShort="$(curl -s https://git.nul.ie/api/v1/repos/dev/nixfiles/tags/installer \
| jq -r .commit.sha | cut -c -7)"
if [ -f nixos-installer/tag.txt ] && [ "$(< nixos-installer/tag.txt)" = "$latestShort" ]; then
echo "NixOS installer is up to date"
return
fi
echo "Updating NixOS installer to $latestShort"
mkdir -p nixos-installer
fname="jackos-installer-netboot-$latestShort.tar.zst"
downloadUrl="$(curl -s https://git.nul.ie/api/v1/repos/dev/nixfiles/releases/tags/installer | \
jq -r ".assets[] | select(.name == \"$fname\").browser_download_url")"
curl -Lo /tmp/nixos-installer-netboot.tar.zst "$downloadUrl"
tar -C nixos-installer --zstd -xf /tmp/nixos-installer-netboot.tar.zst
truncate -s "${cfg.server.installer.storeSize}" nixos-installer/rootfs.ext4
rm /tmp/nixos-installer-netboot.tar.zst
echo "$latestShort" > nixos-installer/tag.txt
}
mkdir -p /srv/netboot
cd /srv/netboot
ln -sf ${menuFile} boot.ipxe
ln -sf "${pkgs.edk2-uefi-shell}/shell.efi" "efi-shell-${config.nixpkgs.localSystem.linuxArch}.efi"
update_nixos
'';
startAt = "06:00";
wantedBy = [ "network-online.target" ];
};
nbd-server = {
serviceConfig = {
PrivateUsers = mkForce false;
CacheDirectory = "netboot";
};
};
};
};
services = {
atftpd = {
enable = true;
root = tftpRoot;
};
nginx = {
virtualHosts."${cfg.server.host}" = {
locations."/" = {
root = "/srv/netboot";
extraConfig = ''
autoindex on;
'';
};
};
};
nbd.server = {
enable = true;
extraOptions = {
allowlist = true;
};
exports = {
nixos-installer = {
path = "/srv/netboot/nixos-installer/rootfs.ext4";
extraOptions = {
copyonwrite = true;
cowdir = "/var/cache/netboot";
sparse_cow = true;
};
};
};
};
nfs = {
server = {
enable = true;
exports = ''
/srv/netboot/systems ${concatMapStringsSep " " (p: "${p}(rw,all_squash)") cfg.server.allowedPrefixes}
'';
};
};
};
my = {
tmproot.persistence.config.directories = [
"/srv/netboot"
{ directory = "/var/cache/netboot"; mode = "0700"; }
];
};
})
];
}

View File

@@ -1,68 +0,0 @@
#!ipxe
set server http://@bootHost@
# Figure out if client is 64-bit capable
cpuid --ext 29 && set arch x86_64 || set arch i386
isset ${menu-default} || set menu-default exit
:start
menu Welcome to /dev/player0's humble iPXE boot menu
item --gap -- Operating Systems
iseq ${arch} x86_64 &&
item --key n nixos NixOS installer
# iseq ${arch} x86_64 &&
# item --key a archlinux Arch Linux (archiso x86_64)
# iseq ${arch} x86_64 &&
# item --key p alpine Alpine Linux
item --gap -- Other Options
item --key e efi_shell UEFI Shell
item --key x xyz netboot.xyz
item --key c config iPXE settings
item --key s shell Drop to iPXE shell
item --key r reboot Reboot
item --key q exit Exit (and continue to next boot device)
choose --timeout 0 --default ${menu-default} selected || goto cancel
goto ${selected}
:cancel
echo You cancelled the menu, dropping you to an iPXE shell
:shell
echo Type 'exit' to go back to the menu
shell
set menu-default nixos
goto start
:failed
echo Booting failed, dropping to shell
goto shell
:reboot
reboot
:exit
exit
:config
config
set menu-default config
goto start
:efi_shell
chain ${server}/efi-shell-${arch}.efi || goto failed
:xyz
chain --autofree https://boot.netboot.xyz || goto failed
:nixos
set cmdline nbd_export=nixos-installer
chain ${server}/nixos-installer/boot.ipxe || goto failed
:archlinux
# set mirrorurl https://arch.nul.ie/
chain ${server}/arch.ipxe || goto failed
:alpine
chain ${server}/alpine.ipxe || goto failed

View File

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

View File

@@ -6,7 +6,7 @@ let
cfg = config.my.nvme; cfg = config.my.nvme;
nvme-cli = pkgs.nvme-cli.override { nvme-cli = pkgs.nvme-cli.override {
libnvme = pkgs.libnvme.overrideAttrs (o: { libnvme = pkgs.libnvme.overrideAttrs (o: {
patches = (if (o ? patches) then o.patches else [ ]) ++ [ ./libnvme-hostconf.patch ]; patches = o.patches ++ [ ./libnvme-hostconf.patch ];
}); });
}; };
@@ -33,43 +33,24 @@ in
etc = etc ""; etc = etc "";
}; };
boot = mkIf (cfg.boot.nqn != null) { boot.initrd.systemd = mkIf (cfg.boot.nqn != null) {
initrd = { contents = etc "/etc/";
availableKernelModules = [ "rdma_cm" "iw_cm" "ib_cm" "nvme_core" "nvme_rdma" ]; extraBin.nvme = "${nvme-cli}/bin/nvme";
kernelModules = [ "nvme-fabrics" ];
systemd = {
contents = etc "/etc/";
extraBin = with pkgs; {
dmesg = "${util-linux}/bin/dmesg";
ip = "${iproute2}/bin/ip";
nvme = "${nvme-cli}/bin/nvme";
};
extraConfig = ''
DefaultTimeoutStartSec=20
DefaultDeviceTimeoutSec=20
'';
network = { services.connect-nvme = {
enable = true; description = "Connect NVMe-oF";
wait-online.enable = true; before = [ "initrd-root-device.target" ];
}; after = [ "systemd-networkd-wait-online.service" ];
requires = [ "systemd-networkd-wait-online.service" ];
services.connect-nvme = { serviceConfig = {
description = "Connect NVMe-oF"; Type = "oneshot";
before = [ "initrd-root-device.target" ]; ExecStart = "${nvme-cli}/bin/nvme connect -t rdma -a ${cfg.boot.address} -n ${cfg.boot.nqn}";
after = [ "systemd-networkd-wait-online.service" ]; Restart = "on-failure";
requires = [ "systemd-networkd-wait-online.service" ]; RestartSec = 10;
serviceConfig = {
Type = "oneshot";
ExecStart = "${nvme-cli}/bin/nvme connect -t rdma -a ${cfg.boot.address} -n ${cfg.boot.nqn}";
Restart = "on-failure";
RestartSec = 10;
};
wantedBy = [ "initrd-root-device.target" ];
};
}; };
wantedBy = [ "initrd-root-device.target" ];
}; };
}; };
}; };

View File

@@ -2,7 +2,7 @@
let let
inherit (lib) inherit (lib)
optionalString concatStringsSep concatMap concatMapStringsSep mkIf mkDefault mkMerge mkForce mkVMOverride optionalString concatStringsSep concatMap concatMapStringsSep mkIf mkDefault mkMerge mkForce mkVMOverride
mkAliasDefinitions mapAttrsToList filterAttrs; mkAliasDefinitions;
inherit (lib.my) mkOpt' mkBoolOpt' mkVMOverride'; inherit (lib.my) mkOpt' mkBoolOpt' mkVMOverride';
cfg = config.my.tmproot; cfg = config.my.tmproot;
@@ -492,53 +492,6 @@ in
} }
]; ];
}) })
(mkIf config.services.wastebin.enable {
my.tmproot.persistence.config.directories = [ "/var/lib/private/wastebin" ];
})
(mkIf config.services.photoprism.enable {
my.tmproot.persistence.config.directories = [
{
directory = config.services.photoprism.storagePath;
mode = "0750";
user = "photoprism";
group = "photoprism";
}
];
})
(mkIf config.services.mautrix-whatsapp.enable {
my.tmproot.persistence.config.directories = [
{
directory = "/var/lib/mautrix-whatsapp";
mode = "0750";
user = "mautrix-whatsapp";
group = "mautrix-whatsapp";
}
];
})
{
my.tmproot.persistence.config.directories = mapAttrsToList (n: i: {
directory = "/var/lib/${i.dataDir}";
mode = "0750";
user = "mautrix-meta-${n}";
group = "mautrix-meta";
}) (filterAttrs (_: i: i.enable) config.services.mautrix-meta.instances);
}
(mkIf config.services.unifi.enable {
my.tmproot.persistence.config.directories = [
{
directory = "/var/lib/unifi";
mode = "0750";
user = "unifi";
group = "unifi";
}
{
directory = "/var/cache/unifi";
mode = "0750";
user = "unifi";
group = "unifi";
}
];
})
])) ]))
]); ]);

View File

@@ -1,49 +0,0 @@
{ lib, stdenv, autoreconfHook, pkg-config, SDL, SDL_mixer, SDL_net
, fetchFromGitHub, fetchpatch, python3 }:
stdenv.mkDerivation rec {
pname = "chocolate-doom";
version = "2.3.0";
src = fetchFromGitHub {
owner = "chocolate-doom";
repo = pname;
rev = "${pname}-${version}";
sha256 = "sha256-1uw/1CYKBvDNgT5XxRBY24Evt3f4Y6YQ6bScU+KNHgM=";
};
patches = [
# Pull upstream patch to fix build against gcc-10:
# https://github.com/chocolate-doom/chocolate-doom/pull/1257
(fetchpatch {
name = "fno-common.patch";
url = "https://github.com/chocolate-doom/chocolate-doom/commit/a8fd4b1f563d24d4296c3e8225c8404e2724d4c2.patch";
sha256 = "1dmbygn952sy5n8qqp0asg11pmygwgygl17lrj7i0fxa0nrhixhj";
})
./demoloopi.patch
];
outputs = [ "out" "man" ];
postPatch = ''
patchShebangs --build man/{simplecpp,docgen}
'';
nativeBuildInputs = [
autoreconfHook
pkg-config
# for documentation
python3
];
buildInputs = [ (SDL.override { cacaSupport = true; }) SDL_mixer SDL_net ];
enableParallelBuilding = true;
meta = {
homepage = "http://chocolate-doom.org/";
description = "A Doom source port that accurately reproduces the experience of Doom as it was played in the 1990s";
license = lib.licenses.gpl2Plus;
platforms = lib.platforms.unix;
hydraPlatforms = lib.platforms.linux; # darwin times out
maintainers = with lib.maintainers; [ ];
};
}

View File

@@ -1,91 +0,0 @@
diff --git a/src/doom/d_main.c b/src/doom/d_main.c
index 65a39a10..3f799b0f 100644
--- a/src/doom/d_main.c
+++ b/src/doom/d_main.c
@@ -483,6 +483,8 @@ void D_DoomLoop (void)
// DEMO LOOP
//
int demosequence;
+int demoloopi;
+char demoloopname[9];
int pagetic;
char *pagename;
@@ -524,6 +526,8 @@ void D_AdvanceDemo (void)
//
void D_DoAdvanceDemo (void)
{
+ int havedemo4;
+
players[consoleplayer].playerstate = PST_LIVE; // not reborn
advancedemo = false;
usergame = false; // no save / end game here
@@ -539,10 +543,14 @@ void D_DoAdvanceDemo (void)
// However! There is an alternate version of Final Doom that
// includes a fixed executable.
- if (gameversion == exe_ultimate || gameversion == exe_final)
+ havedemo4 = gameversion == exe_ultimate || gameversion == exe_final;
+ if (havedemo4)
demosequence = (demosequence+1)%7;
else
demosequence = (demosequence+1)%6;
+
+ if (demoloopi < 0 || demoloopi > (havedemo4 ? 3 : 2))
+ I_Error("Invalid demo loop start %d", demoloopi);
switch (demosequence)
{
@@ -558,17 +566,11 @@ void D_DoAdvanceDemo (void)
else
S_StartMusic (mus_intro);
break;
- case 1:
- G_DeferedPlayDemo(DEH_String("demo1"));
- break;
case 2:
pagetic = 200;
gamestate = GS_DEMOSCREEN;
pagename = DEH_String("CREDIT");
break;
- case 3:
- G_DeferedPlayDemo(DEH_String("demo2"));
- break;
case 4:
gamestate = GS_DEMOSCREEN;
if ( gamemode == commercial)
@@ -587,12 +589,14 @@ void D_DoAdvanceDemo (void)
pagename = DEH_String("HELP2");
}
break;
+ case 1:
+ case 3:
case 5:
- G_DeferedPlayDemo(DEH_String("demo3"));
- break;
// THE DEFINITIVE DOOM Special Edition demo
case 6:
- G_DeferedPlayDemo(DEH_String("demo4"));
+ DEH_snprintf(demoloopname, 9, "demo%d", demoloopi + 1);
+ G_DeferedPlayDemo(demoloopname);
+ demoloopi = (demoloopi+1) % (havedemo4 ? 4 : 3);
break;
}
@@ -1891,7 +1895,15 @@ void D_DoomMain (void)
G_TimeDemo (demolumpname);
D_DoomLoop (); // never returns
}
-
+
+ p = M_CheckParmWithArgs("-demoloopi", 1);
+ if (p)
+ {
+ demoloopi = atoi(myargv[p+1]);
+ } else {
+ demoloopi = 0;
+ }
+
if (startloadgame >= 0)
{
M_StringCopy(file, P_SaveGameFile(startloadgame), sizeof(file));

View File

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

View File

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

View File

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

View File

@@ -81,7 +81,7 @@ rustPlatform.buildRustPackage rec {
dontFixup = true; dontFixup = true;
outputHashMode = "recursive"; outputHashMode = "recursive";
outputHash = "sha256-Txttk8qZpDsAuiF8laKbZss/KEoT1Z+oepbj2s4XjE8="; outputHash = "sha256-9HtTdIotG3sNIlWhd76v7Ia6P69ufp/FFqZfINXSkVc=";
}; };
preBuild = '' preBuild = ''

View File

@@ -1,41 +0,0 @@
{ lib, stdenv, fetchFromGitHub, fetchpatch
, meson, ninja, pkg-config, scdoc, wayland-scanner
, wayland, wayland-protocols, libxkbcommon, cairo, gdk-pixbuf, pam
}:
stdenv.mkDerivation rec {
pname = "swaylock-plugin";
version = "1dd15b6";
src = fetchFromGitHub {
owner = "mstoeckl";
repo = pname;
rev = "1dd15b6ecbe91be7a3dc4a0fa9514fb166fb2e07";
hash = "sha256-xWyDDT8sXAL58HtA9ifzCenKMmOZquzXZaz3ttGGJuY=";
};
strictDeps = true;
depsBuildBuild = [ pkg-config ];
nativeBuildInputs = [ meson ninja pkg-config scdoc wayland-scanner ];
buildInputs = [ wayland wayland-protocols libxkbcommon cairo gdk-pixbuf pam ];
mesonFlags = [
"-Dpam=enabled" "-Dgdk-pixbuf=enabled" "-Dman-pages=enabled"
];
env.NIX_CFLAGS_COMPILE = "-Wno-maybe-uninitialized";
meta = with lib; {
description = "Screen locker for Wayland -- fork with background plugin support";
longDescription = ''
Fork of swaylock, a screen locking utility for Wayland compositors.
With swaylock-plugin, you can for your lockscreen background display
the animated output from any wallpaper program that implements the
wlr-layer-shell-unstable-v1 protocol.
'';
inherit (src.meta) homepage;
mainProgram = "swaylock";
license = licenses.mit;
platforms = platforms.linux;
maintainers = with maintainers; [ devplayer0 ];
};
}

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 +0,0 @@
{ lib
, fetchFromGitLab
, rustPlatform
}:
rustPlatform.buildRustPackage rec {
pname = "windowtolayer";
version = "a5b89c3c";
src = fetchFromGitLab {
domain = "gitlab.freedesktop.org";
owner = "mstoeckl";
repo = pname;
rev = "a5b89c3c047297fd574932860a6c89e9ea02ba5d";
hash = "sha256-rssL2XkbTqUvJqfUFhzULeE4/VBzjeBC5iZWSJ8MJ+M=";
};
cargoHash = "sha256-XHmLsx9qdjlBz4xJFFiO24bR9CMw1o5368K+YMpMIBA=";
}

View File

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

View File

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

View File

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

View File

@@ -1,33 +0,0 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBSS3E0
YWsxbHZXQXo1R3BzL1BDdERxN3d2ek5acFZWK3F6andTeGVacVNVCnhPR3I4dXFV
dFd0N2lsTU5NOCtsM3Z1YUdIaER4YjlrdkNXT1g4dGZXNFkKLT4gWDI1NTE5IDBQ
cHBYSG04eHA1ZG9KN1Q5bFk0eXk0T0o4c2pLVUdNbEtWaDdwckdJVmcKd3lkZmVY
cDc3dGdXSWViNGlMVW9jZENUWXd5MVNheStiVU1adG5MNEpnNAotPiBfJWZ0eWtP
LWdyZWFzZSA/VGRDTT5kSCB4QH05QF96eyAtfUpxQ1ggZU5FQEhZbGMKa2xDUlMw
Wml2QldxcS96YXVJT0hPVStqelhmUEd4K2R3ZDM4Uk83MXV6VlVoKzRiMWhxVlJx
Ykg4ZTJ6SSswTQpTdjYzUkhMWjFwblhzRWV4bFZOVnRjRGMveDFaUTJWM3diK3lj
MUE3dFlhUEVENAotLS0gd2lKQ05PRUF1b1RzZEs0ckY0eFlPaFFBNHRQZ01rZzBV
SW01L0VzUUpYSQrJxWuL6pjjZs+hCS0f6DTNwW6HSD33bUwdBpyTCLeLMyDT646H
4pjAhrVjVH1kgBFmuCjTP+SrD2bie/WhkQPSYrG7qygcmXbdNXlJn1tluEedDLzK
djbOaSuohlgneGw9Z00Zkm8rz//2NSB89+WiWuT5/6Pm/d6763FteRI1LsPOyWx2
vmTZMIcuclmrGn611T1kKR87R5AkaZ6xyhkOrOvWrb7BktmA69Kd9r5fXyxnLRZD
W6vPm4EJLo0b1a4DWlnIvFTy5I6e2fFT9h2+rU1qITn5fwQD5aAYdL8W8ELIEJ98
zYNxpbepHY5fBpHOGvOKM4AAO/R2pjaDaK7DRIFhSx/1RJLJvigXFd7YKl0WWn3w
PGK/YxXnhtxnZngEPrnwf3JPj+zQ3RwKDx/v12s+KTbfQu6sGvw3MhDwYsFrRn+J
T/jqlcZ/RodnxDngMnJCzc+YPkCJ/yAiot1DthVdpW0mWFiPsZvzN3co7t+6nopR
WYnSjp5igjHbO/E3zXQ8qRlOvXSp6zspOIv9AETq49felAxXF7uz28lMnBeCReVq
4hzBII+wDTR1Y/itKcOGm5mTdyvLF4qKRZFJFiJ3ATGZDEYh2dCrO2juaL4VczCl
+qwt9gYF+pOgY4ekOtW6BpvOGZ591LHTMWoP52O0MnZADU8GHkh66AvMDemQGumj
7qI6kI49Rwr5CoDMds5XlUBKlzeLgZLSo46FJghWOOQaiFiXWVQ+jYZpZPkgGjkU
wDkrnbdglkdPO93bT2drkNbPWziHRkV505lGk1s4zCvsUPMH0D6KYkA6o/hCum4B
IK8Sj215CmjQv5LYBwzHTNRusksXDu/+Ud5FpKCNw34aKblLIEPJNSk1BWLwyLzM
oCNTiI490ZBh3vcnXpHZorS1Hxzb536SW03l0Z6q1Izn/vfzhZ7HbFY4qS9Qe+je
Cvx+upRzt+mIQt8edbhrC1twfo/6whuvpT1HqGQDUr62+4zqVJ3lbccmXRX6uOAq
sfK9if7qo0wkfWqa4RutO008ocVSKt0JjDOUpGHHP9Z95NRMyKJiOlv7dgVwWEid
J8YMxexAgkmjByzwt1CBC7XizEHl09ZyjJrzN420NMRzaG3C6PY82cnKdbXNfEM2
0dlN/xUTaOG1dAjdlgr2oMA5o0jFptr3hTFcoOQ/va1zkkNDHvfgjzri9HSID0bP
kE0Akj6H9457cyo+xI+gD+2CtJW37TR/A7GLrzc+BDdDNZWtJz8t7oU0STL38h0d
rfHgC8uFj7Ozh0nvsPbviwHCw6F+Z3lOT2qaFjzWKMuhnB8s3C//vmMFCfY2XglJ
Tmcz+A==
-----END AGE ENCRYPTED FILE-----

View File

@@ -1,14 +0,0 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBBTHhU
TVdvcWhvb0c3NjlTT1JBWlRaRXBYSlFySFJhQVZHRUsxcTFVT1ZzCmVaZW1ucTRG
MVN0VnZEWndlVS9iclNhRlB2dkZPT241dHRxcjBRc1BpVncKLT4gWDI1NTE5IGh1
aitYSmVudUZPS0FHbUliUjFCWXJaTWI1RzRlK1Q0ZlpQNmRwN0haemcKaHhQS1JO
UVYxYUU1OTR0dXJhTm1EMGdER0hYUXVRd2VmNURwTEdVV09tVQotPiAnbHAtZ3Jl
YXNlIH0gLCJ9IDwhIEB2QW0lfSkKMUJLd21ubDVQdWJOR1VvCi0tLSB3N2dJV2o1
WGF2TENYNE8vSzI2UzVPZW01RzRtK1VCaUVKemN1RzVhaGlvChPEVtylQsq+EWK4
X6HxFl3JY+M9clfpicNlSqUjPcB3roEMpD9BmGcG46nVSZVDguVjPzwTltAGE72Q
Q4RP8/yhssA2rrLEuWz+JKcaASF/yEmu9QBILrWBIWz0rQyHfTRvBC9d83MdHS5f
DQl1abC7Lv8imVm0pJ9vthvB56mXlGgm16fnsd/UhgMQSWZuVLSitaoDEFCz/LWi
QAUKYTRVL2UcomgHsQqMx+2g3HT0RYQu1Ud3M5rT9eMSSqPG7IzyjNA3HmH5dw/4
EdnilIaW7c6k1RAYMFY270E6qlxqdQ==
-----END AGE ENCRYPTED FILE-----

View File

@@ -1,15 +0,0 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USB1QUhX
dTlNY3h2SElIMytCTGlmY2syMmlTL1VMeDFnanN2UE9QK3RvRlUwCkVMM3ZKMU52
ZmIrZ1VxUDNWZm1lU2MrWnpkUzBLcDB5cUFCSXZmQ3RXR0UKLT4gWDI1NTE5IE5W
cE5uSlpRd3dIRXEyRnpSZ0VHZ253OE1ZVTd1OTJQYkZVd1NRdnh2aE0KNTFTaHJM
OE9tc0VkMHFHUGN2dFZVSGFBdTh5Tzk0TGU4SWwzYTBOb3FtdwotPiB9WnwtZ3Jl
YXNlIHZVYHxaIEBSbmZ9XiAhfF52YCNwCld0K0RCTFlQamNLeitWM0kwUnVJdXFV
QjNFcEYxWFBkVjJ3QlAwTGVvTE1GTkxCTEdDcmlZMC9xbUcrSHp2V3cKdzJLb011
aEM3a0V4eXBTMjhnCi0tLSBOWHozZTRjRldrOXBmM05BZ1lPRDYwaDFCcHBPNHhQ
SzlaWGM2RXY1THI4Cj4RzG3G1yGkmDyqxCBciqMNPAQYge4mXOib7mqOuyIbkT+k
qrJ8fLnW7Jbnb7+Rzr7BAEC5/dpOfjkyY9JPeg0FRutlkKyPIhRMAEhSsNvUFzXg
uwNbnSBI+9Str6nTKI5c9IWT5eT/8zsKwtK1/pr39mApRY/y6NlA5X7ZRIFeku3K
6I/bCI5cT0qhIMJbF5D0KiCnMCnMdmRLrwLzM2zcJoisxRAvj4dNfLktsUQOauZ+
Gta96qQkAewvrdfz8Z4lTYJQmEqeOs1vTA6sAMf4iLp5EhPE0jN0n6D8v7Lq7+2b
-----END AGE ENCRYPTED FILE-----

View File

@@ -1,14 +0,0 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBJbWVs
bkt4a1RBaU14cjJzRm9KUGhydnZlWGU0NGVYK0NmWXRsclpjVUU0CmNiVDJTODFw
TnloNW1LMUliVmlnUGt0SFFzWmxVTWxZQ3crNWVHVy9IL0EKLT4gWDI1NTE5IDcw
TUQva3UxN3o1MXJ5QmVmQWVmeTFLejVwOVdQZks3a0dVQUJTdUdZdzgKajBFK2dX
R1NNR3l5d010MnJGUktNWldwVjY2cDIwbU1laEMwOWJITEg0NAotPiBeLS1ncmVh
c2UgJjhQIF0pcSB4Ci90SVhIZzRGVlcrd0hRCi0tLSBKdVgwZ0pidC93aEFscm9w
Mm5GbEc3RDdZRDRpeTdONHpWN0xHYXkvVU5zCjjFfwumbetHbq8MKrBIx18YXmny
z+0ifVbksJhYLYk7hViSUDy+F3RRad23dSPvDdd7JCEpj+2PvcezBLkwfUkFdQe7
uQhUJJ9c62oKSX7PMbQeW1tyX10SVkt/P20z6HPXvBlY715lsXspjZERi+DheZk0
ZDc3dPYMeyoAIWicf40ZxH8C6rWl5HOLIaTMbCOKwpD+wPjpzeZHat605YWReFxR
Yd3cKCRqSb2QdAdtZ0XUDSPl7HVwkw0xobCsvtPzmObA3YbLopBq7Dvrvh7XW5ns
BPlTaI8WnrI03CplGP00
-----END AGE ENCRYPTED FILE-----

View File

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

View File

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

View File

@@ -1,16 +1,16 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBQMEJB YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USA3MEFh
VVhIL2ViVUx1Ym9IbFV1UW52NjZYMmJlYmpjY0RuMzhiclJVS0ZnCkY5dEZHTHlC YURySHY5RjVQa1c0QmMvTkZtZElNd1BIeDFpR1U1YXZ5dndnclUwClA2M0ZYMk90
K29uamorWWNJSVV0VlVJNG1VNm9GQ3VPdldJRDNSODVoOVUKLT4gWDI1NTE5IEM0 RmlCZHVISkxZQTZXeEhZVUROSVRGRVg4TmZKZytSL05FcTgKLT4gWDI1NTE5IFY2
UVQvLzFYRTRRMldWSnNnd3V3aXJTeS8vZ1hkdENYVHk1QVVaQVEyQnMKVmN4OUFH V2k3S0VQdGlQZ0hkU2ZoSWdOUG9rQ0p5Ukg3ZHU3MXVvNHlWYVN5VVUKcWtoWDJh
WCtVSW9tREV5RExycnFJejk5UW91dzd5Rm8vcFBTT0ZCdytFWQotPiBCPC0lLTJW LzRwcktWUGQ1bnJvRzVBVlpHU3NhdzYwUDBPTmx3MFNrdWNQYwotPiBKQil6Km0t
LS1ncmVhc2UgRSBjOlg5a0pdQSBSb2YKN0pkalY4VlFDMm8vZzJpQUV4TmdSRHA2 Z3JlYXNlIFdlRTlUU2cgVlxLIzUgJlVyQiJ8Cng3NzF2b3d6MnlEdURQWHgrSFJv
dnB4UzJaWTRXeDdmKzFrUGVMSEFlbFhlNFFycFRQU005d1I2Si9VUQpHbDVxcGxn Y1BMUkZyelJSdDJvUUUwY1k5R3ZBMnJaa1R4NWxlUll2azNseW5MQlpvVWUKYUdN
SVdjZzduSGluYlZnY3lmZmtnOWJYKzkydDhKU0VCNmNvV0EKLS0tIGdaUkpGNy9P d1ZscXVxd1dxSGpzMjBYeWhhYyt5ZlNkSjhmV1ZTTDBTCi0tLSBBTG45VUJOSXZv
Y3BGVGVJenJkTG51c3Z3WFU0eTFXT09pSVFseGRLMmxJVU0KhH9EjbL0zv821Yox N3lYNVlyZldMVkpZdUMvS21NdSswVmU3VThZK2M2eis4CjwfWWJVR9Ty5dBXEr5s
FXc54SXGEkq97qPi3xIoPydWd3FbIuftAhe0xPFGfUOO5/zDni4h+PoNJs2hnkOK U+QrifXvyMJJvqOKEfMYYomFLpt/VtbDAUwNlqLnFIk1VZ2xPUBisXPtReiCK3gq
kHhxtaOj1S6RulI/eYLK/fJjl2aRrTaRFN0TGhFwz5X8HOQe2+Qrq/9wT7pyzOFU P+i6bUONSmPYvmF82VgiuKDuz/kmWqVGg2iSBPIXAGLNIEojndQwmhnrsN9ex4Xy
LsMwe71OhTjA5XrBTawU9QkWjPx2LZyb/WEkzlLOCGoHTUm4X03xY/1UeHVYZt2k lBHkvVsN8EamUJwZ+FEZe4+PjA5yEnANWpeTELOt2gA92/jwwnNIsr07eVTlkh8X
wbLses0JHK1h2ttWnO5y68LovZWJqFdIjoCCkgfo0nNUD5i+e51xEju9OBJMngj+ UmQ2owGwktXP7it6//NV3C7sAdazs2bX65WSnog2E8WPNAorKWI8RCYs33CshVFt
LnPb6YCqFh4Fxy09WORD0A== zzclZ4hRmlAmqMHYqFY=
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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