@le-space/rootfs 0.3.17 → 0.3.19
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/package.json +1 -1
- package/reference/uc-go-peer/rootfs/build-rootfs-image.sh +3 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-bootstrap-deregister.py +299 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-bootstrap-deregister.service +19 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-bootstrap-refresh.py +1 -3
- package/reference/uc-go-peer/rootfs/uc-go-peer-configure.sh +34 -0
package/package.json
CHANGED
|
@@ -86,11 +86,13 @@ virt-customize \
|
|
|
86
86
|
--copy-in "${APP_BINARY}:${GUEST_APP_DIR}" \
|
|
87
87
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-bootstrap.sh:/usr/local/sbin" \
|
|
88
88
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-configure.sh:/usr/local/sbin" \
|
|
89
|
+
--copy-in "${SCRIPT_DIR}/uc-go-peer-bootstrap-deregister.py:/usr/local/sbin" \
|
|
89
90
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-bootstrap-refresh.py:/usr/local/sbin" \
|
|
90
91
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-autotls-refresh.py:/usr/local/sbin" \
|
|
91
92
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-describe.py:/usr/local/sbin" \
|
|
92
93
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-setup-server.py:/usr/local/sbin" \
|
|
93
94
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-bootstrap.service:/etc/systemd/system" \
|
|
95
|
+
--copy-in "${SCRIPT_DIR}/uc-go-peer-bootstrap-deregister.service:/etc/systemd/system" \
|
|
94
96
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-bootstrap-refresh.service:/etc/systemd/system" \
|
|
95
97
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-bootstrap-refresh.timer:/etc/systemd/system" \
|
|
96
98
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-autotls-refresh.service:/etc/systemd/system" \
|
|
@@ -98,6 +100,7 @@ virt-customize \
|
|
|
98
100
|
--run-command "chmod 0755 ${ROOTFS_CONTRACT_BINARY_PATH}" \
|
|
99
101
|
--run-command "chmod 0755 /usr/local/sbin/uc-go-peer-bootstrap.sh" \
|
|
100
102
|
--run-command "chmod 0755 /usr/local/sbin/uc-go-peer-configure.sh" \
|
|
103
|
+
--run-command "chmod 0755 /usr/local/sbin/uc-go-peer-bootstrap-deregister.py" \
|
|
101
104
|
--run-command "chmod 0755 /usr/local/sbin/uc-go-peer-bootstrap-refresh.py" \
|
|
102
105
|
--run-command "chmod 0755 /usr/local/sbin/uc-go-peer-autotls-refresh.py" \
|
|
103
106
|
--run-command "chmod 0755 /usr/local/sbin/uc-go-peer-describe.py" \
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import hashlib
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
import time
|
|
8
|
+
import urllib.error
|
|
9
|
+
import urllib.parse
|
|
10
|
+
import urllib.request
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from eth_account import Account
|
|
14
|
+
from eth_account.messages import encode_defunct
|
|
15
|
+
except ImportError as error: # pragma: no cover - runtime dependency
|
|
16
|
+
raise SystemExit(
|
|
17
|
+
"eth-account is required for guest-side bootstrap deregistration"
|
|
18
|
+
) from error
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
ENV_FILE = os.environ.get("ENV_FILE", "/etc/default/uc-go-peer")
|
|
22
|
+
DESCRIBE_SCRIPT = os.environ.get("DESCRIBE_SCRIPT", "/usr/local/sbin/uc-go-peer-describe.py")
|
|
23
|
+
DEFAULT_API_HOST = os.environ.get("ALEPH_BOOTSTRAP_API_HOST", "https://api2.aleph.im")
|
|
24
|
+
DEFAULT_CHANNEL = os.environ.get("ALEPH_BOOTSTRAP_CHANNEL", "simple-todo")
|
|
25
|
+
DEFAULT_REF = os.environ.get("ALEPH_BOOTSTRAP_REF", "simple-todo-bootstrap")
|
|
26
|
+
DEFAULT_POST_TYPE = os.environ.get("ALEPH_BOOTSTRAP_POST_TYPE", "relay-bootstrap")
|
|
27
|
+
MAX_PREVIOUS_PAGES = int(os.environ.get("ALEPH_BOOTSTRAP_MAX_PREVIOUS_PAGES", "5"))
|
|
28
|
+
PAGINATION = int(os.environ.get("ALEPH_BOOTSTRAP_PAGINATION", "50"))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def parse_env_file(path: str) -> dict[str, str]:
|
|
32
|
+
values: dict[str, str] = {}
|
|
33
|
+
if not os.path.exists(path):
|
|
34
|
+
return values
|
|
35
|
+
|
|
36
|
+
with open(path, encoding="utf-8") as handle:
|
|
37
|
+
for line in handle:
|
|
38
|
+
stripped = line.strip()
|
|
39
|
+
if not stripped or stripped.startswith("#") or "=" not in stripped:
|
|
40
|
+
continue
|
|
41
|
+
key, value = stripped.split("=", 1)
|
|
42
|
+
values[key.strip()] = value.strip()
|
|
43
|
+
return values
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def json_dumps(payload: object) -> str:
|
|
47
|
+
return json.dumps(payload, separators=(",", ":"))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def dedupe(values: list[str]) -> list[str]:
|
|
51
|
+
seen: set[str] = set()
|
|
52
|
+
result: list[str] = []
|
|
53
|
+
for value in values:
|
|
54
|
+
if value and value not in seen:
|
|
55
|
+
seen.add(value)
|
|
56
|
+
result.append(value)
|
|
57
|
+
return result
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def sign_personal_message(private_key: str, payload: str) -> str:
|
|
61
|
+
message = encode_defunct(text=payload)
|
|
62
|
+
signed = Account.sign_message(message, private_key=private_key)
|
|
63
|
+
return signed.signature.hex()
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def address_from_private_key(private_key: str) -> str:
|
|
67
|
+
return Account.from_key(private_key).address
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def signature_payload(chain: str, sender: str, message_type: str, item_hash: str) -> str:
|
|
71
|
+
return "\n".join([chain, sender, message_type, item_hash])
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def post_json(url: str, body: dict[str, object]) -> tuple[int, dict]:
|
|
75
|
+
data = json_dumps(body).encode("utf-8")
|
|
76
|
+
request = urllib.request.Request(
|
|
77
|
+
url,
|
|
78
|
+
data=data,
|
|
79
|
+
headers={"content-type": "application/json"},
|
|
80
|
+
method="POST",
|
|
81
|
+
)
|
|
82
|
+
try:
|
|
83
|
+
with urllib.request.urlopen(request, timeout=30) as response:
|
|
84
|
+
payload = response.read().decode("utf-8")
|
|
85
|
+
return response.status, json.loads(payload or "{}")
|
|
86
|
+
except urllib.error.HTTPError as error:
|
|
87
|
+
payload = error.read().decode("utf-8")
|
|
88
|
+
try:
|
|
89
|
+
return error.code, json.loads(payload or "{}")
|
|
90
|
+
except json.JSONDecodeError:
|
|
91
|
+
return error.code, {"details": payload}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def get_json(url: str) -> dict:
|
|
95
|
+
with urllib.request.urlopen(url, timeout=30) as response:
|
|
96
|
+
return json.loads(response.read().decode("utf-8") or "{}")
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def sign_aleph_message(unsigned_message: dict[str, object], private_key: str) -> dict[str, object]:
|
|
100
|
+
signed = dict(unsigned_message)
|
|
101
|
+
signed["signature"] = sign_personal_message(
|
|
102
|
+
private_key,
|
|
103
|
+
signature_payload(
|
|
104
|
+
str(unsigned_message["chain"]),
|
|
105
|
+
str(unsigned_message["sender"]),
|
|
106
|
+
str(unsigned_message["type"]),
|
|
107
|
+
str(unsigned_message["item_hash"]),
|
|
108
|
+
),
|
|
109
|
+
)
|
|
110
|
+
return signed
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def broadcast_aleph_message(api_host: str, message: dict[str, object]) -> tuple[int, dict]:
|
|
114
|
+
url = urllib.parse.urljoin(api_host.rstrip("/") + "/", "api/v0/messages")
|
|
115
|
+
attempts = [
|
|
116
|
+
{"sync": True, "message": message},
|
|
117
|
+
{**message, "sync": True},
|
|
118
|
+
dict(message),
|
|
119
|
+
]
|
|
120
|
+
last: tuple[int, dict] | None = None
|
|
121
|
+
for attempt in attempts:
|
|
122
|
+
last = post_json(url, attempt)
|
|
123
|
+
if 200 <= last[0] < 300:
|
|
124
|
+
return last
|
|
125
|
+
if last is None:
|
|
126
|
+
raise RuntimeError("Aleph broadcast failed before any attempt was made")
|
|
127
|
+
raise RuntimeError(f"Aleph broadcast failed: {last[0]} {json_dumps(last[1])}")
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def parse_post_record(entry: object) -> dict[str, object] | None:
|
|
131
|
+
if not isinstance(entry, dict):
|
|
132
|
+
return None
|
|
133
|
+
item_hash = entry.get("item_hash") or entry.get("hash")
|
|
134
|
+
if not isinstance(item_hash, str) or not item_hash:
|
|
135
|
+
return None
|
|
136
|
+
|
|
137
|
+
sender = entry.get("address") or entry.get("sender")
|
|
138
|
+
item_content = entry.get("item_content")
|
|
139
|
+
if isinstance(item_content, str):
|
|
140
|
+
try:
|
|
141
|
+
item_content = json.loads(item_content)
|
|
142
|
+
except json.JSONDecodeError:
|
|
143
|
+
item_content = None
|
|
144
|
+
|
|
145
|
+
if not isinstance(item_content, dict):
|
|
146
|
+
return None
|
|
147
|
+
|
|
148
|
+
content = item_content.get("content")
|
|
149
|
+
if not isinstance(content, dict):
|
|
150
|
+
return None
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
"item_hash": item_hash,
|
|
154
|
+
"sender": sender,
|
|
155
|
+
"registration_id": content.get("registrationId"),
|
|
156
|
+
"peer_id": content.get("peerId"),
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def load_peer_id() -> str | None:
|
|
161
|
+
describe = subprocess.run([DESCRIBE_SCRIPT], check=False, capture_output=True, text=True)
|
|
162
|
+
if describe.returncode != 0:
|
|
163
|
+
return None
|
|
164
|
+
try:
|
|
165
|
+
metadata = json.loads(describe.stdout.strip() or "{}")
|
|
166
|
+
except json.JSONDecodeError:
|
|
167
|
+
return None
|
|
168
|
+
peer_id = metadata.get("peer_id")
|
|
169
|
+
if isinstance(peer_id, str) and peer_id.strip():
|
|
170
|
+
return peer_id.strip()
|
|
171
|
+
return None
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def fetch_current_hashes(
|
|
175
|
+
api_host: str,
|
|
176
|
+
channel: str,
|
|
177
|
+
ref: str,
|
|
178
|
+
post_type: str,
|
|
179
|
+
sender: str,
|
|
180
|
+
registration_id: str | None,
|
|
181
|
+
peer_id: str | None,
|
|
182
|
+
) -> list[str]:
|
|
183
|
+
found: list[str] = []
|
|
184
|
+
for page in range(1, MAX_PREVIOUS_PAGES + 1):
|
|
185
|
+
url = (
|
|
186
|
+
f"{api_host.rstrip('/')}/api/v0/posts.json?"
|
|
187
|
+
f"channels={urllib.parse.quote(channel)}&"
|
|
188
|
+
f"refs={urllib.parse.quote(ref)}&"
|
|
189
|
+
f"types={urllib.parse.quote(post_type)}&"
|
|
190
|
+
f"pagination={PAGINATION}&page={page}"
|
|
191
|
+
)
|
|
192
|
+
payload = get_json(url)
|
|
193
|
+
posts = payload.get("posts")
|
|
194
|
+
if not isinstance(posts, list):
|
|
195
|
+
break
|
|
196
|
+
|
|
197
|
+
for entry in posts:
|
|
198
|
+
parsed = parse_post_record(entry)
|
|
199
|
+
if parsed is None:
|
|
200
|
+
continue
|
|
201
|
+
if str(parsed["sender"]).lower() != sender.lower():
|
|
202
|
+
continue
|
|
203
|
+
if registration_id and parsed["registration_id"] == registration_id:
|
|
204
|
+
found.append(str(parsed["item_hash"]))
|
|
205
|
+
continue
|
|
206
|
+
if peer_id and parsed["peer_id"] == peer_id:
|
|
207
|
+
found.append(str(parsed["item_hash"]))
|
|
208
|
+
|
|
209
|
+
if len(posts) < PAGINATION:
|
|
210
|
+
break
|
|
211
|
+
|
|
212
|
+
return dedupe(found)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def broadcast_forget(
|
|
216
|
+
api_host: str,
|
|
217
|
+
sender: str,
|
|
218
|
+
private_key: str,
|
|
219
|
+
hashes: list[str],
|
|
220
|
+
channel: str,
|
|
221
|
+
) -> tuple[int, dict] | None:
|
|
222
|
+
if not hashes:
|
|
223
|
+
return None
|
|
224
|
+
|
|
225
|
+
now_seconds = time.time()
|
|
226
|
+
item_content = json_dumps(
|
|
227
|
+
{
|
|
228
|
+
"address": sender,
|
|
229
|
+
"time": now_seconds,
|
|
230
|
+
"hashes": hashes,
|
|
231
|
+
"aggregates": [],
|
|
232
|
+
"reason": f"Deregister relay bootstrap records for {sender}",
|
|
233
|
+
}
|
|
234
|
+
)
|
|
235
|
+
unsigned = {
|
|
236
|
+
"sender": sender,
|
|
237
|
+
"chain": "ETH",
|
|
238
|
+
"type": "FORGET",
|
|
239
|
+
"item_hash": hashlib.sha256(item_content.encode("utf-8")).hexdigest(),
|
|
240
|
+
"item_type": "inline",
|
|
241
|
+
"item_content": item_content,
|
|
242
|
+
"time": now_seconds,
|
|
243
|
+
"channel": channel,
|
|
244
|
+
}
|
|
245
|
+
return broadcast_aleph_message(api_host, sign_aleph_message(unsigned, private_key))
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def main() -> None:
|
|
249
|
+
env_values = parse_env_file(ENV_FILE)
|
|
250
|
+
publisher_private_key = env_values.get("ALEPH_BOOTSTRAP_PUBLISHER_PRIVATE_KEY", "").strip()
|
|
251
|
+
registration_id = env_values.get("ALEPH_BOOTSTRAP_REGISTRATION_ID", "").strip() or None
|
|
252
|
+
if not publisher_private_key:
|
|
253
|
+
print(json_dumps({"status": "skipped", "reason": "missing publisher key"}))
|
|
254
|
+
return
|
|
255
|
+
|
|
256
|
+
publisher_address = address_from_private_key(publisher_private_key)
|
|
257
|
+
peer_id = load_peer_id()
|
|
258
|
+
channel = env_values.get("ALEPH_BOOTSTRAP_CHANNEL", DEFAULT_CHANNEL).strip() or DEFAULT_CHANNEL
|
|
259
|
+
ref = env_values.get("ALEPH_BOOTSTRAP_REF", DEFAULT_REF).strip() or DEFAULT_REF
|
|
260
|
+
post_type = env_values.get("ALEPH_BOOTSTRAP_POST_TYPE", DEFAULT_POST_TYPE).strip() or DEFAULT_POST_TYPE
|
|
261
|
+
api_host = env_values.get("ALEPH_BOOTSTRAP_API_HOST", DEFAULT_API_HOST).strip() or DEFAULT_API_HOST
|
|
262
|
+
|
|
263
|
+
hashes = fetch_current_hashes(
|
|
264
|
+
api_host,
|
|
265
|
+
channel,
|
|
266
|
+
ref,
|
|
267
|
+
post_type,
|
|
268
|
+
publisher_address,
|
|
269
|
+
registration_id,
|
|
270
|
+
peer_id,
|
|
271
|
+
)
|
|
272
|
+
if not hashes:
|
|
273
|
+
print(json_dumps({"status": "skipped", "reason": "no matching bootstrap records"}))
|
|
274
|
+
return
|
|
275
|
+
|
|
276
|
+
http_status, response = broadcast_forget(
|
|
277
|
+
api_host, publisher_address, publisher_private_key, hashes, channel
|
|
278
|
+
) or (0, {})
|
|
279
|
+
print(
|
|
280
|
+
json_dumps(
|
|
281
|
+
{
|
|
282
|
+
"status": "forgotten",
|
|
283
|
+
"httpStatus": http_status,
|
|
284
|
+
"sender": publisher_address,
|
|
285
|
+
"registrationId": registration_id,
|
|
286
|
+
"peerId": peer_id,
|
|
287
|
+
"forgottenHashes": hashes,
|
|
288
|
+
"response": response,
|
|
289
|
+
}
|
|
290
|
+
)
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
if __name__ == "__main__":
|
|
295
|
+
try:
|
|
296
|
+
main()
|
|
297
|
+
except Exception as error: # pragma: no cover - runtime error path
|
|
298
|
+
print(json_dumps({"status": "error", "error": str(error)}), file=sys.stderr)
|
|
299
|
+
raise
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=Best-effort Aleph bootstrap deregistration on shutdown for uc-go-peer
|
|
3
|
+
After=network-online.target
|
|
4
|
+
Wants=network-online.target
|
|
5
|
+
ConditionPathExists=/etc/default/uc-go-peer.ready
|
|
6
|
+
|
|
7
|
+
[Service]
|
|
8
|
+
Type=oneshot
|
|
9
|
+
RemainAfterExit=yes
|
|
10
|
+
Environment=ENV_FILE=/etc/default/uc-go-peer
|
|
11
|
+
Environment=DESCRIBE_SCRIPT=/usr/local/sbin/uc-go-peer-describe.py
|
|
12
|
+
ExecStart=/bin/true
|
|
13
|
+
ExecStop=/usr/bin/python3 /usr/local/sbin/uc-go-peer-bootstrap-deregister.py
|
|
14
|
+
StandardOutput=journal
|
|
15
|
+
StandardError=journal
|
|
16
|
+
TimeoutStopSec=25
|
|
17
|
+
|
|
18
|
+
[Install]
|
|
19
|
+
WantedBy=multi-user.target
|
|
@@ -466,9 +466,6 @@ def main() -> None:
|
|
|
466
466
|
version,
|
|
467
467
|
now_ms,
|
|
468
468
|
)
|
|
469
|
-
if owner_authorization is None:
|
|
470
|
-
print(json_dumps({"status": "skipped", "reason": "missing owner authorization"}))
|
|
471
|
-
return
|
|
472
469
|
|
|
473
470
|
proof_payload = relay_proof_payload(
|
|
474
471
|
peer_id,
|
|
@@ -529,6 +526,7 @@ def main() -> None:
|
|
|
529
526
|
"publishedMultiaddrs": multiaddrs,
|
|
530
527
|
"publishedBrowserMultiaddrs": browser_multiaddrs,
|
|
531
528
|
"forgottenHashes": previous_hashes,
|
|
529
|
+
"ownerAuthorizationPresent": owner_authorization is not None,
|
|
532
530
|
"forgetResponse": forget_response[1] if forget_response else None,
|
|
533
531
|
"response": response,
|
|
534
532
|
}
|
|
@@ -10,6 +10,8 @@ AUTOTLS_CADDY_READY_FILE="${AUTOTLS_CADDY_READY_FILE:-/etc/default/uc-go-peer.ca
|
|
|
10
10
|
SERVICE_NAME="${SERVICE_NAME:-uc-go-peer.service}"
|
|
11
11
|
AUTOTLS_REFRESH_SERVICE="${AUTOTLS_REFRESH_SERVICE:-uc-go-peer-autotls-refresh.service}"
|
|
12
12
|
BOOTSTRAP_REFRESH_TIMER="${BOOTSTRAP_REFRESH_TIMER:-uc-go-peer-bootstrap-refresh.timer}"
|
|
13
|
+
BOOTSTRAP_REFRESH_SERVICE="${BOOTSTRAP_REFRESH_SERVICE:-uc-go-peer-bootstrap-refresh.service}"
|
|
14
|
+
BOOTSTRAP_DEREGISTER_SERVICE="${BOOTSTRAP_DEREGISTER_SERVICE:-uc-go-peer-bootstrap-deregister.service}"
|
|
13
15
|
CADDY_SERVICE="${CADDY_SERVICE:-caddy.service}"
|
|
14
16
|
CADDYFILE="${CADDYFILE:-/etc/caddy/Caddyfile}"
|
|
15
17
|
BOOTSTRAP_SERVICE="${BOOTSTRAP_SERVICE:-uc-go-peer-bootstrap.service}"
|
|
@@ -96,6 +98,27 @@ current_identity_path() {
|
|
|
96
98
|
printf '/var/lib/uc-go-peer/identity.key\n'
|
|
97
99
|
}
|
|
98
100
|
|
|
101
|
+
current_bootstrap_publisher_private_key() {
|
|
102
|
+
local existing
|
|
103
|
+
existing="$(grep -E '^[#[:space:]]*ALEPH_BOOTSTRAP_PUBLISHER_PRIVATE_KEY=' "${ENV_FILE}" 2>/dev/null | tail -n1 | cut -d= -f2- || true)"
|
|
104
|
+
if [ -n "${existing}" ]; then
|
|
105
|
+
printf '%s\n' "${existing}"
|
|
106
|
+
return
|
|
107
|
+
fi
|
|
108
|
+
printf '\n'
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
generate_bootstrap_publisher_private_key() {
|
|
112
|
+
while true; do
|
|
113
|
+
local candidate
|
|
114
|
+
candidate="$(openssl rand -hex 32)"
|
|
115
|
+
if [ -n "${candidate}" ] && [ "${candidate}" != "0000000000000000000000000000000000000000000000000000000000000000" ]; then
|
|
116
|
+
printf '0x%s\n' "${candidate}"
|
|
117
|
+
return
|
|
118
|
+
fi
|
|
119
|
+
done
|
|
120
|
+
}
|
|
121
|
+
|
|
99
122
|
while [ "$#" -gt 0 ]; do
|
|
100
123
|
case "$1" in
|
|
101
124
|
--public-ipv4)
|
|
@@ -178,6 +201,13 @@ fi
|
|
|
178
201
|
touch "${ENV_FILE}"
|
|
179
202
|
rm -f "${AUTOTLS_READY_FILE}" "${AUTOTLS_ZONE_FILE}" "${AUTOTLS_HOSTS_FILE}" "${AUTOTLS_CADDY_READY_FILE}"
|
|
180
203
|
|
|
204
|
+
if [ -z "${BOOTSTRAP_PUBLISHER_PRIVATE_KEY}" ]; then
|
|
205
|
+
BOOTSTRAP_PUBLISHER_PRIVATE_KEY="$(current_bootstrap_publisher_private_key)"
|
|
206
|
+
fi
|
|
207
|
+
if [ -z "${BOOTSTRAP_PUBLISHER_PRIVATE_KEY}" ]; then
|
|
208
|
+
BOOTSTRAP_PUBLISHER_PRIVATE_KEY="$(generate_bootstrap_publisher_private_key)"
|
|
209
|
+
fi
|
|
210
|
+
|
|
181
211
|
announce=(
|
|
182
212
|
"/ip4/${PUBLIC_IPV4}/tcp/${TCP_PORT}"
|
|
183
213
|
)
|
|
@@ -233,6 +263,7 @@ if [ -n "${UDP_PORT}" ]; then
|
|
|
233
263
|
fi
|
|
234
264
|
if [ -n "${BOOTSTRAP_PUBLISHER_PRIVATE_KEY}" ]; then
|
|
235
265
|
write_env_var "ALEPH_BOOTSTRAP_PUBLISHER_PRIVATE_KEY" "${BOOTSTRAP_PUBLISHER_PRIVATE_KEY}"
|
|
266
|
+
write_env_var "GO_PEER_IDENTITY_EVM_PRIVATE_KEY" "${BOOTSTRAP_PUBLISHER_PRIVATE_KEY}"
|
|
236
267
|
fi
|
|
237
268
|
if [ -n "${BOOTSTRAP_PUBLISHER_LIBP2P_IDENTITY_B64}" ]; then
|
|
238
269
|
identity_path="$(current_identity_path)"
|
|
@@ -260,7 +291,10 @@ if [ "${START_SERVICE}" -eq 1 ]; then
|
|
|
260
291
|
systemctl restart "${SERVICE_NAME}"
|
|
261
292
|
systemctl enable "${AUTOTLS_REFRESH_SERVICE}"
|
|
262
293
|
systemctl enable "${BOOTSTRAP_REFRESH_TIMER}"
|
|
294
|
+
systemctl enable "${BOOTSTRAP_DEREGISTER_SERVICE}"
|
|
295
|
+
systemctl restart "${BOOTSTRAP_DEREGISTER_SERVICE}"
|
|
263
296
|
systemctl start "${BOOTSTRAP_REFRESH_TIMER}"
|
|
297
|
+
systemctl restart --no-block "${BOOTSTRAP_REFRESH_SERVICE}" || true
|
|
264
298
|
if [ -n "${PROXY_HOSTNAME}" ]; then
|
|
265
299
|
systemctl enable "${CADDY_SERVICE}"
|
|
266
300
|
systemctl restart "${CADDY_SERVICE}"
|