22 lines
1.5 KiB
Python
22 lines
1.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Bounded daily backup of Classic persistent accounts, characters and dashboard."""
|
|
import argparse,gzip,json,os,pathlib,shutil,sqlite3,subprocess,time
|
|
p=argparse.ArgumentParser();p.add_argument('--root',type=pathlib.Path,required=True);a=p.parse_args();root=a.root
|
|
base=root/'backups';base.mkdir(mode=0o700,exist_ok=True)
|
|
target=base/time.strftime('%Y%m%dT%H%M%SZ',time.gmtime());target.mkdir(mode=0o700)
|
|
c=json.loads((root/'database-credentials.json').read_text())
|
|
try:
|
|
with gzip.open(target/'classic-auth-characters.sql.gz','wb') as out:
|
|
p=subprocess.Popen(['docker','exec','-e','MYSQL_PWD','azerothai-classic-db','mysqldump','-uroot','--single-transaction','--set-gtid-purged=OFF','--databases','classicrealmd','classiccharacters'],stdout=subprocess.PIPE,stderr=subprocess.PIPE,env=dict(os.environ,MYSQL_PWD=c['root']))
|
|
shutil.copyfileobj(p.stdout,out)
|
|
if p.wait():raise RuntimeError('Classic backup failed')
|
|
dbs=[p for p in (root/'app-staging/.wrangler/state/v3/d1').rglob('*.sqlite') if p.name!='metadata.sqlite'];assert len(dbs)==1
|
|
source=sqlite3.connect(dbs[0]);dest=sqlite3.connect(target/'dashboard.sqlite');source.backup(dest);dest.close();source.close()
|
|
shutil.copytree(root/'run/etc',target/'config')
|
|
(target/'complete.json').write_text(json.dumps({'at':time.time(),'backend':'cmangos-classic'}))
|
|
for old in sorted(base.iterdir(),reverse=True)[3:]:
|
|
if old.is_dir() and (old/'complete.json').exists():shutil.rmtree(old)
|
|
print('Classic backup complete: '+str(target))
|
|
except Exception:
|
|
(target/'failed').touch();raise
|