79 Commits

Author SHA1 Message Date
f79dcb29f5 mob next [ci-skip] [ci skip] [skip ci]
lastFile:routers/yada-house/device.nix
2025-10-10 16:12:15 +07:00
e4bf326191 add Alex's laptop to networks 2025-10-10 15:38:28 +07:00
04fafa32d3 update kurogeek thinkpad zerotier id 2025-10-09 16:42:23 +07:00
ed4e045ffc rm unused args 2025-09-28 13:30:10 +07:00
fd6edd83c2 machines are accessed by zerotier ip 2025-09-28 13:21:46 +07:00
65faa70fa3 no nextcloud on vega 2025-09-28 12:45:29 +07:00
377b63437c no write permission on GLOM samba 2025-09-26 20:26:02 +07:00
43e8252459 samba for vega 2025-09-26 16:46:00 +07:00
800500f57e vega on new device 2025-09-26 12:04:02 +07:00
8b7007b2b8 VPN for b4l 2025-09-25 14:46:26 +07:00
c0f50eb2b5 Glom NAS machine vega 2025-09-24 14:20:21 +07:00
cfbf3a30a0 re-encrypt rigel 2025-09-24 09:56:09 +07:00
6f0d7aa7de re-encrypt b4l 2025-09-24 09:55:25 +07:00
a5ffcf6773 add age-plugin-fido2-hmac as age-plugins 2025-09-24 09:37:39 +07:00
1ad1dd82ea rigel machines sops.defaultGroups is admins 2025-09-24 09:23:36 +07:00
45e4389f78 b4l machines sops.defaultGroups is admins 2025-09-24 09:23:24 +07:00
aa2eb91339 Add user matthewcroughan to group admins 2025-09-23 16:03:13 +07:00
99c24c0b10 Add user vi to group admins 2025-09-23 16:03:06 +07:00
8d31f56092 Add user davhau to group admins 2025-09-23 16:03:03 +07:00
950d34a7fe Add user berwn to group admins 2025-09-23 16:02:57 +07:00
7cb1b483f0 Add user kurogeek to group admins 2025-09-23 16:02:53 +07:00
6c806c1e70 Add machine rigel to group admins 2025-09-23 16:01:59 +07:00
921629216e Add machine b4l to group admins 2025-09-23 16:01:46 +07:00
83ebe8933f Add vi to secret 2025-09-23 15:53:02 +07:00
f9ba5260ab Add user matthewcroughan to secrets 2025-09-23 15:34:08 +07:00
4cf19ff4aa Add user matthewcroughan to secrets 2025-09-23 15:25:38 +07:00
a3a776722f Add berwn to secret 2025-09-22 16:11:51 +07:00
e182dcb248 Add berwn to secret 2025-09-22 16:11:34 +07:00
db5e0e55ce age-plugin-yubikey 2025-09-22 14:37:02 +07:00
aa19ffa9ba add matthewcroughan to admin 2025-09-22 14:36:45 +07:00
d344790bfe add vi to admin 2025-09-22 11:59:50 +07:00
3937ce27db Add user vi to secrets 2025-09-22 11:59:35 +07:00
c78048d53a add davhau to admin 2025-09-22 11:11:59 +07:00
0fb4199965 add berwn to admin 2025-09-22 11:11:16 +07:00
4dd06992e0 Add user davhau to secrets 2025-09-22 10:29:57 +07:00
dbdaa8ae22 Add user berwn to secrets 2025-09-22 10:27:37 +07:00
7c729a065e bump clan-core 2025-08-07 10:15:03 +07:00
16a2d980de paperless service 2025-08-07 10:08:14 +07:00
846d689b2c pingvin service 2025-08-05 17:16:02 +07:00
cc0aaff3ed bump nixpkgs 2025-08-05 15:42:25 +07:00
fca02307a0 grafana service 2025-08-04 15:36:07 +07:00
db855963dc fix wrong instance name 2025-07-31 16:01:03 +07:00
cc628f47b7 rework victoriametrics to be more generic with test 2025-07-31 15:56:46 +07:00
5109c3f4fa rework stirling-pdf to be more generic with test 2025-07-31 10:40:31 +07:00
c5c8e0050d rework actual-budget to be more generic with test 2025-07-30 17:28:23 +07:00
bfd0dd1a41 vikunja service backup folders 2025-07-30 15:38:07 +07:00
d606f9e88e nextcloud service backup folders 2025-07-30 15:37:51 +07:00
5dd4d2c08a b4l missing secrets are fixed 2025-07-30 10:42:05 +07:00
e70b2ef5c9 b4l-nextcloud vars script is fixed 2025-07-30 10:38:06 +07:00
1077a9309e b4l nextcloud secret nextcloud -> b4l-nextcloud 2025-07-30 10:37:21 +07:00
f82d1886cc Update vars via generator b4l-nextcloud for machine b4l 2025-07-30 10:36:34 +07:00
8f3220f8dd b4l-vikunja vars script is fixed 2025-07-30 10:30:29 +07:00
a12fddd386 b4l vikunja subdomain secret 2025-07-30 10:29:38 +07:00
f4418133f8 Update vars via generator b4l-vikunja for machine b4l 2025-07-30 10:27:39 +07:00
dc19d20d73 rework pocket-id to be more generic 2025-07-30 10:21:32 +07:00
49ed4d78c3 rework nextcloud service 2025-07-29 14:38:22 +07:00
99c3ee6ffe rigel machine (Zima board) is running NixOS 2025-07-25 11:18:52 +07:00
f72bb82382 admin access to all machines 2025-07-25 08:47:42 +07:00
4fa7edfa1f vikunja implementation on b4l 2025-07-24 11:39:06 +07:00
1bfda37cba vikunja clanService 2025-07-24 11:38:39 +07:00
aec9eed0b2 clanService framework with test support 2025-07-23 11:43:27 +07:00
b2b0c74bd6 bump inputs 2025-07-21 09:55:00 +07:00
a9b23c823c victoriametrics service 2025-07-18 14:09:14 +07:00
872414c995 actual budget service 2025-07-17 15:24:41 +07:00
528ef9ab77 stirling-pdf service 2025-07-16 16:06:37 +07:00
c716a79703 changeme -> FIXME 2025-07-16 14:57:27 +07:00
b5c20ab4de rm emergency-access, root-password 2025-07-16 14:18:40 +07:00
ba9b6868e4 nextcloud service 2025-07-16 14:17:11 +07:00
0510e56534 enable ACME on main domain 2025-07-16 14:16:42 +07:00
4e7dcebd93 inventory.pocket-id goes into the instances section 2025-07-14 13:48:37 +07:00
64cc66dd2b Update vars via generator pocket-id for machine b4l 2025-07-14 13:46:06 +07:00
6e80cc43ae pocket-id service 2025-07-14 13:45:39 +07:00
2789aa74af b4l fqdn 2025-07-14 11:56:00 +07:00
da9087235e root password for b4l 2025-07-14 11:03:21 +07:00
749f093f09 Update vars via generator root-password for machine b4l 2025-07-14 11:02:20 +07:00
90dd31e1ed inventory has clear sections 2025-07-14 10:48:53 +07:00
a998bc636f Update vars via generator emergency-access for machine b4l 2025-07-14 10:23:25 +07:00
a895e2ceb7 Add machine b4l to secrets 2025-07-14 10:23:25 +07:00
8c0eefc31a Update secret b4l-age.key 2025-07-14 10:23:25 +07:00
201 changed files with 14397 additions and 36 deletions

2
.gitignore vendored
View File

@@ -2,4 +2,4 @@
# Ignore build outputs from performing a nix-build or `nix build` command # Ignore build outputs from performing a nix-build or `nix build` command
result result
result-* result-*
run-vm-*

68
flake.lock generated
View File

@@ -20,11 +20,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1752166475, "lastModified": 1754535625,
"narHash": "sha256-tM4MVm6ENCmay2XZwlKafUXRr+acZigG2GG9kw7q3Y4=", "narHash": "sha256-RdT3/DskBjwx74cvHJHb/mLSO2XeSHitSYViNmYGU/k=",
"ref": "refs/heads/main", "ref": "refs/heads/main",
"rev": "2895c18bba8261fbb91b8b86d33245c6e5c48005", "rev": "f69e28a1333527cdbadb233966a7e19d4b35a1a3",
"revCount": 8320, "revCount": 8886,
"type": "git", "type": "git",
"url": "https://git.clan.lol/clan/clan-core" "url": "https://git.clan.lol/clan/clan-core"
}, },
@@ -43,21 +43,17 @@
"clan-core", "clan-core",
"nixpkgs" "nixpkgs"
], ],
"systems": [
"clan-core",
"systems"
],
"treefmt-nix": [ "treefmt-nix": [
"clan-core", "clan-core",
"treefmt-nix" "treefmt-nix"
] ]
}, },
"locked": { "locked": {
"lastModified": 1751846468, "lastModified": 1753067306,
"narHash": "sha256-h0mpWZIOIAKj4fmLNyI2HDG+c0YOkbYmyJXSj/bQ9s0=", "narHash": "sha256-jyoEbaXa8/MwVQ+PajUdT63y3gYhgD9o7snO/SLaikw=",
"rev": "a2166c13b0cb3febdaf36391cd2019aa2ccf4366", "rev": "18dfd42bdb2cfff510b8c74206005f733e38d8b9",
"type": "tarball", "type": "tarball",
"url": "https://git.clan.lol/api/v1/repos/clan/data-mesher/archive/a2166c13b0cb3febdaf36391cd2019aa2ccf4366.tar.gz" "url": "https://git.clan.lol/api/v1/repos/clan/data-mesher/archive/18dfd42bdb2cfff510b8c74206005f733e38d8b9.tar.gz"
}, },
"original": { "original": {
"type": "tarball", "type": "tarball",
@@ -92,11 +88,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1752113600, "lastModified": 1753140376,
"narHash": "sha256-7LYDxKxZgBQ8LZUuolAQ8UkIB+jb4A2UmiR+kzY9CLI=", "narHash": "sha256-7lrVrE0jSvZHrxEzvnfHFE/Wkk9DDqb+mYCodI5uuB8=",
"owner": "nix-community", "owner": "nix-community",
"repo": "disko", "repo": "disko",
"rev": "79264292b7e3482e5702932949de9cbb69fedf6d", "rev": "545aba02960caa78a31bd9a8709a0ad4b6320a5c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -125,6 +121,34 @@
"type": "github" "type": "github"
} }
}, },
"import-tree": {
"locked": {
"lastModified": 1752730890,
"narHash": "sha256-GES8fapSLGz36MMPRVNkSUWXUTtqvGQNXHjRmRLfJUY=",
"owner": "vic",
"repo": "import-tree",
"rev": "6ebb8cb87987b20264c09296166543fd3761d274",
"type": "github"
},
"original": {
"owner": "vic",
"repo": "import-tree",
"type": "github"
}
},
"liminix": {
"flake": false,
"locked": {
"lastModified": 1760087246,
"narHash": "sha256-HRUkAS5XDuM7yDnz+TIMAre7kFOuqyHL/y26wTbH6Sg=",
"path": "/home/kurogeek/Desktop/gitea/dan/liminix",
"type": "path"
},
"original": {
"path": "/home/kurogeek/Desktop/gitea/dan/liminix",
"type": "path"
}
},
"nix-darwin": { "nix-darwin": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@@ -176,11 +200,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1751949589, "lastModified": 1754278406,
"narHash": "sha256-mgFxAPLWw0Kq+C8P3dRrZrOYEQXOtKuYVlo9xvPntt8=", "narHash": "sha256-jvIQTMN5EzoOP5RaGztpVese8a3wqy0M/h6tNzycW28=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "9b008d60392981ad674e04016d25619281550a9d", "rev": "6a489c9482ca676ce23c0bcd7f2e1795383325fa",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -195,6 +219,8 @@
"clan-core": "clan-core", "clan-core": "clan-core",
"devshell": "devshell", "devshell": "devshell",
"flake-parts": "flake-parts", "flake-parts": "flake-parts",
"import-tree": "import-tree",
"liminix": "liminix",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"treefmt-nix": "treefmt-nix" "treefmt-nix": "treefmt-nix"
} }
@@ -207,11 +233,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1751606940, "lastModified": 1754328224,
"narHash": "sha256-KrDPXobG7DFKTOteqdSVeL1bMVitDcy7otpVZWDE6MA=", "narHash": "sha256-glPK8DF329/dXtosV7YSzRlF4n35WDjaVwdOMEoEXHA=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "3633fc4acf03f43b260244d94c71e9e14a2f6e0d", "rev": "49021900e69812ba7ddb9e40f9170218a7eca9f4",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -15,11 +15,17 @@
inputs.nixpkgs-lib.follows = "nixpkgs"; inputs.nixpkgs-lib.follows = "nixpkgs";
url = "github:hercules-ci/flake-parts"; url = "github:hercules-ci/flake-parts";
}; };
import-tree.url = "github:vic/import-tree";
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
treefmt-nix = { treefmt-nix = {
url = "github:numtide/treefmt-nix"; url = "github:numtide/treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
liminix = {
# url = "git+https://gti.telent.net/dan/liminix?ref=refs/heads/main&rev=29fbb5461d034c4c59b88cbe04937b04ecad18e0";
url = "path:/home/kurogeek/Desktop/gitea/dan/liminix";
flake = false;
};
}; };
outputs = outputs =
{ {
@@ -32,12 +38,32 @@
systems = [ systems = [
"x86_64-linux" "x86_64-linux"
]; ];
flake.legacyPackages.qemu-router = import "${inputs.liminix}/default.nix" {
liminix-config = import "${inputs.liminix}/examples/hello-from-qemu.nix";
device = (import "${inputs.liminix}/devices/qemu-aarch64/default.nix");
};
flake.legacyPackages.yada-router = import "${inputs.liminix}/default.nix" {
liminix-config = import ./routers/yada-house/configuration.nix { inherit inputs; };
device = (import ./routers/yada-house/device.nix { inherit inputs; });
};
flake.legacyPackages.qemu-flake = import "${inputs.liminix}/default.nix" {
liminix-config = import ./routers/qemu/configuration.nix { inherit inputs; };
device = (import ./routers/qemu/device.nix { inherit inputs; });
};
flake.legacyPackages.vanilla = import "${inputs.liminix}/default.nix" {
liminix-config = import ./routers/vanilla/configuration.nix { inherit inputs; };
device = (import "${inputs.liminix}/devices/gl-mt300a/default.nix");
};
imports = [ imports = [
./fmt.nix ./fmt.nix
./shell.nix ./shell.nix
./machines ./machines
./routers
./inventories ./inventories
./modules/clan/flake-module.nix
]; ];
} }
); );

