diff options
author | Lars Wirzenius <liw@liw.fi> | 2015-08-19 19:12:19 +0200 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2015-08-19 19:58:32 +0200 |
commit | 8b39988d0cccff274a7bf7e36448dcc7216c2ea3 (patch) | |
tree | b3dec8118cf8540bdbf804f0cbfcf51f3dadaea4 | |
parent | 7e462bae7d53f08ed6079c522bbe237bbc1c3cc5 (diff) | |
download | obnam-8b39988d0cccff274a7bf7e36448dcc7216c2ea3.tar.gz |
Add get_metadata_from_file_keys and use it
-rw-r--r-- | obnamlib/__init__.py | 3 | ||||
-rw-r--r-- | obnamlib/delegator.py | 5 | ||||
-rw-r--r-- | obnamlib/fmt_ga/client.py | 57 | ||||
-rw-r--r-- | obnamlib/plugins/backup_plugin.py | 18 | ||||
-rw-r--r-- | obnamlib/plugins/fuse_plugin.py | 33 | ||||
-rw-r--r-- | obnamlib/plugins/restore_plugin.py | 31 | ||||
-rw-r--r-- | obnamlib/repo_interface.py | 65 |
7 files changed, 91 insertions, 121 deletions
diff --git a/obnamlib/__init__.py b/obnamlib/__init__.py index 9f2792f7..e4ecfd0e 100644 --- a/obnamlib/__init__.py +++ b/obnamlib/__init__.py @@ -168,7 +168,8 @@ from repo_interface import ( REPO_FILE_DEV, REPO_FILE_INO, REPO_FILE_MD5, - REPO_FILE_INTEGER_KEYS) + REPO_FILE_INTEGER_KEYS, + metadata_file_key_mapping) from .delegator import RepositoryDelegator, GenerationId diff --git a/obnamlib/delegator.py b/obnamlib/delegator.py index e477d706..78eccc98 100644 --- a/obnamlib/delegator.py +++ b/obnamlib/delegator.py @@ -220,6 +220,11 @@ class RepositoryDelegator(obnamlib.RepositoryInterface): client = self._lookup_client_by_generation(generation_id) return client.remove_file(generation_id.gen_number, filename) + def get_metadata_from_file_keys(self, generation_id, filename): + client = self._lookup_client_by_generation(generation_id) + return client.get_metadata_from_file_keys( + generation_id.gen_number, filename) + def get_file_key(self, generation_id, filename, key): if key not in self.get_allowed_file_keys(): raise obnamlib.RepositoryFileKeyNotAllowed( diff --git a/obnamlib/fmt_ga/client.py b/obnamlib/fmt_ga/client.py index 95f4ac73..66a71ab5 100644 --- a/obnamlib/fmt_ga/client.py +++ b/obnamlib/fmt_ga/client.py @@ -262,6 +262,14 @@ class GAClient(object): genspec=gen_number, filename=filename) + def get_metadata_from_file_keys(self, gen_number, filename): + self._load_data() + self._require_file_exists(gen_number, filename) + + generation = self._lookup_generation_by_gen_number(gen_number) + metadata_obj = generation.get_file_metadata() + return metadata_obj.get_metadata_from_file_keys(filename) + def set_file_key(self, gen_number, filename, key, value): self._load_data() generation = self._lookup_generation_by_gen_number(gen_number) @@ -523,27 +531,34 @@ class GAFileMetadata(object): else: return None - def set_file_keys_from_metadata(self, filename, file_metadata): - mapping = [ - (obnamlib.REPO_FILE_MODE, 'st_mode'), - (obnamlib.REPO_FILE_MTIME_SEC, 'st_mtime_sec'), - (obnamlib.REPO_FILE_MTIME_NSEC, 'st_mtime_nsec'), - (obnamlib.REPO_FILE_ATIME_SEC, 'st_atime_sec'), - (obnamlib.REPO_FILE_ATIME_NSEC, 'st_atime_nsec'), - (obnamlib.REPO_FILE_NLINK, 'st_nlink'), - (obnamlib.REPO_FILE_SIZE, 'st_size'), - (obnamlib.REPO_FILE_UID, 'st_uid'), - (obnamlib.REPO_FILE_USERNAME, 'username'), - (obnamlib.REPO_FILE_GID, 'st_gid'), - (obnamlib.REPO_FILE_GROUPNAME, 'groupname'), - (obnamlib.REPO_FILE_SYMLINK_TARGET, 'target'), - (obnamlib.REPO_FILE_XATTR_BLOB, 'xattr'), - (obnamlib.REPO_FILE_BLOCKS, 'st_blocks'), - (obnamlib.REPO_FILE_DEV, 'st_dev'), - (obnamlib.REPO_FILE_INO, 'st_ino'), - (obnamlib.REPO_FILE_MD5, 'md5'), - ] + def get_metadata_from_file_keys(self, filename): + if filename in self._added_files: + return self._make_metadata( + lambda key: self._added_files.get_file_key(filename, key)) + else: + dir_obj, dir_path, basename = self._get_dir_obj(filename) + # We've already verifed the file exists, so we don't need + # to handle the case where dir_obj is None. + assert dir_obj is not None + + return self._make_metadata( + lambda key: dir_obj.get_file_key(basename, key)) + def _make_metadata(self, get_value): + metadata = obnamlib.Metadata() + + for key, field in obnamlib.metadata_file_key_mapping: + value = get_value(key) + if value is None: + if key in obnamlib.REPO_FILE_INTEGER_KEYS: + value = 0 + else: + value = '' + setattr(metadata, field, value) + + return metadata + + def set_file_keys_from_metadata(self, filename, file_metadata): if filename in self._added_files: self._added_files.set_file_key( filename, obnamlib.REPO_FILE_MODE, file_metadata.st_mode) @@ -553,7 +568,7 @@ class GAFileMetadata(object): if not dir_obj: return False - for key, field in mapping: + for key, field in obnamlib.metadata_file_key_mapping: value = getattr(file_metadata, field) dir_obj.set_file_key(basename, key, value) diff --git a/obnamlib/plugins/backup_plugin.py b/obnamlib/plugins/backup_plugin.py index 15dcf21f..09ea3387 100644 --- a/obnamlib/plugins/backup_plugin.py +++ b/obnamlib/plugins/backup_plugin.py @@ -808,23 +808,7 @@ class BackupPlugin(obnamlib.ObnamPlugin): return False def get_metadata_from_generation(self, gen, pathname): - return obnamlib.Metadata( - st_mtime_sec=self.repo.get_file_key( - gen, pathname, obnamlib.REPO_FILE_MTIME_SEC), - st_mtime_nsec=self.repo.get_file_key( - gen, pathname, obnamlib.REPO_FILE_MTIME_NSEC), - st_mode=self.repo.get_file_key( - gen, pathname, obnamlib.REPO_FILE_MODE), - st_nlink=self.repo.get_file_key( - gen, pathname, obnamlib.REPO_FILE_NLINK), - st_size=self.repo.get_file_key( - gen, pathname, obnamlib.REPO_FILE_SIZE), - st_uid=self.repo.get_file_key( - gen, pathname, obnamlib.REPO_FILE_UID), - st_gid=self.repo.get_file_key( - gen, pathname, obnamlib.REPO_FILE_GID), - xattr=self.repo.get_file_key( - gen, pathname, obnamlib.REPO_FILE_XATTR_BLOB)) + return self.repo.get_metadata_from_file_keys(gen, pathname) def add_file_to_generation(self, filename, metadata): self.repo.add_file(self.new_generation, filename) diff --git a/obnamlib/plugins/fuse_plugin.py b/obnamlib/plugins/fuse_plugin.py index 2bf8d0a7..a52b77d6 100644 --- a/obnamlib/plugins/fuse_plugin.py +++ b/obnamlib/plugins/fuse_plugin.py @@ -282,8 +282,8 @@ class ObnamFuse(fuse.Fuse): def get_metadata_in_generation(self, path): tracing.trace('path=%r', path) - metadata = self.construct_metadata_object( - self.obnam.repo, *self.get_gen_path(path)) + gen, filename = self.get_gen_path(path) + metadata = self.obnam.repo.get_metadata_from_file_keys(gen, filename) # FUSE does not allow negative timestamps, truncate to zero if metadata.st_atime_sec < 0: @@ -293,35 +293,6 @@ class ObnamFuse(fuse.Fuse): return metadata - def construct_metadata_object(self, repo, gen, filename): - allowed = set(repo.get_allowed_file_keys()) - - def K(key): - if key in allowed: - return repo.get_file_key(gen, filename, key) - else: - return None - - return obnamlib.Metadata( - st_atime_sec=K(obnamlib.REPO_FILE_ATIME_SEC), - st_atime_nsec=K(obnamlib.REPO_FILE_ATIME_NSEC), - st_mtime_sec=K(obnamlib.REPO_FILE_MTIME_SEC), - st_mtime_nsec=K(obnamlib.REPO_FILE_MTIME_NSEC), - st_blocks=K(obnamlib.REPO_FILE_BLOCKS), - st_dev=K(obnamlib.REPO_FILE_DEV), - st_gid=K(obnamlib.REPO_FILE_GID), - st_ino=K(obnamlib.REPO_FILE_INO), - st_mode=K(obnamlib.REPO_FILE_MODE), - st_nlink=K(obnamlib.REPO_FILE_NLINK), - st_size=K(obnamlib.REPO_FILE_SIZE), - st_uid=K(obnamlib.REPO_FILE_UID), - username=K(obnamlib.REPO_FILE_USERNAME), - groupname=K(obnamlib.REPO_FILE_GROUPNAME), - target=K(obnamlib.REPO_FILE_SYMLINK_TARGET), - xattr=K(obnamlib.REPO_FILE_XATTR_BLOB), - md5=K(obnamlib.REPO_FILE_MD5), - ) - def get_stat_in_generation(self, path): tracing.trace('path=%r', path) metadata = self.get_metadata_in_generation(path) diff --git a/obnamlib/plugins/restore_plugin.py b/obnamlib/plugins/restore_plugin.py index 3f85d74f..71266b62 100644 --- a/obnamlib/plugins/restore_plugin.py +++ b/obnamlib/plugins/restore_plugin.py @@ -198,42 +198,13 @@ class RestorePlugin(obnamlib.ObnamPlugin): self.app.ts['current'] = pathname self.restore_safely(gen, pathname) - def construct_metadata_object(self, gen, filename): - allowed = set(self.repo.get_allowed_file_keys()) - - def K(key): - if key in allowed: - return self.repo.get_file_key(gen, filename, key) - else: - return None - - return obnamlib.Metadata( - st_atime_sec=K(obnamlib.REPO_FILE_ATIME_SEC), - st_atime_nsec=K(obnamlib.REPO_FILE_ATIME_NSEC), - st_mtime_sec=K(obnamlib.REPO_FILE_MTIME_SEC), - st_mtime_nsec=K(obnamlib.REPO_FILE_MTIME_NSEC), - st_blocks=K(obnamlib.REPO_FILE_BLOCKS), - st_dev=K(obnamlib.REPO_FILE_DEV), - st_gid=K(obnamlib.REPO_FILE_GID), - st_ino=K(obnamlib.REPO_FILE_INO), - st_mode=K(obnamlib.REPO_FILE_MODE), - st_nlink=K(obnamlib.REPO_FILE_NLINK), - st_size=K(obnamlib.REPO_FILE_SIZE), - st_uid=K(obnamlib.REPO_FILE_UID), - username=K(obnamlib.REPO_FILE_USERNAME), - groupname=K(obnamlib.REPO_FILE_GROUPNAME), - target=K(obnamlib.REPO_FILE_SYMLINK_TARGET), - xattr=K(obnamlib.REPO_FILE_XATTR_BLOB), - md5=K(obnamlib.REPO_FILE_MD5), - ) - def restore_safely(self, gen, pathname): try: dirname = os.path.dirname(pathname) if self.write_ok and not self.fs.exists('./' + dirname): self.fs.makedirs('./' + dirname) - metadata = self.construct_metadata_object(gen, pathname) + metadata = self.repo.get_metadata_from_file_keys(gen, pathname) set_metadata = True if metadata.isdir(): diff --git a/obnamlib/repo_interface.py b/obnamlib/repo_interface.py index d0d1521a..f51dbc56 100644 --- a/obnamlib/repo_interface.py +++ b/obnamlib/repo_interface.py @@ -94,6 +94,28 @@ def repo_key_name(key_value): WRONG_KEY = -1 +# A mapping between file keys and obnamlib.Metadata object fields. +metadata_file_key_mapping = [ + (REPO_FILE_MODE, 'st_mode'), + (REPO_FILE_MTIME_SEC, 'st_mtime_sec'), + (REPO_FILE_MTIME_NSEC, 'st_mtime_nsec'), + (REPO_FILE_ATIME_SEC, 'st_atime_sec'), + (REPO_FILE_ATIME_NSEC, 'st_atime_nsec'), + (REPO_FILE_NLINK, 'st_nlink'), + (REPO_FILE_SIZE, 'st_size'), + (REPO_FILE_UID, 'st_uid'), + (REPO_FILE_USERNAME, 'username'), + (REPO_FILE_GID, 'st_gid'), + (REPO_FILE_GROUPNAME, 'groupname'), + (REPO_FILE_SYMLINK_TARGET, 'target'), + (REPO_FILE_XATTR_BLOB, 'xattr'), + (REPO_FILE_BLOCKS, 'st_blocks'), + (REPO_FILE_DEV, 'st_dev'), + (REPO_FILE_INO, 'st_ino'), + (REPO_FILE_MD5, 'md5'), +] + + class RepositoryClientListLockingFailed(obnamlib.ObnamError): msg = 'Repository client list could not be locked' @@ -681,7 +703,28 @@ class RepositoryInterface(object): ''' raise NotImplementedError() + def get_metadata_from_file_keys(self, generation_id, filename): + '''Return a Metadata constructed from the file's keys. + + This is equivalent to creating the Metadata object and calling + get_file_key for every allowed key and setting the + corresponding field in the Metadata object. It may be faster + on some repository formats, however. + + ''' + + metadata = obnamlib.Metadata() + + allowed = set(self.get_allowed_file_keys()) + for key, field in obnamlib.metadata_file_key_mapping: + if key in allowed: + value = self.get_file_key(generation_id, filename, key) + setattr(metadata, field, value) + + return metadata + def set_file_key(self, generation_id, filename, key, value): + '''Set value for a file key. It is an error to set the value for a file key if the file does @@ -698,28 +741,8 @@ class RepositoryInterface(object): ''' - mapping = [ - (REPO_FILE_MODE, 'st_mode'), - (REPO_FILE_MTIME_SEC, 'st_mtime_sec'), - (REPO_FILE_MTIME_NSEC, 'st_mtime_nsec'), - (REPO_FILE_ATIME_SEC, 'st_atime_sec'), - (REPO_FILE_ATIME_NSEC, 'st_atime_nsec'), - (REPO_FILE_NLINK, 'st_nlink'), - (REPO_FILE_SIZE, 'st_size'), - (REPO_FILE_UID, 'st_uid'), - (REPO_FILE_USERNAME, 'username'), - (REPO_FILE_GID, 'st_gid'), - (REPO_FILE_GROUPNAME, 'groupname'), - (REPO_FILE_SYMLINK_TARGET, 'target'), - (REPO_FILE_XATTR_BLOB, 'xattr'), - (REPO_FILE_BLOCKS, 'st_blocks'), - (REPO_FILE_DEV, 'st_dev'), - (REPO_FILE_INO, 'st_ino'), - (REPO_FILE_MD5, 'md5'), - ] - allowed = set(self.get_allowed_file_keys()) - for key, field in mapping: + for key, field in obnamlib.metadata_file_key_mapping: if key in allowed: self.set_file_key( generation_id, filename, key, getattr(metadata, field)) |