3 Commits

Author SHA1 Message Date
kurogeek f54cf1c60a mob next [ci-skip] [ci skip] [skip ci]
lastFile:modules/clan/phonebox/default.nix
2025-12-19 16:15:39 +07:00
kurogeek 1fa7da00c2 mob next [ci-skip] [ci skip] [skip ci]
lastFile:modules/clan/phonebox/default.nix
2025-12-19 09:21:24 +07:00
kurogeek 34e9774aa7 mob next [ci-skip] [ci skip] [skip ci]
lastFile:modules/clan/phonebox/default.nix
2025-12-18 15:47:08 +07:00
623 changed files with 522 additions and 26286 deletions
Generated
+40 -604
View File
@@ -1,58 +1,5 @@
{
"nodes": {
"arion": {
"inputs": {
"flake-parts": "flake-parts_2",
"haskell-flake": "haskell-flake",
"nixpkgs": [
"frappix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1733918465,
"narHash": "sha256-hSuGa8Hh67EHr2x812Ay6WFyFT2BGKn+zk+FJWeKXPg=",
"owner": "hercules-ci",
"repo": "arion",
"rev": "f01c95c10f9d4f04bb08d97b3233b530b180f12e",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "arion",
"type": "github"
}
},
"blank": {
"locked": {
"lastModified": 1625557891,
"narHash": "sha256-O8/MWsPBGhhyPoPLHZAuoZiiHo9q6FLlEeIDEXuj6T4=",
"owner": "divnix",
"repo": "blank",
"rev": "5a5d2684073d9f563072ed07c871d577a6c614a8",
"type": "github"
},
"original": {
"owner": "divnix",
"repo": "blank",
"type": "github"
}
},
"call-flake": {
"locked": {
"lastModified": 1687380775,
"narHash": "sha256-bmhE1TmrJG4ba93l9WQTLuYM53kwGQAjYHRvHOeuxWU=",
"owner": "divnix",
"repo": "call-flake",
"rev": "74061f6c241227cd05e79b702db9a300a2e4131a",
"type": "github"
},
"original": {
"owner": "divnix",
"repo": "call-flake",
"type": "github"
}
},
"clan-core": {
"inputs": {
"data-mesher": "data-mesher",
@@ -62,6 +9,7 @@
],
"nix-darwin": "nix-darwin",
"nix-select": "nix-select",
"nixos-facter-modules": "nixos-facter-modules",
"nixpkgs": [
"nixpkgs"
],
@@ -72,11 +20,11 @@
]
},
"locked": {
"lastModified": 1777319722,
"narHash": "sha256-VSJe7kyihvkAGHsb50UYgW9LJ8ItTuF+2+2xp7zwsh0=",
"lastModified": 1764799743,
"narHash": "sha256-MbbiNG/bhqe+4z7ml8TefIs4swSonmiV0CimCntXuCg=",
"ref": "refs/heads/main",
"rev": "6e6700d93f715ff82d8fe6bb59994389f4194d38",
"revCount": 14221,
"rev": "ddc0f9fabf33ad000676a33e97be6b5df12a4560",
"revCount": 11417,
"type": "git",
"url": "https://git.clan.lol/clan/clan-core"
},
@@ -101,11 +49,11 @@
]
},
"locked": {
"lastModified": 1777259361,
"narHash": "sha256-v8n+YBZurGxvVLoOMc+gHbL/j8mpTlWoNZJaKMrC7pM=",
"rev": "39fbab42b97e3d1f0d4cf74673737aacac0de92d",
"lastModified": 1762942435,
"narHash": "sha256-zIWGs5FIytTtJN+dhDb8Yx+q4TQI/yczuL539yVcyPE=",
"rev": "0ee328404b12c65e8106bde9e9fab8abf4ecada4",
"type": "tarball",
"url": "https://git.clan.lol/api/v1/repos/clan/data-mesher/archive/39fbab42b97e3d1f0d4cf74673737aacac0de92d.tar.gz"
"url": "https://git.clan.lol/api/v1/repos/clan/data-mesher/archive/0ee328404b12c65e8106bde9e9fab8abf4ecada4.tar.gz"
},
"original": {
"type": "tarball",
@@ -140,11 +88,11 @@
]
},
"locked": {
"lastModified": 1776613567,
"narHash": "sha256-gC9Cp5ibBmGD5awCA9z7xy6MW6iJufhazTYJOiGlCUI=",
"lastModified": 1764627417,
"narHash": "sha256-D6xc3Rl8Ab6wucJWdvjNsGYGSxNjQHzRc2EZ6eeQ6l4=",
"owner": "nix-community",
"repo": "disko",
"rev": "32f4236bfc141ae930b5ba2fb604f561fed5219d",
"rev": "5a88a6eceb8fd732b983e72b732f6f4b8269bef3",
"type": "github"
},
"original": {
@@ -153,39 +101,6 @@
"type": "github"
}
},
"dmerge": {
"inputs": {
"haumea": [
"frappix",
"std",
"haumea"
],
"nixlib": [
"frappix",
"std",
"lib"
],
"yants": [
"frappix",
"std",
"yants"
]
},
"locked": {
"lastModified": 1686862774,
"narHash": "sha256-ojGtRQ9pIOUrxsQEuEPerUkqIJEuod9hIflfNkY+9CE=",
"owner": "divnix",
"repo": "dmerge",
"rev": "9f7f7a8349d33d7bd02e0f2b484b1f076e503a96",
"type": "github"
},
"original": {
"owner": "divnix",
"ref": "0.2.1",
"repo": "dmerge",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
@@ -206,166 +121,6 @@
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": [
"frappix",
"arion",
"nixpkgs"
]
},
"locked": {
"lastModified": 1733312601,
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_3"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_3": {
"locked": {
"lastModified": 1653893745,
"narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"frappix": {
"inputs": {
"arion": "arion",
"devshell": [
"devshell"
],
"microvm": "microvm",
"n2c": "n2c",
"nixago": "nixago",
"nixpkgs": [
"nixpkgs"
],
"std": "std"
},
"locked": {
"lastModified": 1777566120,
"narHash": "sha256-/FZmeaTm8ExKatIciQ6AIMj0Qw5ChYu/8vApENJ1QEc=",
"owner": "kurogeek",
"repo": "frappix",
"rev": "799d1fa749c69eec65a6aa1880a3346c24a40b7c",
"type": "github"
},
"original": {
"owner": "kurogeek",
"repo": "frappix",
"type": "github"
}
},
"haskell-flake": {
"locked": {
"lastModified": 1675296942,
"narHash": "sha256-u1X1sblozi5qYEcLp1hxcyo8FfDHnRUVX3dJ/tW19jY=",
"owner": "srid",
"repo": "haskell-flake",
"rev": "c2cafce9d57bfca41794dc3b99c593155006c71e",
"type": "github"
},
"original": {
"owner": "srid",
"ref": "0.1.0",
"repo": "haskell-flake",
"type": "github"
}
},
"haumea": {
"inputs": {
"nixpkgs": [
"frappix",
"std",
"lib"
]
},
"locked": {
"lastModified": 1685133229,
"narHash": "sha256-FePm/Gi9PBSNwiDFq3N+DWdfxFq0UKsVVTJS3cQPn94=",
"owner": "nix-community",
"repo": "haumea",
"rev": "34dd58385092a23018748b50f9b23de6266dffc2",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "v0.2.2",
"repo": "haumea",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1768068402,
"narHash": "sha256-bAXnnJZKJiF7Xr6eNW6+PhBf1lg2P1aFUO9+xgWkXfA=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "8bc5473b6bc2b6e1529a9c4040411e1199c43b4c",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"import-tree": {
"locked": {
"lastModified": 1752730890,
@@ -381,99 +136,22 @@
"type": "github"
}
},
"incl": {
"inputs": {
"nixlib": [
"frappix",
"std",
"lib"
]
},
"locked": {
"lastModified": 1693483555,
"narHash": "sha256-Beq4WhSeH3jRTZgC1XopTSU10yLpK1nmMcnGoXO0XYo=",
"owner": "divnix",
"repo": "incl",
"rev": "526751ad3d1e23b07944b14e3f6b7a5948d3007b",
"type": "github"
},
"original": {
"owner": "divnix",
"repo": "incl",
"type": "github"
}
},
"lib": {
"locked": {
"lastModified": 1722128034,
"narHash": "sha256-L8rwzYPsLo/TYtydPJoQyYOfetuiyQYnTWYcyB8UE/s=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "d15f6f6021693898fcd2c6a9bb13707383da9bbc",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"liminix": {
"flake": false,
"locked": {
"lastModified": 1777223456,
"narHash": "sha256-yqZ9OFSXoKgdT6nWwt2d0OFwmfQXASl73hhjtvAD11A=",
"ref": "refs/heads/main",
"rev": "5f2abc0d2b30eb5878d60488a72138958c228976",
"revCount": 1672,
"lastModified": 1760426231,
"narHash": "sha256-r8c5PKtsxAvtQ/k17GH+WNvP47Lr+AbExLMPdLtvAKE=",
"ref": "refs/heads/fix-gl-ar750",
"rev": "3f1f7c08d440130cce9262a93ce78ed7969d93cd",
"revCount": 1574,
"type": "git",
"url": "https://gti.telent.net/dan/liminix"
"url": "https://git.b4l.co.th/newedge/liminix"
},
"original": {
"ref": "refs/heads/fix-gl-ar750",
"rev": "3f1f7c08d440130cce9262a93ce78ed7969d93cd",
"type": "git",
"url": "https://gti.telent.net/dan/liminix"
}
},
"microvm": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [
"frappix",
"nixpkgs"
],
"spectrum": "spectrum"
},
"locked": {
"lastModified": 1737981104,
"narHash": "sha256-7AGmPPBgLHHWgzzFYDJcyhv/NiuCrpgzg8IyA7Q/H9o=",
"owner": "astro",
"repo": "microvm.nix",
"rev": "3768f4937f38334898c67e03f40e244a57a74caa",
"type": "github"
},
"original": {
"owner": "astro",
"repo": "microvm.nix",
"type": "github"
}
},
"n2c": {
"inputs": {
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1730479402,
"narHash": "sha256-79NLeNjpCa4mSasmFsE3QA6obURezF0TUO5Pm+1daog=",
"owner": "nlewo",
"repo": "nix2container",
"rev": "5fb215a1564baa74ce04ad7f903d94ad6617e17a",
"type": "github"
},
"original": {
"owner": "nlewo",
"repo": "nix2container",
"type": "github"
"url": "https://git.b4l.co.th/newedge/liminix"
}
},
"nix-darwin": {
@@ -484,11 +162,11 @@
]
},
"locked": {
"lastModified": 1775037210,
"narHash": "sha256-KM2WYj6EA7M/FVZVCl3rqWY+TFV5QzSyyGE2gQxeODU=",
"lastModified": 1764161084,
"narHash": "sha256-HN84sByg9FhJnojkGGDSrcjcbeioFWoNXfuyYfJ1kBE=",
"owner": "nix-darwin",
"repo": "nix-darwin",
"rev": "06648f4902343228ce2de79f291dd5a58ee12146",
"rev": "e95de00a471d07435e0527ff4db092c84998698e",
"type": "github"
},
"original": {
@@ -510,53 +188,28 @@
"url": "https://git.clan.lol/clan/nix-select/archive/main.tar.gz"
}
},
"nixago": {
"inputs": {
"flake-utils": "flake-utils_3",
"nixago-exts": [
"frappix"
],
"nixpkgs": [
"frappix",
"nixpkgs"
]
},
"nixos-facter-modules": {
"locked": {
"lastModified": 1714086354,
"narHash": "sha256-yKVQMxL9p7zCWUhnGhDzRVT8sDgHoI3V595lBK0C2YA=",
"lastModified": 1764252389,
"narHash": "sha256-3bbuneTKZBkYXlm0bE36kUjiDsasoIC1GWBw/UEJ9T4=",
"owner": "nix-community",
"repo": "nixago",
"rev": "5133633e9fe6b144c8e00e3b212cdbd5a173b63d",
"repo": "nixos-facter-modules",
"rev": "5ea68886d95218646d11d3551a476d458df00778",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixago",
"repo": "nixos-facter-modules",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1712920918,
"narHash": "sha256-1yxFvUcJfUphK9V91KufIQom7gCsztza0H4Rz2VCWUU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "92323443a56f4e9fc4e4b712e3119f66d0969297",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1774794121,
"narHash": "sha256-gih24b728CK8twDNU7VX9vVYK2tLEXvy9gm/GKq2VeE=",
"lastModified": 1761656231,
"narHash": "sha256-krgZxGAIIIKFJS+UB0l8do3sYUDWJc75M72tepmVMzE=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "c397ef6af68c018462d786e1b65384abc472a907",
"rev": "d7f52a7a640bc54c7bb414cca603835bf8dd4b10",
"type": "github"
},
"original": {
@@ -566,102 +219,14 @@
"type": "github"
}
},
"nosys": {
"locked": {
"lastModified": 1668010795,
"narHash": "sha256-JBDVBnos8g0toU7EhIIqQ1If5m/nyBqtHhL3sicdPwI=",
"owner": "divnix",
"repo": "nosys",
"rev": "feade0141487801c71ff55623b421ed535dbdefa",
"type": "github"
},
"original": {
"owner": "divnix",
"repo": "nosys",
"type": "github"
}
},
"paisano": {
"inputs": {
"call-flake": "call-flake",
"nixpkgs": [
"frappix",
"std",
"nixpkgs"
],
"nosys": "nosys",
"yants": [
"frappix",
"std",
"yants"
]
},
"locked": {
"lastModified": 1708640854,
"narHash": "sha256-EpcAmvIS4ErqhXtVEfd2GPpU/E/s8CCRSfYzk6FZ/fY=",
"owner": "paisano-nix",
"repo": "core",
"rev": "adcf742bc9463c08764ca9e6955bd5e7dcf3a3fe",
"type": "github"
},
"original": {
"owner": "paisano-nix",
"ref": "0.2.0",
"repo": "core",
"type": "github"
}
},
"paisano-tui": {
"flake": false,
"locked": {
"lastModified": 1708637035,
"narHash": "sha256-R19YURSK+MY/Rw6FZnojQS9zuDh+OoTAyngQAjjoubc=",
"owner": "paisano-nix",
"repo": "tui",
"rev": "231761b260587a64817e4ffae3afc15defaa15db",
"type": "github"
},
"original": {
"owner": "paisano-nix",
"ref": "v0.5.0",
"repo": "tui",
"type": "github"
}
},
"plasma-manager": {
"inputs": {
"home-manager": [
"home-manager"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1772361940,
"narHash": "sha256-B1Cz+ydL1iaOnGlwOFld/C8lBECPtzhiy/pP93/CuyY=",
"owner": "nix-community",
"repo": "plasma-manager",
"rev": "a4b33606111c9c5dcd10009042bb710307174f51",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "plasma-manager",
"type": "github"
}
},
"root": {
"inputs": {
"clan-core": "clan-core",
"devshell": "devshell",
"flake-parts": "flake-parts",
"frappix": "frappix",
"home-manager": "home-manager",
"import-tree": "import-tree",
"liminix": "liminix",
"nixpkgs": "nixpkgs_2",
"plasma-manager": "plasma-manager",
"nixpkgs": "nixpkgs",
"treefmt-nix": "treefmt-nix"
}
},
@@ -673,11 +238,11 @@
]
},
"locked": {
"lastModified": 1776771786,
"narHash": "sha256-DRFGPfFV6hbrfO9a1PH1FkCi7qR5FgjSqsQGGvk1rdI=",
"lastModified": 1764483358,
"narHash": "sha256-EyyvCzXoHrbL467YSsQBTWWg4sR96MH1sPpKoSOelB4=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "bef289e2248991f7afeb95965c82fbcd8ff72598",
"rev": "5aca6ff67264321d47856a2ed183729271107c9c",
"type": "github"
},
"original": {
@@ -686,114 +251,7 @@
"type": "github"
}
},
"spectrum": {
"flake": false,
"locked": {
"lastModified": 1733308308,
"narHash": "sha256-+RcbMAjSxV1wW5UpS9abIG1lFZC8bITPiFIKNnE7RLs=",
"ref": "refs/heads/main",
"rev": "80c9e9830d460c944c8f730065f18bb733bc7ee2",
"revCount": 792,
"type": "git",
"url": "https://spectrum-os.org/git/spectrum"
},
"original": {
"type": "git",
"url": "https://spectrum-os.org/git/spectrum"
}
},
"std": {
"inputs": {
"arion": [
"frappix",
"arion"
],
"blank": "blank",
"devshell": [
"frappix",
"devshell"
],
"dmerge": "dmerge",
"haumea": "haumea",
"incl": "incl",
"lib": "lib",
"makes": [
"frappix",
"std",
"blank"
],
"microvm": [
"frappix",
"microvm"
],
"n2c": [
"frappix",
"n2c"
],
"nixago": [
"frappix",
"nixago"
],
"nixpkgs": [
"frappix",
"nixpkgs"
],
"paisano": "paisano",
"paisano-tui": "paisano-tui",
"terranix": [
"frappix",
"std",
"blank"
],
"yants": "yants"
},
"locked": {
"lastModified": 1738072995,
"narHash": "sha256-jfwWnAVeQzIBS5Pex0xSUbGk88g1GFF2w+ohOtbRtcY=",
"owner": "divnix",
"repo": "std",
"rev": "2874513c4b76be4c4200779814993b546fe4a909",
"type": "github"
},
"original": {
"owner": "divnix",
"ref": "v0.33.4",
"repo": "std",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1774449309,
"narHash": "sha256-brhZ8DmuGtzkCYHJg4HEd602amKm89Y9ytsFZ5uWD1w=",
"owner": "nix-systems",
"repo": "default",
"rev": "c29398b59d2048c4ab79345812849c9bd15e9150",
"type": "github"
},
"original": {
"owner": "nix-systems",
"ref": "future-26.11",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
@@ -815,11 +273,11 @@
]
},
"locked": {
"lastModified": 1768158989,
"narHash": "sha256-67vyT1+xClLldnumAzCTBvU0jLZ1YBcf4vANRWP3+Ak=",
"lastModified": 1752055615,
"narHash": "sha256-19m7P4O/Aw/6+CzncWMAJu89JaKeMh3aMle1CNQSIwM=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "e96d59dff5c0d7fddb9d113ba108f03c3ef99eca",
"rev": "c9d477b5d5bd7f26adddd3f96cfd6a904768d4f9",
"type": "github"
},
"original": {
@@ -827,28 +285,6 @@
"repo": "treefmt-nix",
"type": "github"
}
},
"yants": {
"inputs": {
"nixpkgs": [
"frappix",
"std",
"lib"
]
},
"locked": {
"lastModified": 1686863218,
"narHash": "sha256-kooxYm3/3ornWtVBNHM3Zh020gACUyFX2G0VQXnB+mk=",
"owner": "divnix",
"repo": "yants",
"rev": "8f0da0dba57149676aa4817ec0c880fbde7a648d",
"type": "github"
},
"original": {
"owner": "divnix",
"repo": "yants",
"type": "github"
}
}
},
"root": "root",
+1 -18
View File
@@ -15,15 +15,6 @@
inputs.nixpkgs-lib.follows = "nixpkgs";
url = "github:hercules-ci/flake-parts";
};
home-manager = {
inputs.nixpkgs.follows = "nixpkgs";
url = "github:nix-community/home-manager";
};
plasma-manager = {
url = "github:nix-community/plasma-manager";
inputs.nixpkgs.follows = "nixpkgs";
inputs.home-manager.follows = "home-manager";
};
import-tree.url = "github:vic/import-tree";
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
treefmt-nix = {
@@ -31,14 +22,9 @@
inputs.nixpkgs.follows = "nixpkgs";
};
liminix = {
url = "git+https://gti.telent.net/dan/liminix";
url = "git+https://git.b4l.co.th/newedge/liminix?ref=refs/heads/fix-gl-ar750&rev=3f1f7c08d440130cce9262a93ce78ed7969d93cd";
flake = false;
};
frappix = {
url = "github:kurogeek/frappix";
inputs.nixpkgs.follows = "nixpkgs";
inputs.devshell.follows = "devshell";
};
};
outputs =
{
@@ -55,8 +41,6 @@
./fmt.nix
./shell.nix
./overlays
./modules/nixos
./machines
./routers
./inventories
@@ -77,7 +61,6 @@
};
packages.think = pkgs.think-gtcm;
packages.think-be = pkgs.think-backend-gtcm;
packages.file-uploader = pkgs.gtcm-file-uploader;
};
}
);
+20 -125
View File
@@ -1,8 +1,4 @@
{
imports = [
./personal-computer.nix
./emmie.nix
];
clan = {
inventory = {
@@ -10,15 +6,11 @@
glom = [
"vega"
"ramus"
"canopus"
];
poy = [ "deneb" ];
w = [ "sirius" ];
b4l = [
"rigel"
"neptune"
"rana"
"petra"
];
phonebox = [
"neptune"
@@ -29,20 +21,16 @@
"adhil"
"buna"
];
global-network = [
"rana"
"sirius"
"hadar"
"procyon"
];
};
instances = {
sshd = {
roles.server.tags."all" = { };
roles.server.settings = {
authorizedKeys = {
admin = {
module = {
name = "admin";
input = "clan-core";
};
roles.default.tags."all" = { };
roles.default.settings.allowedKeys = {
"berwn" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAB/raxJR8gASmquP63weHelbi+da2WBJR1DgzHPNz/f";
"davhau" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDuhpzDHBPvn8nv8RH1MRomDOaXyP4GziQm7r3MZ1Syk";
"vi" =
@@ -57,18 +45,6 @@
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIJMi3TAuwDtIeO4MsORlBZ31HzaV5bji1fFBPcC9/tWuAAAABHNzaDo=";
};
};
};
root-password = {
module = {
name = "users";
input = "clan-core";
};
roles.default.tags."all" = { };
roles.default.settings = {
user = "root";
};
};
tor = {
module = {
@@ -110,34 +86,6 @@
roles.peer.tags.b4l = { };
};
poy-network = {
module = {
name = "zerotier";
input = "clan-core";
};
roles.controller.machines."deneb" = {
settings.allowedIps = [
#kurogeek
"fdfe:7bf:a795:4524:4c99:932b:d36d:b8cc"
];
};
roles.peer.tags."poy" = { };
};
yggdrasil-global-network = {
module = {
name = "yggdrasil";
input = "clan-core";
};
roles.default.tags."global-network" = { };
roles.default.settings.extraPeers = [
"tls://ygg.jjolly.dev:3443"
"tls://[2602:fc24:18:7a42::1]:993"
"tcp://leo.node.3dt.net:9002"
"tcp://ygg-kcmo.incognet.io:8883"
];
};
yggdrasil-phone-network = {
module = {
name = "yggdrasil";
@@ -161,6 +109,12 @@
roles.default.machines."adhil".settings = {
ata-ethernet-iface = "end0";
};
roles.default.machines."rigel".settings = {
extraClientNumbers = [
"01"
"02"
];
};
};
pocket-id = {
@@ -212,6 +166,13 @@
};
roles.default.machines.b4l = { };
};
pingvin = {
module = {
name = "pingvin";
input = "self";
};
roles.default.machines.b4l = { };
};
paperless = {
module = {
name = "paperless";
@@ -245,72 +206,6 @@
};
};
};
git-daemon = {
module = {
name = "git-daemon";
input = "self";
};
roles.default.machines.neptune = {
settings.repositories =
let
defaults = rec {
write-access = [
"10.0.0.0/24"
"200:d7b1:c5d5:ea7:27ad:6837:40f6:404d/128"
];
read-access = write-access;
};
PUBLIC = {
read-access = [
"10.0.0.0/24"
"0200::/7"
];
};
in
builtins.mapAttrs (_: override: defaults // override) {
"9e" = PUBLIC;
archive-dl = { };
barrytown = { };
cleanroom = PUBLIC;
community-memory = { };
eris = { };
ftdi-sd-spi = { };
go-go-gadget = { };
hacking-the-kindle = { };
islands = PUBLIC;
kt = { };
legba = { };
llb = PUBLIC;
llc = PUBLIC;
lora = { };
mute = { };
navi = { };
notmuch-memoryhole = PUBLIC;
pms5003 = { };
thinc = PUBLIC;
toad = { };
yggdrasil-erlang = { };
};
};
};
samba = {
module = {
name = "samba";
input = "self";
};
roles.server.machines."sirius".settings = {
globalUsers = {
w.writePerm = true;
};
sharedFolders = {
WHITEHOUSE = {
allowedGuest = true;
};
};
dataDir = "/mnt/hdd/samba";
};
};
};
};
};
-43
View File
@@ -1,43 +0,0 @@
{ config, ... }:
let
username = "emmie";
userhome = "/home/${username}";
in
{
clan.inventory = {
tags = {
emmie = [ "rana" ];
};
instances = {
emmie-syncthing = {
module = {
name = "syncthing";
input = "clan-core";
};
roles.peer.tags.emmie = { };
roles.peer.settings = {
folders = {
Syncthing.path = "${userhome}/Share/Syncthing";
Desktop.path = "${userhome}/Desktop";
};
extraDevices = {
pixel7a = {
id = "CEUJMEG-SOHXIJF-G2FT5QB-6MZW3EN-PONI3QN-HPEIOSU-IMSLGW7-XUU6BQK";
name = "eris";
addresses = [ "dynamic" ];
};
};
};
roles.peer.extraModules = [
{
config.services.syncthing = {
user = username;
dataDir = "${userhome}/Share";
};
}
];
};
};
};
}
-50
View File
@@ -1,50 +0,0 @@
{
clan.inventory = {
tags = {
kde-desktop = [
"rana"
"petra"
];
personal-computer = [
"rana"
"petra"
];
};
instances = {
emmie-home = {
module = {
name = "emmie-home";
input = "self";
};
roles.default.machines."rana" = { };
};
chocolate-home = {
module = {
name = "home-user";
input = "self";
};
roles.default.settings = {
username = "chocolate";
kbLayout = "us,th";
kbOptions = "grp:win_space_toggle,grp:alt_shift_toggle";
};
roles.default.machines."petra" = { };
};
personal-computer = {
module = {
name = "personal-computer";
input = "self";
};
roles.default.tags."personal-computer" = { };
};
kde = {
module = {
name = "kde";
input = "clan-core";
};
roles.default.tags."kde-desktop" = { };
};
};
};
}
-21
View File
@@ -20,27 +20,6 @@
},
"buna": {
"installedAt": 1765343708
},
"rana": {
"installedAt": 1773134236
},
"petra": {
"installedAt": 1769064458
},
"sirius": {
"installedAt": 1770974584
},
"deneb": {
"installedAt": 1775718970
},
"canopus": {
"installedAt": 1775793532
},
"hadar": {
"installedAt": 1774427255
},
"procyon": {
"installedAt": 1775458442
}
}
}
+2 -3
View File
@@ -7,8 +7,7 @@
clan.core.sops.defaultGroups = [ "admins" ];
# clan.core.networking.targetHost = "root@";
clan.core.settings.name = "adhil";
clan.core.settings.machine.description =
"Raspberry Pi 4 SBC board for one of w phone network. (With w office)";
clan.meta.name = "adhil";
clan.meta.description = "Raspberry Pi 4 SBC board for one of w phone network. (With w office)";
}
+2 -2
View File
@@ -7,7 +7,7 @@
clan.core.sops.defaultGroups = [ "admins" ];
# clan.core.networking.targetHost = "root@";
clan.core.settings.name = "almach";
clan.core.settings.machine.description = "Radxa X4 SBC board for one of w phone network.";
clan.meta.name = "almach";
clan.meta.description = "Radxa X4 SBC board for one of w phone network.";
}
+2 -2
View File
@@ -7,7 +7,7 @@
clan.core.sops.defaultGroups = [ "admins" ];
# clan.core.networking.targetHost = "root@";
clan.core.settings.name = "alpheratz";
clan.core.settings.machine.description = "Radxa X4 SBC board for one of w phone network.";
clan.meta.name = "alpheratz";
clan.meta.description = "Radxa X4 SBC board for one of w phone network.";
}
+1 -1
View File
@@ -19,7 +19,7 @@ in
services.nextcloud = {
hostName = ncDomain;
package = pkgs.nextcloud33;
package = pkgs.nextcloud31;
settings = {
+45
View File
@@ -0,0 +1,45 @@
{
pkgs,
config,
...
}:
let
serviceName = "${config.networking.hostName}-pingvin";
domain-name = "${
config.clan.core.vars.generators."${serviceName}".files.subdomain.value
}.${config.networking.fqdn}";
in
{
clan.core.vars.generators."${serviceName}" = {
files = {
subdomain.secret = false;
};
prompts = {
subdomain = {
persist = true;
type = "line";
description = "Sub-domain for Pingvin. Default:(share)";
};
};
runtimeInputs = [
pkgs.xkcdpass
pkgs.coreutils
];
script = ''
prompt_domain=$(cat "$prompts"/subdomain)
if [[ -n "''${prompt_domain-}" ]]; then
echo $prompt_domain | tr -d "\n" > "$out"/subdomain
else
echo -n "share" > "$out"/subdomain
fi
'';
};
services.pingvin-share = {
nginx.enable = true;
https = true;
hostname = domain-name;
};
}
+2 -3
View File
@@ -7,8 +7,7 @@
clan.core.sops.defaultGroups = [ "admins" ];
# clan.core.networking.targetHost = "root@";
clan.core.settings.name = "buna";
clan.core.settings.machine.description =
"Radxa X4 SBC board for one of w phone network. (With w whitehouse)";
clan.meta.name = "buna";
clan.meta.description = "Radxa X4 SBC board for one of w phone network. (With w whitehouse)";
}
-109
View File
@@ -1,109 +0,0 @@
{
inputs,
pkgs,
config,
...
}:
let
sitename = "glomerp.newedge.house";
nbClientName = "netbird-b4l";
in
{
clan.core.settings.machine.description = "VM machine that host ERPNext for glomglom";
imports = [ inputs.frappix.nixosModules.x86_64-linux.frappix ];
nixpkgs.overlays = [
inputs.self.overlays.frappixFrappeOverlay
inputs.self.overlays.frappixLibsOverlay
inputs.self.overlays.frappixPythonOverlay
inputs.self.overlays.frappixToolsOverlay
];
clan.core.vars.generators.frappix = {
files = {
sslCertificate.secret = false;
sslCertificateKey = {
owner = "nginx";
group = "nginx";
secret = true;
};
adminPassword.secret = true;
};
runtimeInputs = with pkgs; [
openssl
xkcdpass
];
script = ''
openssl req -x509 -newkey rsa:4096 -keyout $out/sslCertificateKey -out $out/sslCertificate -sha256 -days 3650 -nodes -subj "/C=TH/ST=ChiangMai/L=ChiangMai/O=kurogeek/CN=kurogeek.home"
xkcdpass --numwords 4 --delimiter - --count 1 | tr -d "\n" > "$out"/adminPassword
'';
};
services.frappe = {
enable = true;
project = "glomerp";
gunicorn_workers = 2;
adminPassword = config.clan.core.vars.generators.frappix.files.adminPassword.path;
apps = [
pkgs.frappix.erpnext
pkgs.frappix.hrms
];
sites = {
"${sitename}" = {
domains = [ "localhost" ];
apps = [
"frappe"
"erpnext"
"hrms"
];
};
};
};
services.nginx.virtualHosts."${sitename}" = {
sslCertificate = config.clan.core.vars.generators.frappix.files.sslCertificate.path;
sslCertificateKey = config.clan.core.vars.generators.frappix.files.sslCertificateKey.path;
};
nixpkgs.hostPlatform = {
system = "x86_64-linux";
};
clan.core.vars.generators.nginx = {
files = {
sslCert = {
owner = "nginx";
group = "nginx";
secret = true;
};
sslKey = {
owner = "nginx";
group = "nginx";
secret = true;
};
};
runtimeInputs = [
pkgs.openssl
];
script = ''
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout $out/sslKey \
-out $out/sslCert \
-subj "/CN=localhost"
'';
};
networking.firewall.allowedTCPPorts = [
80
443
];
# services.nginx.virtualHosts."${domain}" = {
# forceSSL = true;
# sslCertificate = config.clan.core.vars.generators.nginx.files.sslCert.path;
# sslCertificateKey = config.clan.core.vars.generators.nginx.files.sslKey.path;
# };
system.stateVersion = "25.11";
clan.core.sops.defaultGroups = [ "admins" ];
}
-83
View File
@@ -1,83 +0,0 @@
let
hashDisk = disk: "os-${builtins.substring 0 5 (builtins.hashString "sha256" disk)}";
os = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0";
in
{
boot.loader = {
systemd-boot = {
enable = true;
};
efi = {
canTouchEfiVariables = true;
};
};
disko.devices = {
disk = {
"os-${hashDisk os}" = {
type = "disk";
device = os;
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "nofail" ];
};
};
system = {
size = "100%";
content = {
type = "zfs";
pool = "zroot";
};
};
};
};
};
};
zpool = {
zroot = {
type = "zpool";
rootFsOptions = {
mountpoint = "none";
compression = "lz4";
acltype = "posixacl";
xattr = "sa";
"com.sun:auto-snapshot" = "true";
};
options.ashift = "12";
datasets = {
"root" = {
type = "zfs_fs";
options.mountpoint = "none";
};
"root/nixos" = {
type = "zfs_fs";
options.mountpoint = "/";
mountpoint = "/";
};
"root/home" = {
type = "zfs_fs";
options.mountpoint = "/home";
mountpoint = "/home";
};
"root/tmp" = {
type = "zfs_fs";
mountpoint = "/tmp";
options = {
mountpoint = "/tmp";
sync = "disabled";
};
};
};
};
};
};
}
File diff suppressed because it is too large Load Diff
+1 -5
View File
@@ -1,8 +1,4 @@
{
inputs,
self,
...
}:
{ inputs, self, ... }:
{
imports = [
inputs.clan-core.flakeModules.default
-107
View File
@@ -1,107 +0,0 @@
{
inputs,
pkgs,
config,
...
}:
let
sitename = "poyerp.newedge.house";
in
{
clan.core.settings.machine.description = "VM machine that host ERPNext for poysound";
imports = [ inputs.frappix.nixosModules.x86_64-linux.frappix ];
nixpkgs.overlays = [
inputs.self.overlays.frappixFrappeOverlay
inputs.self.overlays.frappixLibsOverlay
inputs.self.overlays.frappixPythonOverlay
inputs.self.overlays.frappixToolsOverlay
];
clan.core.vars.generators.frappix = {
files = {
sslCertificate.secret = false;
sslCertificateKey = {
owner = "nginx";
group = "nginx";
secret = true;
};
adminPassword.secret = true;
};
runtimeInputs = with pkgs; [
openssl
xkcdpass
];
script = ''
openssl req -x509 -newkey rsa:4096 -keyout $out/sslCertificateKey -out $out/sslCertificate -sha256 -days 3650 -nodes -subj "/C=TH/ST=ChiangMai/L=ChiangMai/O=kurogeek/CN=kurogeek.home"
xkcdpass --numwords 4 --delimiter - --count 1 | tr -d "\n" > "$out"/adminPassword
'';
};
services.frappe = {
enable = true;
project = "poyerp";
gunicorn_workers = 2;
adminPassword = config.clan.core.vars.generators.frappix.files.adminPassword.path;
apps = [
pkgs.frappix.erpnext
pkgs.frappix.hrms
];
sites = {
"${sitename}" = {
domains = [ "localhost" ];
apps = [
"frappe"
"erpnext"
"hrms"
];
};
};
};
services.nginx.virtualHosts."${sitename}" = {
sslCertificate = config.clan.core.vars.generators.frappix.files.sslCertificate.path;
sslCertificateKey = config.clan.core.vars.generators.frappix.files.sslCertificateKey.path;
};
nixpkgs.hostPlatform = {
system = "x86_64-linux";
};
clan.core.vars.generators.nginx = {
files = {
sslCert = {
owner = "nginx";
group = "nginx";
secret = true;
};
sslKey = {
owner = "nginx";
group = "nginx";
secret = true;
};
};
runtimeInputs = [
pkgs.openssl
];
script = ''
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout $out/sslKey \
-out $out/sslCert \
-subj "/CN=localhost"
'';
};
networking.firewall.allowedTCPPorts = [
80
443
];
# services.nginx.virtualHosts."${domain}" = {
# forceSSL = true;
# sslCertificate = config.clan.core.vars.generators.nginx.files.sslCert.path;
# sslCertificateKey = config.clan.core.vars.generators.nginx.files.sslKey.path;
# };
system.stateVersion = "25.11";
clan.core.sops.defaultGroups = [ "admins" ];
}
-83
View File
@@ -1,83 +0,0 @@
let
hashDisk = disk: "os-${builtins.substring 0 5 (builtins.hashString "sha256" disk)}";
os = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0";
in
{
boot.loader = {
systemd-boot = {
enable = true;
};
efi = {
canTouchEfiVariables = true;
};
};
disko.devices = {
disk = {
"os-${hashDisk os}" = {
type = "disk";
device = os;
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "nofail" ];
};
};
system = {
size = "100%";
content = {
type = "zfs";
pool = "zroot";
};
};
};
};
};
};
zpool = {
zroot = {
type = "zpool";
rootFsOptions = {
mountpoint = "none";
compression = "lz4";
acltype = "posixacl";
xattr = "sa";
"com.sun:auto-snapshot" = "true";
};
options.ashift = "12";
datasets = {
"root" = {
type = "zfs_fs";
options.mountpoint = "none";
};
"root/nixos" = {
type = "zfs_fs";
options.mountpoint = "/";
mountpoint = "/";
};
"root/home" = {
type = "zfs_fs";
options.mountpoint = "/home";
mountpoint = "/home";
};
"root/tmp" = {
type = "zfs_fs";
mountpoint = "/tmp";
options = {
mountpoint = "/tmp";
sync = "disabled";
};
};
};
};
};
};
}
File diff suppressed because it is too large Load Diff
-100
View File
@@ -1,100 +0,0 @@
{
inputs,
config,
pkgs,
...
}:
let
domain = "poy-inventory.newedge.house";
in
{
clan.core.settings.machine.description = "VM machine that host Inventree system for Poy";
imports = [
inputs.self.nixosModules.inventree
];
nixpkgs.overlays = [
inputs.self.overlays.packagesOverlay
];
nixpkgs.hostPlatform = {
system = "x86_64-linux";
};
clan.core.vars.generators.inventree = {
files = {
secret-key = {
owner = "inventree";
group = "inventree";
secret = true;
};
oidc-key = {
owner = "inventree";
group = "inventree";
secret = true;
};
admin-password = {
owner = "inventree";
group = "inventree";
secret = true;
};
};
runtimeInputs = [
pkgs.pwgen
pkgs.xkcdpass
];
script = ''
pwgen -s 32 1 > $out/secret-key
pwgen -s 32 1 > $out/oidc-key
xkcdpass --numwords 4 --delimiter - --count 1 | tr -d "\n" > "$out"/admin-password
'';
};
clan.core.vars.generators.nginx = {
files = {
sslCert = {
owner = "nginx";
group = "nginx";
secret = true;
};
sslKey = {
owner = "nginx";
group = "nginx";
secret = true;
};
};
runtimeInputs = [
pkgs.openssl
];
script = ''
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout $out/sslKey \
-out $out/sslCert \
-subj "/CN=localhost"
'';
};
networking.firewall.allowedTCPPorts = [
80
443
];
services.inventree = {
enable = true;
hostName = "${domain}";
config.site_url = "https://${config.services.inventree.hostName}";
secretKeyFile = config.clan.core.vars.generators.inventree.files.secret-key.path;
config.oidc_private_key_file = config.clan.core.vars.generators.inventree.files.oidc-key.path;
config.adminPasswordFile = config.clan.core.vars.generators.inventree.files.admin-password.path;
};
# services.nginx.virtualHosts."${domain}" = {
# forceSSL = true;
# sslCertificate = config.clan.core.vars.generators.nginx.files.sslCert.path;
# sslCertificateKey = config.clan.core.vars.generators.nginx.files.sslKey.path;
# };
system.stateVersion = "25.11";
clan.core.sops.defaultGroups = [ "admins" ];
}
-83
View File
@@ -1,83 +0,0 @@
let
hashDisk = disk: "os-${builtins.substring 0 5 (builtins.hashString "sha256" disk)}";
os = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0";
in
{
boot.loader = {
systemd-boot = {
enable = true;
};
efi = {
canTouchEfiVariables = true;
};
};
disko.devices = {
disk = {
"os-${hashDisk os}" = {
type = "disk";
device = os;
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "nofail" ];
};
};
system = {
size = "100%";
content = {
type = "zfs";
pool = "zroot";
};
};
};
};
};
};
zpool = {
zroot = {
type = "zpool";
rootFsOptions = {
mountpoint = "none";
compression = "lz4";
acltype = "posixacl";
xattr = "sa";
"com.sun:auto-snapshot" = "true";
};
options.ashift = "12";
datasets = {
"root" = {
type = "zfs_fs";
options.mountpoint = "none";
};
"root/nixos" = {
type = "zfs_fs";
options.mountpoint = "/";
mountpoint = "/";
};
"root/home" = {
type = "zfs_fs";
options.mountpoint = "/home";
mountpoint = "/home";
};
"root/tmp" = {
type = "zfs_fs";
mountpoint = "/tmp";
options = {
mountpoint = "/tmp";
sync = "disabled";
};
};
};
};
};
};
}
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@
clan.core.sops.defaultGroups = [ "admins" ];
# clan.core.networking.targetHost = "root@";
clan.core.settings.name = "mirach";
clan.core.settings.machine.description = "Radxa X4 SBC board for one of w phone network.";
clan.meta.name = "mirach";
clan.meta.description = "Radxa X4 SBC board for one of w phone network.";
}
+2 -2
View File
@@ -56,7 +56,7 @@
"tls://astrra.space:55535"
];
clan.core.settings.name = "neptune";
clan.core.settings.machine.description = "Radxa SBC board for testing. (With vi)";
clan.meta.name = "neptune";
clan.meta.description = "Radxa SBC board for testing. (With vi)";
}
-13
View File
@@ -1,13 +0,0 @@
{ self, ... }:
{
imports = [
self.nixosModules.common
];
nixpkgs.hostPlatform = {
system = "x86_64-linux";
};
system.stateVersion = "25.11";
clan.core.sops.defaultGroups = [ "admins" ];
clan.core.settings.machine.description = "A personal computer for Chocolate Shop";
}
-77
View File
@@ -1,77 +0,0 @@
{ ... }:
let
hashDisk = disk: "os-${builtins.substring 0 5 (builtins.hashString "sha256" disk)}";
os = "/dev/disk/by-id/ata-TOSHIBA_MQ01ABD100_85N8C2DPT";
in
{
boot.loader = {
systemd-boot = {
enable = true;
};
efi = {
canTouchEfiVariables = true;
};
};
disko.devices = {
disk = {
"os-${hashDisk os}" = {
type = "disk";
device = os;
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "nofail" ];
};
};
system = {
size = "100%";
content = {
type = "zfs";
pool = "zroot";
};
};
swap = {
size = "16G";
content = {
type = "swap";
};
};
};
};
};
};
zpool = {
zroot = {
type = "zpool";
rootFsOptions = {
mountpoint = "none";
compression = "lz4";
acltype = "posixacl";
xattr = "sa";
"com.sun:auto-snapshot" = "true";
};
options.ashift = "12";
datasets = {
"root" = {
type = "zfs_fs";
options.mountpoint = "none";
};
"root/nixos" = {
type = "zfs_fs";
options.mountpoint = "/";
mountpoint = "/";
};
};
};
};
};
}
File diff suppressed because it is too large Load Diff
-100
View File
@@ -1,100 +0,0 @@
{
inputs,
config,
pkgs,
...
}:
let
domain = "glom-inventory.newedge.house";
in
{
clan.core.settings.machine.description = "VM machine that host Inventree system for Glom";
imports = [
inputs.self.nixosModules.inventree
];
nixpkgs.overlays = [
inputs.self.overlays.packagesOverlay
];
nixpkgs.hostPlatform = {
system = "x86_64-linux";
};
clan.core.vars.generators.inventree = {
files = {
secret-key = {
owner = "inventree";
group = "inventree";
secret = true;
};
oidc-key = {
owner = "inventree";
group = "inventree";
secret = true;
};
admin-password = {
owner = "inventree";
group = "inventree";
secret = true;
};
};
runtimeInputs = [
pkgs.pwgen
pkgs.xkcdpass
];
script = ''
pwgen -s 32 1 > $out/secret-key
pwgen -s 32 1 > $out/oidc-key
xkcdpass --numwords 4 --delimiter - --count 1 | tr -d "\n" > "$out"/admin-password
'';
};
clan.core.vars.generators.nginx = {
files = {
sslCert = {
owner = "nginx";
group = "nginx";
secret = true;
};
sslKey = {
owner = "nginx";
group = "nginx";
secret = true;
};
};
runtimeInputs = [
pkgs.openssl
];
script = ''
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout $out/sslKey \
-out $out/sslCert \
-subj "/CN=localhost"
'';
};
networking.firewall.allowedTCPPorts = [
80
443
];
services.inventree = {
enable = true;
hostName = "${domain}";
config.site_url = "https://${config.services.inventree.hostName}";
secretKeyFile = config.clan.core.vars.generators.inventree.files.secret-key.path;
config.oidc_private_key_file = config.clan.core.vars.generators.inventree.files.oidc-key.path;
config.adminPasswordFile = config.clan.core.vars.generators.inventree.files.admin-password.path;
};
# services.nginx.virtualHosts."${domain}" = {
# forceSSL = true;
# sslCertificate = config.clan.core.vars.generators.nginx.files.sslCert.path;
# sslCertificateKey = config.clan.core.vars.generators.nginx.files.sslKey.path;
# };
system.stateVersion = "25.11";
clan.core.sops.defaultGroups = [ "admins" ];
}
-83
View File
@@ -1,83 +0,0 @@
let
hashDisk = disk: "os-${builtins.substring 0 5 (builtins.hashString "sha256" disk)}";
os = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0";
in
{
boot.loader = {
systemd-boot = {
enable = true;
};
efi = {
canTouchEfiVariables = true;
};
};
disko.devices = {
disk = {
"os-${hashDisk os}" = {
type = "disk";
device = os;
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "nofail" ];
};
};
system = {
size = "100%";
content = {
type = "zfs";
pool = "zroot";
};
};
};
};
};
};
zpool = {
zroot = {
type = "zpool";
rootFsOptions = {
mountpoint = "none";
compression = "lz4";
acltype = "posixacl";
xattr = "sa";
"com.sun:auto-snapshot" = "true";
};
options.ashift = "12";
datasets = {
"root" = {
type = "zfs_fs";
options.mountpoint = "none";
};
"root/nixos" = {
type = "zfs_fs";
options.mountpoint = "/";
mountpoint = "/";
};
"root/home" = {
type = "zfs_fs";
options.mountpoint = "/home";
mountpoint = "/home";
};
"root/tmp" = {
type = "zfs_fs";
mountpoint = "/tmp";
options = {
mountpoint = "/tmp";
sync = "disabled";
};
};
};
};
};
};
}
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -5,8 +5,10 @@
system = "x86_64-linux";
};
clan.core.settings.name = "ramus";
clan.core.settings.machine.description = "A Hetzner VPS machine own by Alex.";
clan.meta.name = "ramus";
clan.meta.description = ''
A Hetzner VPS machine own by Alex.
'';
clan.core.sops.defaultGroups = [ "admins" ];
clan.core.networking.targetHost = "root@[${config.clan.core.vars.generators.zerotier.files.zerotier-ip.value}]";
+1 -4
View File
@@ -1,6 +1,6 @@
{ self, config, ... }:
let
commonSettings = rec {
commonSettings = {
APP_NAME = "Laravel";
APP_ENV = "local";
APP_KEY._secret = config.clan.core.vars.generators.greaterchiangmai.files.app_key.path;
@@ -13,7 +13,6 @@ let
DB_DATABASE = "thinkgtcm";
DB_USERNAME = "gtcm";
R2_SCHEMA_URL = "https://${R2_BUCKET}.${R2_REGION}.your-objectstorage.com/test-large-files/";
R2_ACCESS_KEY_ID = config.clan.core.vars.generators.greaterchiangmai-s3.files.access_key_id.value;
R2_SECRET_ACCESS_KEY._secret =
config.clan.core.vars.generators.greaterchiangmai-s3.files.secret_access_key.path;
@@ -21,8 +20,6 @@ let
R2_BUCKET = config.clan.core.vars.generators.greaterchiangmai-s3.files.bucket.value;
R2_ENDPOINT = config.clan.core.vars.generators.greaterchiangmai-s3.files.endpoint.value;
R2_BUCKET_NAME = R2_BUCKET;
LOG_CHANNEL = "stack";
LOG_LEVEL = "debug";
-22
View File
@@ -1,22 +0,0 @@
{ self, pkgs, ... }:
{
clan.core.settings.machine.description = "Emmie personal computer";
imports = [
self.nixosModules.common
];
nixpkgs.hostPlatform = {
system = "x86_64-linux";
};
system.stateVersion = "25.11";
clan.core.sops.defaultGroups = [ "admins" ];
boot.kernelParams = [
"amdgpu.dcdebugmask=0x10"
"amdgpu.cwsr_enable=0"
"amdgpu.gpu_recovery=1"
];
boot.kernelPackages = pkgs.linuxKernel.packages.linux_6_12;
}
File diff suppressed because it is too large Load Diff
-2
View File
@@ -13,6 +13,4 @@
system.stateVersion = "25.11";
clan.core.sops.defaultGroups = [ "admins" ];
clan.core.networking.targetHost = "root@[${config.clan.core.vars.generators.zerotier.files.zerotier-ip.value}]";
clan.core.settings.machine.description = "Zima board computer for testing in B4L";
}
-21
View File
@@ -1,21 +0,0 @@
## How to setup this machine.
This machine cannot be setup the same way as other machines are setup. Meaning that `clan machine install` won't work. Because of `disko` issue. So, below is how the machine is setup.
1. Build an image to flash to an sd-card using
```
nix build -L --show-trace .\#nixosConfigurations.sirius.config.system.build.images.sd-card
```
2. Import the `zdata`
```
zpool import zdata
```
3. Update configuration
```
clan machine update sirius
```
+6 -75
View File
@@ -1,94 +1,25 @@
{
inputs,
config,
self,
pkgs,
...
}:
{
imports = [
self.nixosModules.common
./hardware-configuration.nix
];
(inputs.import-tree ./services)
image.modules.sd-card = {
disabledModules = [
./hardware-configuration.nix
];
};
clan.core.settings.machine.description = "w NAS";
clan.core.sops.defaultGroups = [ "admins" ];
clan.core.networking.targetHost = "root@[${config.clan.core.vars.generators.zerotier.files.zerotier-ip.value}]";
nixpkgs.hostPlatform = {
system = "aarch64-linux";
system = "x86_64-linux";
};
networking.fqdn = config.clan.core.vars.generators.vega-internal-domain.files.name.value;
system.stateVersion = "25.11";
services.journald.extraConfig = ''
Storage=volatile
RuntimeMaxUse=30M
RuntimeMaxFileSize=10M
'';
services.udisks2.enable = false;
nix.settings.log-lines = 25;
nix.settings.auto-optimise-store = true;
nix.gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 15d";
};
boot.loader.grub.enable = false;
boot.loader.generic-extlinux-compatible.enable = true;
boot.zfs.extraPools = [ "zdata" ];
boot.supportedFilesystems = [ "zfs" ];
boot.initrd.availableKernelModules = [
"usb_storage"
"sd_mod"
];
fileSystems."/mnt/hdd" = {
device = "zdata/nas";
fsType = "zfs";
mountPoint = "/mnt/hdd";
options = [
"nofail"
"zfsutil"
];
};
fileSystems."/var/lib" = {
device = "zdata/service-data";
fsType = "zfs";
mountPoint = "/var/lib";
options = [
"x-initrd.mount"
"nofail"
"zfsutil"
];
};
systemd.services.heartbeat-push = {
description = "Heartbeat push to uptime monitor";
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.curl}/bin/curl -s -o /dev/null https://uptime.b4l.co.th/api/push/X0WCHAcY5gPf1U8If7BT1FLjpacZqGZu?status=up&msg=OK&ping=";
};
};
systemd.timers.heartbeat-push = {
description = "Heartbeat push timer";
wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = "60s";
OnUnitActiveSec = "60s";
Unit = "heartbeat-push.service";
};
};
}
-150
View File
@@ -1,150 +0,0 @@
{ lib, pkgs, ... }:
let
hashDisk = disk: "os-${builtins.substring 0 5 (builtins.hashString "sha256" disk)}";
# os = "/dev/disk/by-id/mmc-SD64G_0x8336354b";
vdev = [
"/dev/disk/by-id/ata-ST20000NM002H-3KV133_ZYDBVV7Z"
"/dev/disk/by-id/ata-ST20000NM002H-3KV133_ZYDBSJRE"
];
configTxt = pkgs.writeText "config.txt" ''
[pi4]
kernel=u-boot-rpi4.bin
enable_gic=1
# Otherwise the resolution will be weird in most cases, compared to
# what the pi3 firmware does by default.
disable_overscan=1
# Supported in newer board revisions
arm_boost=1
[all]
# Boot in 64-bit mode.
arm_64bit=1
# U-Boot needs this to work, regardless of whether UART is actually used or not.
# Look in arch/arm/mach-bcm283x/Kconfig in the U-Boot tree to see if this is still
# a requirement in the future.
enable_uart=1
# Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
# when attempting to show low-voltage or overtemperature warnings.
avoid_warnings=1
'';
in
{
boot.loader = {
systemd-boot = {
enable = true;
};
efi = {
canTouchEfiVariables = true;
};
};
# boot.tmp.useTmpfs = true;
disko.devices = {
disk = {
# "os-${hashDisk os}" = {
# type = "disk";
# device = os;
# content = {
# type = "gpt";
# partitions = {
# firmware = {
# size = "60M";
# priority = 1;
# type = "0700";
# content = {
# type = "filesystem";
# format = "vfat";
# mountpoint = "/firmware";
# postMountHook = toString (
# pkgs.writeScript "postMountHook.sh" ''
# (cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf *.dtb /mnt/firmware/)
# cp ${pkgs.ubootRaspberryPi4_64bit}/u-boot.bin /mnt/firmware/u-boot-rpi4.bin
# cp ${configTxt} /mnt/firmware/config.txt
# ''
# );
# };
# };
# ESP = {
# size = "2G";
# type = "EF00";
# content = {
# type = "filesystem";
# format = "vfat";
# mountpoint = "/boot";
# mountOptions = [ "umask=0077" ];
# };
# };
# root = {
# name = "root";
# end = "-0";
# content = {
# type = "filesystem";
# format = "f2fs";
# mountpoint = "/";
# extraArgs = [
# "-O"
# "extra_attr,inode_checksum,sb_checksum,compression"
# ];
# mountOptions = [ "compress_algorithm=zstd:6,compress_chksum,atgc,gc_merge,lazytime,nodiscard" ];
# };
# };
# };
# };
# };
}
// (lib.listToAttrs (
map (disk: {
name = "data-${hashDisk disk}";
value = {
type = "disk";
device = disk;
content = {
type = "zfs";
pool = "zdata";
};
};
}) vdev
));
zpool = {
zdata = {
type = "zpool";
options.ashift = "12";
rootFsOptions = {
mountpoint = "none";
compression = "lz4";
acltype = "posixacl";
xattr = "sa";
"com.sun:auto-snapshot" = "true";
};
mode = {
topology = {
type = "topology";
vdev = [
{
mode = "mirror";
members = vdev;
}
];
};
};
datasets = {
"nas" = {
type = "zfs_fs";
mountpoint = "/mnt/hdd";
mountOptions = [ "nofail" ];
};
"service-data" = {
type = "zfs_fs";
mountpoint = "/var/lib";
mountOptions = [ "nofail" ];
};
};
};
};
};
}
@@ -1,7 +1,11 @@
{ ... }:
{ lib, ... }:
let
hashDisk = disk: "os-${builtins.substring 0 5 (builtins.hashString "sha256" disk)}";
os = "/dev/disk/by-id/nvme-SAMSUNG_MZVL81T0HFLB-00BLL_S7XKNF0Y966645";
os = "/dev/disk/by-id/mmc-FIXME";
vdev = [
"/dev/disk/by-id/ata-FIXME"
"/dev/disk/by-id/ata-FIXME"
];
in
{
@@ -48,14 +52,24 @@ in
};
};
};
}
// (lib.listToAttrs (
map (disk: {
name = "data-${hashDisk disk}";
value = {
type = "disk";
device = disk;
content = {
type = "zfs";
pool = "zdata";
};
};
}) vdev
));
zpool = {
zroot = {
type = "zpool";
rootFsOptions = {
encryption = "aes-256-gcm";
keyformat = "passphrase";
keylocation = "file:///tmp/secret.key";
mountpoint = "none";
compression = "lz4";
acltype = "posixacl";
@@ -88,6 +102,40 @@ in
};
};
};
zdata = {
type = "zpool";
options.ashift = "12";
rootFsOptions = {
mountpoint = "none";
compression = "lz4";
acltype = "posixacl";
xattr = "sa";
"com.sun:auto-snapshot" = "true";
};
mode = {
topology = {
type = "topology";
vdev = [
{
mode = "mirror";
members = vdev;
}
];
};
};
datasets = {
"nas" = {
type = "zfs_fs";
mountpoint = "/mnt/hdd";
mountOptions = [ "nofail" ];
};
"service-data" = {
type = "zfs_fs";
mountpoint = "/var/lib";
mountOptions = [ "nofail" ];
};
};
};
};
};
}
@@ -1,6 +0,0 @@
{
fileSystems."/" = {
device = "/dev/disk/by-uuid/44444444-4444-4444-8888-888888888888";
fsType = "ext4";
};
}
+93
View File
@@ -0,0 +1,93 @@
{
config,
lib,
...
}:
let
sambaUser = lib.filterAttrs (
name: user: user.isNormalUser && builtins.elem "samba" user.extraGroups
) config.users.users;
sharedFolders = {
WhiteHouse.users = [
"w"
"kurogeek"
"berwn"
];
};
in
{
services.samba = {
enable = true;
openFirewall = true;
settings = {
global = {
security = "user";
workgroup = "WORKGROUP";
"server string" = "WhiteHouse NAS";
interfaces = "eth* en*";
"max log size" = "50";
"dns proxy" = false;
"syslog only" = true;
"map to guest" = "Bad User";
"guest account" = "nobody";
};
}
// lib.mapAttrs (share: opts: {
path = "/mnt/hdd/samba/${share}";
comment = share;
"force user" = share;
"force group" = share;
public = "yes";
"guest ok" = "yes";
"create mask" = "0640";
"directory mask" = "0750";
writable = "no";
browseable = "yes";
printable = "no";
# TODO
# "valid users" = toString opts.users;
}) sharedFolders;
};
users.users = lib.mapAttrs (share: opts: {
isSystemUser = true;
group = share;
}) sharedFolders;
users.groups = lib.mapAttrs (share: opts: { }) sharedFolders;
systemd.services.samba-smbd.postStart =
lib.concatMapStrings (
user:
let
password = config.clan.core.vars.generators."${user}-smb-password".files.password.path;
in
''
mkdir -p /mnt/hdd/samba/${user}
chown ${user}:users /mnt/hdd/samba/${user}
# if a password is unchanged, this will error
(echo $(<${password}); echo $(<${password})) | ${config.services.samba.package}/bin/smbpasswd -s -a ${user}
''
) (lib.attrNames sambaUser)
+ lib.concatMapStrings (share: ''
mkdir -p /mnt/hdd/samba/${share}
chown ${share}:${share} /mnt/hdd/samba/${share}
'') (lib.attrNames sharedFolders);
services.samba-wsdd = {
enable = true;
openFirewall = true;
};
services.avahi = {
publish.enable = true;
publish.userServices = true;
# ^^ Needed to allow samba to automatically register mDNS records (without the need for an `extraServiceFile`
nssmdns4 = true;
# ^^ Not one hundred percent sure if this is needed- if it aint broke, don't fix it
enable = true;
openFirewall = true;
};
}
-2
View File
@@ -22,8 +22,6 @@
clan.core.sops.defaultGroups = [ "admins" ];
clan.core.networking.targetHost = "root@[${config.clan.core.vars.generators.zerotier.files.zerotier-ip.value}]";
clan.core.settings.machine.description = "Glom NAS";
nixpkgs.hostPlatform = {
system = "x86_64-linux";
};
-2
View File
@@ -3,11 +3,9 @@
_class = "clan.service";
manifest.name = "actual-budget";
manifest.description = "A local-first personal finance app ";
manifest.readme = "A local-first personal finance app";
manifest.categories = [ "System" ];
roles.default = {
description = "A default server role.";
perInstance.nixosModule =
{
@@ -5,7 +5,6 @@
name = "service-actual-budget";
clan = {
test.useContainers = false;
directory = ./.;
inventory = {
machines.server = { };
-174
View File
@@ -1,174 +0,0 @@
{ ... }:
{
_class = "clan.service";
manifest.name = "git-daemon";
manifest.description = "a really simple server for git repositories";
manifest.readme = "a really simple server for git repositories";
manifest.categories = [ "System" ];
roles.default = {
description = "a default server role";
interface =
{ lib, ... }:
{
options = with lib; {
directory = lib.mkOption {
type = types.str;
default = "/var/git";
};
repositories = lib.mkOption {
type =
with lib.types;
attrsOf (
submodule (
{ name, ... }:
{
options = {
name = lib.mkOption {
type = str;
default = name;
};
read-access = lib.mkOption {
type = listOf str;
default = [ ];
};
write-access = lib.mkOption {
type = listOf str;
default = [ ];
};
};
}
)
);
default = { };
};
};
};
perInstance =
{
settings,
...
}:
{
nixosModule =
{
pkgs,
lib,
config,
...
}:
{
systemd.services.git-init = {
serviceConfig = {
Type = "oneshot";
User = config.services.gitDaemon.user;
Group = config.services.gitDaemon.group;
ExecStartPre = toString [
"+${pkgs.coreutils}/bin/install"
"--directory"
"--owner=${config.services.gitDaemon.user}"
"--group=${config.services.gitDaemon.group}"
"--mode=0750"
settings.directory
];
ExecStart =
let
git-template = pkgs.stdenv.mkDerivation {
name = "git-template";
buildCommand = ''
cp --no-preserve=mode,ownership --recursive \
${pkgs.git}/share/git-core/templates $out
install -m550 $out/hooks/post-update{.sample,}
'';
};
init-script =
{ name, ... }:
pkgs.writeShellScript "git-init-${name}" ''
${pkgs.git}/bin/git init \
--bare --template=${git-template} --shared=0660 \
${settings.directory}/${name}.git
${pkgs.git}/bin/git \
-C ${settings.directory}/${name}.git \
config set receive.denyNonFastforwards false
'';
in
map init-script (lib.attrValues settings.repositories);
};
};
services.gitDaemon = {
enable = true;
user = "git";
group = "git";
options =
let
firewall = pkgs.writeText "git-daemon-firewall.json" (
builtins.toJSON (builtins.attrValues settings.repositories)
);
hook = pkgs.writers.writePython3 "hook.py" { flakeIgnore = [ "E" ]; } ''
import os, sys, enum, pathlib, ipaddress, json
class Service(enum.Enum):
UploadPack = enum.auto()
ReceivePack = enum.auto()
UploadArchive = enum.auto()
@classmethod
def parse(cls, string):
return {
'upload-pack': cls.UploadPack,
'receive-pack': cls.ReceivePack,
'upload-archive': cls.UploadArchive
}[string]
@property
def service(self):
return {
UploadPack: 'read-access',
ReceivePack: 'write-access'
}[self]
UploadPack = Service.UploadPack
ReceivePack = Service.ReceivePack
def parse_remote_addr(remote_addr):
if remote_addr.startswith('[') and remote_addr.endswith(']'):
return ipaddress.ip_address(remote_addr[1:-1])
return ipaddress.ip_address(remote_addr)
service = Service.parse(sys.argv[1])
repo = pathlib.Path(sys.argv[2]).stem
client = parse_remote_addr(os.environ['REMOTE_ADDR'])
with open("${firewall}", 'r') as f:
firewall = json.load(f)
for rule in firewall:
if rule["name"] == repo:
for network in rule[service.service]:
if client in ipaddress.ip_network(network):
sys.exit(0)
print('stairway denied')
sys.exit(1)
'';
in
toString [
"--enable=upload-pack"
"--enable=receive-pack"
"--disable=upload-archive"
"--access-hook=${hook}"
"--informative-errors"
];
exportAll = true;
basePath = settings.directory;
};
systemd.services.git-daemon = {
requires = [ "git-init.service" ];
after = [ "git-init.service" ];
};
networking.firewall.allowedTCPPorts = [ 9418 ];
};
};
};
}
-9
View File
@@ -1,9 +0,0 @@
{ lib, ... }:
let
module = lib.modules.importApply ./default.nix { };
in
{
clan.modules = {
git-daemon = module;
};
}
-19
View File
@@ -3,38 +3,19 @@
_class = "clan.service";
manifest.name = "grafana";
manifest.description = "Platform for data analytics and monitoring";
manifest.readme = "Platform for data analytics and monitoring";
manifest.categories = [ "System" ];
roles.default = {
description = "A default server role";
perInstance.nixosModule =
{
config,
lib,
pkgs,
...
}:
{
clan.core.vars.generators.grafana = {
files = {
secret_key = {
owner = "grafana";
group = "grafana";
secret = true;
};
};
script = ''
openssl rand -hex 32 > "$out"/secret_key
'';
runtimeInputs = [
pkgs.openssl
];
};
services.grafana = {
enable = lib.mkDefault true;
settings.security.secret_key = "$__file{${config.clan.core.vars.generators.grafana.files.secret_key.path}}";
};
clan.core.state.grafana.folders = [ config.services.grafana.dataDir ];
+2 -3
View File
@@ -1,6 +1,6 @@
{ self, inputs, ... }:
{ lib, ... }:
let
module = ./default.nix;
module = lib.modules.importApply ./default.nix { };
in
{
clan.modules = {
@@ -11,7 +11,6 @@ in
{
clan.nixosTests.service-grafana = {
imports = [ ./tests/vm/default.nix ];
_module.args = { inherit self inputs; };
clan.modules."@clan/grafana" = module;
};
-16
View File
@@ -1,26 +1,10 @@
{
self,
config,
lib,
hostPkgs,
...
}:
{
name = "service-grafana";
result.update-vars =
let
relativeDir = lib.removePrefix "${self}/" (toString config.clan.directory);
in
hostPkgs.writeShellScriptBin "update-vars" ''
set -x
export PRJ_ROOT=$(git rev-parse --show-toplevel)
${
self.inputs.clan-core.packages.${hostPkgs.system}.clan-cli
}/bin/clan-generate-test-vars $PRJ_ROOT/${relativeDir} ${config.name}
'';
clan = {
test.useContainers = false;
directory = ./.;
inventory = {
machines.server = { };
@@ -1,6 +0,0 @@
[
{
"publickey": "age1chfz220hkkxvv25x4cmqsen38ppat9erplqus8gvynv0ajnu4uaqgfq3tj",
"type": "age"
}
]
@@ -1,14 +0,0 @@
{
"data": "ENC[AES256_GCM,data:ZGt489y6VugKlhVLz6hC5sL+E+IDT6MkHS7jMU36WFWK9Co9btY4HRo+JtH/3C5iVuGLf/0j7n6W8SYZXigVCUTUQJvE56RfZ1s=,iv:rQM4ZZhN345KE2A16J9/ZKMZ9O+Qvb5y6kwXA/6SuZg=,tag:C+oeBtNFcImKd3HV/6yFCQ==,type:str]",
"sops": {
"age": [
{
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZU0hqYmtDKzBRWDVMNVdm\nUW5XMXd4WDNha0ppbENwOHk1bk1mVWxVV0F3CktYT01XdktyenNvUzU4UXBReEVp\nZXJKS05kS0NsbFNqamlXMkVzRmRhUkEKLS0tIEgweFVCT2tOZmMrdERDV0FBN3N2\nVjZPZXR3L0x0dER4T1Q4cTBlV20vUjAK9QJ2p8VzNqVY/lrcKwL56YF2JBfJp11M\ns801/6IQ5WvMPziG/E/nppv/9zL0kQTh9EPGqevy0juGcvqQgn1KQw==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2026-03-02T07:38:10Z",
"mac": "ENC[AES256_GCM,data:ShP6xVJaIIyj5kqRJeIbTNJBkY3H/xvj/RgbEl65RZbJNVE0HTHkTmartKVEyROWQlMyhwesJr8FEKAnOrWysUOKQUKV9Cgfvr6J/IXZj1ZJkXbE9NcFmsRshv4Po4sCig7Hq7qt/hQLBqutUjXnpvLaKgARz2dcOv8HSoVkCKU=,iv:bvl6lFb2z8DGQkShEWe5XlYmhtXNf3bL5RHSsk9LAXs=,tag:HomMsFH3jEHCR0L6aXVsBw==,type:str]",
"version": "3.12.1"
}
}
@@ -1 +0,0 @@
../../../users/admin
@@ -1,4 +0,0 @@
{
"publickey": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
"type": "age"
}
@@ -1 +0,0 @@
../../../../../../sops/machines/server
@@ -1,18 +0,0 @@
{
"data": "ENC[AES256_GCM,data:xXGuIJCmajuSHV3rBaAC0+XZZekqPd3rTr1bTKjMIU34IF9ueairclcSAUjFHakRG5EeGJ90PTosuC1vnqk/emQ=,iv:9Od0lV3SeTlT9sgJHY6yw/tLz5WNbaMDDFfjvIMO76M=,tag:T4ybZEUDGrp+p4I5NEr+Xg==,type:str]",
"sops": {
"age": [
{
"recipient": "age1chfz220hkkxvv25x4cmqsen38ppat9erplqus8gvynv0ajnu4uaqgfq3tj",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4aUc5Yy8xOU0xcW02eDVK\nR0d5eXVtVU50dVk4L2dnZ3pObTJjOGQycHlnCjJBSndpdGNhRWVxeGZGdTJwZklU\nekdQTjZ1UTUzYklRVDd6WlVFeko0cEEKLS0tIDB2SkVpRXVEcG9nSGM0OG5hYmlR\ncXBMdUZ2MHdZd2hCaFF5Y1duOVlzc3MKgFUx3NZSoXiALUWj0gxPZLbmwfzRuq5w\nSc3CPCuEEALGq1unzndXJLSg+q4u/PAsZ/Q4l2CDHxuk5INct3Px7g==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTTmxFL0UyNlhCaVhKWVJ5\nRUpLV3ZJdnNpYWZLa2phTlVNMmpzd20yd0FnCk9sOTFOZWQ3MzRHb3EwNUdzRDZ1\ndDk4eDVJRGFrOVIwd0xsb3c1b3VpWmcKLS0tIG16Nkc1TmlvbDNaYWZwcUFHYkV4\nT3Y5M1VOMWF3MHBMVlNMam1sSXIwNTQKRVvOVcV5GWua5hfS2ijKT5+C6Y5rZsXN\nKVzvemCk7pEGjVRSi4P0hrPnD37A6uwwj8FJqiLd7Y1p3hIVvBqR3w==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2026-03-02T07:38:11Z",
"mac": "ENC[AES256_GCM,data:HiiWGBruyPo/vGDdz/Zc/8Vd8oB2aMqoDjJCTybe9tRTJAojiSYZR4YyBO2ApCnYDyStJqXL0ZRjjRB73dwvldaNASz2odl/GGprmxcCH3T0A+Zrgu2gN9yNA5i+LkBLC2URXYwra4Den/WvIOTnrvvQcszN9SUBs+MOJM56KZo=,iv:+pjWMIf0+wBvWzkvsvqP7CI6zJpO3+8sqaZUEocXkXU=,tag:yp2CpOb38Kp13f2CJSzHEg==,type:str]",
"version": "3.12.1"
}
}
@@ -1 +0,0 @@
../../../../../../sops/users/admin
@@ -1,7 +0,0 @@
{ lib, ... }:
{
clan.modules = {
home-user = lib.modules.importApply ./home-user { };
emmie-home = lib.modules.importApply ./home-user/emmie.nix { };
};
}
@@ -1,64 +0,0 @@
{ ... }:
{
_class = "clan.service";
manifest.name = "common-user-home-manager";
manifest.description = "General users' home-manager profile generator";
manifest.readme = "General users' home-manager profile generator";
manifest.categories = [ "System" ];
roles.default = {
description = "a default role for the user";
interface =
{ lib, ... }:
{
options = {
username = lib.mkOption {
type = lib.types.str;
};
kbLayout = lib.mkOption {
type = lib.types.str;
default = "us";
};
kbOptions = lib.mkOption {
type = lib.types.str;
default = "grp:win_space_toggle";
};
};
};
perInstance =
{ settings, ... }:
{
nixosModule =
{ inputs, ... }:
let
username = settings.username;
in
{
imports = [ inputs.home-manager.nixosModules.home-manager ];
users.users.${username} = {
initialPassword = "";
isNormalUser = true;
extraGroups = [
"audio"
"video"
"networkmanager"
];
};
services.xserver = {
enable = true;
xkb.layout = settings.kbLayout;
xkb.options = settings.kbOptions;
};
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.${username} = ./home.nix;
home-manager.extraSpecialArgs = {
inherit inputs username;
};
};
};
};
}
@@ -1,127 +0,0 @@
{ ... }:
{
_class = "clan.service";
manifest.name = "emmie-home-manager";
manifest.description = "Emmie's home-manager profile generator";
manifest.readme = "Emmie's home-manager profile generator";
manifest.categories = [ "System" ];
roles.default = {
description = "a default role for the user";
perInstance =
{ ... }:
{
nixosModule =
{ inputs, pkgs, ... }:
let
username = "emmie";
in
{
imports = [ inputs.home-manager.nixosModules.home-manager ];
users.users.${username} = {
initialPassword = "";
isNormalUser = true;
extraGroups = [
"audio"
"video"
"networkmanager"
];
};
services.xserver = {
enable = true;
xkb.layout = "us,th";
xkb.options = "grp:win_space_toggle,grp:alt_shift_toggle";
};
programs.chromium = {
enable = true;
extraOpts = {
"BlockThirdPartyCookies" = true;
"ClearBrowsingDataOnExitList" = [
"download_history"
"cookies_and_other_site_data"
"cached_images_and_files"
"password_signin"
"autofill"
"site_settings"
"hosted_app_data"
];
"BraveRewardsDisabled" = true;
"BraveWalletDisabled" = true;
"BraveAIChatEnabled" = false;
"BraveNewsDisabled" = true;
"BraveSpeedreaderEnabled" = false;
"BraveWaybackMachineEnabled" = false;
"BraveStatsPingEnabled" = false;
"BraveWebDiscoveryEnabled" = false;
"BravePlaylistEnabled" = false;
"BraveVPNDisabled" = true;
"TorDisabled" = true;
"BraveP3AEnabled" = false;
"BraveTalkDisabled" = true;
"SyncDisabled" = false;
"PasswordManagerEnabled" = false;
"AutofillAddressEnabled" = false;
"AutofillCreditCardEnabled" = false;
"TranslateEnabled" = false;
"DnsOverHttpsMode" = "secure";
"DnsOverHttpsTemplates" = "https://dns.adguard-dns.com/dns-query";
};
};
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.${username} =
{
osConfig,
pkgs,
lib,
inputs,
...
}:
{
imports = [ inputs.plasma-manager.homeModules.plasma-manager ];
home = {
homeDirectory = lib.mkForce "/home/${username}";
stateVersion = osConfig.system.stateVersion;
packages = with pkgs; [
libreoffice-fresh
element-desktop
signal-desktop
brave
keepassxc
vlc
thunderbird
wasabiwallet
protonmail-desktop
];
};
programs.chromium.package = pkgs.brave;
programs.home-manager.enable = true;
services.syncthing.tray.enable = osConfig.services.syncthing.enable;
programs.plasma.enable = true;
programs.plasma.powerdevil = {
AC = {
autoSuspend.action = "shutDown";
autoSuspend.idleTimeout = 1800;
};
battery = {
autoSuspend.action = "shutDown";
autoSuspend.idleTimeout = 1800;
};
lowBattery = {
autoSuspend.action = "shutDown";
autoSuspend.idleTimeout = 1800;
};
};
};
home-manager.extraSpecialArgs = {
inherit inputs;
};
};
};
};
}
@@ -1,26 +0,0 @@
{
osConfig,
pkgs,
lib,
username,
...
}:
{
home = {
inherit username;
homeDirectory = lib.mkForce "/home/${username}";
stateVersion = osConfig.system.stateVersion;
packages = with pkgs; [
libreoffice-fresh
element-desktop
signal-desktop
brave
firefox
keepassxc
vlc
thunderbird
];
};
programs.home-manager.enable = true;
services.syncthing.tray.enable = osConfig.services.syncthing.enable;
}
+9 -14
View File
@@ -3,11 +3,9 @@
_class = "clan.service";
manifest.name = "jukebox";
manifest.description = "mpd server, library on removable disks";
manifest.readme = "mpd server, library on removable disks";
manifest.categories = [ "System" ];
roles.default = {
description = "a default server role";
interface =
{ lib, ... }:
{
@@ -113,22 +111,19 @@
services.mpd = {
enable = true;
openFirewall = true;
settings = {
bind_to_address = "any";
music_directory = settings.baseDir;
audio_output = [
{
type = "pulse";
name = "jukebox";
server = "localhost";
musicDirectory = settings.baseDir;
network.listenAddress = "any";
extraConfig = ''
audio_output {
type "pulse"
name "jukebox"
server "localhost"
}
];
};
'';
};
networking.firewall.interfaces = lib.genAttrs settings.binds (_: {
allowedTCPPorts = [ config.services.mpd.settings.port ];
allowedTCPPorts = [ config.services.mpd.network.port ];
});
environment.systemPackages = [ pkgs.mpc ];
-2
View File
@@ -3,11 +3,9 @@
_class = "clan.service";
manifest.name = "nextcloud";
manifest.description = "Nextcloud server, a safe home for all your data";
manifest.readme = "Nextcloud server, a safe home for all your data";
manifest.categories = [ "System" ];
roles.default = {
description = "a default server role";
perInstance.nixosModule =
{
@@ -5,7 +5,6 @@
name = "service-nextcloud";
clan = {
test.useContainers = false;
directory = ./.;
inventory = {
machines.server = { };
-14
View File
@@ -3,11 +3,9 @@
_class = "clan.service";
manifest.name = "paperless";
manifest.description = "A community-supported supercharged document management system: scan, index and archive all your documents";
manifest.readme = "A community-supported supercharged document management system: scan, index and archive all your documents";
manifest.categories = [ "System" ];
roles.default = {
description = "a default server role";
perInstance.nixosModule =
{
@@ -16,18 +14,6 @@
...
}:
{
nixpkgs.overlays = [
(final: prev: {
pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [
(pyFinal: pyPrev: {
psycopg = pyPrev.psycopg.overrideAttrs (old: {
disabledTests = old.disabledTests ++ [ "test_stats_connect" ];
});
})
];
})
];
services.paperless = {
enable = lib.mkDefault true;
};
@@ -5,7 +5,6 @@
name = "service-paperless";
clan = {
test.useContainers = false;
directory = ./.;
inventory = {
machines.server = { };
@@ -1,8 +0,0 @@
{ lib, ... }:
{
services.automatic-timezoned.enable = true;
services.geoclue2 = {
enableDemoAgent = lib.mkForce true;
geoProviderUrl = "https://beacondb.net/v1/geolocate";
};
}
@@ -1,21 +0,0 @@
{ ... }:
{
_class = "clan.service";
manifest.name = "personal-computer";
manifest.description = "A service for configuring personal computer such as printing, automatic-timezone, etc.";
manifest.readme = "A service for configuring personal computer such as printing, automatic-timezone, etc.";
manifest.categories = [ "System" ];
roles.default = {
description = "an only one default role";
perInstance.nixosModule =
{ inputs, lib, ... }:
{
imports = [
(inputs.import-tree.initFilter (
p: !lib.hasSuffix "default.nix" p && !lib.hasSuffix "flake-module.nix" p
) ./.)
];
};
};
}
@@ -1,9 +0,0 @@
{ config, lib, ... }:
{
security.pam.services."sddm".kwallet.enable = config.services.desktopManager.plasma6.enable;
security.pam.services."gdm".kwallet.enable = config.services.desktopManager.plasma6.enable;
services.displayManager.sddm.enable = lib.mkForce false;
services.displayManager.gdm.enable = true;
services.displayManager.gdm.wayland = true;
}
@@ -1,6 +0,0 @@
{ lib, ... }:
{
clan.modules = {
personal-computer = lib.modules.importApply ./default.nix { };
};
}
@@ -1,11 +0,0 @@
{
services = {
libinput = {
enable = true;
touchpad = {
disableWhileTyping = true;
naturalScrolling = true;
};
};
};
}
@@ -1,78 +0,0 @@
{
pkgs,
lib,
config,
...
}:
let
allowManageGroups = [
"root"
"wheel"
"lpadmin"
];
polkitAllowGroups = builtins.concatStringsSep "||" (
builtins.map (group: ''subject.isInGroup("${group}")'') allowManageGroups
);
printerMember = lib.map (user: user.name) (
lib.attrsets.attrsToList (
lib.attrsets.filterAttrs (name: value: value.isNormalUser) config.users.users
)
);
in
{
environment.systemPackages = [ pkgs.simple-scan ];
nixpkgs.config.allowUnfreePredicate =
pkg:
builtins.elem (lib.getName pkg) [
"brgenml1lpr"
"cups-brother-dcpt310"
"cups-brother-dcpt720dw"
"cups-brother-dcpt725dw"
];
# nixpkgs.config.allowUnfree = true;
services.ipp-usb.enable = true;
services.printing = {
enable = true;
drivers = [
pkgs.brlaser
pkgs.gutenprint
pkgs.brgenml1lpr
pkgs.brgenml1cupswrapper
pkgs.cups-brother-dcpt310
pkgs.cups-brother-dcpt720dw
pkgs.cups-brother-dcpt725dw
];
extraFilesConf = ''
SystemGroup ${builtins.concatStringsSep " " allowManageGroups}
'';
};
security.polkit = {
enable = true;
extraConfig = ''
polkit.addRule(function(action, subject) {
var actionMatchs = (
action.id.indexOf('org.opensuse.cupspkhelper.mechanism.') === 0
);
if (actionMatchs) {
if (${polkitAllowGroups}) {
return polkit.Result.YES
}
}
});
'';
};
hardware.sane = {
enable = true;
};
users.groups.lpadmin.members = printerMember;
users.groups.lp.members = printerMember;
users.groups.scanner.members = printerMember;
}
-11
View File
@@ -1,11 +0,0 @@
{ lib, ... }:
{
users.mutableUsers = lib.mkForce true;
security.polkit.extraConfig = ''
polkit.addRule(function(action, subject) {
if ((action.id == "org.freedesktop.accounts.change-own-password")) {
return polkit.Result.YES;
}
});
'';
}
@@ -1,4 +0,0 @@
{
networking.networkmanager.enable = true;
hardware.bluetooth.enable = true;
}
+32 -80
View File
@@ -1,16 +1,11 @@
{
clanLib,
...
}:
{ clanLib, ... }:
{
_class = "clan.service";
manifest.name = "phonebox";
manifest.description = "A peer to peer phone relay network built on top of yggdrasil.";
manifest.readme = "A peer to peer phone relay network built on top of yggdrasil.";
manifest.description = "";
manifest.categories = [ "System" ];
roles.default = {
description = "a default server role";
interface =
{ lib, ... }:
{
@@ -19,10 +14,10 @@
description = "An Ethernet interface that connect to ATA box.";
default = "enp2s0";
};
options.ownerName = lib.mkOption {
type = lib.types.str;
description = "";
default = "";
options.extraClientNumbers = lib.mkOption {
type = with lib.types; listOf str;
description = "List of client suffix number.";
default = [ ];
};
};
perInstance =
@@ -32,7 +27,6 @@
...
}:
{
nixosModule =
{
lib,
@@ -45,57 +39,12 @@
propagatedNativeBuildInputs = [ pkgs.spandsp3 ];
});
machines = lib.attrNames roles.default.machines;
user = "asterisk";
faxDir = "/run/asterisk/fax";
rtpPortFrom = 10000;
rtpPortTo = 20000;
ata-interface = settings.ata-ethernet-iface;
contactList = builtins.map (machineName: {
name = "${clanLib.getPublicValue {
flake = config.clan.core.settings.directory;
machine = machineName;
generator = "phonebox";
file = "owner-name";
default = null;
}}";
number = "${
clanLib.getPublicValue {
flake = config.clan.core.settings.directory;
machine = machineName;
generator = "phonebox";
file = "server-prefix-number";
default = null;
}
}${
clanLib.getPublicValue {
flake = config.clan.core.settings.directory;
machine = machineName;
generator = "phonebox";
file = "ata-local-number";
default = null;
}
}";
}) machines;
createContactListTiff =
let
contactTXT = lib.concatStringsSep "\n" (
builtins.map (contact: "${contact.number}\t\t: \t\t${contact.name}") contactList
);
in
pkgs.writeShellApplication {
name = "create-contact-tiff";
text = ''
magick -background white -fill black -pointsize 20 -font DejaVu-Sans label:"${contactTXT}" "$1"
magick "$1" -border 20x50 -bordercolor white "$1"
magick "$1" -resize 1728x -units PixelsPerInch -compress Group4 -density 204x196 -monochrome -depth 1 "$1"
'';
runtimeInputs = [ pkgs.imagemagick ];
};
genServerSIPEndpoint =
{ hostname, address }:
''
@@ -123,7 +72,22 @@
[${localNumber}](dynamiic_aor)
max_contacts=1
remove_existing=yes
'';
genLocalSIPEndpointV6 =
{ localNumber }:
''
[${localNumber}](internal_endpoint)
transport=transport-udp6
aors=${localNumber}
auth=${localNumber}
[${localNumber}](userpass_auth)
username=${localNumber}
password=${localNumber}
[${localNumber}](dynamiic_aor)
max_contacts=1
'';
genLocalExtenConf =
@@ -159,35 +123,26 @@
throw "clanService/yggdrasil is required";
in
{
clan.core.vars.generators.phonebox = builtins.break {
clan.core.vars.generators.phonebox = {
files = {
server-prefix-number.secret = false;
ata-local-number.secret = false;
owner-name.secret = false;
};
prompts = {
server-prefix-number = {
type = "line";
persist = true;
description = "Server prefix number: indicate server to connect to [10XX]";
};
ata-local-number = {
persist = true;
type = "line";
description = "Local suffix number: indicate local number on the server [XX00]";
};
owner-name = {
persist = true;
type = "line";
description = "The owner's name for this unit";
};
};
script = ''
cat $prompts/server-prefix-number > $out/server-prefix-number
cat $prompts/ata-local-number > $out/ata-local-number
cat $prompts/owner-name > $out/owner-name
'';
};
@@ -265,6 +220,7 @@
package = lib.mkDefault asterisk;
confFiles =
let
machines = lib.attrNames roles.default.machines;
nodes = builtins.foldl' (
nodes: name:
nodes
@@ -340,22 +296,18 @@
same => n,Set(FAXFILE=${faxDir}/echo-''${UNIQUEID}.tiff)
same => n,Set(FAXECHO=true)
exten => 888,1,Answer()
same => n,Set(FAXFILE=${faxDir}/contact.tiff)
same => n,System(${lib.getExe createContactListTiff} ''${FAXFILE})
same => n,Set(FAXECHO=true)
same => n,Playback(vm-goodbye)
same => n,Wait(3)
exten => h,1,GotoIf($[''${FAXECHO}]?sendfax)
same => n,Hangup()
same => n(sendfax),Originate(PJSIP/00,app,SendFAX,''${FAXFILE})
same => n(sendfax),Originate(PJSIP/00,app,SendFAX,${faxDir}/echo-''${UNIQUEID}.tiff)
same => n,Set(FAXECHO=false)
''
+ (genLocalExtenConf {
localNumber = config.clan.core.vars.generators.phonebox.files.ata-local-number.value;
})
+ lib.concatStringsSep "\n" (
builtins.map (number: genLocalExtenConf { localNumber = number; }) settings.extraClientNumbers
)
+ serverConf;
"rtp.conf" = ''
@@ -387,6 +339,7 @@
[base_endpoint](!)
type=endpoint
transport=transport-udp
disallow=all
allow=ulaw,alaw,g722,gsm
direct_media=no
@@ -409,14 +362,13 @@
+ (genLocalSIPEndpoint {
localNumber = config.clan.core.vars.generators.phonebox.files.ata-local-number.value;
})
+ lib.concatStringsSep "\n" (
builtins.map (number: genLocalSIPEndpointV6 { localNumber = number; }) settings.extraClientNumbers
)
+ serverConf;
};
};
environment.systemPackages = [
createContactListTiff
];
systemd.tmpfiles.rules = [
"d ${faxDir} 0755 ${user} ${user} - -"
];
@@ -21,7 +21,6 @@
'';
clan = {
test.useContainers = false;
directory = ./.;
inventory = {
machines.server = { };
@@ -1 +0,0 @@
fake_line_value
+23
View File
@@ -0,0 +1,23 @@
{ ... }:
{
_class = "clan.service";
manifest.name = "pingvin";
manifest.description = "A self-hosted file sharing platform that combines lightness and beauty, perfect for seamless and efficient file sharing.";
manifest.categories = [ "System" ];
roles.default = {
perInstance.nixosModule =
{
config,
...
}:
{
services.pingvin-share = {
enable = true;
};
clan.core.state.pingvin-share.folders = [ config.services.pingvin-share.dataDir ];
};
};
}
+19
View File
@@ -0,0 +1,19 @@
{ lib, ... }:
let
module = lib.modules.importApply ./default.nix { };
in
{
clan.modules = {
pingvin = module;
};
perSystem =
{ ... }:
{
clan.nixosTests.service-pingvin = {
imports = [ ./tests/vm/default.nix ];
clan.modules."@clan/pingvin" = module;
};
};
}
+42
View File
@@ -0,0 +1,42 @@
{
...
}:
{
name = "service-pingvin";
clan = {
directory = ./.;
inventory = {
machines.server = { };
instances = {
pingvin-test = {
module.name = "@clan/pingvin";
module.input = "self";
roles.default.machines."server".settings = { };
};
};
};
};
nodes = {
server = {
services.pingvin-share = {
hostname = "share.localhost";
frontend.port = 3000;
backend.port = 8000;
};
};
};
testScript = ''
start_all()
server.wait_for_unit("pingvin-share-frontend")
server.succeed("systemctl status pingvin-share-frontend")
server.wait_for_open_port(3000)
server.wait_for_open_port(8000)
server.succeed("curl -H \"Host: share.localhost\" http://127.0.0.1:3000 ")
'';
}
-2
View File
@@ -3,11 +3,9 @@
_class = "clan.service";
manifest.name = "pocket-id";
manifest.description = "A simple and easy-to-use OIDC provider that allows users to authenticate with their passkeys to your services.";
manifest.readme = "A simple and easy-to-use OIDC provider that allows users to authenticate with their passkeys to your services.";
manifest.categories = [ "System" ];
roles.default = {
description = "a default server role";
perInstance.nixosModule =
{
@@ -3,7 +3,6 @@
name = "service-pocket-id";
clan = {
test.useContainers = false;
directory = ./.;
inventory = {
machines.server = { };
-2
View File
@@ -3,11 +3,9 @@
_class = "clan.service";
manifest.name = "pulse-stream";
manifest.description = "stream audio to attached speakers";
manifest.readme = "stream audio to attached speakers";
manifest.categories = [ "System" ];
roles.default = {
description = "a default role";
interface =
{ lib, ... }:
{
-253
View File
@@ -1,253 +0,0 @@
{ lib, ... }:
{
_class = "clan.service";
manifest.name = "samba";
manifest.description = "Samba configuration for NAS";
manifest.readme = "Samba configuration for NAS";
manifest.categories = [ "System" ];
roles.server = {
description = "A server role that host files";
interface =
{ lib, ... }:
let
userOptions = {
readPerm = lib.mkOption {
type = with lib.types; bool;
description = "Permission to read";
default = false;
};
writePerm = lib.mkOption {
type = with lib.types; bool;
description = "Permission to write";
default = false;
};
};
in
{
options = {
globalUsers = lib.mkOption {
type =
with lib.types;
attrsOf (submodule {
options = userOptions;
});
description = "List of global users with permissions, this will be applied to all the folders.";
default = {
admin = {
readPerm = true;
writePerm = true;
};
};
};
sharedFolders = lib.mkOption {
type =
with lib.types;
attrsOf (submodule {
options = {
users = lib.mkOption {
type =
with lib.types;
attrsOf (submodule {
options = userOptions;
});
description = "List of users with permissions, this will only applied to this particular folder.";
default = { };
};
allowedGuest = lib.mkOption {
type = with lib.types; bool;
description = "Whether to allow guest access to this folder.";
default = false;
};
};
});
description = "List of folders with users permissions.";
default = [
{
name = "DEFAULT";
}
];
};
dataDir = lib.mkOption {
type =
with lib.types;
oneOf [
str
path
];
description = "A directory where all samba folders will be.";
};
};
};
perInstance =
{ settings, ... }:
let
allUsernameList = lib.uniqueStrings (
lib.flatten (
(lib.mapAttrsToList (name: share: builtins.attrNames share.users) settings.sharedFolders)
++ builtins.attrNames settings.globalUsers
)
);
in
{
nixosModule =
{
lib,
config,
pkgs,
...
}:
{
users.users = builtins.listToAttrs (
map (
username:
lib.nameValuePair username {
isSystemUser = true;
group = username;
}
) (allUsernameList ++ builtins.attrNames settings.sharedFolders)
);
users.groups = builtins.listToAttrs (
map (username: lib.nameValuePair username { }) (
allUsernameList ++ builtins.attrNames settings.sharedFolders
)
);
clan.core.vars.generators = builtins.listToAttrs (
map (
username:
lib.nameValuePair "${username}-smb-password" {
files.password = { };
runtimeInputs = with pkgs; [
coreutils
xkcdpass
mkpasswd
];
script = ''
xkcdpass --numwords 3 --delimiter - --count 1 > $out/password
'';
}
) allUsernameList
);
systemd.services.samba-smbd.postStart =
lib.concatMapStrings (
user:
let
passwordPath = config.clan.core.vars.generators."${user}-smb-password".files.password.path;
userDir = "${settings.dataDir}/${user}";
in
''
mkdir -p ${userDir}
chown ${user}:users ${userDir}
# if a password is unchanged, this will error
(echo $(<${passwordPath}); echo $(<${passwordPath})) | ${config.services.samba.package}/bin/smbpasswd -s -a ${user}
''
) allUsernameList
+ lib.concatMapStrings (
share:
let
shareDir = "${settings.dataDir}/${share}";
in
''
mkdir -p ${shareDir}
chown ${share}:${share} ${shareDir}
''
) (builtins.attrNames settings.sharedFolders);
services.samba = {
enable = true;
openFirewall = true;
settings = {
global = {
security = "user";
workgroup = "WORKGROUP";
"server string" = "WhiteHouse NAS";
"max log size" = "50";
"dns proxy" = false;
"syslog only" = true;
"map to guest" = "Bad User";
"guest account" = "nobody";
};
}
// lib.mapAttrs (
shareName: value:
{
path = "${settings.dataDir}/${shareName}";
comment = shareName;
"force user" = shareName;
"force group" = shareName;
"create mask" = "0640";
"directory mask" = "0750";
"read only" = "yes";
browseable = "yes";
printable = "no";
"read list" = lib.concatStringsSep " " (
lib.uniqueStrings (
lib.flatten (
(builtins.attrNames (lib.filterAttrs (n: v: v.readPerm) value.users))
++ (builtins.attrNames (lib.filterAttrs (n: v: v.readPerm) settings.globalUsers))
)
)
);
"write list" = lib.concatStringsSep " " (
lib.uniqueStrings (
lib.flatten (
(builtins.attrNames (lib.filterAttrs (n: v: v.writePerm) value.users))
++ (builtins.attrNames (lib.filterAttrs (n: v: v.writePerm) settings.globalUsers))
)
)
);
}
// lib.optionalAttrs (value.allowedGuest) {
public = "yes";
"guest ok" = "yes";
}
) settings.sharedFolders
// builtins.listToAttrs (
map (
user:
lib.nameValuePair user {
comment = user;
path = "${settings.dataDir}/${user}";
"force user" = user;
"force group" = "users";
public = "yes";
"guest ok" = "no";
"create mask" = "0640";
"directory mask" = "0750";
writable = "yes";
browseable = "yes";
printable = "no";
"valid users" = user;
}
) allUsernameList
);
};
services.samba-wsdd = {
enable = true;
openFirewall = true;
};
services.avahi = {
publish.enable = true;
publish.userServices = true;
# ^^ Needed to allow samba to automatically register mDNS records (without the need for an `extraServiceFile`
nssmdns4 = true;
# ^^ Not one hundred percent sure if this is needed- if it aint broke, don't fix it
enable = true;
openFirewall = true;
};
};
};
};
}
-20
View File
@@ -1,20 +0,0 @@
{ inputs, self, ... }:
let
module = ./default.nix;
in
{
clan.modules = {
samba = module;
};
perSystem =
{ ... }:
{
clan.nixosTests.service-samba = {
imports = [ ./tests/vm/default.nix ];
_module.args = { inherit self inputs; };
clan.modules."@clan/samba" = module;
};
};
}
-87
View File
@@ -1,87 +0,0 @@
{
lib,
self,
config,
hostPkgs,
...
}:
let
testDir = "/mnt/hdd/samba";
in
{
name = "service-samba";
result.update-vars =
let
relativeDir = lib.removePrefix "${self}/" (toString config.clan.directory);
in
hostPkgs.writeShellScriptBin "update-vars" ''
set -x
export PRJ_ROOT=$(git rev-parse --show-toplevel)
${
self.inputs.clan-core.packages.${hostPkgs.system}.clan-cli
}/bin/clan-generate-test-vars $PRJ_ROOT/${relativeDir} ${config.name}
'';
clan = {
test.useContainers = false;
directory = ./.;
inventory = {
machines.server = { };
instances = {
samba-test = {
module.name = "@clan/samba";
module.input = "self";
roles.server.machines."server".settings = {
dataDir = testDir;
globalUsers = {
guser1 = {
readPerm = true;
writePerm = true;
};
};
sharedFolders = {
"share1" = {
users = {
"u1share1" = { };
"u2share1" = { };
};
};
"share2" = {
users = {
"u1share2" = { };
"u2share2" = { };
};
};
"share3" = { };
};
};
};
};
};
};
nodes = {
server = { };
};
testScript = ''
start_all()
server.wait_for_unit("samba-smbd")
server.succeed("systemctl status samba-smbd")
server.succeed("test -d ${testDir}/guser1")
server.succeed("test -d ${testDir}/u1share1")
server.succeed("test -d ${testDir}/u2share1")
server.succeed("test -d ${testDir}/u1share2")
server.succeed("test -d ${testDir}/u2share2")
server.succeed("test -d ${testDir}/share1")
server.succeed("test -d ${testDir}/share2")
server.succeed("runuser -u guser1 -- test -r ${testDir}/share1")
server.succeed("runuser -u guser1 -- test -r ${testDir}/share1")
server.succeed("runuser -u u1share1 -- test -r ${testDir}/share1")
'';
}
@@ -1,6 +0,0 @@
[
{
"publickey": "age1jked5ykp2ch5k4030cewmgqr44jc9e7cxsyrfek4v3j4g3fydcxs4jk8jn",
"type": "age"
}
]
@@ -1,14 +0,0 @@
{
"data": "ENC[AES256_GCM,data:EH+rEfBdg4O7dEsk0o95T7xBQK/7duVCnLpdFOC1rWVbwdt/qYzEobZCo9awzvmh6YlC9Ld/OKv5wIBJJJI8PpTII2jdlWMG778=,iv:nhswri4dJ+Yj/1zarXzvLUhfJPSlWCGjVYOP6sYOT3w=,tag:WKFP6xhiSAfuDY880tEyAw==,type:str]",
"sops": {
"age": [
{
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBheUV1blJCMFFoQmxVaGdK\nUmpsZHRkWDJXczFRaDdqWVRXeXYzSVZhdFUwCmY1Ym1uVWF2akJlc2JScWZWUUtI\nbXgvTFYvS0d1aXVSVkFUakJNSVdrZUEKLS0tIFA5WllweEhrK2hwYkFMaTRYeGJT\nU3YxY1ZIblhYdlJZaERodWVsSW1yYmsK5ow3QIvOt7nelW+aiBo1Z08SCqXTThTb\nAimCwnhqBhW08ipZ5hmQFqZc4cfoDapmemOBqW9Q6NPyNB0Mr2EIdg==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2026-02-11T02:53:23Z",
"mac": "ENC[AES256_GCM,data:TxoCasCZ4fRLU4gFWSDl4oi5YUIFSKirYV1kI5oMJcFqSFUZ0ZXCbuBX4i5UA/VWkY0/Th4scRqgvVCFcr/sO8DGh+oi14Ayu1o70Pjf/f0u6S3ROa84f5nBybq8oVQTzP23+a0OkpJTB2vS+ELB2Q7GOeQ7MIrya58XB+40QCg=,iv:9H+0luICB18332YyuUnF+d8sYDWYWakiIK95dmqOZVA=,tag:ldPbuLykRCp9sqI+vHoO3w==,type:str]",
"version": "3.11.0"
}
}
@@ -1 +0,0 @@
../../../users/admin
@@ -1,4 +0,0 @@
{
"publickey": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
"type": "age"
}
@@ -1 +0,0 @@
../../../../../../sops/machines/server
@@ -1,18 +0,0 @@
{
"data": "ENC[AES256_GCM,data:WU0RGh0P17GqEfENAZO9/orLxtU8wpc=,iv:yFINf8UCfkSKmWSghHB1wsrsgMcgAxjXbuSbtQY7WhI=,tag:sugSGytBTks5EYk5gZUw/Q==,type:str]",
"sops": {
"age": [
{
"recipient": "age1jked5ykp2ch5k4030cewmgqr44jc9e7cxsyrfek4v3j4g3fydcxs4jk8jn",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBER2VuTUVpTnRDNzVKcW5I\nMTZ3NW5JVEJSVnB4UTBJQ2g5S3ZRdnZBaTFRCmZWTUwyckZwL1RhdXJaZUkyL1lH\nODdienVFWENrb0VDWENOK0hseFBKLzgKLS0tIHMrWDd3ZW9UM3lWZU9Vb2JYUC91\nZGhTTVBmSURPVmNITVlIM2swNXAxUW8K2/88jwpUI+gZ8B289I/AvxtXpQHRabcy\nS2tK1rww6umRYmEvN8X3Ek5cz7XeulgY3gMlS+IbtScjXCGySw5tTg==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZRlFGV0FveEpkZVNhbjE0\nZ0c2cWtYTEVVTWlkeFMvT2twQVF1ZkRQcVJjCkVLRUpUY0RBQW54dU5McjUzbGQv\nSEorSFpXM3J3ZFgveUg3WDdMOVlwZWsKLS0tIHR2bXRVMnkxNThtNE5McmhzWWRE\ncHAyYW5FZXJ5T2piREhHY1F5WXpsQ0UKFyeMvgOogS9n8puvB0/0lq5+sOSq8yfZ\nSIGlqE0KTmFryNpPUINiJj5SpvdXvUeVqahoCB1QOGbodX1vKiwdgA==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2026-02-11T02:53:23Z",
"mac": "ENC[AES256_GCM,data:gRxnr9F8mT7OuooHRVgtNLut1BAEQiWpVr9iw7oN2mKlbZxq0X09K8jYZu0/dEMijbRfDoZ2bUmW7VIcqAZXwAZqLoqx3vzBqOGAQFcxyVFk0yRqPzR6odMYBdOeLFufN9l1IXOKiH4wZZB1kHean7XBlLzNUCTts12l+wInisY=,iv:zz7g/VcsBkY0kCELIIOBByLOj9bfXVOkw7JdTnlKRWc=,tag:FcGO6rsv+fBTHt+ymL6c0A==,type:str]",
"version": "3.11.0"
}
}
@@ -1 +0,0 @@
../../../../../../sops/users/admin
@@ -1 +0,0 @@
../../../../../../sops/machines/server
@@ -1,18 +0,0 @@
{
"data": "ENC[AES256_GCM,data:bgmzK6ERM6e6uJMW8Cqfgo1ktvM6l83LxNJV,iv:aYAYbWvBLZZx9zdUUZ/K29heR/yKXRDeR48g8rhKIQY=,tag:ZhXGRovVumEa0lpT8P8KaQ==,type:str]",
"sops": {
"age": [
{
"recipient": "age1jked5ykp2ch5k4030cewmgqr44jc9e7cxsyrfek4v3j4g3fydcxs4jk8jn",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTTG4yRFM5T1B1SWdzWWYv\nQTd0M2RjVTVKNy9rNUM1TmtvcEZsTVZ1U0JFCjNTOS95alh6MVZubXhOTGRwakUz\nZDBFck8rUVhYay9iRTRHY0pCZDJsSEEKLS0tIHJPUXpOVnMxMk9aSjYrTEFvSEJo\ndTd1MmNabVI1YkkwbVhkMnJLRzZzYjQKP6ehM8PTOrPVMgViUPGsXTyOdr9k5OAO\npf0faZpfH/GHiVBT7vaLrE/BLOhxLNkltldqyS1IUy19iXG9wEjbOQ==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRVDVZM3U4b0JveXVQL3BS\nR2x0SnlyK3FHMGdPL0hsb3lLOWt6aHBRbWdBClpzYWxEWUJHOGxzM0ZrUWhEa2hv\ncnFmOElUUkw5NEtEMmV3VDdiUGkyWlkKLS0tIHVtUlN0VTR1Y3ZxQ3JyRjA4ZzNk\nZWthMDJ5K1Z4Uzc0dVdWY2xWQUgzYkkKE0WIA/a1ZJXDS+qZyqadNYPRg7ixB8fU\n/mqsnJ6imb4+436LDfAd+ZknhS38IKe+56Tj27/frHFvcM4XIdBOuQ==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2026-02-11T02:53:27Z",
"mac": "ENC[AES256_GCM,data:rTA80/5n6DcTQns0UfuIJ61700exGeY/9zZaFA29bPFVzjuWz7EF4kQB8c3Qt1NcgGECn39pI/cT8SO1fWvz5mMRpBuoPthG8vzHGtjpqYYQhvOXh4CPmPA2EpWsC5Yz+ixSNF5BsrQqr+nnHLncmqVtdwKNx5WHZ+cHGHscqlk=,iv:ve7d0esVdq74ABai4NnS/W2hcLTmEf4QpxoJ24dLMNw=,tag:u99X2k0L7/iWSIJoTBR3KQ==,type:str]",
"version": "3.11.0"
}
}
@@ -1 +0,0 @@
../../../../../../sops/users/admin
@@ -1 +0,0 @@
../../../../../../sops/machines/server
@@ -1,18 +0,0 @@
{
"data": "ENC[AES256_GCM,data:WgDWZkhHWOV+ziaXtaeTWQicasUPRXE=,iv:Mwgc7cohAOLNsN77fEMBuOQaeQYAUL2CpEE1WaXm0lk=,tag:05Xxc/rJg1bt1PF79MLd/g==,type:str]",
"sops": {
"age": [
{
"recipient": "age1jked5ykp2ch5k4030cewmgqr44jc9e7cxsyrfek4v3j4g3fydcxs4jk8jn",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpWThaNElOVmhxbWFuTkJR\nQlJYMkVNTW5oRUNqRlowK2RLelhqb2hwSldFCjMycUpGelo1M2N1QWsxT3BCYktR\nUlpTYTUxTnVGMVZoelU3ZUlvQ1pMcTQKLS0tIGNmd1NQSlROR3lzQ2JQdkF0elkz\nNkN0Y2Z2T0Q2QUk0d0kzQmwrcVZEOVEKiM3Y/uGy4dB/5rGKAjjZM95y8INx+e+q\nxU9TUfGQBgYVzZtloLz3O7mlwhlamk1BvPvHttU+35paw26IbUlIoA==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWczZZWk5OTGtCTUw3b1c3\ncU9UaE1RaHNMS01NeXNmYVVqVHhJOXdmUmxvClh4R0ZtZjVmblZCWjlBb2VEaUlE\nUDBmWTV5Wnhpa2tnTWo3bEhOYXlYRFkKLS0tIE5jV1Ivdzdxc0R6V1ZiZU5NWFNL\ndnNsK0dhTElVWDVMRUZiTG5kMnJVSlkKVXmgoqF2bdwia9VDlOOKA6DTZCqpl9DP\n2ClATf3YXnKQ/uBNpfWrKoqJDL2y+26rEeoisPUrkrgYbpr3hq6Nqg==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2026-02-11T02:53:29Z",
"mac": "ENC[AES256_GCM,data:Yf5hFEEQ+yYH6OOjI7GLBahLL8UPuLIhIIdYkRoj6cSHgqm/ZpQGcd8MlHLGq0dpUcGOYJV9CM9pBqX0MjpABiK4XdTpoTn80EOV+mI2k6idE5N0doDecymI5A9ueB+5lO187HP57j5blJIn9aW+xO6MI9kYRYOz3sroAPq/JX0=,iv:yH1mB6DD+h869bsmovywJQm2ccd1PmqA7sZ9DGQ2+W4=,tag:sqLDW7JjT+K0JeWr8cUAQg==,type:str]",
"version": "3.11.0"
}
}
@@ -1 +0,0 @@
../../../../../../sops/users/admin

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