@le-space/rootfs 0.1.4 → 0.1.5
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.
- package/index.js +17 -3
- package/package.json +1 -1
- package/reference/uc-go-peer/contract.json +58 -0
- package/reference/uc-go-peer/rootfs/Dockerfile.rootfs +24 -0
- package/reference/uc-go-peer/rootfs/build-rootfs-image.sh +94 -0
- package/reference/uc-go-peer/rootfs/build-rootfs.sh +489 -0
- package/reference/uc-go-peer/rootfs/read-rootfs-contract.py +72 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-autotls-refresh.py +144 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-autotls-refresh.service +23 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-bootstrap.service +17 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-bootstrap.sh +118 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-configure.sh +204 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-describe.py +195 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-setup-server.py +221 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer.service +19 -0
|
@@ -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}"
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
import re
|
|
5
|
+
import subprocess
|
|
6
|
+
import time
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
ENV_FILE = os.environ.get("ENV_FILE", "/etc/default/uc-go-peer")
|
|
10
|
+
SERVICE_NAME = os.environ.get("SERVICE_NAME", "uc-go-peer.service")
|
|
11
|
+
WAIT_TIMEOUT_SECONDS = int(os.environ.get("DESCRIBE_WAIT_TIMEOUT_SECONDS", "240"))
|
|
12
|
+
WAIT_INTERVAL_SECONDS = float(os.environ.get("DESCRIBE_WAIT_INTERVAL_SECONDS", "2"))
|
|
13
|
+
AUTOTLS_EXTRA_WAIT_SECONDS = int(os.environ.get("DESCRIBE_AUTOTLS_EXTRA_WAIT_SECONDS", "120"))
|
|
14
|
+
|
|
15
|
+
PEER_ID_PATTERNS = [
|
|
16
|
+
re.compile(r"PeerID:\s+(\S+)"),
|
|
17
|
+
re.compile(r"Host created with PeerID:\s+(\S+)"),
|
|
18
|
+
]
|
|
19
|
+
LISTENING_PATTERN = re.compile(r"Listening on:\s+(\S+)/p2p/(\S+)")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def parse_env_file(path: str) -> dict[str, str]:
|
|
23
|
+
values: dict[str, str] = {}
|
|
24
|
+
if not os.path.exists(path):
|
|
25
|
+
return values
|
|
26
|
+
|
|
27
|
+
with open(path, encoding="utf-8") as handle:
|
|
28
|
+
for line in handle:
|
|
29
|
+
stripped = line.strip()
|
|
30
|
+
if not stripped or stripped.startswith("#") or "=" not in stripped:
|
|
31
|
+
continue
|
|
32
|
+
key, value = stripped.split("=", 1)
|
|
33
|
+
values[key.strip()] = value.strip()
|
|
34
|
+
return values
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def dedupe(values: list[str]) -> list[str]:
|
|
38
|
+
seen: set[str] = set()
|
|
39
|
+
result: list[str] = []
|
|
40
|
+
for value in values:
|
|
41
|
+
if value and value not in seen:
|
|
42
|
+
seen.add(value)
|
|
43
|
+
result.append(value)
|
|
44
|
+
return result
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def append_peer_id(addr: str, peer_id: str) -> str:
|
|
48
|
+
return addr if "/p2p/" in addr else f"{addr}/p2p/{peer_id}"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def parse_logs() -> tuple[str | None, list[str]]:
|
|
52
|
+
result = subprocess.run(
|
|
53
|
+
["journalctl", "-u", SERVICE_NAME, "-n", "500", "--no-pager"],
|
|
54
|
+
capture_output=True,
|
|
55
|
+
text=True,
|
|
56
|
+
check=False,
|
|
57
|
+
)
|
|
58
|
+
output = result.stdout or ""
|
|
59
|
+
|
|
60
|
+
peer_id = None
|
|
61
|
+
for pattern in PEER_ID_PATTERNS:
|
|
62
|
+
match = pattern.search(output)
|
|
63
|
+
if match:
|
|
64
|
+
peer_id = match.group(1)
|
|
65
|
+
break
|
|
66
|
+
|
|
67
|
+
listening_addrs = []
|
|
68
|
+
for addr, logged_peer_id in LISTENING_PATTERN.findall(output):
|
|
69
|
+
if peer_id is None:
|
|
70
|
+
peer_id = logged_peer_id
|
|
71
|
+
listening_addrs.append(addr)
|
|
72
|
+
|
|
73
|
+
return peer_id, dedupe(listening_addrs)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def build_probe_multiaddrs(env_values: dict[str, str], peer_id: str, listening_addrs: list[str]) -> dict[str, list[str]]:
|
|
77
|
+
announce_addrs = [
|
|
78
|
+
entry.strip()
|
|
79
|
+
for entry in env_values.get("LIBP2P_ANNOUNCE_ADDRS", "").split(",")
|
|
80
|
+
if entry.strip()
|
|
81
|
+
]
|
|
82
|
+
probe_multiaddrs: list[str] = []
|
|
83
|
+
direct_tcp_multiaddrs: list[str] = []
|
|
84
|
+
autotls_multiaddrs: list[str] = []
|
|
85
|
+
proxy_multiaddrs: list[str] = []
|
|
86
|
+
webtransport_multiaddrs: list[str] = []
|
|
87
|
+
webrtc_direct_multiaddrs: list[str] = []
|
|
88
|
+
|
|
89
|
+
for addr in announce_addrs:
|
|
90
|
+
if "/tcp/" in addr and "/tls/" not in addr and "/ws" not in addr:
|
|
91
|
+
direct_tcp_multiaddrs.append(append_peer_id(addr, peer_id))
|
|
92
|
+
|
|
93
|
+
ws_port = env_values.get("EXTERNAL_RELAY_WS_PORT", "").strip()
|
|
94
|
+
for addr in listening_addrs:
|
|
95
|
+
if "/tls/" not in addr or not addr.endswith("/ws"):
|
|
96
|
+
continue
|
|
97
|
+
|
|
98
|
+
dns_match = re.search(r"/dns[46]/([^/]+)/tcp/(\d+)/tls/ws$", addr)
|
|
99
|
+
if dns_match:
|
|
100
|
+
host = dns_match.group(1)
|
|
101
|
+
autotls_multiaddrs.append(f"/dns4/{host}/tcp/{ws_port or dns_match.group(2)}/tls/ws/p2p/{peer_id}")
|
|
102
|
+
autotls_multiaddrs.append(f"/dns6/{host}/tcp/{ws_port or dns_match.group(2)}/tls/ws/p2p/{peer_id}")
|
|
103
|
+
continue
|
|
104
|
+
|
|
105
|
+
sni_match = re.search(r"/tls/sni/([^/]+)/ws$", addr)
|
|
106
|
+
if sni_match:
|
|
107
|
+
host = sni_match.group(1)
|
|
108
|
+
if ws_port:
|
|
109
|
+
autotls_multiaddrs.append(f"/dns4/{host}/tcp/{ws_port}/tls/ws/p2p/{peer_id}")
|
|
110
|
+
autotls_multiaddrs.append(f"/dns6/{host}/tcp/{ws_port}/tls/ws/p2p/{peer_id}")
|
|
111
|
+
|
|
112
|
+
proxy_hostname = env_values.get("PROXY_HOSTNAME", "").strip()
|
|
113
|
+
if proxy_hostname:
|
|
114
|
+
proxy_multiaddrs.append(f"/dns4/{proxy_hostname}/tcp/443/tls/ws/p2p/{peer_id}")
|
|
115
|
+
proxy_multiaddrs.append(f"/dns6/{proxy_hostname}/tcp/443/tls/ws/p2p/{peer_id}")
|
|
116
|
+
|
|
117
|
+
public_ipv4 = env_values.get("PUBLIC_IPV4", "").strip()
|
|
118
|
+
public_ipv6 = env_values.get("PUBLIC_IPV6", "").strip()
|
|
119
|
+
udp_port = env_values.get("EXTERNAL_RELAY_UDP_PORT", "").strip()
|
|
120
|
+
if udp_port:
|
|
121
|
+
if public_ipv4:
|
|
122
|
+
webtransport_multiaddrs.append(f"/ip4/{public_ipv4}/udp/{udp_port}/quic-v1/webtransport/p2p/{peer_id}")
|
|
123
|
+
webrtc_direct_multiaddrs.append(f"/ip4/{public_ipv4}/udp/{udp_port}/webrtc-direct/p2p/{peer_id}")
|
|
124
|
+
if public_ipv6:
|
|
125
|
+
webtransport_multiaddrs.append(f"/ip6/{public_ipv6}/udp/{udp_port}/quic-v1/webtransport/p2p/{peer_id}")
|
|
126
|
+
webrtc_direct_multiaddrs.append(f"/ip6/{public_ipv6}/udp/{udp_port}/webrtc-direct/p2p/{peer_id}")
|
|
127
|
+
|
|
128
|
+
probe_multiaddrs.extend(direct_tcp_multiaddrs)
|
|
129
|
+
probe_multiaddrs.extend(autotls_multiaddrs)
|
|
130
|
+
probe_multiaddrs.extend(proxy_multiaddrs)
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
"direct_tcp_multiaddrs": dedupe(direct_tcp_multiaddrs),
|
|
134
|
+
"autotls_wss_multiaddrs": dedupe(autotls_multiaddrs),
|
|
135
|
+
"proxy_wss_multiaddrs": dedupe(proxy_multiaddrs),
|
|
136
|
+
"webtransport_multiaddrs": dedupe(webtransport_multiaddrs),
|
|
137
|
+
"webrtc_direct_multiaddrs": dedupe(webrtc_direct_multiaddrs),
|
|
138
|
+
"browser_bootstrap_multiaddrs": dedupe(
|
|
139
|
+
autotls_multiaddrs + proxy_multiaddrs + webtransport_multiaddrs + webrtc_direct_multiaddrs
|
|
140
|
+
),
|
|
141
|
+
"probe_multiaddrs": dedupe(probe_multiaddrs),
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def main() -> None:
|
|
146
|
+
started_at = time.monotonic()
|
|
147
|
+
deadline = time.monotonic() + WAIT_TIMEOUT_SECONDS
|
|
148
|
+
peer_id = None
|
|
149
|
+
listening_addrs: list[str] = []
|
|
150
|
+
grouped = {
|
|
151
|
+
"direct_tcp_multiaddrs": [],
|
|
152
|
+
"autotls_wss_multiaddrs": [],
|
|
153
|
+
"proxy_wss_multiaddrs": [],
|
|
154
|
+
"webtransport_multiaddrs": [],
|
|
155
|
+
"webrtc_direct_multiaddrs": [],
|
|
156
|
+
"browser_bootstrap_multiaddrs": [],
|
|
157
|
+
"probe_multiaddrs": [],
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
while time.monotonic() < deadline:
|
|
161
|
+
env_values = parse_env_file(ENV_FILE)
|
|
162
|
+
peer_id, listening_addrs = parse_logs()
|
|
163
|
+
if not peer_id:
|
|
164
|
+
time.sleep(WAIT_INTERVAL_SECONDS)
|
|
165
|
+
continue
|
|
166
|
+
|
|
167
|
+
grouped = build_probe_multiaddrs(env_values, peer_id, listening_addrs)
|
|
168
|
+
proxy_hostname = env_values.get("PROXY_HOSTNAME", "").strip()
|
|
169
|
+
if grouped["autotls_wss_multiaddrs"]:
|
|
170
|
+
break
|
|
171
|
+
if proxy_hostname and grouped["proxy_wss_multiaddrs"] and time.monotonic() - started_at >= AUTOTLS_EXTRA_WAIT_SECONDS:
|
|
172
|
+
break
|
|
173
|
+
if not proxy_hostname and time.monotonic() - started_at >= AUTOTLS_EXTRA_WAIT_SECONDS:
|
|
174
|
+
break
|
|
175
|
+
time.sleep(WAIT_INTERVAL_SECONDS)
|
|
176
|
+
|
|
177
|
+
if not peer_id:
|
|
178
|
+
raise SystemExit("unable to discover relay peer ID from service logs")
|
|
179
|
+
|
|
180
|
+
env_values = parse_env_file(ENV_FILE)
|
|
181
|
+
payload = {
|
|
182
|
+
"peer_id": peer_id,
|
|
183
|
+
"announce_addrs": [
|
|
184
|
+
entry.strip()
|
|
185
|
+
for entry in env_values.get("LIBP2P_ANNOUNCE_ADDRS", "").split(",")
|
|
186
|
+
if entry.strip()
|
|
187
|
+
],
|
|
188
|
+
"listening_addrs": listening_addrs,
|
|
189
|
+
**grouped,
|
|
190
|
+
}
|
|
191
|
+
print(json.dumps(payload))
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
if __name__ == "__main__":
|
|
195
|
+
main()
|