diff --git a/scripts/hn/gateway/install.py b/scripts/hn/gateway/install.py index c301cdf..af852c1 100755 --- a/scripts/hn/gateway/install.py +++ b/scripts/hn/gateway/install.py @@ -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()