View File

@@ -17,6 +17,8 @@
global.excludes = [ global.excludes = [
"sops/*" "sops/*"
"vars/*" "vars/*"
"*/sops/*"
"*/vars/*"
"*/.gitignore" "*/.gitignore"
"LICENSE" "LICENSE"

View File

@@ -1,18 +1,116 @@
{ inputs, self, ... }:
{ {
clan = { clan = {
inventory = { inventory = {
instances.emergency-access = { tags = {
module = { glom = [ "vega" ];
name = "emergency-access"; b4l = [ "rigel" ];
input = "clan-core";
};
roles.default.tags."all" = { };
}; };
services.admin = { instances = {
default.config.allowedKeys = [ ]; 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" =
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAmgyEGuY/r7SDlJgrzYmQqpcWS5W+fCzRi3OS59ne4W openpgp:0xFF687387";
"kurogeek" =
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEcZ/p1Ofa9liwIzPWzNtONhJ7+FUWd2lCz33r81t8+w kurogeek@kurogeek";
"matthewcroughan" =
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIOJDRQfb1+7VK5tOe8W40iryfBWYRO6Uf1r2viDjmsJtAAAABHNzaDo=";
"matthewcroughan-1" =
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIDgsWq+G/tcr6eUQYT7+sJeBtRmOMabgFiIgIV44XNc6AAAABHNzaDo=";
"matthewcroughan-2" =
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIJMi3TAuwDtIeO4MsORlBZ31HzaV5bji1fFBPcC9/tWuAAAABHNzaDo=";
};
};
glom-network = {
module = {
name = "zerotier";
input = "clan-core";
};
roles.controller.machines."vega" = { };
roles.peer.tags.glom = { };
};
b4l-network = {
module = {
name = "zerotier";
input = "clan-core";
};
roles.controller.machines."rigel" = { };
roles.peer.tags.b4l = { };
};
pocket-id = {
module = {
name = "pocket-id";
input = "self";
};
roles.default.machines.b4l = { };
};
nextcloud = {
module = {
name = "nextcloud";
input = "self";
};
roles.default.machines.b4l = { };
};
stirling-pdf = {
module = {
name = "stirling-pdf";
input = "self";
};
roles.default.machines.b4l = { };
};
actual-budget = {
module = {
name = "actual-budget";
input = "self";
};
roles.default.machines.b4l = { };
};
victoriametrics = {
module = {
name = "victoriametrics";
input = "self";
};
roles.default.machines.b4l = { };
};
vikunja = {
module = {
name = "vikunja";
input = "self";
};
roles.default.machines.b4l = { };
};
grafana = {
module = {
name = "grafana";
input = "self";
};
roles.default.machines.b4l = { };
};
pingvin = {
module = {
name = "pingvin";
input = "self";
};
roles.default.machines.b4l = { };
};
paperless = {
module = {
name = "paperless";
input = "self";
};
roles.default.machines.b4l = { };
};
}; };
}; };
}; };

View File

@@ -0,0 +1,21 @@
{
memberIds,
}:
{
config,
lib,
pkgs,
...
}:
{
systemd.services.zerotier-accept-external = {
wantedBy = [ "multi-user.target" ];
after = [ "zerotierone.service" ];
path = [ config.clan.core.clanPkgs.zerotierone ];
serviceConfig.ExecStart = pkgs.writeShellScript "zerotier-inventory-autoaccept" ''
${lib.concatMapStringsSep "\n" (zerotier-id: ''
${config.clan.core.clanPkgs.zerotier-members}/bin/zerotier-members allow ${zerotier-id}
'') memberIds}
'';
};
}

View File

@@ -1,14 +1,22 @@
{ inputs, config, ... }:
{ {
imports = [ imports = [
(inputs.import-tree ./services)
]; ];
nixpkgs.hostPlatform = { nixpkgs.hostPlatform = {
system = "x86_64-linux"; system = "x86_64-linux";
}; };
boot.loader.grub.devices = [ "/dev/disk/by-id/changeme" ]; boot.loader.grub.devices = [ "/dev/disk/by-id/FIXME" ];
fileSystems = { fileSystems = {
"/".device = "/dev/changeme"; "/".device = "/dev/FIXME";
}; };
networking.fqdn = "b4l.co.th";
system.stateVersion = "25.11"; system.stateVersion = "25.11";
clan.core.sops.defaultGroups = [ "admins" ];
security.acme.defaults.email = "admin@b4l.co.th";
security.acme.acceptTerms = true;
services.nginx.virtualHosts."${config.networking.fqdn}" = {
enableACME = true;
};
} }

View File

@@ -0,0 +1,36 @@
{ config, ... }:
let
abDomain = "${config.clan.core.vars.generators.b4l-actual-budget.files.subdomain.value}.${config.networking.fqdn}";
in
{
clan.core.vars.generators.b4l-actual-budget = {
files.subdomain.secret = false;
prompts = {
subdomain = {
persist = true;
type = "line";
description = "Sub-domain for Actual Budget app. Default:(budget)";
};
};
script = ''cat $prompts/subdomain || echo -n "budget" > $out/subdomain'';
};
services.actual = {
settings = {
allowedLoginMethods = [
"password"
"openid"
];
trustedProxies = [ "127.0.0.1" ];
};
};
services.nginx.virtualHosts."${abDomain}" = {
useACMEHost = "${config.networking.fqdn}";
forceSSL = true;
locations."/" = {
proxyPass = "http://localhost:${builtins.toString config.services.actual.settings.port}";
};
};
}

View File

@@ -0,0 +1,79 @@
{
pkgs,
config,
lib,
...
}:
with lib;
let
serviceName = "${config.networking.hostName}-grafana";
gfDomain = "${
config.clan.core.vars.generators."${serviceName}".files.subdomain.value
}.${config.networking.fqdn}";
settingsFormatIni = pkgs.formats.ini {
listToValue = concatMapStringsSep " " (generators.mkValueStringDefault { });
mkKeyValue = generators.mkKeyValueDefault {
mkValueString = v: if v == null then "" else generators.mkValueStringDefault { } v;
} "=";
};
configFile = settingsFormatIni.generate "config.ini" config.services.grafana.settings;
in
{
clan.core.vars.generators."${serviceName}" = {
files = {
adminpassword.secret = true;
subdomain.secret = false;
};
prompts = {
subdomain = {
persist = true;
type = "line";
description = "Sub-domain for Grafana. Default:(grafana)";
};
adminpassword = {
persist = true;
type = "hidden";
description = "Password for the admin user. Leave empty to auto-generate.";
};
};
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 "grafana" > "$out"/subdomain
fi
prompt_password=$(cat "$prompts"/adminpassword)
if [[ -n "''${prompt_password-}" ]]; then
echo "$prompt_password" | tr -d "\n" > "$out"/adminpassword
else
xkcdpass --numwords 4 --delimiter - --count 1 | tr -d "\n" > "$out"/adminpassword
fi
'';
};
systemd.services.grafana.serviceConfig.ExecStartPre = [
"+${pkgs.writeShellScript "grafana-set-password" ''
${pkgs.grafana}/bin/grafana cli --homepath ${config.services.grafana.dataDir} --config ${configFile} admin reset-admin-password $(cat ${
config.clan.core.vars.generators."${serviceName}".files.adminpassword.path
})
''}"
];
services.nginx.virtualHosts."${gfDomain}" = {
forceSSL = true;
useACMEHost = "${config.networking.fqdn}";
locations."/" = {
proxyPass = "http://localhost:${builtins.toString config.services.grafana.settings.server.http_port}";
};
};
}

View File

@@ -0,0 +1,35 @@
{ config, pkgs, ... }:
let
ncDomain = "${config.clan.core.vars.generators.b4l-nextcloud.files.subdomain.value}.${config.networking.fqdn}";
in
{
clan.core.vars.generators.b4l-nextcloud = {
files.subdomain.secret = false;
prompts = {
subdomain = {
persist = true;
type = "line";
description = "Sub-domain for Nextcloud app. Default:(cloud)";
};
};
script = ''cat $prompts/subdomain || echo -n "cloud" > $out/subdomain'';
};
services.nextcloud = {
hostName = ncDomain;
package = pkgs.nextcloud31;
settings = {
overwriteprotocol = "https";
trusted_domains = [ ];
trusted_proxies = [ ];
};
};
services.nginx.virtualHosts."${ncDomain}" = {
useACMEHost = "${config.networking.fqdn}";
forceSSL = true;
};
}

View File

@@ -0,0 +1,67 @@
{ config, pkgs, ... }:
let
serviceName = "${config.networking.hostName}-paperless";
domain-name = "${
config.clan.core.vars.generators."${serviceName}".files.subdomain.value
}.${config.networking.fqdn}";
in
{
clan.core.vars.generators."${serviceName}" = {
files = {
subdomain.secret = false;
adminpassword = {
secret = true;
owner = config.services.paperless.user;
group = config.services.paperless.user;
};
};
prompts = {
subdomain = {
persist = true;
type = "line";
description = "Sub-domain for Paperless. Default:(paperless)";
};
adminpassword = {
persist = true;
type = "hidden";
description = "Password for the admin user. Leave empty to auto-generate.";
};
};
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 "paperless" > "$out"/subdomain
fi
prompt_password=$(cat "$prompts"/adminpassword)
if [[ -n "''${prompt_password-}" ]]; then
echo "$prompt_password" | tr -d "\n" > "$out"/adminpassword
else
xkcdpass --numwords 4 --delimiter - --count 1 | tr -d "\n" > "$out"/adminpassword
fi
'';
};
environment.systemPackages = [ pkgs.toybox ];
services.paperless = {
passwordFile = config.clan.core.vars.generators."${serviceName}".files.adminpassword.path;
};
services.nginx.virtualHosts."${domain-name}" = {
forceSSL = true;
useACMEHost = "${config.networking.fqdn}";
locations."/" = {
proxyPass = "http://localhost:${builtins.toString config.services.paperless.port}";
};
};
}

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;
};
}

View File

@@ -0,0 +1,35 @@
{ config, ... }:
let
pidDomain = "${config.clan.core.vars.generators.b4l-pocket-id.files.subdomain.value}.${config.networking.fqdn}";
in
{
clan.core.vars.generators.b4l-pocket-id = {
files.subdomain.secret = false;
prompts = {
subdomain = {
persist = true;
type = "line";
description = "Sub-domain for Pocket-ID app. Default:(auth)";
};
};
script = ''cat $prompts/subdomain || echo -n "auth" > $out/subdomain'';
};
services.pocket-id = {
settings = {
APP_ENV = "production";
APP_URL = "https://${pidDomain}";
TRUST_PROXY = true;
};
};
services.nginx.virtualHosts."${pidDomain}" = {
useACMEHost = "${config.networking.fqdn}";
forceSSL = true;
locations."/" = {
proxyPass = "http://localhost:${builtins.toString config.services.pocket-id.settings.PORT}";
};
};
}

View File

@@ -0,0 +1,26 @@
{ config, ... }:
let
stDomain = "${config.clan.core.vars.generators.b4l-stirling-pdf.files.subdomain.value}.${config.networking.fqdn}";
in
{
clan.core.vars.generators.b4l-stirling-pdf = {
files.subdomain.secret = false;
prompts = {
subdomain = {
persist = true;
type = "line";
description = "Sub-domain for Stirling PDF app. Default:(pdf)";
};
};
script = ''cat $prompts/subdomain || echo -n "pdf" > $out/subdomain'';
};
services.nginx.virtualHosts."${stDomain}" = {
forceSSL = true;
useACMEHost = "${config.networking.fqdn}";
locations."/" = {
proxyPass = "http://localhost:${builtins.toString config.services.stirling-pdf.environment.SERVER_PORT}";
};
};
}

View File

@@ -0,0 +1,73 @@
{ config, pkgs, ... }:
let
vmDomain = "${config.clan.core.vars.generators.b4l-victoriametrics.files.subdomain.value}.${config.networking.fqdn}";
in
{
clan.core.vars.generators.b4l-victoriametrics = {
files.subdomain.secret = false;
files.adminuser.secret = false;
files.adminpassword.secret = true;
prompts = {
subdomain = {
persist = true;
type = "line";
description = "Sub-domain for Victoria Metrics app. Default:(metrics)";
};
adminuser = {
persist = true;
type = "line";
description = "Username for an admin user. Default:(admin)";
};
adminpassword = {
persist = true;
type = "hidden";
description = "Password for the admin user. Leave empty to auto-generate.";
};
};
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 "metrics" > "$out"/subdomain
fi
prompt_adminuser=$(cat "$prompts"/adminuser)
if [[ -n "''${prompt_adminuser-}" ]]; then
echo $prompt_adminuser | tr -d "\n" > "$out"/adminuser
else
echo -n "admin" > "$out"/adminuser
fi
prompt_password=$(cat "$prompts"/adminpassword)
if [[ -n "''${prompt_password-}" ]]; then
echo "$prompt_password" | tr -d "\n" > "$out"/adminpassword
else
xkcdpass --numwords 4 --delimiter - --count 1 | tr -d "\n" > "$out"/adminpassword
fi
'';
};
services.victoriametrics = {
extraOptions = [
"-httpAuth.username=file://${config.clan.core.vars.generators.b4l-victoriametrics.files.adminuser.path}"
"-httpAuth.password=file://${config.clan.core.vars.generators.b4l-victoriametrics.files.adminpassword.path}"
];
};
services.nginx.virtualHosts."${vmDomain}" = {
forceSSL = true;
useACMEHost = "${config.networking.fqdn}";
locations."/" = {
proxyPass = "http://localhost${builtins.toString config.services.victoriametrics.listenAddress}";
};
};
}

View File

