aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--LICENSE17
-rw-r--r--README.md4
-rw-r--r--flake.lock492
-rw-r--r--flake.nix37
-rw-r--r--lib/README.md13
-rw-r--r--lib/attrs.nix26
-rw-r--r--lib/default.nix18
-rw-r--r--lib/misc.nix9
-rw-r--r--lib/modules.nix54
-rw-r--r--lib/system.nix22
-rw-r--r--modules/README.md9
-rw-r--r--modules/cachix/caches/nix-community.nix12
-rw-r--r--modules/cachix/default.nix23
-rw-r--r--modules/flakes.nix36
-rw-r--r--modules/nix.nix34
-rw-r--r--modules/persistence.nix47
-rw-r--r--modules/security.nix69
-rw-r--r--modules/services/_template.nix13
-rw-r--r--modules/services/acme.nix52
-rw-r--r--modules/services/akkoma/blocklist.toml164
-rw-r--r--modules/services/akkoma/default.nix102
-rw-r--r--modules/services/akkoma/favicon-withbg.pngbin0 -> 17371 bytes
-rw-r--r--modules/services/akkoma/favicon.pngbin0 -> 16693 bytes
-rw-r--r--modules/services/akkoma/logo.pngbin0 -> 1304 bytes
-rw-r--r--modules/services/akkoma/logo.svg71
-rw-r--r--modules/services/akkoma/robots.txt2
-rw-r--r--modules/services/akkoma/terms-of-service.html26
-rw-r--r--modules/services/authentik.nix69
-rw-r--r--modules/services/backup.nix81
-rw-r--r--modules/services/cgit/cgit-exotic.css953
-rw-r--r--modules/services/cgit/default.nix129
-rw-r--r--modules/services/cinny-web.nix34
-rw-r--r--modules/services/coredns/_corefile.nix3
-rw-r--r--modules/services/coredns/default.nix18
-rw-r--r--modules/services/coturn.nix64
-rw-r--r--modules/services/dovecot.nix18
-rw-r--r--modules/services/element-web.nix47
-rw-r--r--modules/services/fail2ban.nix20
-rw-r--r--modules/services/git-daemon/_git-daemon-module.nix137
-rw-r--r--modules/services/git-daemon/default.nix31
-rw-r--r--modules/services/gitolite/default.nix110
-rw-r--r--modules/services/gitolite/fix-refs9
-rw-r--r--modules/services/gitolite/post-receive19
-rw-r--r--modules/services/gitolite/rename63
-rw-r--r--modules/services/jitsi.nix43
-rw-r--r--modules/services/ldap.nix76
-rw-r--r--modules/services/matrix-bridge/_mautrix-discord-module.nix205
-rw-r--r--modules/services/matrix-bridge/_mautrix-signal-module.nix204
-rw-r--r--modules/services/matrix-bridge/default.nix390
-rw-r--r--modules/services/matrix-homeserver.nix190
-rw-r--r--modules/services/matrix-moderation.nix58
-rw-r--r--modules/services/metrics.nix169
-rw-r--r--modules/services/nebula.nix18
-rw-r--r--modules/services/nginx.nix37
-rw-r--r--modules/services/nixos-mailserver.nix159
-rw-r--r--modules/services/obsidian-livesync.nix63
-rw-r--r--modules/services/postgresql.nix34
-rw-r--r--modules/services/rss.nix64
-rw-r--r--modules/services/searx.nix50
-rw-r--r--modules/services/sefidel-web.nix26
-rw-r--r--modules/services/soju.nix40
-rw-r--r--modules/services/tailscale.nix22
-rw-r--r--modules/services/vikunja.nix50
-rw-r--r--modules/sops.nix19
65 files changed, 5077 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f3790b5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+result
+*.qcow2
+**/**/.DS_Store
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f08ca97
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,17 @@
+ISC License
+===================================
+
+Copyright (c) 2024, sefidel <sef@exotic.sh>
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..43d47eb
--- /dev/null
+++ b/README.md
@@ -0,0 +1,4 @@
+exotic->infra-modules
+=============
+
+High-level NixOS configuration modules for exotic.sh infrastructure.
diff --git a/flake.lock b/flake.lock
new file mode 100644
index 0000000..4735c71
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,492 @@
+{
+ "nodes": {
+ "authentik-nix": {
+ "inputs": {
+ "authentik-src": "authentik-src",
+ "flake-compat": "flake-compat",
+ "flake-parts": "flake-parts",
+ "flake-utils": "flake-utils",
+ "napalm": "napalm",
+ "nixpkgs": [
+ "unstable"
+ ],
+ "nixpkgs-23-05": "nixpkgs-23-05",
+ "poetry2nix": "poetry2nix"
+ },
+ "locked": {
+ "lastModified": 1704822856,
+ "narHash": "sha256-LHng0EWMNh/1pRIitisMzu4XVHswjDZpfAa5cfRO6kE=",
+ "owner": "nix-community",
+ "repo": "authentik-nix",
+ "rev": "8ff62523708d1a3e9cf99891aaa7692dafd445a5",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "authentik-nix",
+ "type": "github"
+ }
+ },
+ "authentik-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1704822648,
+ "narHash": "sha256-N6FeNUlenbBQPAAUSqC+2GWFfte3G+Zfu5KGVJOqNZQ=",
+ "owner": "goauthentik",
+ "repo": "authentik",
+ "rev": "1cd000dfe204b9605c85e6cebc051586a0329604",
+ "type": "github"
+ },
+ "original": {
+ "owner": "goauthentik",
+ "ref": "version/2023.10.6",
+ "repo": "authentik",
+ "type": "github"
+ }
+ },
+ "blobs": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1604995301,
+ "narHash": "sha256-wcLzgLec6SGJA8fx1OEN1yV/Py5b+U5iyYpksUY/yLw=",
+ "owner": "simple-nixos-mailserver",
+ "repo": "blobs",
+ "rev": "2cccdf1ca48316f2cfd1c9a0017e8de5a7156265",
+ "type": "gitlab"
+ },
+ "original": {
+ "owner": "simple-nixos-mailserver",
+ "repo": "blobs",
+ "type": "gitlab"
+ }
+ },
+ "flake-compat": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1696426674,
+ "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
+ "type": "github"
+ },
+ "original": {
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
+ "flake-compat_2": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1668681692,
+ "narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "009399224d5e398d03b22badca40a37ac85412a1",
+ "type": "github"
+ },
+ "original": {
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
+ "flake-parts": {
+ "inputs": {
+ "nixpkgs-lib": "nixpkgs-lib"
+ },
+ "locked": {
+ "lastModified": 1701473968,
+ "narHash": "sha256-YcVE5emp1qQ8ieHUnxt1wCZCC3ZfAS+SRRWZ2TMda7E=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "34fed993f1674c8d06d58b37ce1e0fe5eebcb9f5",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "type": "github"
+ }
+ },
+ "flake-utils": {
+ "inputs": {
+ "systems": "systems"
+ },
+ "locked": {
+ "lastModified": 1701680307,
+ "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "flake-utils_2": {
+ "locked": {
+ "lastModified": 1667395993,
+ "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "impermanence": {
+ "locked": {
+ "lastModified": 1703656108,
+ "narHash": "sha256-hCSUqdFJKHHbER8Cenf5JRzjMlBjIdwdftGQsO0xoJs=",
+ "owner": "nix-community",
+ "repo": "impermanence",
+ "rev": "033643a45a4a920660ef91caa391fbffb14da466",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "impermanence",
+ "type": "github"
+ }
+ },
+ "napalm": {
+ "inputs": {
+ "flake-utils": [
+ "authentik-nix",
+ "flake-utils"
+ ],
+ "nixpkgs": [
+ "authentik-nix",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1703102458,
+ "narHash": "sha256-3pOV731qi34Q2G8e2SqjUXqnftuFrbcq+NdagEZXISo=",
+ "owner": "nix-community",
+ "repo": "napalm",
+ "rev": "edcb26c266ca37c9521f6a97f33234633cbec186",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "napalm",
+ "type": "github"
+ }
+ },
+ "nix-github-actions": {
+ "inputs": {
+ "nixpkgs": [
+ "authentik-nix",
+ "poetry2nix",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1698974481,
+ "narHash": "sha256-yPncV9Ohdz1zPZxYHQf47S8S0VrnhV7nNhCawY46hDA=",
+ "owner": "nix-community",
+ "repo": "nix-github-actions",
+ "rev": "4bb5e752616262457bc7ca5882192a564c0472d2",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "nix-github-actions",
+ "type": "github"
+ }
+ },
+ "nixos-mailserver": {
+ "inputs": {
+ "blobs": "blobs",
+ "flake-compat": "flake-compat_2",
+ "nixpkgs": [
+ "unstable"
+ ],
+ "nixpkgs-22_11": "nixpkgs-22_11",
+ "nixpkgs-23_05": "nixpkgs-23_05",
+ "utils": "utils"
+ },
+ "locked": {
+ "lastModified": 1703666786,
+ "narHash": "sha256-SLPNpM/rI8XPyVJAxMYAe+n6NiYSpuXvdwPILHP4yZI=",
+ "owner": "simple-nixos-mailserver",
+ "repo": "nixos-mailserver",
+ "rev": "b5023b36a1f6628865cb42b4353bd2ddde0ea9f4",
+ "type": "gitlab"
+ },
+ "original": {
+ "owner": "simple-nixos-mailserver",
+ "repo": "nixos-mailserver",
+ "type": "gitlab"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1673606088,
+ "narHash": "sha256-wdYD41UwNwPhTdMaG0AIe7fE1bAdyHe6bB4HLUqUvck=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "37b97ae3dd714de9a17923d004a2c5b5543dfa6d",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-22_11": {
+ "locked": {
+ "lastModified": 1669558522,
+ "narHash": "sha256-yqxn+wOiPqe6cxzOo4leeJOp1bXE/fjPEi/3F/bBHv8=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "ce5fe99df1f15a09a91a86be9738d68fadfbad82",
+ "type": "github"
+ },
+ "original": {
+ "id": "nixpkgs",
+ "ref": "nixos-22.11",
+ "type": "indirect"
+ }
+ },
+ "nixpkgs-23-05": {
+ "locked": {
+ "lastModified": 1701615100,
+ "narHash": "sha256-7VI84NGBvlCTduw2aHLVB62NvCiZUlALLqBe5v684Aw=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "e9f06adb793d1cca5384907b3b8a4071d5d7cb19",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-23.05",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-23_05": {
+ "locked": {
+ "lastModified": 1684782344,
+ "narHash": "sha256-SHN8hPYYSX0thDrMLMWPWYulK3YFgASOrCsIL3AJ78g=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "8966c43feba2c701ed624302b6a935f97bcbdf88",
+ "type": "github"
+ },
+ "original": {
+ "id": "nixpkgs",
+ "ref": "nixos-23.05",
+ "type": "indirect"
+ }
+ },
+ "nixpkgs-lib": {
+ "locked": {
+ "dir": "lib",
+ "lastModified": 1701253981,
+ "narHash": "sha256-ztaDIyZ7HrTAfEEUt9AtTDNoCYxUdSd6NrRHaYOIxtk=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "e92039b55bcd58469325ded85d4f58dd5a4eaf58",
+ "type": "github"
+ },
+ "original": {
+ "dir": "lib",
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-stable": {
+ "locked": {
+ "lastModified": 1704290814,
+ "narHash": "sha256-LWvKHp7kGxk/GEtlrGYV68qIvPHkU9iToomNFGagixU=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "70bdadeb94ffc8806c0570eb5c2695ad29f0e421",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "release-23.05",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "poetry2nix": {
+ "inputs": {
+ "flake-utils": [
+ "authentik-nix",
+ "flake-utils"
+ ],
+ "nix-github-actions": "nix-github-actions",
+ "nixpkgs": [
+ "authentik-nix",
+ "nixpkgs"
+ ],
+ "systems": "systems_2",
+ "treefmt-nix": "treefmt-nix"
+ },
+ "locked": {
+ "lastModified": 1701861752,
+ "narHash": "sha256-QfrE05P66856b1SMan69NPhjc9e82VtLxBKg3yiQGW8=",
+ "owner": "nix-community",
+ "repo": "poetry2nix",
+ "rev": "9fc487b32a68473da4bf9573f85b388043c5ecda",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "poetry2nix",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "authentik-nix": "authentik-nix",
+ "impermanence": "impermanence",
+ "nixos-mailserver": "nixos-mailserver",
+ "sefidel-web": "sefidel-web",
+ "sops-nix": "sops-nix",
+ "unstable": "unstable"
+ }
+ },
+ "sefidel-web": {
+ "inputs": {
+ "flake-utils": "flake-utils_2",
+ "nixpkgs": "nixpkgs"
+ },
+ "locked": {
+ "lastModified": 1696069380,
+ "narHash": "sha256-KKTX1XKGnglV+vGbvKjduT2QjE2snbyy8R7nNuXvnMc=",
+ "ref": "refs/heads/main",
+ "rev": "305ee346ca81883de4fc6575460021a57cacefeb",
+ "revCount": 6,
+ "type": "git",
+ "url": "https://git.exotic.sh/pub/sefidel/sefidel-web"
+ },
+ "original": {
+ "type": "git",
+ "url": "https://git.exotic.sh/pub/sefidel/sefidel-web"
+ }
+ },
+ "sops-nix": {
+ "inputs": {
+ "nixpkgs": [
+ "unstable"
+ ],
+ "nixpkgs-stable": "nixpkgs-stable"
+ },
+ "locked": {
+ "lastModified": 1704908274,
+ "narHash": "sha256-74W9Yyomv3COGRmKi8zvyA5tL2KLiVkBeaYmYLjXyOw=",
+ "owner": "Mic92",
+ "repo": "sops-nix",
+ "rev": "c0b3a5af90fae3ba95645bbf85d2b64880addd76",
+ "type": "github"
+ },
+ "original": {
+ "owner": "Mic92",
+ "repo": "sops-nix",
+ "type": "github"
+ }
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ },
+ "systems_2": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "id": "systems",
+ "type": "indirect"
+ }
+ },
+ "treefmt-nix": {
+ "inputs": {
+ "nixpkgs": [
+ "authentik-nix",
+ "poetry2nix",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1699786194,
+ "narHash": "sha256-3h3EH1FXQkIeAuzaWB+nK0XK54uSD46pp+dMD3gAcB4=",
+ "owner": "numtide",
+ "repo": "treefmt-nix",
+ "rev": "e82f32aa7f06bbbd56d7b12186d555223dc399d1",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "treefmt-nix",
+ "type": "github"
+ }
+ },
+ "unstable": {
+ "locked": {
+ "lastModified": 1704722960,
+ "narHash": "sha256-mKGJ3sPsT6//s+Knglai5YflJUF2DGj7Ai6Ynopz0kI=",
+ "owner": "nixos",
+ "repo": "nixpkgs",
+ "rev": "317484b1ead87b9c1b8ac5261a8d2dd748a0492d",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nixos",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "utils": {
+ "locked": {
+ "lastModified": 1605370193,
+ "narHash": "sha256-YyMTf3URDL/otKdKgtoMChu4vfVL3vCMkRqpGifhUn0=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "5021eac20303a61fafe17224c087f5519baed54d",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644
index 0000000..823a86f
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,37 @@
+{
+ description = "exotic.sh shared system modules";
+
+ inputs = {
+ unstable.url = "github:nixos/nixpkgs/nixos-unstable";
+
+ impermanence.url = "github:nix-community/impermanence";
+
+ authentik-nix.url = "github:nix-community/authentik-nix";
+ authentik-nix.inputs.nixpkgs.follows = "unstable";
+
+ sops-nix.url = "github:Mic92/sops-nix";
+ sops-nix.inputs.nixpkgs.follows = "unstable";
+
+ nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
+ nixos-mailserver.inputs.nixpkgs.follows = "unstable";
+
+ sefidel-web.url = "git+https://git.exotic.sh/pub/sefidel/sefidel-web";
+ };
+
+ outputs = { self, unstable, ... } @ inputs:
+ let
+ inherit (lib.my) mapModulesRec mapModulesRec';
+
+ system = "x86_64-linux";
+
+ pkgs = import unstable { inherit system; };
+
+ lib = unstable.lib.extend
+ (self: super: { my = import ./lib { inherit pkgs inputs; lib = self; }; });
+ in
+ {
+ lib = lib.my;
+
+ nixosModules = mapModulesRec ./modules import;
+ };
+}
diff --git a/lib/README.md b/lib/README.md
new file mode 100644
index 0000000..21ca023
--- /dev/null
+++ b/lib/README.md
@@ -0,0 +1,13 @@
+infra->lib
+==========
+
+Attribution
+-----------
+
+Most of the 'moving parts' of this is largely copied/modified from:
+
+- [hlissner/dotfiles][hlissner]: 2023-Feb, MIT (C) Henrik Lissner
+- [NobbZ/nixos-config][nobbz]: 2022, MIT (C) Nobert Melzer
+
+[hlissner]: https://github.com/hlissner/dotfiles
+[nobbz]: https://github.com/NobbZ/nixos-config
diff --git a/lib/attrs.nix b/lib/attrs.nix
new file mode 100644
index 0000000..0f8ebd1
--- /dev/null
+++ b/lib/attrs.nix
@@ -0,0 +1,26 @@
+{ lib, ... }:
+
+with builtins;
+with lib;
+rec {
+ # attrsToList
+ attrsToList = attrs:
+ mapAttrsToList (name: value: { inherit name value; }) attrs;
+
+ # mapFilterAttrs ::
+ # (name -> value -> bool)
+ # (name -> value -> { name = any; value = any; })
+ # attrs
+ mapFilterAttrs = pred: f: attrs: filterAttrs pred (mapAttrs' f attrs);
+
+ # Generate an attribute set by mapping a function over a list of values.
+ genAttrs' = values: f: listToAttrs (map f values);
+
+ # anyAttrs :: (name -> value -> bool) attrs
+ anyAttrs = pred: attrs:
+ any (attr: pred attr.name attr.value) (attrsToList attrs);
+
+ # countAttrs :: (name -> value -> bool) attrs
+ countAttrs = pred: attrs:
+ count (attr: pred attr.name attr.value) (attrsToList attrs);
+}
diff --git a/lib/default.nix b/lib/default.nix
new file mode 100644
index 0000000..a275c09
--- /dev/null
+++ b/lib/default.nix
@@ -0,0 +1,18 @@
+{ inputs, lib, pkgs, ... }:
+
+let
+ inherit (lib) makeExtensible attrValues foldr;
+ inherit (modules) mapModules;
+
+ modules = import ./modules.nix {
+ inherit lib;
+ self.attrs = import ./attrs.nix { inherit lib; self = { }; };
+ };
+
+ mylib = makeExtensible (self:
+ with self; mapModules ./.
+ (file: import file { inherit self lib pkgs inputs; }));
+in
+mylib.extend
+ (self: super:
+ foldr (a: b: a // b) { } (attrValues super))
diff --git a/lib/misc.nix b/lib/misc.nix
new file mode 100644
index 0000000..484d0d5
--- /dev/null
+++ b/lib/misc.nix
@@ -0,0 +1,9 @@
+{ pkgs, ... }:
+
+rec {
+ # ifd3f/infra
+ wrapFile = name: path:
+ (pkgs.runCommand name { inherit path; } ''
+ cp -r "$path" "$out"
+ '');
+}
diff --git a/lib/modules.nix b/lib/modules.nix
new file mode 100644
index 0000000..ef7c289
--- /dev/null
+++ b/lib/modules.nix
@@ -0,0 +1,54 @@
+{ self, lib, ... }:
+
+let
+ inherit (builtins) attrValues readDir pathExists concatLists;
+ inherit (lib) id mapAttrsToList filterAttrs hasPrefix hasSuffix nameValuePair removeSuffix;
+ inherit (self.attrs) mapFilterAttrs;
+in
+rec {
+ mapModules = dir: fn:
+ mapFilterAttrs
+ (n: v:
+ v != null &&
+ !(hasPrefix "_" n))
+ (n: v:
+ let path = "${toString dir}/${n}"; in
+ if v == "directory" && pathExists "${path}/default.nix"
+ then nameValuePair n (fn path)
+ else if v == "regular" &&
+ n != "default.nix" &&
+ hasSuffix ".nix" n
+ then nameValuePair (removeSuffix ".nix" n) (fn path)
+ else nameValuePair "" null)
+ (readDir dir);
+
+ mapModules' = dir: fn:
+ attrValues (mapModules dir fn);
+
+ mapModulesRec = dir: fn:
+ mapFilterAttrs
+ (n: v:
+ v != null &&
+ !(hasPrefix "_" n))
+ (n: v:
+ let path = "${toString dir}/${n}"; in
+ if v == "directory"
+ then nameValuePair n (mapModulesRec path fn)
+ else if v == "regular" && n != "default.nix" && hasSuffix ".nix" n
+ then nameValuePair (removeSuffix ".nix" n) (fn path)
+ else nameValuePair "" null)
+ (readDir dir);
+
+ mapModulesRec' = dir: fn:
+ let
+ dirs =
+ mapAttrsToList
+ (k: _: "${dir}/${k}")
+ (filterAttrs
+ (n: v: v == "directory" && !(hasPrefix "_" n))
+ (readDir dir));
+ files = attrValues (mapModules dir id);
+ paths = files ++ concatLists (map (d: mapModulesRec' d id) dirs);
+ in
+ map fn paths;
+}
diff --git a/lib/system.nix b/lib/system.nix
new file mode 100644
index 0000000..8fc4dce
--- /dev/null
+++ b/lib/system.nix
@@ -0,0 +1,22 @@
+{ self, inputs, lib, pkgs, ... }:
+
+with lib;
+with lib.my;
+{
+ mkSystem = path: attrs @ { ... }: {
+ imports = [
+ {
+ networking.hostName = mkDefault
+ (removeSuffix ".nix" (baseNameOf path));
+ system.configurationRevision = self.rev or "dirty";
+ }
+ ../. # /default.nix