28 lines
1.4 KiB
Python
28 lines
1.4 KiB
Python
"""Consistent SQLite backup plus attachment files; only IKAR paths are used."""
|
|
from pathlib import Path
|
|
import datetime, os, sqlite3, tarfile, tempfile
|
|
|
|
root = Path('/mnt/data/ikar_server')
|
|
if not os.path.ismount('/mnt/data'):
|
|
raise SystemExit('External disk is not mounted')
|
|
source = root / 'shared/data'
|
|
stamp = datetime.datetime.now(datetime.timezone.utc).strftime('%Y%m%dT%H%M%SZ')
|
|
destination = root / f'backups/ikar-{stamp}.tar.gz'
|
|
with tempfile.TemporaryDirectory(prefix='backup-', dir=root / 'backups') as temp:
|
|
database = Path(temp) / 'ikar.db'
|
|
with sqlite3.connect(f'file:{source / "ikar.db"}?mode=ro', uri=True) as live, sqlite3.connect(database) as backup:
|
|
live.backup(backup)
|
|
if backup.execute('pragma quick_check').fetchone()[0] != 'ok':
|
|
raise SystemExit('Database backup failed integrity check')
|
|
with tarfile.open(destination, 'w:gz') as bundle:
|
|
bundle.add(database, arcname='data/ikar.db')
|
|
for directory in source.iterdir():
|
|
if directory.is_dir() and directory.name not in ('QlyraUploads', 'AppUpdates'):
|
|
bundle.add(directory, arcname=f'data/{directory.name}')
|
|
os.chmod(destination, 0o600)
|
|
cutoff = datetime.datetime.now(datetime.timezone.utc).timestamp() - 14 * 86400
|
|
for previous in (root / 'backups').glob('ikar-*.tar.gz'):
|
|
if previous != destination and previous.is_file() and previous.stat().st_mtime < cutoff:
|
|
previous.unlink()
|
|
print(destination)
|