@@ -0,0 +1,26 @@
{ config, ... }:
{
clan.core.vars.generators.b4l-vikunja = {
files.subdomain.secret = false;
prompts = {
subdomain = {
persist = true;
type = "line";
description = "Sub-domain for Vikunja todo app. Default:(todo)";
};
};
script = ''cat $prompts/subdomain || echo "todo" > $out/subdomain'';
};
services.vikunja = {
frontendHostname = "${config.clan.core.vars.generators.b4l-vikunja.files.subdomain.value}.${config.networking.fqdn}";
};
services.nginx.virtualHosts."${config.services.vikunja.frontendHostname}" = {
useACMEHost = "${config.networking.fqdn}";
forceSSL = true;
locations."/" = {
proxyPass = "${config.services.vikunja.frontendScheme}://${config.services.vikunja.frontendHostname}:${builtins.toString config.services.vikunja.port}";
};
};
}

View File

@@ -6,7 +6,11 @@
clan = { clan = {
meta.name = "NewEdgeClan"; meta.name = "NewEdgeClan";
machines = { }; machines = { };
specialArgs = { inherit self; }; secrets.age.plugins = [
"age-plugin-yubikey"
"age-plugin-fido2-hmac"
];
specialArgs = { inherit inputs self; };
inherit self; inherit self;
}; };
} }

View File

@@ -0,0 +1,16 @@
{ config, ... }:
{
imports = [
(import ../../lib/auto-accept-zerotier-members.nix {
memberIds = [
"dbe44c0287" # Alex-gateway
"b0e0b84fd3" # Alex
"2bd36db8cc" # kurogeek-thinkpad
];
})
];
system.stateVersion = "25.11";
clan.core.sops.defaultGroups = [ "admins" ];
clan.core.networking.targetHost = "root@[${config.clan.core.vars.generators.zerotier.files.zerotier-ip.value}]";
}

50
machines/rigel/disko.nix Normal file
View File

@@ -0,0 +1,50 @@
# ---
# schema = "single-disk"
# [placeholders]
# mainDisk = "/dev/disk/by-id/mmc-C9A551_0x157f3bd0"
# ---
# This file was automatically generated!
# CHANGING this configuration requires wiping and reinstalling the machine
{
boot.loader.grub.efiSupport = true;
boot.loader.grub.efiInstallAsRemovable = true;
boot.loader.grub.enable = true;
disko.devices = {
disk = {
main = {
name = "main-598d9832330c4a02b021deca9caa267b";
device = "/dev/disk/by-id/mmc-C9A551_0x157f3bd0";
type = "disk";
content = {
type = "gpt";
partitions = {
"boot" = {
size = "1M";
type = "EF02"; # for grub MBR
priority = 1;
};
ESP = {
type = "EF00";
size = "500M";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
root = {
size = "100%";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
};
};
}

3593
machines/rigel/facter.json Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,62 @@
{
inputs,
config,
...
}:
{
imports = [
(inputs.import-tree ./services)
(import ../../lib/auto-accept-zerotier-members.nix {
memberIds = [
"dbe44c0287" # Alex-gateway
"b0e0b84fd3" # Alex
"2bd36db8cc" # kurogeek-thinkpad
];
})
];
clan.core.sops.defaultGroups = [ "admins" ];
clan.core.networking.targetHost = "root@[${config.clan.core.vars.generators.zerotier.files.zerotier-ip.value}]";
nixpkgs.hostPlatform = {
system = "x86_64-linux";
};
clan.core.vars.generators.vega-public-domain = {
files.name.secret = false;
prompts = {
name = {
persist = true;
type = "line";
description = "Base public domain for Vega machine. Default:(glomglom.fun)";
};
};
script = ''cat $prompts/name || echo -n "glomglom.fun" > $out/name'';
};
clan.core.vars.generators.vega-internal-domain = {
files.name.secret = false;
prompts = {
name = {
persist = true;
type = "line";
description = "Base internal domain for Vega machine. Default:(glom.newedge.house)";
};
};
script = ''cat $prompts/name || echo -n "glom.newedge.house" > $out/name'';
};
networking.fqdn = config.clan.core.vars.generators.vega-internal-domain.files.name.value;
system.stateVersion = "25.11";
# security.acme.defaults.email = "admin@b4l.co.th";
# security.acme.acceptTerms = true;
# services.nginx.virtualHosts."${config.networking.fqdn}" = {
# enableACME = true;
# };
}

141
machines/vega/disko.nix Normal file
View File

@@ -0,0 +1,141 @@
{ lib, ... }:
let
hashDisk = disk: "os-${builtins.substring 0 5 (builtins.hashString "sha256" disk)}";
os = "/dev/disk/by-id/mmc-CUTB42_0x95d14f9e";
vdev = [
"/dev/disk/by-id/ata-ST20000NM002H-3KV133_ZYD5RYRG"
"/dev/disk/by-id/ata-ST20000NM002H-3KV133_ZYD5S02X"
];
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";
};
};
};
};
};
}
// (lib.listToAttrs (
map (disk: {
name = "data-${hashDisk disk}";
value = {
type = "disk";
device = disk;
content = {
type = "zfs";
pool = "zdata";
};
};
}) vdev
));
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";
};
};
};
};
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" ];
};
};
};
};
};
}

4118
machines/vega/facter.json Normal file

File diff suppressed because it is too large Load Diff

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 = {
GLOM.users = [
"w"
"kurogeek"
"berwn"
];
};
in
{
services.samba = {
enable = true;
openFirewall = true;
settings = {
global = {
security = "user";
workgroup = "WORKGROUP";
"server string" = "Glom Vega";
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;
};
}

View File

@@ -0,0 +1,26 @@
{ ... }:
{
_class = "clan.service";
manifest.name = "actual-budget";
manifest.description = "A local-first personal finance app ";
manifest.categories = [ "System" ];
roles.default = {
perInstance.nixosModule =
{
lib,
config,
...
}:
{
services.actual = {
enable = lib.mkDefault true;
};
clan.core.state.actual-budget.folders = [
config.systemd.services.actual.serviceConfig.WorkingDirectory
];
};
};
}

View File

@@ -0,0 +1,19 @@
{ lib, ... }:
let
module = lib.modules.importApply ./default.nix { };
in
{
clan.modules = {
actual-budget = module;
};
perSystem =
{ ... }:
{
clan.nixosTests.actual-budget = {
imports = [ ./tests/vm/default.nix ];
clan.modules."@clan/actual-budget" = module;
};
};
}

View File

@@ -0,0 +1,34 @@
{
...
}:
{
name = "service-actual-budget";
clan = {
directory = ./.;
inventory = {
machines.server = { };
instances = {
actual-budget-test = {
module.name = "@clan/actual-budget";
module.input = "self";
roles.default.machines."server".settings = { };
};
};
};
};
nodes = {
server = { };
};
testScript = ''
start_all()
server.wait_for_unit("actual")
server.succeed("systemctl status actual")
'';
}

View File

@@ -0,0 +1,28 @@
{ inputs, lib, ... }:
{
imports =
let
# Get all subdirectories in the current directory
dirContents = builtins.readDir ./.;
# Filter to include only directories that have a flake-module.nix file
# and exclude special directories like 'result'
validModuleDirs = builtins.filter (
name:
name != "result"
&& dirContents.${name} == "directory"
&& builtins.pathExists (./. + "/${name}/flake-module.nix")
) (builtins.attrNames dirContents);
# Create import paths for each valid directory
imports = (map (name: ./. + "/${name}/flake-module.nix") validModuleDirs) ++ [
(import (inputs.clan-core + "/lib/flake-parts/clan-nixos-test.nix") {
inherit lib;
flake-parts-lib = inputs.flake-parts.lib;
self = inputs.clan-core;
inputs = inputs.clan-core.clan.self.inputs;
})
];
in
imports;
}

View File

@@ -0,0 +1,24 @@
{ ... }:
{
_class = "clan.service";
manifest.name = "grafana";
manifest.description = "Platform for data analytics and monitoring";
manifest.categories = [ "System" ];
roles.default = {
perInstance.nixosModule =
{
config,
lib,
...
}:
{
services.grafana = {
enable = lib.mkDefault true;
};
clan.core.state.grafana.folders = [ config.services.grafana.dataDir ];
};
};
}

View File

@@ -0,0 +1,18 @@
{ lib, ... }:
let
module = lib.modules.importApply ./default.nix { };
in
{
clan.modules = {
grafana = module;
};
perSystem =
{ ... }:
{
clan.nixosTests.grafana = {
imports = [ ./tests/vm/default.nix ];
clan.modules."@clan/grafana" = module;
};
};
}

View File

@@ -0,0 +1,42 @@
{
...
}:
{
name = "service-grafana";
clan = {
directory = ./.;
inventory = {
machines.server = { };
instances = {
grafana-test = {
module.name = "@clan/grafana";
module.input = "self";
roles.default.machines."server".settings = { };
};
};
};
};
nodes = {
server = {
services.grafana = {
settings = {
server.domain = "grafana.localhost";
};
};
};
};
testScript = ''
start_all()
server.wait_for_unit("grafana")
server.succeed("systemctl status grafana")
server.wait_for_open_port(3000)
server.succeed("curl -H \"Host: grafana.localhost\" http://127.0.0.1:3000 ")
server.succeed("grafana cli -v")
'';
}

View File

@@ -0,0 +1,60 @@
{ ... }:
{
_class = "clan.service";
manifest.name = "nextcloud";
manifest.description = "Nextcloud server, a safe home for all your data";
manifest.categories = [ "System" ];
roles.default = {
perInstance.nixosModule =
{
config,
pkgs,
lib,
...
}:
{
clan.core.vars.generators.nextcloud = {
files = {
adminpassFile = {
owner = "nextcloud";
group = "nextcloud";
secret = true;
};
};
script = ''
xkcdpass --numwords 4 --delimiter - --count 1 | tr -d "\n" > "$out"/adminpassFile
'';
runtimeInputs = [
pkgs.xkcdpass
];
};
services.nextcloud = {
enable = lib.mkDefault true;
hostName = lib.mkDefault "localhost";
database.createLocally = lib.mkDefault true;
config = {
dbtype = lib.mkDefault "pgsql";
dbhost = lib.mkDefault "/run/postgresql";
dbuser = lib.mkDefault "nextcloud";
dbname = lib.mkDefault "nextcloud";
adminuser = lib.mkDefault "admin";
adminpassFile = lib.mkDefault config.clan.core.vars.generators.nextcloud.files.adminpassFile.path;
};
};
clan.core.state.nextcloud.folders = [
config.services.nextcloud.home
]
++ (
if config.services.nextcloud.home != config.services.nextcloud.datadir then
[ config.services.nextcloud.datadir ]
else
[ ]
);
};
};
}

View File

@@ -0,0 +1,19 @@
{ lib, ... }:
let
module = lib.modules.importApply ./default.nix { };
in
{
clan.modules = {
nextcloud = module;
};
perSystem =
{ ... }:
{
clan.nixosTests.nextcloud = {
imports = [ ./tests/vm/default.nix ];
clan.modules."@clan/nextcloud" = module;
};
};
}

View File

@@ -0,0 +1,36 @@
{
...
}:
{
name = "service-nextcloud";
clan = {
directory = ./.;
inventory = {
machines.server = { };
instances = {
nextcloud-test = {
module.name = "@clan/nextcloud";
module.input = "self";
roles.default.machines."server" = { };
};
};
};
};
nodes = {
server = {
services.nextcloud = { };
};
};
testScript = ''
start_all()
server.wait_for_unit("phpfpm-nextcloud.service")
# Check that garage is running
server.succeed("systemctl status phpfpm-nextcloud.service")
'';
}

View File

@@ -0,0 +1,6 @@
[
{
"publickey": "age15md5wyqzn4jwc7pgyjkjhcd6nfuct9gxgrl7x5qxdzgvrh32ruvqmk3wfq",
"type": "age"
}
]

View File

@@ -0,0 +1,15 @@
{
"data": "ENC[AES256_GCM,data:LtzjjbqrzdiFqw5sEI6nYAjLuWJOqiEcO9T8POnjDHK0l55RAxLLzlc1w2DTRPd46vAFy04IYgPiwwQJj8WuYdgjymXTyVqGvNA=,iv:q/L8DpR9E/NNIW2cNFft/e65xGHK9HN19W8ISd6lgdA=,tag:7XFi8VgfG40I0wSHqasXSQ==,type:str]",
"sops": {
"age": [
{
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxMGF5Q3V5T29ub09XL0Mx\nUVBlSUc2TnRkaGxoQW5uMzUzd04xOWFYRkNBClZ3eVU3dEovWDVZSkR0bnRRY3Bn\nOFNQWDFRckFxVlpvTVRsa01ad0NkRDAKLS0tIGd2UDV3cWZTTkF6V3p4Y3ZKOXdo\nY1doTFoyT2dSaG93b0lGb01YaExDTXMKe4wjgOysbF+NKlnmQgard1N6Xhazex7y\nCuvGnbcy2TLxDNhjdgjoOxUV1xQWnwoYOF1QDbL7l2k59iE3lzUG8Q==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-07-29T03:24:54Z",
"mac": "ENC[AES256_GCM,data:s6W/U0FekNcDdKk9/L54Q0V/XZhrDQwP/moNFbxbucD0sAXzEYMWbWTDNCz6/NVtqr3A++Vk65LFr8bgWuh4uxekXrLDN0Pyb7AJpDkp7IlE6ijT3cQk+OVpcpTt+FgFt3JZLyrmOL/H638sg4c0bptN+Fj8LrNXFdauWCDBlkA=,iv:oiEPi/zvH0m312ezyT0SnUavlX47pduzyz8NIwuCaNs=,tag:e6KkwWAJSZbiliKm4VT6yw==,type:str]",
"unencrypted_suffix": "_unencrypted",
"version": "3.10.2"
}
}

View File

@@ -0,0 +1 @@
../../../users/admin

View File

@@ -0,0 +1,4 @@
{
"publickey": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
"type": "age"
}

View File

@@ -0,0 +1 @@
../../../../../../sops/machines/server

View File

@@ -0,0 +1,19 @@
{
"data": "ENC[AES256_GCM,data:NVuUW3KNwUUs/Cwswvi4kDo8GZM453y/TRlHWut3OA==,iv:7rSqlQxgJCRecmpNrmGZeT03f1eOuO+W8O2QBkoKdXc=,tag:F9WkMVBV8zh4L86sBA4LVQ==,type:str]",
"sops": {
"age": [
{
"recipient": "age15md5wyqzn4jwc7pgyjkjhcd6nfuct9gxgrl7x5qxdzgvrh32ruvqmk3wfq",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBic1hPNFdyYzE5UndKNEtj\neDdJc2RuN0Y5WTB2d1h0ZFVJRUpnTnA3TW5JCklqUzFucVNKU3JLeG5JVG1KR05q\ncVg2OFBRNW1RZ0pwWnc2eFlmYzEzZ2MKLS0tIEJod0QvMHBZVlpxMldGdTRmRTNB\nQmVOQ2U2bDd0WTQvRFJnZ2NybFJoTFEKiimfshCLluicTeVyLbFQDm+8JMXBx/n0\n9NwAb4mJwQ8B0qlFsdiXZU4pP02aw7f/NH4hX6BvBBw+SP42plkmfw==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFV3FmNlJHeEhKT3NUVG9K\nNXNGdDlsVmtnWng5dGlIaVNRdXlaWVdNdmhrCi9KLzZYVWxpanlLUzJKVDlRSHlM\nRFFtditYZ1lXY3pFeUNXTk9OVitSd3MKLS0tIERVWHFNZitETlRuNEpDS1FxVS9C\nMk5UNlBjTkNRTFc5T0J1TTlZZm1ZOG8KWwGkEKK8nEWib4Va9lrVFnHU0m0zPjFE\n/3eMObt62ngwrmbAq0bNe2gFiC/OhLDf5BixldSgSeu9AenRz3Mdjg==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-07-29T03:24:55Z",
"mac": "ENC[AES256_GCM,data:B3LUWx3g6P5R006NrsFMZNc466qFadfnlXS5hitToZrNEf9VN3NlINwi2liYf9JjgSXXVV6IybVoW7LYDFRNRrG2QXfvWEfozVr/JtjvufcmuyM96PbzURUfOKndau1GbJagUO4MH3l3AEvkZnSRR3nIKWGYZDiJTNo8yRIK7nw=,iv:IXdWo8y9jPYgII5HRJ6sRxb3WOcKdifDsZoU4tusDuQ=,tag:xdqph+Y2nMYNDD3hbxCcXA==,type:str]",
"unencrypted_suffix": "_unencrypted",
"version": "3.10.2"
}
}

View File

@@ -0,0 +1 @@
../../../../../../sops/users/admin

View File

@@ -0,0 +1,24 @@
{ ... }:
{
_class = "clan.service";
manifest.name = "paperless";
manifest.description = "A community-supported supercharged document management system: scan, index and archive all your documents";
manifest.categories = [ "System" ];
roles.default = {
perInstance.nixosModule =
{
lib,
config,
...
}:
{
services.paperless = {
enable = lib.mkDefault true;
};
clan.core.state.paperless.folders = [ config.services.paperless.dataDir ];
};
};
}

View File

@@ -0,0 +1,19 @@
{ lib, ... }:
let
module = lib.modules.importApply ./default.nix { };
in
{
clan.modules = {
paperless = module;
};
perSystem =
{ ... }:
{
clan.nixosTests.paperless = {
imports = [ ./tests/vm/default.nix ];
clan.modules."@clan/paperless" = module;
};
};
}

View File

@@ -0,0 +1,38 @@
{
...
}:
{
name = "service-paperless";
clan = {
directory = ./.;
inventory = {
machines.server = { };
instances = {
paperless-test = {
module.name = "@clan/paperless";
module.input = "self";
roles.default.machines."server".settings = { };
};
};
};
};
nodes = {
server = {
services.paperless = {
};
};
};
testScript = ''
start_all()
server.wait_for_unit("paperless-web")
server.succeed("systemctl status paperless-web")
server.wait_for_open_port(28981)
server.succeed("curl http://127.0.0.1:28981")
'';
}

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 ];
};
};
}

View File

@@ -0,0 +1,19 @@
{ lib, ... }:
let
module = lib.modules.importApply ./default.nix { };
in
{
clan.modules = {
pingvin = module;
};
perSystem =
{ ... }:
{
clan.nixosTests.pingvin = {
imports = [ ./tests/vm/default.nix ];
clan.modules."@clan/pingvin" = module;
};
};
}

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 ")
'';
}

View File

@@ -0,0 +1,45 @@
{ ... }:
{
_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.categories = [ "System" ];
roles.default = {
perInstance.nixosModule =
{
config,
pkgs,
lib,
...
}:
{
clan.core.vars.generators.pocket-id = {
files = {
encryption-key = {
owner = "${config.services.pocket-id.user}";
group = "${config.services.pocket-id.group}";
secret = true;
};
};
runtimeInputs = [ pkgs.pwgen ];
script = ''
pwgen -s 32 1 > $out/encryption-key
'';
};
clan.core.state.pocket-id.folders = [ config.services.pocket-id.dataDir ];
services.pocket-id = {
enable = lib.mkDefault true;
settings = {
ENCRYPTION_KEY_FILE = config.clan.core.vars.generators.pocket-id.files.encryption-key.path;
PORT = lib.mkDefault 1411;
ANALYTICS_DISABLED = lib.mkDefault true;
UI_CONFIG_DISABLED = lib.mkDefault true;
};
};
};
};
}

View File

@@ -0,0 +1,19 @@
{ lib, ... }:
let
module = lib.modules.importApply ./default.nix { };
in
{
clan.modules = {
pocket-id = module;
};
perSystem =
{ ... }:
{
clan.nixosTests.pocket-id = {
imports = [ ./tests/vm/default.nix ];
clan.modules."@clan/pocket-id" = module;
};
};
}

View File

@@ -0,0 +1,34 @@
{ ... }:
{
name = "service-pocket-id";
clan = {
directory = ./.;
inventory = {
machines.server = { };
instances = {
pocket-id-test = {
module.name = "@clan/pocket-id";
module.input = "self";
roles.default.machines."server" = { };
};
};
};
};
nodes = {
server = {
services.pocket-id = { };
};
};
testScript = ''
start_all()
server.wait_for_unit("pocket-id")
# Check that garage is running
server.succeed("systemctl status pocket-id")
'';
}

View File

@@ -0,0 +1,6 @@
[
{
"publickey": "age1jvhs79a367ynhupy6gndyafg5f6wzrsa3p3r27d8y4zpvlp5vd6qwysnc2",
"type": "age"
}
]

View File

@@ -0,0 +1,15 @@
{
"data": "ENC[AES256_GCM,data:MheRz91AzSqUV0gz3PHdort06igblp8dVku2GIeXbBiTpG3Dnlqzw6QEvTeRVtZ4ol0gHS8CQQ4Lc4H9IyHGiTfJkSUM7pXY/vM=,iv:mMibIfA6gqvJlbau9sKkjRoYrDcqCpTG0b+jrZCHIkE=,tag:MN5I9AO1U7sJfq/9GxSFCg==,type:str]",
"sops": {
"age": [
{
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1dnVqRXVibTFYeUlsc09J\nQnRSRVE0NklWWFNlbHZaaWJ3dDlEaTJKVkZnCnJEZHhoSzd3T3NEVjFjY0NkRFNq\nL1owbmR0SENSWVQxOXVlNWJFb0JsSEEKLS0tIHhESEI2Y3MzMU9WRzhYNWZhUUd2\nTVpldG5qbDF6UG9jNnBRTnZRdzAweDAKl4FpFTp7NyTHXJEF7tIO0CnsgTY4maJ2\n7KfQRwQuhW73WqVdzJSZ7i/Xapwglx0ISBvSEDgBTiQhFlBLCMEzYg==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-07-29T09:50:44Z",
"mac": "ENC[AES256_GCM,data:lZ7SAQkkH441L3Ss9nEI1fm6SgcysIcOBg9it0m80CiNhtittsFNcP7l0ApkIBQLhMsan93bLMG3kcDKzqxld3XDRPUwlJkKElh8Dc8q7qqtOqgKNnsFDcx4Zh3HdiTPywyIBnUMYAul4tVPpEzqh1GSD1GF9fsBxLiwxBwalY4=,iv:wmhz1k5LMNNxuacQj+A5FryJwzqxpXf5AnFoeL1TF4k=,tag:cl5OcxGYvC6DGQDRuhqRRw==,type:str]",
"unencrypted_suffix": "_unencrypted",
"version": "3.10.2"
}
}

View File

@@ -0,0 +1 @@
../../../users/admin

View File

@@ -0,0 +1,4 @@
{
"publickey": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
"type": "age"
}

View File

@@ -0,0 +1 @@
../../../../../../sops/machines/server

View File

@@ -0,0 +1,19 @@
{
"data": "ENC[AES256_GCM,data:o1BHipQXow25uobhojeSIvSaIM4SiOtjfpNBi11E7kRX,iv:mheOssj84dp1+QAG0rpdyaf5O4WWaTWh1y/DC/I9nnA=,tag:M8zSZ4GWwy5rOcOEOBbwIA==,type:str]",
"sops": {
"age": [
{
"recipient": "age1jvhs79a367ynhupy6gndyafg5f6wzrsa3p3r27d8y4zpvlp5vd6qwysnc2",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXaXFvL0JES28rUkhNT3Bj\neDVYZlNubC8wV1VGTHN1Vzh6NEV3YWI3L3pJClh2T0FhQURXRkRJSnFVYjVsZkdq\ncWRFL1crVm1EK2NHNUtlc1RMVlZ5aWMKLS0tIFczWUcxTWFMdkhXb2ZTZlRSNDBT\nNmxWak50M1JTV2R3M0FXclRGc0JuVjgKtsxU2a3DNhe9CeJFK+HK7lFhrpV7UuES\nqasLv4crL7+4eJFhmUxVwzT0ubPAuG3CBMbbmrYmAs2CUXWtcmqGMA==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0TGwzeUNLbkJ4bFBPVjJy\nd3pLTWRPVytrK1plQ3kzd1ZOMjBtcGJjY25nCk5mNDRxNmJjTHh4a2pBSldvQ0Y5\nUXVPbWZ1WW1QcU03MWtuL29udGFUQ1EKLS0tIHFSY1VZUGJFanhyZmN6WHJKTzEr\nbjBkVDNJUUZNZHhjSDlDZ3Z4Y0d3Q3MKHm3Ar31B2RviANl+tCeNmtYvQp5hVdui\n9Khkd3R6MshF4rZWrWhD9vea1RX9ugJJawCTU3+4zFDEWQ6XQ+tpTw==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-07-29T09:50:44Z",
"mac": "ENC[AES256_GCM,data:B3iNE0/ve2EazWNQJ6MhSaa3EAmte5GUJrVjLB7ysIoe+pf7kQy9HE2ObEypFezvbfBYAbXd+XIq8J+jTjh4X11i6/BDNsvFQKuYbTLaK+dqZzeuOQU3ntTQuhyx5qdKyXq5FtHYyJI9XsYvSFRHe2UYy4L5i6LvMoc3ka/vUHI=,iv:mXuhXp63D1UkBJX5U7RY+NqYsU5SkolDABrSDRXegFk=,tag:LJ/BnU9xKMQyr+nAAHnGFA==,type:str]",
"unencrypted_suffix": "_unencrypted",
"version": "3.10.2"
}
}

View File

@@ -0,0 +1 @@
../../../../../../sops/users/admin

View File

@@ -0,0 +1,23 @@
{ ... }:
{
_class = "clan.service";
manifest.name = "stirling-pdf";
manifest.description = "Your locally hosted one-stop-shop for all your PDF needs.";
manifest.categories = [ "System" ];
roles.default = {
perInstance.nixosModule =
{
lib,
...
}:
{
services.stirling-pdf = {
enable = lib.mkDefault true;
environment = {
SERVER_PORT = lib.mkDefault 8080;
};
};
};
};
}

View File

@@ -0,0 +1,19 @@
{ lib, ... }:
let
module = lib.modules.importApply ./default.nix { };
in
{
clan.modules = {
stirling-pdf = module;
};
perSystem =
{ ... }:
{
clan.nixosTests.stirling-pdf = {
imports = [ ./tests/vm/default.nix ];
clan.modules."@clan/stirling-pdf" = module;
};
};
}

View File

@@ -0,0 +1,34 @@
{
...
}:
{
name = "service-stirling-pdf";
clan = {
directory = ./.;
inventory = {
machines.server = { };
instances = {
stirling-pdf-test = {
module.name = "@clan/stirling-pdf";
module.input = "self";
roles.default.machines."server".settings = { };
};
};
};
};
nodes = {
server = { };
};
testScript = ''
start_all()
server.wait_for_unit("stirling-pdf")
server.succeed("systemctl status stirling-pdf")
'';
}

View File

@@ -0,0 +1,25 @@
{ ... }:
{
_class = "clan.service";
manifest.name = "Victoria Metrics";
manifest.description = "VictoriaMetrics: fast, cost-effective monitoring solution and time series database";
manifest.categories = [ "System" ];
roles.default = {
perInstance.nixosModule =
{
config,
lib,
...
}:
{
services.victoriametrics = {
enable = lib.mkDefault true;
};
clan.core.state.victoriametrics.folders = lib.mkDefault [
"/var/lib/${config.services.victoriametrics.stateDir}"
];
};
};
}

View File

@@ -0,0 +1,19 @@
{ lib, ... }:
let
module = lib.modules.importApply ./default.nix { };
in
{
clan.modules = {
victoriametrics = module;
};
perSystem =
{ ... }:
{
clan.nixosTests.victoriametrics = {
imports = [ ./tests/vm/default.nix ];
clan.modules."@clan/victoriametrics" = module;
};
};
}

View File

@@ -0,0 +1,34 @@
{
...
}:
{
name = "service-victoriametrics";
clan = {
directory = ./.;
inventory = {
machines.server = { };
instances = {
victoriametrics-test = {
module.name = "@clan/victoriametrics";
module.input = "self";
roles.default.machines."server".settings = { };
};
};
};
};
nodes = {
server = { };
};
testScript = ''
start_all()
server.wait_for_unit("victoriametrics")
server.succeed("systemctl status victoriametrics")
'';
}

View File

@@ -0,0 +1,32 @@
{ ... }:
{
_class = "clan.service";
manifest.name = "vikunja";
manifest.description = "The to-do app to organize your life.";
manifest.categories = [ "System" ];
roles.default = {
perInstance.nixosModule =
{
lib,
config,
...
}:
{
clan.core.state.vikunja.folders = [
config.services.vikunja.settings.files.basepath
]
++ (
if config.services.vikunja.settings.database.type == "sqlite" then
[ config.services.vikunja.settings.database.path ]
else
[ ]
);
services.vikunja = {
enable = lib.mkDefault true;
frontendScheme = lib.mkDefault "http";
frontendHostname = lib.mkDefault "localhost";
};
};
};
}

View File

@@ -0,0 +1,18 @@
{ lib, ... }:
let
module = lib.modules.importApply ./default.nix { };
in
{
clan.modules = {
vikunja = module;
};
perSystem =
{ ... }:
{
clan.nixosTests.vikunja = {
imports = [ ./tests/vm/default.nix ];
clan.modules."@clan/vikunja" = module;
};
};
}

View File

@@ -0,0 +1,39 @@
{
pkgs,
...
}:
{
name = "service-vikunja";
clan = {
directory = ./.;
inventory = {
machines.server = { };
instances = {
vikunja-test = {
module.name = "@clan/vikunja";
module.input = "self";
roles.default.machines."server".settings = { };
};
};
};
};
nodes = {
server = {
services.vikunja = {
};
};
};
testScript = ''
start_all()
server.wait_for_unit("vikunja")
# Check that garage is running
server.succeed("systemctl status vikunja")
'';
}

25
routers/default.nix Normal file
View File

@@ -0,0 +1,25 @@
{ inputs, ... }:
{
flake.legacyPackages = {
qemu-router = import "${inputs.liminix}/default.nix" {
liminix-config = import "${inputs.liminix}/examples/hello-from-qemu.nix";
device = (import "${inputs.liminix}/devices/qemu-aarch64/default.nix");
};
yada-router = import "${inputs.liminix}/default.nix" {
liminix-config = import ./routers/yada-house/configuration.nix { inherit inputs; };
device = (import ./routers/yada-house/device.nix { inherit inputs; });
};
qemu-flake = import "${inputs.liminix}/default.nix" {
liminix-config = import ./routers/qemu/configuration.nix { inherit inputs; };
device = (import ./routers/qemu/device.nix { inherit inputs; });
};
vanilla = import "${inputs.liminix}/default.nix" {
liminix-config = import ./routers/vanilla/configuration.nix { inherit inputs; };
device = (import "${inputs.liminix}/devices/gl-mt300a/default.nix");
};
fax-router = import "${inputs.liminix}/default.nix" {
device = (import "${inputs.liminix}/devices/gl-ar750");
liminix-config = import ./fax-router/configuration.nix { inherit inputs; };
};
};
}

View File

@@ -0,0 +1,46 @@
# This is an example that uses the "gateway" profile to create a
# "typical home wireless router" configuration suitable for a Gl.inet
# gl-ar750 router. It should be fairly simple to edit it for other
# devices: mostly you will need to attend to the number of wlan and lan
# interfaces
{ inputs }:
{ config, pkgs, ... }:
let
inherit (pkgs.liminix.services) target;
svc = config.system.service;
in
rec {
imports = [
"${inputs.liminix}/modules/wlan.nix"
"${inputs.liminix}/modules/network"
"${inputs.liminix}/modules/ntp"
"${inputs.liminix}/modules/vlan"
];
services.dhcpv4 =
let
iface = svc.network.link.build { ifname = "eth1"; };
in
svc.network.dhcp.client.build { interface = iface; };
services.defaultroute4 = svc.network.route.build {
via = "$(output ${services.dhcpv4} ip)";
target = "default";
dependencies = [ services.dhcpv4 ];
};
services.packet_forwarding = svc.network.forward.build { };
services.ntp = config.system.service.ntp.build {
pools = {
"pool.ntp.org" = [ "iburst" ];
};
};
boot.tftp = {
serverip = "192.168.8.148";
ipaddr = "192.168.8.251";
};
defaultProfile.packages = [ pkgs.hello ];
}

View File

@@ -0,0 +1,17 @@
{
wpa_passphrase = "you bring light in";
ssid = "liminix";
l2tp = {
name = "abcde@a.1";
password = "NotMyIspPassword";
};
root = {
# mkpasswd -m sha512crypt
passwd = "$6$6pt0mpbgcB7kC2RJ$kSBoCYGyi1.qxt7dqmexLj1l8E6oTZJZmfGyJSsMYMW.jlsETxdgQSdv6ptOYDM7DHAwf6vLG0pz3UD31XBfC1";
openssh.authorizedKeys.keys = [ ];
};
lan = {
prefix = "10.8.0";
};
}

View File

@@ -0,0 +1,49 @@
{ inputs }:
{ config, pkgs, ... }:
let
svc = config.system.service;
in
rec {
imports = [
"${inputs.liminix}/modules/network"
"${inputs.liminix}/modules/dnsmasq"
"${inputs.liminix}/modules/ssh"
];
hostname = "hello";
# configure the internal network (LAN) with an address
services.int = svc.network.address.build {
interface = config.hardware.networkInterfaces.lan;
family = "inet";
address = "10.3.0.1";
prefixLength = 16;
};
services.sshd = svc.ssh.build { };
users.root = {
# the password is "secret". Use mkpasswd -m sha512crypt to
# create this hashed password string
passwd = "$6$y7WZ5hM6l5nriLmo$5AJlmzQZ6WA.7uBC7S8L4o19ESR28Dg25v64/vDvvCN01Ms9QoHeGByj8lGlJ4/b.dbwR9Hq2KXurSnLigt1W1";
};
services.dns =
let
interface = services.int;
in
svc.dnsmasq.build {
inherit interface;
ranges = [
"10.3.0.10,10.3.0.240"
"::,constructor:$(output ${interface} ifname),ra-stateless"
];
domain = "example.org";
};
defaultProfile.packages = with pkgs; [
figlet
];
}

58
routers/qemu/device.nix Normal file
View File

@@ -0,0 +1,58 @@
# This "device" generates images that can be used with the QEMU
# emulator. The default output is a directory containing separate
# kernel ("Image" format) and root filesystem (squashfs or jffs2)
# images
{ inputs }:
{
system = {
crossSystem = {
config = "aarch64-unknown-linux-musl";
};
};
description = ''
QEMU Aarch64
************
This target produces an image for
the `QEMU "virt" platform <https://www.qemu.org/docs/master/system/arm/virt.html>`_ using a 64 bit CPU type.
ARM targets differ from MIPS in that the kernel format expected
by QEMU is an "Image" (raw binary file) rather than an ELF
file, but this is taken care of by :command:`run.sh`. Check the
documentation for the :ref:`qemu` target for more information.
'';
# this device is described by the "qemu" device
installer = "vmroot";
module =
{ config, lim, ... }:
{
imports = [
"${inputs.liminix}/modules/arch/aarch64.nix"
"${inputs.liminix}/devices/families/qemu.nix"
];
kernel = {
config = {
VIRTUALIZATION = "y";
PCI_HOST_GENERIC = "y";
SERIAL_AMBA_PL011 = "y";
SERIAL_AMBA_PL011_CONSOLE = "y";
};
};
boot.commandLine = [
"console=ttyAMA0,38400"
];
hardware =
let
addr = lim.parseInt "0x40010000";
in
{
loadAddress = addr;
entryPoint = addr;
};
};
}

View File

@@ -0,0 +1,41 @@
{ inputs }:
{ config, pkgs, ... }:
let
inherit (pkgs.liminix.services) target;
svc = config.system.service;
in
rec {
imports = [
"${inputs.liminix}/modules/wlan.nix"
"${inputs.liminix}/modules/network"
"${inputs.liminix}/modules/ntp"
"${inputs.liminix}/modules/vlan"
];
services.dhcpv4 =
let
iface = svc.network.link.build { ifname = "eth1"; };
in
svc.network.dhcp.client.build { interface = iface; };
services.defaultroute4 = svc.network.route.build {
via = "$(output ${services.dhcpv4} ip)";
target = "default";
dependencies = [ services.dhcpv4 ];
};
services.packet_forwarding = svc.network.forward.build { };
services.ntp = config.system.service.ntp.build {
pools = {
"pool.ntp.org" = [ "iburst" ];
};
};
boot.tftp = {
serverip = "192.168.8.148";
ipaddr = "192.168.8.251";
};
defaultProfile.packages = [ pkgs.hello ];
}

View File

@@ -0,0 +1,86 @@
# This "device" generates images that can be used with the QEMU
# emulator. The default output is a directory containing separate
# kernel (uncompressed vmlinux) and initrd (squashfs) images
{ inputs }:
{
system = {
crossSystem = {
config = "mips-unknown-linux-musl";
gcc = {
abi = "32";
arch = "mips32"; # maybe mips_24kc-
};
};
};
description = ''
QEMU MIPS
*********
This target produces an image for
QEMU, the "generic and open source machine emulator and
virtualizer".
MIPS QEMU emulates a "Malta" board, which was an ATX form factor
evaluation board made by MIPS Technologies, but mostly in Liminix
we use paravirtualized devices (Virtio) instead of emulating
hardware.
Building an image for QEMU results in a :file:`result/` directory
containing ``run.sh`` ``vmlinux``, and ``rootfs`` files. To invoke
the emulator, run ``run.sh``.
The configuration includes two emulated "hardware" ethernet
devices and the kernel :code:`mac80211_hwsim` module to
provide an emulated wlan device. To read more about how
to connect to this network, refer to :ref:`qemu-networking`
in the Development manual.
'';
module =
{
config,
lib,
lim,
...
}:
{
imports = [
"${inputs.liminix}/modules/arch/mipseb.nix"
"${inputs.liminix}/devices/families/qemu.nix"
];
kernel = {
config = {
MIPS_MALTA = "y";
CPU_MIPS32_R2 = "y";
POWER_RESET = "y";
POWER_RESET_SYSCON = "y";
SERIAL_8250 = "y";
SERIAL_8250_CONSOLE = "y";
};
};
hardware =
# from arch/mips/mti-malta/Platform:load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000
let
addr = lim.parseInt "0x80100000";
in
{
loadAddress = addr;
entryPoint = addr;
# Unlike the arm qemu targets, we need a static dts when
# running u-boot-using tests, qemu dumpdtb command doesn't
# work for this board. I am not at all sure this dts is
# *correct* but it does at least boot
dts = lib.mkForce {
src = "${config.system.outputs.kernel.modulesupport}/arch/mips/boot/dts/mti/malta.dts";
includePaths = [
"${config.system.outputs.kernel.modulesupport}/arch/mips/boot/dts/"
];
};
};
};
}

View File

@@ -0,0 +1,54 @@
{ inputs }:
{
config,
pkgs,
...
}:
let
svc = config.system.service;
in
rec {
imports = [
"${inputs.liminix}/modules/network"
"${inputs.liminix}/modules/dnsmasq"
"${inputs.liminix}/modules/ssh"
];
hostname = "hello";
# configure the internal network (LAN) with an address
services.int = svc.network.address.build {
interface = config.hardware.networkInterfaces.lan2;
family = "inet";
address = "192.168.8.1";
prefixLength = 24;
};
services.sshd = svc.ssh.build { };
users.root = {
# the password is "secret". Use mkpasswd -m sha512crypt to
# create this hashed password string
passwd = "$6$y7WZ5hM6l5nriLmo$5AJlmzQZ6WA.7uBC7S8L4o19ESR28Dg25v64/vDvvCN01Ms9QoHeGByj8lGlJ4/b.dbwR9Hq2KXurSnLigt1W1";
};
services.dns =
let
interface = services.int;
in
svc.dnsmasq.build {
inherit interface;
ranges = [
"192.168.8.1,192.168.8.240"
"::,constructor:$(output ${interface} ifname),ra-stateless"
];
domain = "example.org";
};
# defaultProfile.packages = with pkgs; [
# figlet
# ];
}

View File

@@ -0,0 +1,127 @@
# GL.iNet GL-MT6000
{ inputs }:
{
system = {
crossSystem = {
config = "aarch64-unknown-linux-musl";
gcc = {
arch = "armv8-a";
};
};
};
description = ''
Device configuration for Yada/White house router.
'';
module =
{
pkgs,
config,
lib,
lim,
...
}:
let
inherit (pkgs) openwrt_24_10;
# mac80211 = pkgs.kmodloader.override {
# targets = [ "rt2800soc" ];
# inherit (config.system.outputs) kernel;
# };
in
{
imports = [
"${inputs.liminix}/modules/outputs/mtdimage.nix"
"${inputs.liminix}/modules/outputs/squashfs.nix"
"${inputs.liminix}/modules/outputs/tftpboot.nix"
"${inputs.liminix}/modules/outputs/vmroot.nix"
"${inputs.liminix}/modules/arch/aarch64.nix"
# "${inputs.liminix}/modules/base.nix"
"${inputs.liminix}/modules/vlan"
];
boot.tftp = {
serverip = "192.168.1.254";
ipaddr = "192.168.1.1";
loadAddress = lim.parseInt "0x46000000";
};
boot.imageFormat = "fit";
boot.loader.fit.enable = true;
rootfsType = "squashfs";
hardware = {
loadAddress = lim.parseInt "0x48080000";
entryPoint = lim.parseInt "0x48080000";
flash = {
address = lim.parseInt "0x41e00000";
size = lim.parseInt "0x4000";
eraseBlockSize = 65536;
};
rootDevice = "/dev/root";
dts = {
src = "${openwrt_24_10.src}/target/linux/mediatek/dts/mt7986a-glinet-gl-mt6000.dts";
includePaths = [
"${openwrt_24_10.src}/target/linux/mediatek/dts"
"${config.system.outputs.kernel.modulesupport}/arch/arm64/boot/dts/mediatek/"
];
};
networkInterfaces =
let
inherit (config.system.service.network) link;
inherit (config.system.service) vlan;
in
rec {
eth0 = link.build { ifname = "eth0"; };
wan = link.build { ifname = "eth1"; };
lan1 = vlan.build {
ifname = "lan1@eth0";
primary = eth0;
vid = "1";
};
lan2 = vlan.build {
ifname = "lan2@eth0";
primary = eth0;
vid = "2";
};
lan3 = vlan.build {
ifname = "lan3@eth0";
primary = eth0;
vid = "3";
};
lan4 = vlan.build {
ifname = "lan4@eth0";
primary = eth0;
vid = "4";
};
lan5 = vlan.build {
ifname = "lan5@eth0";
primary = eth0;
vid = "5";
};
# wlan = link.build {
# ifname = "wlan0";
# dependencies = [ mac80211 ];
# };
};
};
kernel = {
src = openwrt_24_10.kernelSrc;
version = openwrt_24_10.kernelVersion;
extraPatchPhase = ''
echo ==================================================
ls ${openwrt_24_10.src}/config
echo ==================================================
patch ${openwrt_24_10.src}/package/boot/uboot-mediatek/patches/436-add-glinet-mt6000.patch
echo --------------------------------------------------
ls ${openwrt_24_10.src}/config
echo --------------------------------------------------
${openwrt_24_10.applyPatches.mediatek}
'';
config = {
};
};
};
}

View File

@@ -0,0 +1,645 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
* Copyright (C) 2021 MediaTek Inc.
* Author: Sam.Shih <sam.shih@mediatek.com>
*/
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/mt7986-clk.h>
#include <dt-bindings/reset/mt7986-resets.h>
#include <dt-bindings/phy/phy.h>
/ {
compatible = "mediatek,mt7986a";
interrupt-parent = <&gic>;
#address-cells = <2>;
#size-cells = <2>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
compatible = "arm,cortex-a53";
reg = <0x0>;
device_type = "cpu";
enable-method = "psci";
#cooling-cells = <2>;
};
cpu1: cpu@1 {
compatible = "arm,cortex-a53";
reg = <0x1>;
device_type = "cpu";
enable-method = "psci";
#cooling-cells = <2>;
};
cpu2: cpu@2 {
compatible = "arm,cortex-a53";
reg = <0x2>;
device_type = "cpu";
enable-method = "psci";
#cooling-cells = <2>;
};
cpu3: cpu@3 {
compatible = "arm,cortex-a53";
reg = <0x3>;
device_type = "cpu";
enable-method = "psci";
#cooling-cells = <2>;
};
};
clk40m: oscillator-40m {
compatible = "fixed-clock";
clock-frequency = <40000000>;
#clock-cells = <0>;
clock-output-names = "clkxtal";
};
psci {
compatible = "arm,psci-0.2";
method = "smc";
};
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
/* 192 KiB reserved for ARM Trusted Firmware (BL31) */
secmon_reserved: secmon@43000000 {
reg = <0 0x43000000 0 0x30000>;
no-map;
};
wmcpu_emi: wmcpu-reserved@4fc00000 {
no-map;
reg = <0 0x4fc00000 0 0x00100000>;
};
wo_emi0: wo-emi@4fd00000 {
reg = <0 0x4fd00000 0 0x40000>;
no-map;
};
wo_emi1: wo-emi@4fd40000 {
reg = <0 0x4fd40000 0 0x40000>;
no-map;
};
wo_ilm0: wo-ilm@151e0000 {
reg = <0 0x151e0000 0 0x8000>;
no-map;
};
wo_ilm1: wo-ilm@151f0000 {
reg = <0 0x151f0000 0 0x8000>;
no-map;
};
wo_data: wo-data@4fd80000 {
reg = <0 0x4fd80000 0 0x240000>;
no-map;
};
wo_dlm0: wo-dlm@151e8000 {
reg = <0 0x151e8000 0 0x2000>;
no-map;
};
wo_dlm1: wo-dlm@151f8000 {
reg = <0 0x151f8000 0 0x2000>;
no-map;
};
wo_boot: wo-boot@15194000 {
reg = <0 0x15194000 0 0x1000>;
no-map;
};
};
soc {
compatible = "simple-bus";
ranges;
#address-cells = <2>;
#size-cells = <2>;
gic: interrupt-controller@c000000 {
compatible = "arm,gic-v3";
reg = <0 0x0c000000 0 0x10000>, /* GICD */
<0 0x0c080000 0 0x80000>, /* GICR */
<0 0x0c400000 0 0x2000>, /* GICC */
<0 0x0c410000 0 0x1000>, /* GICH */
<0 0x0c420000 0 0x2000>; /* GICV */
interrupt-parent = <&gic>;
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <3>;
};
infracfg: infracfg@10001000 {
compatible = "mediatek,mt7986-infracfg", "syscon";
reg = <0 0x10001000 0 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
};
wed_pcie: wed-pcie@10003000 {
compatible = "mediatek,mt7986-wed-pcie",
"syscon";
reg = <0 0x10003000 0 0x10>;
};
topckgen: topckgen@1001b000 {
compatible = "mediatek,mt7986-topckgen", "syscon";
reg = <0 0x1001B000 0 0x1000>;
#clock-cells = <1>;
};
watchdog: watchdog@1001c000 {
compatible = "mediatek,mt7986-wdt";
reg = <0 0x1001c000 0 0x1000>;
interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
#reset-cells = <1>;
status = "disabled";
};
apmixedsys: apmixedsys@1001e000 {
compatible = "mediatek,mt7986-apmixedsys";
reg = <0 0x1001E000 0 0x1000>;
#clock-cells = <1>;
};
pio: pinctrl@1001f000 {
compatible = "mediatek,mt7986a-pinctrl";
reg = <0 0x1001f000 0 0x1000>,
<0 0x11c30000 0 0x1000>,
<0 0x11c40000 0 0x1000>,
<0 0x11e20000 0 0x1000>,
<0 0x11e30000 0 0x1000>,
<0 0x11f00000 0 0x1000>,
<0 0x11f10000 0 0x1000>,
<0 0x1000b000 0 0x1000>;
reg-names = "gpio", "iocfg_rt", "iocfg_rb", "iocfg_lt",
"iocfg_lb", "iocfg_tr", "iocfg_tl", "eint";
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pio 0 0 100>;
interrupt-controller;
interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&gic>;
#interrupt-cells = <2>;
};
pwm: pwm@10048000 {
compatible = "mediatek,mt7986-pwm";
reg = <0 0x10048000 0 0x1000>;
#pwm-cells = <2>;
interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&topckgen CLK_TOP_PWM_SEL>,
<&infracfg CLK_INFRA_PWM_STA>,
<&infracfg CLK_INFRA_PWM1_CK>,
<&infracfg CLK_INFRA_PWM2_CK>;
clock-names = "top", "main", "pwm1", "pwm2";
status = "disabled";
};
sgmiisys0: syscon@10060000 {
compatible = "mediatek,mt7986-sgmiisys_0",
"syscon";
reg = <0 0x10060000 0 0x1000>;
#clock-cells = <1>;
};
sgmiisys1: syscon@10070000 {
compatible = "mediatek,mt7986-sgmiisys_1",
"syscon";
reg = <0 0x10070000 0 0x1000>;
#clock-cells = <1>;
};
trng: rng@1020f000 {
compatible = "mediatek,mt7986-rng",
"mediatek,mt7623-rng";
reg = <0 0x1020f000 0 0x100>;
clocks = <&infracfg CLK_INFRA_TRNG_CK>;
clock-names = "rng";
status = "disabled";
};
crypto: crypto@10320000 {
compatible = "inside-secure,safexcel-eip97";
reg = <0 0x10320000 0 0x40000>;
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "ring0", "ring1", "ring2", "ring3";
clocks = <&infracfg CLK_INFRA_EIP97_CK>;
assigned-clocks = <&topckgen CLK_TOP_EIP_B_SEL>;
assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>;
status = "disabled";
};
uart0: serial@11002000 {
compatible = "mediatek,mt7986-uart",
"mediatek,mt6577-uart";
reg = <0 0x11002000 0 0x400>;
interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&infracfg CLK_INFRA_UART0_SEL>,
<&infracfg CLK_INFRA_UART0_CK>;
clock-names = "baud", "bus";
assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
<&infracfg CLK_INFRA_UART0_SEL>;
assigned-clock-parents = <&topckgen CLK_TOP_XTAL>,
<&topckgen CLK_TOP_UART_SEL>;
status = "disabled";
};
uart1: serial@11003000 {
compatible = "mediatek,mt7986-uart",
"mediatek,mt6577-uart";
reg = <0 0x11003000 0 0x400>;
interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&infracfg CLK_INFRA_UART1_SEL>,
<&infracfg CLK_INFRA_UART1_CK>;
clock-names = "baud", "bus";
assigned-clocks = <&infracfg CLK_INFRA_UART1_SEL>;
assigned-clock-parents = <&topckgen CLK_TOP_F26M_SEL>;
status = "disabled";
};
uart2: serial@11004000 {
compatible = "mediatek,mt7986-uart",
"mediatek,mt6577-uart";
reg = <0 0x11004000 0 0x400>;
interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&infracfg CLK_INFRA_UART2_SEL>,
<&infracfg CLK_INFRA_UART2_CK>;
clock-names = "baud", "bus";
assigned-clocks = <&infracfg CLK_INFRA_UART2_SEL>;
assigned-clock-parents = <&topckgen CLK_TOP_F26M_SEL>;
status = "disabled";
};
i2c0: i2c@11008000 {
compatible = "mediatek,mt7986-i2c";
reg = <0 0x11008000 0 0x90>,
<0 0x10217080 0 0x80>;
interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
clock-div = <5>;
clocks = <&infracfg CLK_INFRA_I2C0_CK>,
<&infracfg CLK_INFRA_AP_DMA_CK>;
clock-names = "main", "dma";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
spi0: spi@1100a000 {
compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
reg = <0 0x1100a000 0 0x100>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&topckgen CLK_TOP_MPLL_D2>,
<&topckgen CLK_TOP_SPI_SEL>,
<&infracfg CLK_INFRA_SPI0_CK>,
<&infracfg CLK_INFRA_SPI0_HCK_CK>;
clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk";
status = "disabled";
};
spi1: spi@1100b000 {
compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
reg = <0 0x1100b000 0 0x100>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&topckgen CLK_TOP_MPLL_D2>,
<&topckgen CLK_TOP_SPIM_MST_SEL>,
<&infracfg CLK_INFRA_SPI1_CK>,
<&infracfg CLK_INFRA_SPI1_HCK_CK>;
clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk";
status = "disabled";
};
thermal: thermal@1100c800 {
compatible = "mediatek,mt7986-thermal";
reg = <0 0x1100c800 0 0x800>;
interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&infracfg CLK_INFRA_THERM_CK>,
<&infracfg CLK_INFRA_ADC_26M_CK>;
clock-names = "therm", "auxadc";
nvmem-cells = <&thermal_calibration>;
nvmem-cell-names = "calibration-data";
#thermal-sensor-cells = <1>;
mediatek,auxadc = <&auxadc>;
mediatek,apmixedsys = <&apmixedsys>;
};
auxadc: adc@1100d000 {
compatible = "mediatek,mt7986-auxadc";
reg = <0 0x1100d000 0 0x1000>;
clocks = <&infracfg CLK_INFRA_ADC_26M_CK>;
clock-names = "main";
#io-channel-cells = <1>;
status = "disabled";
};
ssusb: usb@11200000 {
compatible = "mediatek,mt7986-xhci",
"mediatek,mtk-xhci";
reg = <0 0x11200000 0 0x2e00>,
<0 0x11203e00 0 0x0100>;
reg-names = "mac", "ippc";
interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&infracfg CLK_INFRA_IUSB_SYS_CK>,
<&infracfg CLK_INFRA_IUSB_CK>,
<&infracfg CLK_INFRA_IUSB_133_CK>,
<&infracfg CLK_INFRA_IUSB_66M_CK>,
<&topckgen CLK_TOP_U2U3_XHCI_SEL>;
clock-names = "sys_ck",
"ref_ck",
"mcu_ck",
"dma_ck",
"xhci_ck";
phys = <&u2port0 PHY_TYPE_USB2>,
<&u3port0 PHY_TYPE_USB3>,
<&u2port1 PHY_TYPE_USB2>;
status = "disabled";
};
mmc0: mmc@11230000 {
compatible = "mediatek,mt7986-mmc";
reg = <0 0x11230000 0 0x1000>,
<0 0x11c20000 0 0x1000>;
interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
assigned-clocks = <&topckgen CLK_TOP_EMMC_416M_SEL>,
<&topckgen CLK_TOP_EMMC_250M_SEL>;
assigned-clock-parents = <&apmixedsys CLK_APMIXED_MPLL>,
<&topckgen CLK_TOP_NET1PLL_D5_D2>;
clocks = <&topckgen CLK_TOP_EMMC_416M_SEL>,
<&infracfg CLK_INFRA_MSDC_HCK_CK>,
<&infracfg CLK_INFRA_MSDC_CK>,
<&infracfg CLK_INFRA_MSDC_133M_CK>,
<&infracfg CLK_INFRA_MSDC_66M_CK>;
clock-names = "source", "hclk", "source_cg", "bus_clk",
"sys_cg";
status = "disabled";
};
pcie: pcie@11280000 {
compatible = "mediatek,mt7986-pcie",
"mediatek,mt8192-pcie";
reg = <0x00 0x11280000 0x00 0x4000>;
reg-names = "pcie-mac";
ranges = <0x82000000 0x00 0x20000000 0x00
0x20000000 0x00 0x10000000>;
device_type = "pci";
#address-cells = <3>;
#size-cells = <2>;
interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
bus-range = <0x00 0xff>;
clocks = <&infracfg CLK_INFRA_IPCIE_PIPE_CK>,
<&infracfg CLK_INFRA_IPCIE_CK>,
<&infracfg CLK_INFRA_IPCIER_CK>,
<&infracfg CLK_INFRA_IPCIEB_CK>;
clock-names = "pl_250m", "tl_26m", "peri_26m", "top_133m";
phys = <&pcie_port PHY_TYPE_PCIE>;
phy-names = "pcie-phy";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &pcie_intc 0>,
<0 0 0 2 &pcie_intc 1>,
<0 0 0 3 &pcie_intc 2>,
<0 0 0 4 &pcie_intc 3>;
status = "disabled";
pcie_intc: interrupt-controller {
#address-cells = <0>;
#interrupt-cells = <1>;
interrupt-controller;
};
};
pcie_phy: t-phy {
compatible = "mediatek,mt7986-tphy",
"mediatek,generic-tphy-v2";
ranges;
#address-cells = <2>;
#size-cells = <2>;
status = "disabled";
pcie_port: pcie-phy@11c00000 {
reg = <0 0x11c00000 0 0x20000>;
clocks = <&clk40m>;
clock-names = "ref";
#phy-cells = <1>;
};
};
efuse: efuse@11d00000 {
compatible = "mediatek,mt7986-efuse", "mediatek,efuse";
reg = <0 0x11d00000 0 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
thermal_calibration: calib@274 {
reg = <0x274 0xc>;
};
};
usb_phy: t-phy@11e10000 {
compatible = "mediatek,mt7986-tphy",
"mediatek,generic-tphy-v2";
ranges = <0 0 0x11e10000 0x1700>;
#address-cells = <1>;
#size-cells = <1>;
status = "disabled";
u2port0: usb-phy@0 {
reg = <0x0 0x700>;
clocks = <&topckgen CLK_TOP_DA_U2_REFSEL>,
<&topckgen CLK_TOP_DA_U2_CK_1P_SEL>;
clock-names = "ref", "da_ref";
#phy-cells = <1>;
};
u3port0: usb-phy@700 {
reg = <0x700 0x900>;
clocks = <&topckgen CLK_TOP_USB3_PHY_SEL>;
clock-names = "ref";
#phy-cells = <1>;
};
u2port1: usb-phy@1000 {
reg = <0x1000 0x700>;
clocks = <&topckgen CLK_TOP_DA_U2_REFSEL>,
<&topckgen CLK_TOP_DA_U2_CK_1P_SEL>;
clock-names = "ref", "da_ref";
#phy-cells = <1>;
};
};
ethsys: syscon@15000000 {
compatible = "mediatek,mt7986-ethsys",
"syscon";
reg = <0 0x15000000 0 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
};
wed0: wed@15010000 {
compatible = "mediatek,mt7986-wed",
"syscon";
reg = <0 0x15010000 0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
memory-region = <&wo_emi0>, <&wo_ilm0>, <&wo_dlm0>,
<&wo_data>, <&wo_boot>;
memory-region-names = "wo-emi", "wo-ilm", "wo-dlm",
"wo-data", "wo-boot";
mediatek,wo-ccif = <&wo_ccif0>;
};
wed1: wed@15011000 {
compatible = "mediatek,mt7986-wed",
"syscon";
reg = <0 0x15011000 0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
memory-region = <&wo_emi1>, <&wo_ilm1>, <&wo_dlm1>,
<&wo_data>, <&wo_boot>;
memory-region-names = "wo-emi", "wo-ilm", "wo-dlm",
"wo-data", "wo-boot";
mediatek,wo-ccif = <&wo_ccif1>;
};
eth: ethernet@15100000 {
compatible = "mediatek,mt7986-eth";
reg = <0 0x15100000 0 0x80000>;
interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ethsys CLK_ETH_FE_EN>,
<&ethsys CLK_ETH_GP2_EN>,
<&ethsys CLK_ETH_GP1_EN>,
<&ethsys CLK_ETH_WOCPU1_EN>,
<&ethsys CLK_ETH_WOCPU0_EN>,
<&sgmiisys0 CLK_SGMII0_TX250M_EN>,
<&sgmiisys0 CLK_SGMII0_RX250M_EN>,
<&sgmiisys0 CLK_SGMII0_CDR_REF>,
<&sgmiisys0 CLK_SGMII0_CDR_FB>,
<&sgmiisys1 CLK_SGMII1_TX250M_EN>,
<&sgmiisys1 CLK_SGMII1_RX250M_EN>,
<&sgmiisys1 CLK_SGMII1_CDR_REF>,
<&sgmiisys1 CLK_SGMII1_CDR_FB>,
<&topckgen CLK_TOP_NETSYS_SEL>,
<&topckgen CLK_TOP_NETSYS_500M_SEL>;
clock-names = "fe", "gp2", "gp1", "wocpu1", "wocpu0",
"sgmii_tx250m", "sgmii_rx250m",
"sgmii_cdr_ref", "sgmii_cdr_fb",
"sgmii2_tx250m", "sgmii2_rx250m",
"sgmii2_cdr_ref", "sgmii2_cdr_fb",
"netsys0", "netsys1";
assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
<&topckgen CLK_TOP_SGM_325M_SEL>;
assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
<&apmixedsys CLK_APMIXED_SGMPLL>;
#address-cells = <1>;
#size-cells = <0>;
mediatek,ethsys = <&ethsys>;
mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
mediatek,wed-pcie = <&wed_pcie>;
mediatek,wed = <&wed0>, <&wed1>;
status = "disabled";
};
wo_ccif0: syscon@151a5000 {
compatible = "mediatek,mt7986-wo-ccif", "syscon";
reg = <0 0x151a5000 0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
};
wo_ccif1: syscon@151ad000 {
compatible = "mediatek,mt7986-wo-ccif", "syscon";
reg = <0 0x151ad000 0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
};
wifi: wifi@18000000 {
compatible = "mediatek,mt7986-wmac";
reg = <0 0x18000000 0 0x1000000>,
<0 0x10003000 0 0x1000>,
<0 0x11d10000 0 0x1000>;
resets = <&watchdog MT7986_TOPRGU_CONSYS_SW_RST>;
reset-names = "consys";
clocks = <&topckgen CLK_TOP_CONN_MCUSYS_SEL>,
<&topckgen CLK_TOP_AP2CNN_HOST_SEL>;
clock-names = "mcu", "ap2conn";
interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>;
memory-region = <&wmcpu_emi>;
};
};
thermal-zones {
cpu_thermal: cpu-thermal {
polling-delay-passive = <1000>;
polling-delay = <1000>;
thermal-sensors = <&thermal 0>;
trips {
cpu_trip_crit: crit {
temperature = <125000>;
hysteresis = <2000>;
type = "critical";
};
cpu_trip_hot: hot {
temperature = <120000>;
hysteresis = <2000>;
type = "hot";
};
cpu_trip_active_high: active-high {
temperature = <115000>;
hysteresis = <2000>;
type = "active";
};
cpu_trip_active_med: active-med {
temperature = <85000>;
hysteresis = <2000>;
type = "active";
};
cpu_trip_active_low: active-low {
temperature = <60000>;
hysteresis = <2000>;
type = "active";
};
};
};
};
timer {
compatible = "arm,armv8-timer";
interrupt-parent = <&gic>;
interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
};
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,103 @@
ARM="y";
SYS_HAS_NONCACHED_MEMORY="y";
POSITION_INDEPENDENT="y";
ARCH_MEDIATEK="y";
TEXT_BASE="0x41e00000";
SYS_MALLOC_F_LEN="0x4000";
NR_DRAM_BANKS="1";
ENV_SIZE="0x80000";
ENV_OFFSET="0x400000";
DEFAULT_DEVICE_TREE="mt7986a-glinet-gl-mt6000";
OF_LIBFDT_OVERLAY="y";
TARGET_MT7986="y";
SYS_LOAD_ADDR="0x46000000";
PRE_CON_BUF_ADDR="0x4007EF00";
DEBUG_UART_BASE="0x11002000";
DEBUG_UART_CLOCK="40000000";
DEBUG_UART="y";
AHCI="y";
FIT="y";
AUTOBOOT_KEYED="y";
AUTOBOOT_MENU_SHOW="y";
DEFAULT_FDT_FILE="mediatek/mt7986a-glinet-gl-mt6000.dtb";
LOGLEVEL="7";
PRE_CONSOLE_BUFFER="y";
LOG="y";
BOARD_LATE_INIT="y";
HUSH_PARSER="y";
SYS_PROMPT="MT7986> ";
CMD_CPU="y";
CMD_LICENSE="y";
CMD_BOOTMENU="y";
CMD_ASKENV="y";
CMD_ERASEENV="y";
CMD_ENV_FLAGS="y";
CMD_STRINGS="y";
CMD_DM="y";
CMD_GPIO="y";
CMD_PWM="y";
CMD_GPT="y";
CMD_MMC="y";
CMD_PART="y";
CMD_USB="y";
CMD_TFTPSRV="y";
CMD_RARP="y";
CMD_CDP="y";
CMD_SNTP="y";
CMD_LINK_LOCAL="y";
CMD_DHCP="y";
CMD_DNS="y";
CMD_PING="y";
CMD_CACHE="y";
CMD_PSTORE="y";
CMD_PSTORE_MEM_ADDR="0x42ff0000";
CMD_UUID="y";
CMD_HASH="y";
CMD_SMC="y";
OF_EMBED="y";
ENV_OVERWRITE="y";
ENV_IS_IN_MMC="y";
SYS_RELOC_GD_ENV_ADDR="y";
USE_DEFAULT_ENV_FILE="y";
DEFAULT_ENV_FILE="defenvs/glinet_gl-mt6000_env";
ENV_VARS_UBOOT_RUNTIME_CONFIG="y";
VERSION_VARIABLE="y";
NETCONSOLE="y";
USE_IPADDR="y";
IPADDR="192.168.1.1";
USE_SERVERIP="y";
SERVERIP="192.168.1.254";
NET_RANDOM_ETHADDR="y";
BUTTON="y";
BUTTON_GPIO="y";
CLK="y";
GPIO_HOG="y";
LED="y";
LED_BLINK="y";
LED_GPIO="y";
SUPPORT_EMMC_BOOT="y";
MMC_HS200_SUPPORT="y";
MMC_MTK="y";
PHY_FIXED="y";
MEDIATEK_ETH="y";
PHY="y";
PHY_MTK_TPHY="y";
PINCTRL="y";
PINCONF="y";
PINCTRL_MT7986="y";
POWER_DOMAIN="y";
MTK_POWER_DOMAIN="y";
DM_REGULATOR="y";
DM_REGULATOR_FIXED="y";
DM_REGULATOR_GPIO="y";
DM_PWM="y";
PWM_MTK="y";
RAM="y";
DM_SERIAL="y";
SERIAL_RX_BUFFER="y";
MTK_SERIAL="y";
USB="y";
USB_XHCI_HCD="y";
USB_XHCI_MTK="y";
USB_STORAGE="y";
HEXDUMP="y";

View File

@@ -0,0 +1,356 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/mt65xx.h>
#include "mt7986a.dtsi"
/ {
model = "GL.iNet GL-MT6000";
compatible = "glinet,gl-mt6000", "mediatek,mt7986a";
aliases {
serial0 = &uart0;
label-mac-device = &gmac1;
led-boot = &led_blue;
led-failsafe = &led_blue;
led-running = &led_white;
led-upgrade = &led_white;
};
chosen {
stdout-path = "serial0:115200n8";
bootargs-append = " root=PARTLABEL=rootfs rootwait";
};
reg_1p8v: regulator-1p8v {
compatible = "regulator-fixed";
regulator-name = "1.8vd";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-boot-on;
regulator-always-on;
};
reg_3p3v: regulator-3p3v {
compatible = "regulator-fixed";
regulator-name = "fixed-3.3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
regulator-always-on;
};
keys {
compatible = "gpio-keys";
reset {
label = "reset";
linux,code = <KEY_RESTART>;
gpios = <&pio 9 GPIO_ACTIVE_LOW>;
};
};
leds {
compatible = "gpio-leds";
led_blue: led-0 {
label = "blue:run";
gpios = <&pio 38 GPIO_ACTIVE_LOW>;
};
led_white: led-1 {
label = "white:system";
gpios = <&pio 37 GPIO_ACTIVE_LOW>;
};
};
usb_vbus: regulator-usb-vbus {
compatible = "regulator-fixed";
regulator-name = "usb_vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
gpios = <&pio 24 GPIO_ACTIVE_HIGH>;
enable-active-high;
regulator-boot-on;
};
};
&eth {
status = "okay";
gmac0: mac@0 {
compatible = "mediatek,eth-mac";
reg = <0>;
phy-mode = "2500base-x";
nvmem-cells = <&macaddr_factory_a 2>;
nvmem-cell-names = "mac-address";
fixed-link {
speed = <2500>;
full-duplex;
pause;
};
};
gmac1: mac@1 {
compatible = "mediatek,eth-mac";
reg = <1>;
nvmem-cells = <&macaddr_factory_a 0>;
nvmem-cell-names = "mac-address";
phy-mode = "2500base-x";
phy-handle = <&phy1>;
};
mdio: mdio-bus {
#address-cells = <1>;
#size-cells = <0>;
phy1: phy@1 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <1>;
reset-assert-us = <100000>;
reset-deassert-us = <100000>;
reset-gpios = <&pio 10 GPIO_ACTIVE_LOW>;
interrupt-parent = <&pio>;
interrupts = <46 IRQ_TYPE_LEVEL_LOW>;
realtek,aldps-enable;
};
phy7: ethernet-phy@7 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <7>;
reset-assert-us = <100000>;
reset-deassert-us = <100000>;
reset-gpios = <&pio 19 GPIO_ACTIVE_LOW>;
interrupt-parent = <&pio>;
interrupts = <47 IRQ_TYPE_LEVEL_LOW>;
realtek,aldps-enable;
};
switch: switch@1f {
compatible = "mediatek,mt7531";
reg = <31>;
reset-gpios = <&pio 18 GPIO_ACTIVE_HIGH>;
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&pio>;
interrupts = <66 IRQ_TYPE_LEVEL_HIGH>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
label = "lan2";
};
port@1 {
reg = <1>;
label = "lan3";
};
port@2 {
reg = <2>;
label = "lan4";
};
port@3 {
reg = <3>;
label = "lan5";
};
port@5 {
reg = <5>;
label = "lan1";
phy-handle = <&phy7>;
phy-mode = "2500base-x";
};
port@6 {
reg = <6>;
ethernet = <&gmac0>;
phy-mode = "2500base-x";
fixed-link {
speed = <2500>;
full-duplex;
pause;
};
};
};
};
};
};
&pio {
wf_2g_5g_pins: wf_2g_5g-pins {
mux {
function = "wifi";
groups = "wf_2g", "wf_5g";
};
conf {
pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4",
"WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6",
"WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10",
"WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1",
"WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0",
"WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8",
"WF1_TOP_CLK", "WF1_TOP_DATA";
drive-strength = <MTK_DRIVE_4mA>;
};
};
mmc0_pins_default: mmc0-pins {
mux {
function = "emmc";
groups = "emmc_51";
};
conf-cmd-dat {
pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
"EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
"EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
input-enable;
drive-strength = <MTK_DRIVE_4mA>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
};
conf-clk {
pins = "EMMC_CK";
drive-strength = <MTK_DRIVE_6mA>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
};
conf-ds {
pins = "EMMC_DSL";
bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
};
conf-rst {
pins = "EMMC_RSTB";
drive-strength = <MTK_DRIVE_4mA>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
};
};
mmc0_pins_uhs: mmc0-uhs-pins {
mux {
function = "emmc";
groups = "emmc_51";
};
conf-cmd-dat {
pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
"EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
"EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
input-enable;
drive-strength = <MTK_DRIVE_4mA>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
};
conf-clk {
pins = "EMMC_CK";
drive-strength = <MTK_DRIVE_6mA>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
};
conf-ds {
pins = "EMMC_DSL";
bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
};
conf-rst {
pins = "EMMC_RSTB";
drive-strength = <MTK_DRIVE_4mA>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
};
};
};
&crypto {
status = "okay";
};
&ssusb {
vusb33-supply = <&reg_3p3v>;
vbus-supply = <&usb_vbus>;
status = "okay";
};
&trng {
status = "okay";
};
&uart0 {
status = "okay";
};
&usb_phy {
status = "okay";
};
&watchdog {
status = "okay";
};
&wifi {
nvmem-cells = <&eeprom_factory_0>;
nvmem-cell-names = "eeprom";
pinctrl-names = "default";
pinctrl-0 = <&wf_2g_5g_pins>;
status = "okay";
};
&mmc0 {
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default", "state_uhs";
pinctrl-0 = <&mmc0_pins_default>;
pinctrl-1 = <&mmc0_pins_uhs>;
bus-width = <8>;
max-frequency = <200000000>;
cap-mmc-highspeed;
mmc-hs200-1_8v;
mmc-hs400-1_8v;
hs400-ds-delay = <0x14014>;
vmmc-supply = <&reg_3p3v>;
vqmmc-supply = <&reg_1p8v>;
non-removable;
no-sd;
no-sdio;
status = "okay";
card@0 {
compatible = "mmc-card";
reg = <0>;
block {
compatible = "block-device";
partitions {
block-partition-env {
partname = "u-boot-env";
nvmem-layout {
compatible = "u-boot,env";
};
};
block-partition-factory {
partname = "factory";
nvmem-layout {
compatible = "fixed-layout";
#address-cells = <1>;
#size-cells = <1>;
eeprom_factory_0: eeprom@0 {
reg = <0x0 0x1000>;
};
macaddr_factory_a: macaddr@a {
compatible = "mac-base";
reg = <0xa 0x6>;
#nvmem-cell-cells = <1>;
};
};
};
};
};
};
};

