def _run_internal(self, endpoint, ks_manifest, component): """Backup the cassandra file and keyspace manifest. Let errors from here buble out. Returns `True` if the file was uploaded, `False` otherwise. """ self.log.info("Uploading file %s", component) if component.is_deleted: endpoint.backup_keyspace(ks_manifest) self.log.info("Uploaded backup set %s after deletion of %s", ks_manifest.backup_path, component) return # Create a BackupFile, this will have checksums backup_file = cassandra.BackupFile(component.file_path, host=self.args.host, component=component) # Store the cassandra file if endpoint.exists(backup_file.backup_path): if endpoint.validate_checksum(backup_file.backup_path, backup_file.md5): self.log.info("Skipping file %s skipping as there is a "\ "valid backup", backup_file) else: self.log.warn("Possibly corrupt file %s in the backup, "\ "skipping.", backup_file) return False uploaded_path = endpoint.backup_file(backup_file) endpoint.backup_keyspace(ks_manifest) self.log.info("Uploaded file %s to %s", backup_file.file_path, uploaded_path) return True
def _do_run(self): """ """ def safe_get(): try: ks_backup_json, component_json = self.work_queue.get_nowait() return (cassandra.KeyspaceBackup.deserialise( json.loads(ks_backup_json)), cassandra.SSTableComponent.deserialise( json.loads(component_json))) except (Queue.Empty): return (None, None) endpoint = self._endpoint(self.args) manifest, component = safe_get() while component is not None: self.log.info("Restoring component %s under %s", component, self.args.data_dir) # We need a backup file for the component, so we know # where it is stored and where it will backup to # we also want the MD5, that is on disk backup_file = endpoint.read_backup_file( cassandra.BackupFile(None, component=component, md5="", host=manifest.host).backup_path) operation = RestoreOperation(endpoint, backup_file, copy.copy(self.args)) op_result = operation() self.work_queue.task_done() self.result_queue.put(json.dumps(op_result.serialise())) manifest, component = safe_get() return
def __call__(self): self.log.info("Starting sub command %s", self.command_name) endpoint = self._endpoint(self.args) manifest = self._load_manifest_by_name(endpoint, self.args.backup_name) missing_files = [] present_files = [] corrupt_files = [] for component in manifest.iter_components(): # Read the backup file try: backup_file = endpoint.read_backup_file( cassandra.BackupFile(None, component=component, md5="", host=manifest.host).backup_path) except (EnvironmentError) as e: if e.errno != errno.ENOENT: raise # Set null so we know the file was not found backup_file = None if backup_file is None: # Could not find the meta. missing_files.append(component) elif endpoint.exists(backup_file.backup_path): # Found the meta, and the file actually exists. if not self.args.checksum: present_files.append(component) elif endpoint.validate_checksum(backup_file.backup_path, backup_file.md5): present_files.append(component) else: corrupt_files.append(component) else: missing_files.append(component) buffer = [] if missing_files or corrupt_files: buffer.append("Missing or corrupt files found for backup " "%s" % (self.args.backup_name, )) else: buffer.append("All files present for backup %s" % (self.args.backup_name, )) if self.args.checksum: buffer.append("Files were checksummed") else: buffer.append("Files were not checksummed") buffer.append("") if corrupt_files: buffer.append("Corrupt Files:") buffer.extend(component.file_name for component in corrupt_files) if missing_files: buffer.append("Missing Files:") buffer.extend(component.file_name for component in missing_files) if present_files: buffer.append("Files:") buffer.extend(component.file_name for component in present_files) self.log.info("Finished sub command %s", self.command_name) return (0 if not missing_files and not corrupt_files else 1, "\n".join(buffer))