def test_corrupt_filelist(self): vi1 = manifest.VolumeInfo() vi1.set_info(3, (b"hello", ), None, (), None) vi2 = manifest.VolumeInfo() vi2.set_info(4, (b"goodbye", b"there"), None, (b"aoeusht", ), None) vi3 = manifest.VolumeInfo() vi3.set_info(34, (), None, (), None) m = manifest.Manifest() for vi in [vi1, vi2, vi3]: m.add_volume_info(vi) self.set_config(u'local_path', path.Path(u"Foobar")) m.set_dirinfo() m.set_files_changed_info([ (b'one', b'new'), (b'two', b'changed'), (b'three', b'new'), ]) # build manifest string s = m.to_string() # make filecount higher than files in list s2 = re.sub(b'Filelist 3', b'Filelist 5', s) m2 = manifest.Manifest().from_string(s2) assert hasattr(m2, u'corrupt_filelist')
def get_local_manifest(self): """ Return manifest object by reading local manifest file """ assert self.local_manifest_path manifest_buffer = self.local_manifest_path.get_data() return manifest.Manifest().from_string(manifest_buffer)
def get_local_manifest(self): """ Return manifest object by reading local manifest file """ assert self.local_manifest_path manifest_buffer = self.local_manifest_path.get_data() log.Info(_("Processing local manifest %s (%s)") % ( self.local_manifest_path.name, len(manifest_buffer))) return manifest.Manifest().from_string(manifest_buffer)
def test_basic(self): vi1 = manifest.VolumeInfo() vi1.set_info(3, ("hello", ), None, (), None) vi2 = manifest.VolumeInfo() vi2.set_info(4, ("goodbye", "there"), None, ("aoeusht", ), None) vi3 = manifest.VolumeInfo() vi3.set_info(34, (), None, (), None) m = manifest.Manifest() for vi in [vi1, vi2, vi3]: m.add_volume_info(vi) self.set_global('local_path', path.Path("Foobar")) m.set_dirinfo() s = m.to_string() assert s.lower().startswith("hostname") assert s.endswith("\n") m2 = manifest.Manifest().from_string(s) assert m == m2
def get_remote_manifest(self): """ Return manifest by reading remote manifest on backend """ assert self.remote_manifest_name try: manifest_buffer = self.backend.get_data(self.remote_manifest_name) except GPGError as message: log.Error(_("Error processing remote manifest (%s): %s") % (util.ufn(self.remote_manifest_name), util.uexc(message))) return None log.Info(_("Processing remote manifest %s (%s)") % ( util.ufn(self.remote_manifest_name), len(manifest_buffer))) return manifest.Manifest().from_string(manifest_buffer)
def get_remote_manifest(self): """ Return manifest by reading remote manifest on backend """ assert self.remote_manifest_name # Following by MDR. Should catch if remote encrypted with # public key w/o secret key try: manifest_buffer = self.backend.get_data(self.remote_manifest_name) except GPGError as message: # TODO: We check for gpg v1 and v2 messages, should be an error code if ("secret key not available" in message.args[0] or "No secret key" in message.args[0]): return None else: raise return manifest.Manifest().from_string(manifest_buffer)
def test_hostname_checks(self): self.set_config(u'hostname', u'hostname') self.set_config(u'fqdn', u'fqdn') m = manifest.Manifest() # Matching hostname should work m.hostname = u'hostname' m.check_dirinfo() # Matching fqdn should also work for backwards compatibility m.hostname = u'fqdn' m.check_dirinfo() # Bad match should throw a fatal error and quit m.hostname = u'foobar' self.assertRaises(SystemExit, m.check_dirinfo) # But not if we tell the system to ignore it self.set_config(u'allow_source_mismatch', True) m.check_dirinfo()
class BackupSet: """ Backup set - the backup information produced by one session """ def __init__(self, backend): """ Initialize new backup set, only backend is required at first """ self.backend = backend self.info_set = False # true if fields are set self.volume_name_dict = {} # dict from volume number to filename self.remote_manifest_name = None # full name of remote manifest self.local_manifest_path = None # full path to local manifest self.time = None # will be set if is full backup set self.start_time = None # will be set if inc self.end_time = None # will be set if inc self.partial = False # true if a partial backup self.encrypted = False # true if an encrypted backup def is_complete(self): """ Assume complete if found manifest file """ return self.remote_manifest_name def add_filename(self, filename): """ Add a filename to given set. Return true if it fits. The filename will match the given set if it has the right times and is of the right type. The information will be set from the first filename given. @param filename: name of file to add @type filename: string """ pr = file_naming.parse(filename) if not pr or not (pr.type == "full" or pr.type == "inc"): return False if not self.info_set: self.set_info(pr) else: if pr.type != self.type: return False if pr.time != self.time: return False if (pr.start_time != self.start_time or pr.end_time != self.end_time): return False if bool(pr.encrypted) != bool(self.encrypted): if self.partial and pr.encrypted: self.encrypted = pr.encrypted if pr.manifest: self.set_manifest(filename) else: assert pr.volume_number is not None assert not self.volume_name_dict.has_key(pr.volume_number), \ (self.volume_name_dict, filename) self.volume_name_dict[pr.volume_number] = filename return True def set_info(self, pr): """ Set BackupSet information from ParseResults object @param pr: parse results @type pf: ParseResults """ assert not self.info_set self.type = pr.type self.time = pr.time self.start_time = pr.start_time self.end_time = pr.end_time self.time = pr.time self.partial = pr.partial self.encrypted = bool(pr.encrypted) self.info_set = True def set_manifest(self, remote_filename): """ Add local and remote manifest filenames to backup set """ assert not self.remote_manifest_name, (self.remote_manifest_name, remote_filename) self.remote_manifest_name = remote_filename for local_filename in globals.archive_dir.listdir(): pr = file_naming.parse(local_filename) if (pr and pr.manifest and pr.type == self.type and pr.time == self.time and pr.start_time == self.start_time and pr.end_time == self.end_time): self.local_manifest_path = \ globals.archive_dir.append(local_filename) break def delete(self): """ Remove all files in set, both local and remote """ rfn = self.get_filenames() rfn.reverse() try: self.backend.delete(rfn) except Exception: log.Debug("BackupSet.delete: missing %s" % rfn) pass for lfn in globals.archive_dir.listdir(): pr = file_naming.parse(lfn) if (pr and pr.time == self.time and pr.start_time == self.start_time and pr.end_time == self.end_time): try: globals.archive_dir.append(lfn).delete() except Exception: log.Debug("BackupSet.delete: missing %s" % lfn) pass def __str__(self): """ For now just list files in set """ filelist = [] if self.remote_manifest_name: filelist.append(self.remote_manifest_name) filelist.extend(self.volume_name_dict.values()) return "[%s]" % ", ".join(filelist) def get_timestr(self): """ Return time string suitable for log statements """ return dup_time.timetopretty(self.time or self.end_time) def check_manifests(self): """ Make sure remote manifest is equal to local one """ if not self.remote_manifest_name and not self.local_manifest_path: log.FatalError(_("Fatal Error: No manifests found for most recent backup"), log.ErrorCode.no_manifests) assert self.remote_manifest_name, "if only one, should be remote" remote_manifest = self.get_remote_manifest() if self.local_manifest_path: local_manifest = self.get_local_manifest() if remote_manifest and self.local_manifest_path and local_manifest: if remote_manifest != local_manifest: log.FatalError(_("Fatal Error: Remote manifest does not match " "local one. Either the remote backup set or " "the local archive directory has been corrupted."), log.ErrorCode.mismatched_manifests) if not remote_manifest: if self.local_manifest_path: remote_manifest = local_manifest else: log.FatalError(_("Fatal Error: Neither remote nor local " "manifest is readable."), log.ErrorCode.unreadable_manifests) remote_manifest.check_dirinfo() def get_local_manifest(self): """ Return manifest object by reading local manifest file """ assert self.local_manifest_path manifest_buffer = self.local_manifest_path.get_data() return manifest.Manifest().from_string(manifest_buffer) def get_remote_manifest(self): """ Return manifest by reading remote manifest on backend """ assert self.remote_manifest_name # Following by MDR. Should catch if remote encrypted with # public key w/o secret key try: manifest_buffer = self.backend.get_data(self.remote_manifest_name) except GPGError, message: #TODO: We check for gpg v1 and v2 messages, should be an error code. if ("secret key not available" in message.args[0] or "No secret key" in message.args[0]): return None else: raise return manifest.Manifest().from_string(manifest_buffer)