View File

@@ -8,7 +8,10 @@
{ {
devshells.default = { devshells.default = {
devshell = { devshell = {
packages = [ inputs.clan-core.packages.${system}.clan-cli ]; packages = [
inputs.clan-core.packages.${system}.clan-cli
inputs.clan-core.packages.${system}.generate-test-vars
];
}; };
}; };
}; };

View File

@@ -0,0 +1 @@
../../../machines/b4l

View File

@@ -0,0 +1 @@
../../../machines/rigel

View File

@@ -0,0 +1 @@
../../../users/berwn

View File

@@ -0,0 +1 @@
../../../users/davhau

View File

@@ -0,0 +1 @@
../../../users/kurogeek

View File

@@ -0,0 +1 @@
../../../users/matthewcroughan

1
sops/groups/admins/users/vi Symbolic link
View File

@@ -0,0 +1 @@
../../../users/vi

6
sops/machines/b4l/key.json Executable file
View File

@@ -0,0 +1,6 @@
[
{
"publickey": "age1sg0rvgyetdcqw7j2x983fh69kdkvqsngpe5x36e5920qa7fze3cqhj4wgx",
"type": "age"
}
]

6
sops/machines/rigel/key.json Executable file
View File

@@ -0,0 +1,6 @@
[
{
"publickey": "age17d4qt0n9edq57tgcqyk8eu5mrendl59yt6z2y3a4vkq7el8krqtq6lq28g",
"type": "age"
}
]

