ops: wait for HN gateway initialization and allow safe resume

This commit is contained in:
hellcat 2026-10-27 20:41:00 +08:00
parent d8a509114a
commit ad9a4fe587

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""Guarded HN gateway first deployment; never operates existing DPL/FUC containers."""
from pathlib import Path
import argparse,hashlib,ipaddress,json,os,shutil,socket,subprocess,sys
import argparse,hashlib,ipaddress,json,os,shutil,socket,subprocess,sys,time
BASE=Path(__file__).resolve().parent
STATE=Path('/var/lib/hn-sgw')
BACKUP=Path('/root/codex-backups/hn-gateway/20261027-first-install')
@ -70,15 +70,25 @@ def start():
secret=json.load(sys.stdin)
assert isinstance(secret.get('username'),str)and isinstance(secret.get('password'),str)
assert all('\n' not in secret[k]for k in ['username','password'])
assert not (STATE/'admin.env').exists()
write(STATE/'admin.env','ADMIN_USER='+secret['username']+'\nADMIN_PASS='+secret['password']+'\nV2B_BACKEND=https://hardnerd.net\nV2B_HOST=hardnerd.net\n',0o600)
environment='ADMIN_USER='+secret['username']+'\nADMIN_PASS='+secret['password']+'\nV2B_BACKEND=https://hardnerd.net\nV2B_HOST=hardnerd.net\n'
if (STATE/'admin.env').exists():assert (STATE/'admin.env').read_text()==environment,'Existing HN credentials differ; stop for inspection'
else:write(STATE/'admin.env',environment,0o600)
for name,target in [('cert.pem',CERT/'live/c2.hardnerd-nodes.com/fullchain.pem'),('key.pem',CERT/'live/c2.hardnerd-nodes.com/privkey.pem')]:
(STATE/'ssl'/name).symlink_to(target)
link=STATE/'ssl'/name
if link.is_symlink():assert link.resolve()==target.resolve()
else:link.symlink_to(target)
run(['docker','volume','create','hn_sgw_config'],stdout=subprocess.DEVNULL)
directory=Path(output(['docker','volume','inspect','-f','{{.Mountpoint}}','hn_sgw_config']).strip())
write(directory/'whitelist_ips.txt','104.168.30.40\n')
if not (directory/'whitelist_ips.txt').exists():write(directory/'whitelist_ips.txt','104.168.30.40\n')
else:assert (directory/'whitelist_ips.txt').read_text()=='104.168.30.40\n'
compose('config','--quiet');compose('up','-d')
for name in NEW:run(['docker','exec',name,'nginx','-t'])
# The image downloads its public IP list on first start before creating cloud_geo.conf.
deadline=time.monotonic()+55
for name in NEW:
while subprocess.run(['docker','exec',name,'nginx','-t'],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL).returncode:
assert time.monotonic()<deadline,'HN initialization timeout; inspect and safely resume start'
time.sleep(2)
run(['docker','exec',name,'nginx','-t'])
old=HOST.read_text();write(BACKUP/'hn-http-only.conf',old,0o600)
HOST.write_text((BASE/'host.conf').read_text())
try:run(['nginx','-t']);run(['systemctl','reload','nginx'])