Files
duplicati/Tools/Verification/DuplicatiVerify.py
T

98 lines
3.1 KiB
Python

#!/usr/bin/env python
"""
This file is a standalone python script that is tested with python 2.7
If Duplicati is producing a backup with the option --upload-verification-file,
it will produce a *-verification.json file on the backend, which can be verified
by this script. Simply run this script with the path to the backup
folder as input, and it will verify all *-verification.json files in the folder.
"""
import sys
import os
import string
import json
import base64
import codecs
from hashlib import sha256
""" Utility function to return byte chunks from a binary file """
def bytes_from_file(filename, chunksize=8192):
with open(filename, "rb") as f:
while True:
chunk = f.read(chunksize)
if chunk:
for b in chunk:
yield b
else:
break
""" Verifies a single -verification.json file """
def verifyHashes(filename):
errorCount = 0
checked = 0
if (not os.path.exists(filename)):
print "Specified file does not exist: ", filename
return -1
folder = os.path.dirname(filename)
with codecs.open(filename, "r", "utf-8-sig") as f:
doc = json.load(f)
for file in doc:
filename = file["Name"]
hash = file["Hash"]
size = file["Size"]
fullpath = os.path.join(folder, filename)
if not os.path.exists(fullpath):
print "File missing: ", fullpath
errorCount += 1
else:
checked += 1
print "Verifying file ", filename
hashalg = sha256()
for b in bytes_from_file(fullpath):
hashalg.update(b)
hashval = base64.b64encode(hashalg.digest())
if hashval != hash:
print "*** Hash check failed for file: ", fullpath
errorCount += 1
if errorCount > 0:
print "Errors were found"
else:
print "No errors found"
return errorCount
if __name__ == "__main__":
if len(sys.argv) != 1 and len(sys.argv) != 2:
print "Usage:", len(sys.argv)
print "DuplicatiVerify.py <path to verification file>"
print "DuplicatiVerify.py <folder with verification files>"
print "DuplicatiVerify.py (no arguments, uses current dir)"
else:
if len(sys.argv) == 1:
argument = os.getcwd()
else:
argument = sys.argv[1]
if not os.path.exists(argument):
print "No such file or directory: ", argument
else:
if os.path.isfile(argument):
verifyHashes(argument)
else:
files = 0
for f in os.listdir(argument):
if (f.endswith("-verification.json")):
print "Verifying file: ", f
files += 1
verifyHashes(os.path.join(argument, f))
if files == 0:
print "No verification files in folder: ", argument