Allow bounded atomic import of full Forgejo SQL archive
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a06ecb-456a-71c2-b41e-0755d336e883
This commit is contained in:
parent
a9c1da4bd7
commit
121f11de6a
1 changed files with 19 additions and 4 deletions
|
|
@ -29,9 +29,24 @@ def run(archive, receipt):
|
||||||
staging=archive.parent/(prefix+'-staging')
|
staging=archive.parent/(prefix+'-staging')
|
||||||
staging.mkdir(mode=0o700)
|
staging.mkdir(mode=0o700)
|
||||||
resources=[]
|
resources=[]
|
||||||
def command(args, payload=None, env=None, check=True):
|
def command(args, payload=None, env=None, check=True, timeout=180):
|
||||||
r=subprocess.run(args,input=payload,capture_output=True,env=env,timeout=180)
|
try:
|
||||||
if check and r.returncode: raise ValueError('isolated_command_failed')
|
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
|
return r
|
||||||
def docker(*args, **kw): return command(['docker',*args],**kw)
|
def docker(*args, **kw): return command(['docker',*args],**kw)
|
||||||
try:
|
try:
|
||||||
|
|
@ -95,7 +110,7 @@ LEVEL = Error
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
else: raise ValueError('database_not_ready')
|
else: raise ValueError('database_not_ready')
|
||||||
sql=(staging/'forgejo-db.sql').read_bytes()
|
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
|
receipt['database_import']=True
|
||||||
counts=docker('exec',db,'psql','-U','forgejo','-d','forgejo','-Atqc',
|
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()
|
'SELECT (SELECT count(*) FROM repository),(SELECT count(*) FROM "user"),(SELECT count(*) FROM package_blob);').stdout.decode().strip()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue