Allow bounded atomic import of full Forgejo SQL archive
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a06ecb-456a-71c2-b41e-0755d336e883
This commit is contained in:
codex 2026-09-06 01:16:43 +02:00
parent a9c1da4bd7
commit 121f11de6a

View file

@ -29,9 +29,24 @@ def run(archive, receipt):
staging=archive.parent/(prefix+'-staging')
staging.mkdir(mode=0o700)
resources=[]
def command(args, payload=None, env=None, check=True):
r=subprocess.run(args,input=payload,capture_output=True,env=env,timeout=180)
if check and r.returncode: raise ValueError('isolated_command_failed')
def command(args, payload=None, env=None, check=True, timeout=180):
try:
r=subprocess.run(args,input=payload,capture_output=True,env=env,timeout=timeout)
except subprocess.TimeoutExpired:
receipt['failure_kind']='command_timeout'
raise ValueError('isolated_command_timeout') from None
if check and r.returncode:
receipt['failure_kind']='command_nonzero'
receipt['command_exit_code']=r.returncode
# Classify only fixed diagnostics; never publish captured output.
for marker, category in [(b'out of memory', 'memory_limit'),
(b'syntax error', 'sql_syntax'),
(b'does not exist', 'missing_database_object'),
(b'duplicate key', 'duplicate_database_key')]:
if marker in r.stderr.lower():
receipt['failure_kind']=category
break
raise ValueError('isolated_command_failed')
return r
def docker(*args, **kw): return command(['docker',*args],**kw)
try:
@ -95,7 +110,7 @@ LEVEL = Error
time.sleep(2)
else: raise ValueError('database_not_ready')
sql=(staging/'forgejo-db.sql').read_bytes()
docker('exec','-i',db,'psql','-U','forgejo','-d','forgejo','-v','ON_ERROR_STOP=1',payload=sql)
docker('exec','-i',db,'psql','-U','forgejo','-d','forgejo','--single-transaction','-v','ON_ERROR_STOP=1',payload=sql,timeout=900)
receipt['database_import']=True
counts=docker('exec',db,'psql','-U','forgejo','-d','forgejo','-Atqc',
'SELECT (SELECT count(*) FROM repository),(SELECT count(*) FROM "user"),(SELECT count(*) FROM package_blob);').stdout.decode().strip()