This repository has no description
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 metricsListenAddr = mkOption {
40 type = types.str;
41 default = "0.0.0.0:7100";
42 description = "Listen address for the Prometheus metrics endpoint";
43 };
44
45 hostname = mkOption {
46 type = types.str;
47 example = "my.knotmirror.com";
48 description = "Hostname for the server (required)";
49 };
50
51 dbUrl = mkOption {
52 type = types.str;
53 example = "postgresql://...";
54 description = "Database URL. postgresql expected (required)";
55 };
56
57 atpPlcUrl = mkOption {
58 type = types.str;
59 default = "https://plc.directory";
60 description = "atproto PLC directory";
61 };
62
63 atpRelayUrl = mkOption {
64 type = types.str;
65 default = "https://relay1.us-east.bsky.network";
66 description = "atproto relay";
67 };
68
69 fullNetwork = mkOption {
70 type = types.bool;
71 default = false;
72 description = "Whether to automatically mirror from entire network";
73 };
74
75 knotUseSSL = mkOption {
76 type = types.bool;
77 default = true;
78 description = "Use SSL for knot connection";
79 };
80
81 knotSSRF = mkOption {
82 type = types.bool;
83 default = true;
84 description = "enable SSRF protection for knots";
85 };
86
87 zoektUrl = mkOption {
88 type = types.str;
89 example = "https://zoekt.tngl.boltless.dev/indexserver";
90 description = "zoekt-tnglserver url";
91 };
92
93 tap = {
94 port = mkOption {
95 type = types.port;
96 default = 7480;
97 description = "Internal port to run the knotmirror tap";
98 };
99
100 dbUrl = mkOption {
101 type = types.str;
102 default = "sqlite:///var/lib/knotmirror-tap/tap.db";
103 description = "database connection string (sqlite://path or postgres://...)";
104 };
105 };
106 };
107 config = mkIf cfg.enable {
108 environment.systemPackages = [
109 pkgs.git
110 cfg.package
111 ];
112
113 services.redis.servers.knotmirror = {
114 enable = true;
115 port = 6377;
116 };
117
118 systemd.services.tap-knotmirror = {
119 description = "knotmirror tap service";
120 after = ["network.target"];
121 wantedBy = ["multi-user.target"];
122 serviceConfig = {
123 LogsDirectory = "knotmirror-tap";
124 StateDirectory = "knotmirror-tap";
125 Environment = [
126 "TAP_BIND=:${toString cfg.tap.port}"
127 "TAP_PLC_URL=${cfg.atpPlcUrl}"
128 "TAP_RELAY_URL=${cfg.atpRelayUrl}"
129 "TAP_RESYNC_PARALLELISM=10"
130 "TAP_DATABASE_URL=${cfg.tap.dbUrl}"
131 "TAP_RETRY_TIMEOUT=60s"
132 "TAP_COLLECTION_FILTERS=sh.tangled.repo"
133 (
134 if cfg.fullNetwork
135 then "TAP_SIGNAL_COLLECTION=sh.tangled.repo"
136 else "TAP_FULL_NETWORK=false"
137 )
138 ];
139 ExecStart = "${getExe cfg.tap-package} run";
140 };
141 };
142
143 systemd.services.knotmirror = {
144 description = "knotmirror service";
145 after = ["network.target" "tap-knotmirror.service"];
146 wantedBy = ["multi-user.target"];
147 path = [
148 pkgs.git
149 ];
150 serviceConfig = {
151 LogsDirectory = "knotmirror";
152 StateDirectory = "knotmirror";
153 Environment = [
154 # TODO: add environment variables
155 "MIRROR_LISTEN=${cfg.listenAddr}"
156 "MIRROR_HOSTNAME=${cfg.hostname}"
157 "MIRROR_TAP_URL=http://localhost:${toString cfg.tap.port}"
158 "MIRROR_DB_URL=${cfg.dbUrl}"
159 "MIRROR_REDIS_ADDR=localhost:6377"
160 "MIRROR_GIT_BASEPATH=/var/lib/knotmirror/repos"
161 "MIRROR_KNOT_USE_SSL=${boolToString cfg.knotUseSSL}"
162 "MIRROR_KNOT_SSRF=${boolToString cfg.knotSSRF}"
163 "MIRROR_RESYNC_PARALLELISM=12"
164 "MIRROR_METRICS_LISTEN=${cfg.metricsListenAddr}"
165 "MIRROR_ADMIN_LISTEN=${cfg.adminListenAddr}"
166 "MIRROR_SLURPER_CONCURRENCY=4"
167 "MIRROR_SEARCH_ZOEKT_URL=${cfg.zoektUrl}"
168 ];
169 ExecStart = "${getExe cfg.package} serve";
170 Restart = "always";
171 };
172 };
173 };
174 }