@le-space/rootfs 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env python3
2
+ import os
3
+ import re
4
+ import subprocess
5
+ import time
6
+ from typing import Iterable
7
+
8
+
9
+ ENV_FILE = os.environ.get("ENV_FILE", "/etc/default/uc-go-peer")
10
+ READY_FILE = os.environ.get("READY_FILE", "/etc/default/uc-go-peer.ready")
11
+ AUTOTLS_READY_FILE = os.environ.get("AUTOTLS_READY_FILE", "/etc/default/uc-go-peer.autotls-ready")
12
+ AUTOTLS_ZONE_FILE = os.environ.get("AUTOTLS_ZONE_FILE", "/etc/default/uc-go-peer.autotls-zone")
13
+ AUTOTLS_HOSTS_FILE = os.environ.get("AUTOTLS_HOSTS_FILE", "/etc/default/uc-go-peer.autotls-hosts")
14
+ SERVICE_NAME = os.environ.get("SERVICE_NAME", "uc-go-peer.service")
15
+ WAIT_TIMEOUT_SECONDS = int(os.environ.get("AUTOTLS_WAIT_TIMEOUT_SECONDS", "900"))
16
+ WAIT_INTERVAL_SECONDS = float(os.environ.get("AUTOTLS_WAIT_INTERVAL_SECONDS", "5"))
17
+ WS_BACKEND_PORT = os.environ.get("WS_BACKEND_PORT", "9097").strip()
18
+
19
+
20
+ def parse_env_file(path: str) -> dict[str, str]:
21
+ values: dict[str, str] = {}
22
+ if not os.path.exists(path):
23
+ return values
24
+
25
+ with open(path, encoding="utf-8") as handle:
26
+ for line in handle:
27
+ stripped = line.strip()
28
+ if not stripped or stripped.startswith("#") or "=" not in stripped:
29
+ continue
30
+ key, value = stripped.split("=", 1)
31
+ values[key.strip()] = value.strip()
32
+ return values
33
+
34
+
35
+ def write_env_var(path: str, key: str, value: str) -> None:
36
+ lines: list[str] = []
37
+ replaced = False
38
+
39
+ if os.path.exists(path):
40
+ with open(path, encoding="utf-8") as handle:
41
+ lines = handle.readlines()
42
+
43
+ with open(path, "w", encoding="utf-8") as handle:
44
+ for line in lines:
45
+ stripped = line.lstrip()
46
+ if stripped.startswith(f"{key}=") or stripped.startswith(f"#{key}="):
47
+ handle.write(f"{key}={value}\n")
48
+ replaced = True
49
+ else:
50
+ handle.write(line)
51
+
52
+ if not replaced:
53
+ handle.write(f"{key}={value}\n")
54
+
55
+
56
+ def dedupe(sequence: Iterable[str]) -> list[str]:
57
+ seen: set[str] = set()
58
+ values: list[str] = []
59
+ for item in sequence:
60
+ if item and item not in seen:
61
+ seen.add(item)
62
+ values.append(item)
63
+ return values
64
+
65
+
66
+ def wait_for_exact_hosts(ws_port: str) -> tuple[str, list[str], list[str]]:
67
+ deadline = time.monotonic() + WAIT_TIMEOUT_SECONDS
68
+ regex = re.compile(rf"(/(?:ip4|ip6)/[^ ]+/tcp/{re.escape(ws_port)}/tls/sni/([^/]+)/ws)")
69
+ zone_regex = re.compile(r'identifier": "\\*\.([^"]+)"')
70
+ last_error = "AutoTLS websocket hostnames not advertised yet"
71
+
72
+ while time.monotonic() < deadline:
73
+ result = subprocess.run(
74
+ ["journalctl", "-u", SERVICE_NAME, "-n", "400", "--no-pager"],
75
+ capture_output=True,
76
+ text=True,
77
+ check=False,
78
+ )
79
+ output = result.stdout
80
+ pairs = regex.findall(output)
81
+ addrs = dedupe([pair[0] for pair in pairs])
82
+ hosts = dedupe([pair[1] for pair in pairs])
83
+ zone_match = zone_regex.search(output)
84
+ zone = zone_match.group(1) if zone_match else ""
85
+ if zone and hosts:
86
+ return zone, hosts, addrs
87
+ if hosts:
88
+ return "", hosts, addrs
89
+ if result.stderr.strip():
90
+ last_error = result.stderr.strip()
91
+ time.sleep(WAIT_INTERVAL_SECONDS)
92
+
93
+ raise RuntimeError(last_error)
94
+
95
+
96
+ def main() -> None:
97
+ if not os.path.exists(READY_FILE):
98
+ raise SystemExit(f"missing ready file: {READY_FILE}")
99
+
100
+ env_values = parse_env_file(ENV_FILE)
101
+ ws_port = env_values.get("GO_PEER_WSS_PORT", "").strip() or WS_BACKEND_PORT
102
+ if not ws_port:
103
+ raise RuntimeError("missing GO_PEER_WSS_PORT in environment file")
104
+
105
+ proxy_hostname = env_values.get("PROXY_HOSTNAME", "").strip()
106
+
107
+ zone, exact_hosts, exact_logged_addrs = wait_for_exact_hosts(ws_port)
108
+ if not exact_hosts:
109
+ raise RuntimeError("no AutoTLS websocket hostnames found in logs")
110
+
111
+ existing = [entry.strip() for entry in env_values.get("LIBP2P_ANNOUNCE_ADDRS", "").split(",") if entry.strip()]
112
+ wildcard_filtered = [entry for entry in existing if "/tls/sni/*." not in entry]
113
+ exact_announces: list[str] = list(exact_logged_addrs)
114
+
115
+ if proxy_hostname:
116
+ exact_announces.append(f"/dns4/{proxy_hostname}/tcp/443/tls/ws")
117
+ exact_announces.append(f"/dns6/{proxy_hostname}/tcp/443/tls/ws")
118
+
119
+ merged = dedupe(wildcard_filtered + exact_announces)
120
+ announce_value = ",".join(merged)
121
+ write_env_var(ENV_FILE, "LIBP2P_ANNOUNCE_ADDRS", announce_value)
122
+ if zone:
123
+ write_env_var(ENV_FILE, "AUTOTLS_SERVING_ZONE", zone)
124
+
125
+ with open(AUTOTLS_HOSTS_FILE, "w", encoding="utf-8") as handle:
126
+ for host in exact_hosts:
127
+ handle.write(f"{host}\n")
128
+ if zone:
129
+ with open(AUTOTLS_ZONE_FILE, "w", encoding="utf-8") as handle:
130
+ handle.write(f"{zone}\n")
131
+
132
+ service_restarted = False
133
+ if env_values.get("LIBP2P_ANNOUNCE_ADDRS", "") != announce_value:
134
+ subprocess.run(["systemctl", "restart", SERVICE_NAME], check=True)
135
+ service_restarted = True
136
+
137
+ open(AUTOTLS_READY_FILE, "a", encoding="utf-8").close()
138
+ print(f"Updated LIBP2P_ANNOUNCE_ADDRS={announce_value}")
139
+ if service_restarted:
140
+ print(f"Restarted {SERVICE_NAME} after AutoTLS hostname refresh")
141
+
142
+
143
+ if __name__ == "__main__":
144
+ main()
@@ -0,0 +1,23 @@
1
+ [Unit]
2
+ Description=Persist AutoTLS secure announce addresses for uc-go-peer
3
+ After=uc-go-peer.service
4
+ Wants=uc-go-peer.service
5
+ ConditionPathExists=/etc/default/uc-go-peer.ready
6
+ ConditionPathExists=!/etc/default/uc-go-peer.autotls-ready
7
+
8
+ [Service]
9
+ Type=oneshot
10
+ Environment=ENV_FILE=/etc/default/uc-go-peer
11
+ Environment=READY_FILE=/etc/default/uc-go-peer.ready
12
+ Environment=AUTOTLS_READY_FILE=/etc/default/uc-go-peer.autotls-ready
13
+ Environment=AUTOTLS_ZONE_FILE=/etc/default/uc-go-peer.autotls-zone
14
+ Environment=AUTOTLS_HOSTS_FILE=/etc/default/uc-go-peer.autotls-hosts
15
+ Environment=AUTOTLS_CADDY_READY_FILE=/etc/default/uc-go-peer.caddy-ready
16
+ Environment=SERVICE_NAME=uc-go-peer.service
17
+ Environment=WS_BACKEND_PORT=9097
18
+ ExecStart=/usr/bin/python3 /usr/local/sbin/uc-go-peer-autotls-refresh.py
19
+ StandardOutput=journal
20
+ StandardError=journal
21
+
22
+ [Install]
23
+ WantedBy=multi-user.target
@@ -0,0 +1,17 @@
1
+ [Unit]
2
+ Description=Temporary universal-connectivity go-peer setup endpoint
3
+ Wants=network-online.target
4
+ After=network-online.target
5
+ ConditionPathExists=!/etc/default/uc-go-peer.ready
6
+
7
+ [Service]
8
+ Environment=ENV_FILE=/etc/default/uc-go-peer
9
+ Environment=READY_FILE=/etc/default/uc-go-peer.ready
10
+ ExecStart=/usr/bin/python3 /usr/local/sbin/uc-go-peer-setup-server.py
11
+ StandardOutput=journal
12
+ StandardError=journal
13
+ Restart=on-failure
14
+ RestartSec=2s
15
+
16
+ [Install]
17
+ WantedBy=multi-user.target
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ set -x
4
+
5
+ INSTALL_DIR="${INSTALL_DIR:-/opt/go-peer}"
6
+ SERVICE_USER="${SERVICE_USER:-uc-go-peer}"
7
+ DATA_DIR="${DATA_DIR:-/var/lib/uc-go-peer}"
8
+ ENV_FILE="${ENV_FILE:-/etc/default/uc-go-peer}"
9
+ READY_FILE="${READY_FILE:-/etc/default/uc-go-peer.ready}"
10
+ AUTOTLS_READY_FILE="${AUTOTLS_READY_FILE:-/etc/default/uc-go-peer.autotls-ready}"
11
+ AUTOTLS_ZONE_FILE="${AUTOTLS_ZONE_FILE:-/etc/default/uc-go-peer.autotls-zone}"
12
+ AUTOTLS_HOSTS_FILE="${AUTOTLS_HOSTS_FILE:-/etc/default/uc-go-peer.autotls-hosts}"
13
+ AUTOTLS_CADDY_READY_FILE="${AUTOTLS_CADDY_READY_FILE:-/etc/default/uc-go-peer.caddy-ready}"
14
+ APP_BINARY="${APP_BINARY:-/usr/local/bin/universal-chat-go}"
15
+ PHASE="${1:-all}"
16
+
17
+ if [ ! -d "${INSTALL_DIR}" ]; then
18
+ echo "Missing ${INSTALL_DIR}; the rootfs build did not create the relay support directory."
19
+ exit 1
20
+ fi
21
+
22
+ echo "[uc-go-peer-bootstrap] starting"
23
+ echo "[uc-go-peer-bootstrap] support dir: ${INSTALL_DIR}"
24
+ echo "[uc-go-peer-bootstrap] data dir: ${DATA_DIR}"
25
+ echo "[uc-go-peer-bootstrap] env file: ${ENV_FILE}"
26
+ echo "[uc-go-peer-bootstrap] app binary: ${APP_BINARY}"
27
+
28
+ run_phase_base() {
29
+ export DEBIAN_FRONTEND=noninteractive
30
+ echo "[uc-go-peer-bootstrap] phase=base"
31
+ echo "[uc-go-peer-bootstrap] running apt-get update"
32
+ apt-get update
33
+ echo "[uc-go-peer-bootstrap] installing base packages"
34
+ apt-get install -y ca-certificates curl caddy
35
+ rm -rf /var/lib/apt/lists/*
36
+ }
37
+
38
+ run_phase_build() {
39
+ echo "[uc-go-peer-bootstrap] phase=build"
40
+ if [ ! -x "${APP_BINARY}" ]; then
41
+ echo "[uc-go-peer-bootstrap] missing application binary: ${APP_BINARY}"
42
+ exit 1
43
+ fi
44
+ echo "[uc-go-peer-bootstrap] application binary already provisioned"
45
+ }
46
+
47
+ run_phase_finalize() {
48
+ echo "[uc-go-peer-bootstrap] phase=finalize"
49
+ echo "[uc-go-peer-bootstrap] creating runtime directories"
50
+ mkdir -p "${DATA_DIR}" "$(dirname "${ENV_FILE}")"
51
+
52
+ if ! id "${SERVICE_USER}" >/dev/null 2>&1; then
53
+ echo "[uc-go-peer-bootstrap] creating service user ${SERVICE_USER}"
54
+ useradd --system --home "${DATA_DIR}" --create-home --shell /usr/sbin/nologin "${SERVICE_USER}"
55
+ fi
56
+
57
+ echo "[uc-go-peer-bootstrap] fixing ownership"
58
+ chown -R "${SERVICE_USER}:${SERVICE_USER}" "${DATA_DIR}" "${INSTALL_DIR}"
59
+
60
+ echo "[uc-go-peer-bootstrap] preparing environment file"
61
+ touch "${ENV_FILE}"
62
+ chmod 0640 "${ENV_FILE}"
63
+ chown "root:${SERVICE_USER}" "${ENV_FILE}"
64
+ rm -f "${READY_FILE}" "${AUTOTLS_READY_FILE}" "${AUTOTLS_ZONE_FILE}" "${AUTOTLS_HOSTS_FILE}" "${AUTOTLS_CADDY_READY_FILE}"
65
+
66
+ mkdir -p /etc/caddy /etc/systemd/system/caddy.service.d
67
+ cat > /etc/systemd/system/caddy.service.d/uc-go-peer.conf <<EOF
68
+ [Unit]
69
+ ConditionPathExists=${AUTOTLS_CADDY_READY_FILE}
70
+ EOF
71
+ }
72
+
73
+ write_env_var() {
74
+ local key="$1"
75
+ local value="$2"
76
+
77
+ if grep -Eq "^[#[:space:]]*${key}=" "${ENV_FILE}"; then
78
+ sed -i "s|^[#[:space:]]*${key}=.*|${key}=${value}|" "${ENV_FILE}"
79
+ else
80
+ printf '%s=%s\n' "${key}" "${value}" >> "${ENV_FILE}"
81
+ fi
82
+ }
83
+
84
+ seed_env() {
85
+ write_env_var "GO_PEER_DATA_DIR" "${DATA_DIR}"
86
+ write_env_var "GO_PEER_TCP_PORT" "9095"
87
+ write_env_var "GO_PEER_WS_PORT" "9096"
88
+ write_env_var "GO_PEER_WSS_PORT" "9097"
89
+ write_env_var "GO_PEER_IDENTITY_PATH" "${DATA_DIR}/identity.key"
90
+ write_env_var "GO_PEER_WS_BACKEND_PORT" "9096"
91
+ write_env_var "GO_PEER_AUTOTLS_CERT_DIR" "${DATA_DIR}/p2p-forge-certs"
92
+ write_env_var "LIBP2P_AUTO_PUBLIC_IP" "0"
93
+ }
94
+
95
+ case "${PHASE}" in
96
+ base)
97
+ run_phase_base
98
+ ;;
99
+ build)
100
+ run_phase_build
101
+ ;;
102
+ finalize)
103
+ run_phase_finalize
104
+ seed_env
105
+ ;;
106
+ all)
107
+ run_phase_base
108
+ run_phase_build
109
+ run_phase_finalize
110
+ seed_env
111
+ ;;
112
+ *)
113
+ echo "Unknown phase: ${PHASE}" >&2
114
+ exit 1
115
+ ;;
116
+ esac
117
+
118
+ echo "[uc-go-peer-bootstrap] completed phase ${PHASE}"
@@ -0,0 +1,204 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ENV_FILE="${ENV_FILE:-/etc/default/uc-go-peer}"
5
+ READY_FILE="${READY_FILE:-/etc/default/uc-go-peer.ready}"
6
+ AUTOTLS_READY_FILE="${AUTOTLS_READY_FILE:-/etc/default/uc-go-peer.autotls-ready}"
7
+ AUTOTLS_ZONE_FILE="${AUTOTLS_ZONE_FILE:-/etc/default/uc-go-peer.autotls-zone}"
8
+ AUTOTLS_HOSTS_FILE="${AUTOTLS_HOSTS_FILE:-/etc/default/uc-go-peer.autotls-hosts}"
9
+ AUTOTLS_CADDY_READY_FILE="${AUTOTLS_CADDY_READY_FILE:-/etc/default/uc-go-peer.caddy-ready}"
10
+ SERVICE_NAME="${SERVICE_NAME:-uc-go-peer.service}"
11
+ AUTOTLS_REFRESH_SERVICE="${AUTOTLS_REFRESH_SERVICE:-uc-go-peer-autotls-refresh.service}"
12
+ CADDY_SERVICE="${CADDY_SERVICE:-caddy.service}"
13
+ CADDYFILE="${CADDYFILE:-/etc/caddy/Caddyfile}"
14
+ BOOTSTRAP_SERVICE="${BOOTSTRAP_SERVICE:-uc-go-peer-bootstrap.service}"
15
+ P2P_FORGE_DOMAIN="${P2P_FORGE_DOMAIN:-libp2p.direct}"
16
+ PUBLIC_IPV4=""
17
+ PUBLIC_IPV6=""
18
+ TCP_PORT="9095"
19
+ WS_PORT="9097"
20
+ WS_BACKEND_PORT="9096"
21
+ PROXY_HOSTNAME=""
22
+ UDP_PORT=""
23
+ START_SERVICE=1
24
+
25
+ usage() {
26
+ cat <<'EOF'
27
+ Usage:
28
+ uc-go-peer-configure.sh \
29
+ --public-ipv4 <ip> \
30
+ [--public-ipv6 <ipv6>] \
31
+ [--proxy-hostname <hostname>] \
32
+ [--tcp-port <host-port>] \
33
+ [--ws-port <host-port>] \
34
+ [--udp-port <host-port>] \
35
+ [--quic-port <host-port>] \
36
+ [--webtransport-port <host-port>] \
37
+ [--webrtc-port <host-port>] \
38
+ [--no-start]
39
+ EOF
40
+ }
41
+
42
+ write_env_var() {
43
+ local key="$1"
44
+ local value="$2"
45
+
46
+ if grep -Eq "^[#[:space:]]*${key}=" "${ENV_FILE}"; then
47
+ sed -i "s|^[#[:space:]]*${key}=.*|${key}=${value}|" "${ENV_FILE}"
48
+ else
49
+ printf '%s=%s\n' "${key}" "${value}" >> "${ENV_FILE}"
50
+ fi
51
+ }
52
+
53
+ render_proxy_caddyfile() {
54
+ local proxy_hostname="$1"
55
+ cat <<EOF
56
+ {
57
+ auto_https disable_redirects
58
+ }
59
+
60
+ https://${proxy_hostname} {
61
+ tls {
62
+ issuer acme {
63
+ disable_http_challenge
64
+ }
65
+ }
66
+ reverse_proxy http://127.0.0.1:${WS_BACKEND_PORT}
67
+ }
68
+ EOF
69
+ }
70
+
71
+ while [ "$#" -gt 0 ]; do
72
+ case "$1" in
73
+ --public-ipv4)
74
+ PUBLIC_IPV4="${2:-}"
75
+ shift 2
76
+ ;;
77
+ --public-ipv6)
78
+ PUBLIC_IPV6="${2:-}"
79
+ shift 2
80
+ ;;
81
+ --tcp-port)
82
+ TCP_PORT="${2:-}"
83
+ shift 2
84
+ ;;
85
+ --ws-port)
86
+ WS_PORT="${2:-}"
87
+ shift 2
88
+ ;;
89
+ --udp-port)
90
+ UDP_PORT="${2:-}"
91
+ shift 2
92
+ ;;
93
+ --proxy-hostname)
94
+ PROXY_HOSTNAME="${2:-}"
95
+ shift 2
96
+ ;;
97
+ --quic-port)
98
+ UDP_PORT="${2:-}"
99
+ shift 2
100
+ ;;
101
+ --webtransport-port)
102
+ UDP_PORT="${2:-}"
103
+ shift 2
104
+ ;;
105
+ --webrtc-port)
106
+ UDP_PORT="${2:-}"
107
+ shift 2
108
+ ;;
109
+ --no-start)
110
+ START_SERVICE=0
111
+ shift
112
+ ;;
113
+ -h|--help)
114
+ usage
115
+ exit 0
116
+ ;;
117
+ *)
118
+ echo "Unknown argument: $1" >&2
119
+ usage >&2
120
+ exit 1
121
+ ;;
122
+ esac
123
+ done
124
+
125
+ if [ -z "${PUBLIC_IPV4}" ]; then
126
+ usage >&2
127
+ exit 1
128
+ fi
129
+
130
+ touch "${ENV_FILE}"
131
+ rm -f "${AUTOTLS_READY_FILE}" "${AUTOTLS_ZONE_FILE}" "${AUTOTLS_HOSTS_FILE}" "${AUTOTLS_CADDY_READY_FILE}"
132
+
133
+ announce=(
134
+ "/ip4/${PUBLIC_IPV4}/tcp/${TCP_PORT}"
135
+ )
136
+
137
+ if [ -n "${WS_PORT}" ]; then
138
+ announce+=("/ip4/${PUBLIC_IPV4}/tcp/${WS_PORT}/tls/sni/*.${P2P_FORGE_DOMAIN}/ws")
139
+ fi
140
+
141
+ if [ -n "${UDP_PORT}" ]; then
142
+ announce+=(
143
+ "/ip4/${PUBLIC_IPV4}/udp/${UDP_PORT}/quic-v1"
144
+ "/ip4/${PUBLIC_IPV4}/udp/${UDP_PORT}/quic-v1/webtransport"
145
+ "/ip4/${PUBLIC_IPV4}/udp/${UDP_PORT}/webrtc-direct"
146
+ )
147
+ fi
148
+
149
+ if [ -n "${PUBLIC_IPV6}" ]; then
150
+ announce+=("/ip6/${PUBLIC_IPV6}/tcp/${TCP_PORT}")
151
+ if [ -n "${WS_PORT}" ]; then
152
+ announce+=("/ip6/${PUBLIC_IPV6}/tcp/${WS_PORT}/tls/sni/*.${P2P_FORGE_DOMAIN}/ws")
153
+ fi
154
+ if [ -n "${UDP_PORT}" ]; then
155
+ announce+=(
156
+ "/ip6/${PUBLIC_IPV6}/udp/${UDP_PORT}/quic-v1"
157
+ "/ip6/${PUBLIC_IPV6}/udp/${UDP_PORT}/quic-v1/webtransport"
158
+ "/ip6/${PUBLIC_IPV6}/udp/${UDP_PORT}/webrtc-direct"
159
+ )
160
+ fi
161
+ fi
162
+
163
+ announce_value="$(IFS=,; printf '%s' "${announce[*]}")"
164
+ write_env_var "PUBLIC_IPV4" "${PUBLIC_IPV4}"
165
+ if [ -n "${PUBLIC_IPV6}" ]; then
166
+ write_env_var "PUBLIC_IPV6" "${PUBLIC_IPV6}"
167
+ fi
168
+ write_env_var "EXTERNAL_RELAY_TCP_PORT" "${TCP_PORT}"
169
+ write_env_var "EXTERNAL_RELAY_WS_PORT" "${WS_PORT}"
170
+ write_env_var "GO_PEER_WSS_PORT" "${GO_PEER_WSS_PORT:-9097}"
171
+ if [ -n "${PROXY_HOSTNAME}" ]; then
172
+ write_env_var "PROXY_HOSTNAME" "${PROXY_HOSTNAME}"
173
+ mkdir -p "$(dirname "${CADDYFILE}")"
174
+ render_proxy_caddyfile "${PROXY_HOSTNAME}" > "${CADDYFILE}"
175
+ touch "${AUTOTLS_CADDY_READY_FILE}"
176
+ else
177
+ write_env_var "PROXY_HOSTNAME" ""
178
+ rm -f "${AUTOTLS_CADDY_READY_FILE}"
179
+ fi
180
+ if [ -n "${UDP_PORT}" ]; then
181
+ write_env_var "EXTERNAL_RELAY_UDP_PORT" "${UDP_PORT}"
182
+ write_env_var "EXTERNAL_RELAY_QUIC_PORT" "${UDP_PORT}"
183
+ write_env_var "EXTERNAL_RELAY_WEBTRANSPORT_PORT" "${UDP_PORT}"
184
+ write_env_var "EXTERNAL_RELAY_WEBRTC_PORT" "${UDP_PORT}"
185
+ fi
186
+ write_env_var "LIBP2P_ANNOUNCE_ADDRS" "${announce_value}"
187
+ touch "${READY_FILE}"
188
+
189
+ if [ "${START_SERVICE}" -eq 1 ]; then
190
+ systemctl daemon-reload
191
+ systemctl enable "${SERVICE_NAME}"
192
+ systemctl restart "${SERVICE_NAME}"
193
+ systemctl enable "${AUTOTLS_REFRESH_SERVICE}"
194
+ if [ -n "${PROXY_HOSTNAME}" ]; then
195
+ systemctl enable "${CADDY_SERVICE}"
196
+ systemctl restart "${CADDY_SERVICE}"
197
+ else
198
+ systemctl stop "${CADDY_SERVICE}" || true
199
+ fi
200
+ systemctl restart --no-block "${AUTOTLS_REFRESH_SERVICE}"
201
+ fi
202
+
203
+ printf 'Configured LIBP2P_ANNOUNCE_ADDRS=%s\n' "${announce_value}"
204
+ printf 'Ready file: %s\n' "${READY_FILE}"