Exemplo n.º 1
0
    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')
Exemplo n.º 2
0
 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)
Exemplo n.º 3
0
 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)
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
 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)
Exemplo n.º 6
0
 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()
Exemplo n.º 8
0
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)