from ops import *

assert not (R/'recovery-started.json').exists()
plan=json.loads((R/'plan.json').read_text())
now=inspect('contextra-redis-1')
assert not now['State']['Running']
assert now['Image']==plan['redis']['Image']
assert inventory()==plan['others']
save('first-failure.json',dict(reason='root-owned mode0600 bind config/ACL unreadable to image redis UID999',logs=subprocess.check_output(['docker','logs','--tail','25','contextra-redis-1'],stderr=subprocess.STDOUT,text=True),auto_restart_disabled=True))
save('recovery-started.json',dict(at=time.time(),correction='Owner UID999/GID1000, mode0600 for exact two bind files only',files={k:dict(uid=FILES[k].stat().st_uid,gid=FILES[k].stat().st_gid,mode=oct(FILES[k].stat().st_mode&0o777),hash=g.sha(FILES[k])) for k in ['config','acl']}))
for k in ['config','acl']:
    os.chown(FILES[k],999,1000)
    os.chmod(FILES[k],0o600)
subprocess.run(['docker','start','contextra-redis-1'],check=True,capture_output=True,timeout=10)
for _ in range(25):
    now=inspect('contextra-redis-1')
    if now['State'].get('Health',{}).get('Status')=='healthy':break
    if not now['State']['Running']:raise RuntimeError('RECOVERY_FAILED_NO_RETRY')
    time.sleep(1)
else:raise RuntimeError('RECOVERY_HEALTH_FAILED_NO_RETRY')
assert m.query('admin','CONFIG','GET','maxmemory')['maxmemory']=='8589934592'
assert next(x['Name'] for x in now['Mounts'] if x['Destination']=='/data')==next(x['Name'] for x in plan['redis']['Mounts'] if x['Destination']=='/data')
result=checks()
assert inventory()==plan['others']
streams()
subprocess.run(['docker','update','--restart='+plan['redis']['HostConfig']['RestartPolicy']['Name'],'contextra-redis-1'],check=True,capture_output=True,timeout=10)
clients=m.query('admin','CLIENT','LIST')
users=[dict(f.split('=',1) for f in line.split() if '=' in f).get('user') for line in clients.splitlines()]
save('recreate-result.json',dict(new_id=now['Id'],cmd=now['Config']['Cmd'],config=m.query('admin','CONFIG','GET','maxmemory','maxmemory-policy','save','appendonly'),checks=result,keys=keys(),publisher=m.api('/api/v1/metadata/status'),streams=streams(),others_preserved=True,client_users=users,logs=subprocess.check_output(['docker','logs','--tail','35','contextra-redis-1'],stderr=subprocess.STDOUT,text=True),completed_at=time.time(),permission_correction=True,extra_start=1))
save('ledger.json',dict(gate=1,acl=1,shutdown_save=1,recreate=1,failed_boot_boundary=1,corrective_start=1,ai_start=0,extra_validation_restart=0))
print(json.dumps(dict(recovery='PASS',redis='healthy8gb',dryrun=len(result),publisher_connected='contextra_publisher' in users,others_preserved=True)))
