49 lines
1.5 KiB
Python
49 lines
1.5 KiB
Python
#!/usr/bin/env python3
|
|
import json
|
|
import os
|
|
import sys
|
|
import gzip
|
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
|
|
backup_dir = "/mnt2/backed-up-drive/backupstore/volumes/2c/df/pvc-5c1f48e3-346f-4c35-8e6a-8fc0c4c3a842"
|
|
output_img = "/mnt/nextcloud-restored.img"
|
|
|
|
backup_cfg = f"{backup_dir}/backups/backup_backup-eac0221d1cab4a9c.cfg"
|
|
blocks_dir = f"{backup_dir}/blocks"
|
|
|
|
with open(backup_cfg) as f:
|
|
data = json.load(f)
|
|
|
|
blocks = data['Blocks']
|
|
total = len(blocks)
|
|
size = int(data['Size'])
|
|
|
|
print(f"Volume size: {size // 1024 // 1024 // 1024} GB")
|
|
print(f"Block count: {total}")
|
|
|
|
os.makedirs(os.path.dirname(output_img) if os.path.dirname(output_img) else '.', exist_ok=True)
|
|
|
|
if not os.path.exists(output_img):
|
|
import subprocess
|
|
subprocess.run(['truncate', '-s', str(size), output_img], check=True)
|
|
|
|
with open(output_img, 'r+b') as img:
|
|
for i, block in enumerate(blocks):
|
|
offset = block['Offset']
|
|
checksum = block['BlockChecksum']
|
|
|
|
block_path = f"{blocks_dir}/{checksum[:2]}/{checksum[2:4]}/{checksum}.blk"
|
|
|
|
if os.path.exists(block_path):
|
|
with gzip.open(block_path, 'rb') as bf:
|
|
img.seek(offset)
|
|
img.write(bf.read())
|
|
|
|
if (i + 1) % 500 == 0:
|
|
percent = (i + 1) * 100 // total
|
|
bar = '=' * (percent // 2) + ' ' * (50 - percent // 2)
|
|
sys.stdout.write(f"\r[{bar}] {percent}% ({i + 1}/{total})")
|
|
sys.stdout.flush()
|
|
|
|
print(f"\nDone! Image: {output_img}")
|