def prepare_input(self, run, backup, store): ''' Open the tar file. Connect the output of the tar to either: a) the storage handler b) to encryption (openssl), THEN the storage handler ''' log.trace("Setting up input processes") # Set up the encryptor (use TEE for now) self.crypt_proc = None if backup.encrypt: log.debug("Creating crypt objects") self.crypto = cryptor.DecryptStream(self.config.data_passphrase) else: self.crypto = cryptor.Buffer() # Set up the storage handler log.debug("Starting storage thread") self.store_thread = StreamIn(self.crypto, store, run.folder) self.store_thread.start() log.debug("Connecting tar object") self.tarfile = tarfile.open(mode="r|gz", fileobj=self.crypto, bufsize=const.BufferSize) log.trace("Completed input preparation")
class Verify(): def __init__(self, backup_name, run_date): ''' Verify a run to ensure it is valid ''' self.config = Config.get_config() self.backup = self.config.backups[backup_name] self.store = self.config.storage[self.backup.store].copy() self.db = DB() # Find the run runs = self.db.runs(self.backup.name, run_date) if len(runs) == 0: raise Exception(_("Verify failed: Backup run does not exist")) self.vrun = runs[0] def run(self): self.test_store() # Get config and packages self.fetch_config() # We only check the data if there is actually something stored there. if self.vrun.nfiles == 0 and self.vrun.nfolders == 0: return True self.prepare_input(self.vrun, self.backup, self.store) try: # Only check for tar data if there are files backed up # Otherwise the tar will simply return an error tarinfo = self.tarfile.next() while tarinfo: tarinfo = self.tarfile.next() finally: self.close_input(self.backup) store_size, store_hash, = self.store_thread.get_hash() run_hash = self.vrun.hash run_size = self.vrun.size if store_size == run_size and store_hash == run_hash: return True # print(store_size, store_hash, run_size, run_hash) raise Exception(_("Verify failed - Run data is corrupt")) def test_store(self): store = self.config.storage[self.store.name].copy() store.connect() try: store.test() finally: store.disconnect() def fetch_config(self): store = self.config.storage[self.store.name].copy() store.connect() try: encrypted = False config = os.path.join(self.vrun.folder, const.ConfigName) if not store.exists(config): encrypted = True config = config + const.EncryptionSuffix if not store.exists(config): raise Exception(_("Configuration file missing. Bad run")) store.get(config, os.path.join(tempfile.gettempdir(), "__vault__tmp__")) os.remove(os.path.join(tempfile.gettempdir(), "__vault__tmp__")) if self.backup.include_packages: packages = os.path.join(self.vrun.folder, const.PackageFile) if encrypted: packages = packages + const.EncryptionSuffix store.get(packages, os.path.join(tempfile.gettempdir(), "__vault__tmp__")) os.remove(os.path.join(tempfile.gettempdir(), "__vault__tmp__")) finally: store.disconnect() def prepare_input(self, run, backup, store): ''' Open the tar file. Connect the output of the tar to either: a) the storage handler b) to encryption (openssl), THEN the storage handler ''' log.trace("Setting up input processes") # Set up the encryptor (use TEE for now) self.crypt_proc = None if backup.encrypt: log.debug("Creating crypt objects") self.crypto = cryptor.DecryptStream(self.config.data_passphrase) else: self.crypto = cryptor.Buffer() # Set up the storage handler log.debug("Starting storage thread") self.store_thread = StreamIn(self.crypto, store, run.folder) self.store_thread.start() log.debug("Connecting tar object") self.tarfile = tarfile.open(mode="r|gz", fileobj=self.crypto, bufsize=const.BufferSize) log.trace("Completed input preparation") def close_input(self, backup): log.trace("Closing output managers") # If we are using an external save command, we do nothing here try: self.tarfile.close() self.crypto.close() # Now we are ready to wait for the storage. self.store_thread.join() if self.store_thread.error: log.error("Closing store. Got error", str(self.store_thread.error)) # self.db.save_message("Error saving backup: %s" % str(self.store_thread.error)) raise self.store_thread.error finally: pass log.debug("All input closed")