6
sops/machines/vega/key.json Executable file
View File

@@ -0,0 +1,6 @@
[
{
"publickey": "age1pl3nej4ayvuk75cydwyz5ttzelqqdkun8hweu40vypvspzh9j4vqp9rl0j",
"type": "age"
}
]

View File

@@ -0,0 +1,23 @@
{
"data": "ENC[AES256_GCM,data:wcR+EaC64JexQCShFc1I6mncHGQ+bMfjAOMnoTq3/bOa0T+NCqcDmrxoHGdR2q/TV453uMiokeAm+uggpZNQ9/1Kf5mX2KQsJtE=,iv:FcyIA1uAOISu/+mfTtdQ8lgyieoCObbZ6BMvkmIVoto=,tag:ew7jg+oXP0JUBBfDJoir7A==,type:str]",
"sops": {
"age": [
{
"recipient": "age134vt63pjqpd0m7702fyn8vhdlzyj2deqc2q78sp9uw9052kxsgwq6d25ez",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsdnlFYjVtdGhHSmczV0Nk\nN0IwL0dLVTdkTWhIK2tmV1E5bE1wZjcyZkVnCkV4VEhlL2lyVkxXMzFQVTZ5dHBY\nSUJWRUh2MjgwZ2RmaVRFVHdmQm00ck0KLS0tIG1oTlE1alJDK0FuNGhDQmcrKzZk\nWDhZNEJIWmd1QkVJc0pLemVOSjhqQ2cKMDYUbT8wQ89mNBJFYp2igHB2aQtxBFtM\nilUU83E0stiVKWHrCnBlmQng4UDr0rPxOWa+JpbR4bSbLPXyKIPtrw==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1swlyyk2rzvevqawyeekv75nx2dz34zpe3xqhkqme26gcgeavy4dqrfpcd8",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxZmVHaWRsa3Y0TGNIM0dx\ncThRc09ZdU5YVkpWdTdzTlRXa3pjMTRVd3lNCk4waktab2lzNDJhZ0hiOTh5MFVu\nTzR4clA5Mko4Y0o3cFMra0IyTUUydU0KLS0tIC9RWXUvMEduUkp1VXpSdjNUUkQ1\nN1NuTFY4ei9TdkVjK1lUQldOVG9sc1EKFwRbPZyd7TARXkvHD74DGqwvxOjIty+X\nBHFw8H5CWp2FCCQ+9bebMamG3ShzhM21Hju9uVbMXA/WACU/9dAJhg==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1hlzrpqqgndcthq5m5yj9egfgyet2fzrxwa6ynjzwx2r22uy6m3hqr3rd06",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOekRKMG5VdWpmcm96WEdK\nTnoyL3piaCtxVnN5b1E2RXh1SzZ1cGU3OFdrCjNNMGUxMDF6NzFUNFpPb0VNa2Q1\nL1VacitPRzU3MHh3dXpTNWxYeGFxeFkKLS0tIHV3TUkxTG5mQ3haZVRSTTB2bFBk\nU0dDaGQ0ZjhEOGdqZTFEQXlPczZWdm8KiDHBQQRL4qTnStFr8nmdhet+7gBELCvd\noRvky46oEsS36L9o477ZH134wrSqAcD0NCOO06hA/jEXNvLFig9yHw==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-07-14T03:23:25Z",
"mac": "ENC[AES256_GCM,data:luP+HWuNzrYwDn+vT73A9+Lt2SzhAwWO47bhoCNmmkYoV3AqX6Okv1I+vkbZWZQS2XOMeZTzSBYQcVhjwXYphZobXcGgAlqcpdx6I4YcDFqmBNOvOy40NvrpVrVLUK6Mvk3gO0pFGWpoRqs/KVHnGacy0pIksVEf5cJr/qx/sHE=,iv:a6B2/ftUFAy9xlmrwiJZMksxXbvuLOB4lVQiLUNYbNw=,tag:3Ik6zRB3k6eM5S1geYlDVQ==,type:str]",
"unencrypted_suffix": "_unencrypted",
"version": "3.10.2"
}
}

View File

@@ -0,0 +1 @@
../../../users/berwn

View File

@@ -0,0 +1 @@
../../../users/kurogeek

View File

@@ -0,0 +1 @@
../../../users/vi

View File

@@ -0,0 +1,19 @@
{
"data": "ENC[AES256_GCM,data:WJO4V1cuzrxw1tg034RNG4f7X2N6pLFE1VIsjkWfUoKSScBbi8e4m62M5WpM6P7f/2/FHxQWRhWcwa3clHXoCCQmNa7j8UIkkik=,iv:qcqQBaJQkpMJimh7xU0u6p9v9uqf1KyvMlePP2k6e78=,tag:5XuWJcODVTRYM6twHEwOxQ==,type:str]",
"sops": {
"age": [
{
"recipient": "age1hlzrpqqgndcthq5m5yj9egfgyet2fzrxwa6ynjzwx2r22uy6m3hqr3rd06",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWWk9KTEJHR0d1WTRDWGFS\naW16L3E1WEFBNFpwSVZ3T0xUMEZBcXBrSGs0Cllua20yVHV2djEzOE55Qk5zKzlp\nQmo3UVMreVFKVTJTVGl4ajdVZ0FZNk0KLS0tIGF0VWVJNGU0M05ZajF1Q1NscHpC\naG1vblk4NmY2KzIzN1V6bWVrYW01OUUKAfMKTPzIhVd0W8yfob9No53RnaNC67Fy\nMohQHZ38caz8LhqFfDzm1vm8xi1F8kcaW6ugcPH532fdDxkS6dfnoQ==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1swlyyk2rzvevqawyeekv75nx2dz34zpe3xqhkqme26gcgeavy4dqrfpcd8",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6YnFMZ3F5cjJDa1poTGpD\nRURZYVZNLzByMzgwZytWZDhBaVFIbndmbldzCjlvYnRVTnNwRWVKRG40MWJrQXJz\naENEWWh3TFE4Uit2ODhncWJHZ1hvdk0KLS0tIFlIUmlqVWRlQzRxcFZHMFlzVmJh\nYkdBSzJlT0pnYlRacmhINFRyZzVIdVEKJJL7XFqZafNQmfzwwjVDMw/cPob830oI\nsVQe1HaUK7IujWTCbD8l0uoqsODdaWOMDVwxuiKr+yHY4iwar+rI6w==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-07-25T02:12:20Z",
"mac": "ENC[AES256_GCM,data:36VgVubO5xybFuFu7lX73XBlODhUTg2sLfi1e8fqHkPPwtYylgORuXyypsZOTF0LSJS1VbU0NZjU9fvQpjMY2Sl7BxdqQKfz0OG8iuYloHmQM26QQ9TPDYIHvIJrCYIdKJSl83IqLZq+IWbInTha3xrTeH7MlgWII3mJSCPQiPM=,iv:7eR2YYBbApScElcNxg77F7rb6OLuc+2x1IVN56aJADM=,tag:LLfCm1jGkvs56SfkjqRZXQ==,type:str]",
"unencrypted_suffix": "_unencrypted",
"version": "3.10.2"
}
}

View File

@@ -0,0 +1 @@
../../../users/berwn

View File

@@ -0,0 +1 @@
../../../users/kurogeek

View File

@@ -0,0 +1,15 @@
{
"data": "ENC[AES256_GCM,data:3WgicB2mjBGo3YWFG9mVBYnapj1ZoH6ohwxIUcA9byWVTCS0ZKyIJZlPeyvKWEzX9ZnxgLd1DPDfFfppwsnkxYOvEJsBAf0AanI=,iv:OKSKHu3h8Kl/qAlQ1xiYElDjaql0FdIWVPJYicfvH8Y=,tag:Xa9RfEBC8l8VgHbJHTr4jQ==,type:str]",
"sops": {
"age": [
{
"recipient": "age1hlzrpqqgndcthq5m5yj9egfgyet2fzrxwa6ynjzwx2r22uy6m3hqr3rd06",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCK0NJR2VzVU1xVGZBd3Fh\nU0xEdmFhTllBU1dpMDM4V3NjTjB6dWxoRGdNCmdMS0duUUV1bVdtVmF1Nml5YTRV\naHpLMExzTGxKclJDZkl2UWdFUHRxY2cKLS0tIER1ajBQdEFuTDQvSERQTDZialBp\nN2RJdS9tVk8wb1lMclNrQzBCTWx3UUUKVKrK0KHOAcd0oMlzeCbN9xX35QKG+za2\nMqEmG/duejDVVzxjIcMBhsXD3EytUMw6IJ/dQtGYS3lJUXH0tiq1Iw==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-09-11T04:36:12Z",
"mac": "ENC[AES256_GCM,data:Nvb0JIeARvwzDQSiUkqNMsTFQpGLDTtM0v8ZDyYzQY9yloS1AsGtehbWPgq9Rzr6L5I71bubw8LWpa6UnlqQSrC8GLOy+ojvu/KknkNaVrWQFCw0BDJk4ypBUaQk8n3dGjkG8UUvKCy7dkwwkP3nNbsQ8HA9R5zSYHNakZmWpes=,iv:iozu9qC8nY2XCPG5aBPihCjoNIxXV3kKLcoesFYPSj4=,tag:NkqiJVwj35VY5teW7eTtsQ==,type:str]",
"unencrypted_suffix": "_unencrypted",
"version": "3.10.2"
}
}

View File

@@ -0,0 +1 @@
../../../users/kurogeek

6
sops/users/berwn/key.json Executable file
View File

@@ -0,0 +1,6 @@
[
{
"publickey": "age1swlyyk2rzvevqawyeekv75nx2dz34zpe3xqhkqme26gcgeavy4dqrfpcd8",
"type": "age"
}
]

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