forked from
tangled.org/core
Monorepo for Tangled
1{
2 config,
3 pkgs,
4 lib,
5 ...
6}: let
7 cfg = config.services.tangled.knotmirror;
8in
9 with lib; {
10 options.services.tangled.knotmirror = {
11 enable = mkOption {
12 type = types.bool;
13 default = false;
14 description = "Enable a tangled knot";
15 };
16
17 package = mkOption {
18 type = types.package;
19 description = "Package to use for the knotmirror";
20 };
21
22 tap-package = mkOption {
23 type = types.package;
24 description = "tap package to use for the knotmirror";
25 };
26
27 listenAddr = mkOption {
28 type = types.str;
29 default = "0.0.0.0:7000";
30 description = "Address to listen on";
31 };
32
33 adminListenAddr = mkOption {
34 type = types.str;
35 default = "127.0.0.1:7200";
36 description = "Address to listen on";
37 };
38
39 hostname = mkOption {
40 type = types.str;
41 example = "my.knotmirror.com";
42 description = "Hostname for the server (required)";
43 };
44
45 dbUrl = mkOption {
46 type = types.str;
47 example = "postgresql://...";
48 description = "Database URL. postgresql expected (required)";
49 };
50
51 atpPlcUrl = mkOption {
52 type = types.str;
53 default = "https://plc.directory";
54 description = "atproto PLC directory";
55 };
56
57 atpRelayUrl = mkOption {
58 type = types.str;
59 default = "https://relay1.us-east.bsky.network";
60 description = "atproto relay";
61 };
62
63 fullNetwork = mkOption {
64 type = types.bool;
65 default = false;
66 description = "Whether to automatically mirror from entire network";
67 };
68
69 knotUseSSL = mkOption {
70 type = types.bool;
71 default = true;
72 description = "Use SSL for knot connection";
73 };
74
75 knotSSRF = mkOption {
76 type = types.bool;
77 default = true;
78 description = "enable SSRF protection for knots";
79 };
80
81 tap = {
82 port = mkOption {
83 type = types.port;
84 default = 7480;
85 description = "Internal port to run the knotmirror tap";
86 };
87
88 dbUrl = mkOption {
89 type = types.str;
90 default = "sqlite:///var/lib/knotmirror-tap/tap.db";
91 description = "database connection string (sqlite://path or postgres://...)";
92 };
93 };
94 };
95 config = mkIf cfg.enable {
96 environment.systemPackages = [
97 pkgs.git
98 cfg.package
99 ];
100
101 systemd.services.tap-knotmirror = {
102 description = "knotmirror tap service";
103 after = ["network.target"];
104 wantedBy = ["multi-user.target"];
105 serviceConfig = {
106 LogsDirectory = "knotmirror-tap";
107 StateDirectory = "knotmirror-tap";
108 Environment = [
109 "TAP_BIND=:${toString cfg.tap.port}"
110 "TAP_PLC_URL=${cfg.atpPlcUrl}"
111 "TAP_RELAY_URL=${cfg.atpRelayUrl}"
112 "TAP_RESYNC_PARALLELISM=10"
113 "TAP_DATABASE_URL=${cfg.tap.dbUrl}"
114 "TAP_RETRY_TIMEOUT=60s"
115 "TAP_COLLECTION_FILTERS=sh.tangled.repo"
116 (
117 if cfg.fullNetwork
118 then "TAP_SIGNAL_COLLECTION=sh.tangled.repo"
119 else "TAP_FULL_NETWORK=false"
120 )
121 ];
122 ExecStart = "${getExe cfg.tap-package} run";
123 };
124 };
125
126 systemd.services.knotmirror = {
127 description = "knotmirror service";
128 after = ["network.target" "tap-knotmirror.service"];
129 wantedBy = ["multi-user.target"];
130 path = [
131 pkgs.git
132 ];
133 serviceConfig = {
134 LogsDirectory = "knotmirror";
135 StateDirectory = "knotmirror";
136 Environment = [
137 # TODO: add environment variables
138 "MIRROR_LISTEN=${cfg.listenAddr}"
139 "MIRROR_HOSTNAME=${cfg.hostname}"
140 "MIRROR_TAP_URL=http://localhost:${toString cfg.tap.port}"
141 "MIRROR_DB_URL=${cfg.dbUrl}"
142 "MIRROR_GIT_BASEPATH=/var/lib/knotmirror/repos"
143 "MIRROR_KNOT_USE_SSL=${boolToString cfg.knotUseSSL}"
144 "MIRROR_KNOT_SSRF=${boolToString cfg.knotSSRF}"
145 "MIRROR_RESYNC_PARALLELISM=12"
146 "MIRROR_METRICS_LISTEN=127.0.0.1:7100"
147 "MIRROR_ADMIN_LISTEN=${cfg.adminListenAddr}"
148 "MIRROR_SLURPER_CONCURRENCY=4"
149 ];
150 ExecStart = "${getExe cfg.package} serve";
151 Restart = "always";
152 };
153 };
154 };
155 }