"""Boot the actual server image with the actual rendered configuration, then probe/save/restart it.""" import json,os,secrets,subprocess,sys,tempfile,time from pathlib import Path import yaml docs=list(yaml.safe_load_all(Path(sys.argv[1]).read_text())) d=next(d for d in docs if d['kind']=='Deployment') c=next(c for c in d['spec']['template']['spec']['containers'] if c['name']=='factorio') cms={d['metadata']['name']:d['data'] for d in docs if d['kind']=='ConfigMap'} run=lambda *a,**kw: subprocess.run(a,check=True,**kw) with tempfile.TemporaryDirectory() as directory: root=Path(directory) for name in ['scripts','settings','credentials','data']:(root/name).mkdir() for folder,name in [('scripts','factorio-scripts'),('settings','factorio-settings')]: for key,value in cms[name].items(): file=root/folder/key; file.write_text(value); file.chmod(0o755 if key.endswith('.sh') else 0o644) (root/'credentials/rcon-password').write_text(secrets.token_urlsafe(32)) args=['docker','run','--detach','--name','factorio-smoke-'+secrets.token_hex(5)] for env in c['env']:args+=['--env',env['name']+'='+env['value']] for mount in c['volumeMounts']: folder={'data':'data','scripts':'scripts','settings':'settings','credentials':'credentials'}[mount['name']] args+=['--volume',f'{root/folder}:{mount["mountPath"]}'+(':ro' if mount.get('readOnly') else '')] args+=['--entrypoint',c['command'][0],c['image'],*c['command'][1:]] container=subprocess.check_output(args,text=True).strip() def ready(): command=c['readinessProbe']['exec']['command'] for _ in range(90): if subprocess.run(['docker','exec',container,*command],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL,timeout=15).returncode==0:return time.sleep(2) raise RuntimeError('Server did not pass the production readiness probe') try: ready() run('docker','exec',container,'rcon','/server-save') run('docker','stop','--time','180',container,stdout=subprocess.DEVNULL) assert list((root/'data/saves').glob('*.zip')), 'No persistent save' run('docker','start',container,stdout=subprocess.DEVNULL) ready() assert list((root/'data/upgrade-backups').glob('*/*.zip')), 'No pre-upgrade backup' print('Actual image passed RCON readiness, persistent save, restart, and upgrade-backup checks') finally: run('docker','rm','--force',container,stdout=subprocess.DEVNULL) # The upstream image owns its world files; cleanup through the same image. run('docker','run','--rm','--volume',f'{root}/data:/cleanup','--entrypoint','sh',c['image'],'-c','rm -rf /cleanup/*',stdout=subprocess.DEVNULL)