mirror of https://github.com/borgbackup/borg.git
[FEATURE] #4489 – Deprecate --nobsdflags option
Replaced by --noflags. In internal data structure the key 'bsdflags' is kept for backwards compatibility.
This commit is contained in:
parent
e388fabd5b
commit
08a7661e67
|
@ -19,7 +19,7 @@ BorgBackup is not run with root privileges.
|
|||
SSHFS is a FUSE file system and uses the SFTP protocol, so there may be also
|
||||
other unsupported features that the actual implementations of ssfs, libfuse and
|
||||
sftp on the backup server do not support, like file name encodings, ACLs, xattrs
|
||||
or bsdflags. So there is no guarantee that you are able to restore a system
|
||||
or flags. So there is no guarantee that you are able to restore a system
|
||||
completely in every aspect from such a backup.
|
||||
|
||||
.. warning::
|
||||
|
|
|
@ -563,7 +563,7 @@ dictionary created by the ``Item`` class that contains:
|
|||
* mtime, atime, ctime in nanoseconds
|
||||
* xattrs
|
||||
* acl (various OS-dependent fields)
|
||||
* bsdflags
|
||||
* flags
|
||||
|
||||
All items are serialized using msgpack and the resulting byte stream
|
||||
is fed into the same chunker algorithm as used for regular file data
|
||||
|
|
|
@ -71,15 +71,15 @@ affect metadata stream deduplication: if only this timestamp changes between
|
|||
backups and is stored into the metadata stream, the metadata stream chunks
|
||||
won't deduplicate just because of that.
|
||||
|
||||
``--nobsdflags``
|
||||
~~~~~~~~~~~~~~~~
|
||||
``--nobsdflags / --noflags``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can use this to not query and store (or not extract and set) bsdflags -
|
||||
in case you don't need them or if they are broken somehow for your fs.
|
||||
You can use this to not query and store (or not extract and set) flags - in case
|
||||
you don't need them or if they are broken somehow for your fs.
|
||||
|
||||
On Linux, dealing with the bsflags needs some additional syscalls.
|
||||
Especially when dealing with lots of small files, this causes a noticable
|
||||
overhead, so you can use this option also for speeding up operations.
|
||||
On Linux, dealing with the flags needs some additional syscalls. Especially when
|
||||
dealing with lots of small files, this causes a noticable overhead, so you can
|
||||
use this option also for speeding up operations.
|
||||
|
||||
``--umask``
|
||||
~~~~~~~~~~~
|
||||
|
|
|
@ -75,10 +75,10 @@ _borg()
|
|||
local opts="-e --encryption --append-only --storage-quota --make-parent-dirs ${common_opts}"
|
||||
;;
|
||||
*' create '*)
|
||||
local opts="-n --dry-run -s --stats --list --filter --json --no-cache-sync --stdin-name -e --exclude --exclude-from --pattern --patterns-from --exclude-caches --exclude-if-present --keep-exclude-tags --exclude-nodump -x --one-file-system --numeric-owner --noatime --noctime --nobirthtime --nobsdflags --files-cache --read-special --comment --timestamp -c --checkpoint-interval --chunker-params -C --compression ${common_opts}"
|
||||
local opts="-n --dry-run -s --stats --list --filter --json --no-cache-sync --stdin-name -e --exclude --exclude-from --pattern --patterns-from --exclude-caches --exclude-if-present --keep-exclude-tags --exclude-nodump -x --one-file-system --numeric-owner --noatime --noctime --nobirthtime --nobsdflags --noflags --files-cache --read-special --comment --timestamp -c --checkpoint-interval --chunker-params -C --compression ${common_opts}"
|
||||
;;
|
||||
*' extract '*)
|
||||
local opts="--list -n --dry-run --numeric-owner --nobsdflags --stdout --sparse -e --exclude --exclude-from --pattern --patterns-from --strip-components ${common_opts}"
|
||||
local opts="--list -n --dry-run --numeric-owner --nobsdflags --noflags --stdout --sparse -e --exclude --exclude-from --pattern --patterns-from --strip-components ${common_opts}"
|
||||
;;
|
||||
*' check '*)
|
||||
local opts="--repository-only --archives-only --verify-data --repair --save-space --max-duration -P --prefix -a --glob-archives --sort-by --first --last ${common_opts}"
|
||||
|
|
|
@ -117,6 +117,7 @@ complete -c borg -f -l 'noatime' -d 'Do not store atime'
|
|||
complete -c borg -f -l 'noctime' -d 'Do not store ctime' -n "__fish_seen_subcommand_from create"
|
||||
complete -c borg -f -l 'nobirthtime' -d 'Do not store creation date' -n "__fish_seen_subcommand_from create"
|
||||
complete -c borg -f -l 'nobsdflags' -d 'Do not store bsdflags' -n "__fish_seen_subcommand_from create"
|
||||
complete -c borg -f -l 'noflags' -d 'Do not store flags' -n "__fish_seen_subcommand_from create"
|
||||
set -l files_cache_mode "ctime,size,inode mtime,size,inode ctime,size mtime,size rechunk,ctime rechunk,mtime disabled"
|
||||
complete -c borg -f -l 'files-cache' -d 'Operate files cache in MODE' -a "$files_cache_mode" -n "__fish_seen_subcommand_from create"
|
||||
complete -c borg -f -l 'read-special' -d 'Open device files like regular files' -n "__fish_seen_subcommand_from create"
|
||||
|
@ -134,6 +135,7 @@ complete -c borg -f -l 'list' -d 'Print verbose list of it
|
|||
complete -c borg -f -s n -l 'dry-run' -d 'Do not actually extract any files' -n "__fish_seen_subcommand_from extract"
|
||||
complete -c borg -f -l 'numeric-owner' -d 'Only obey numeric user:group identifiers' -n "__fish_seen_subcommand_from extract"
|
||||
complete -c borg -f -l 'nobsdflags' -d 'Do not extract/set bsdflags' -n "__fish_seen_subcommand_from extract"
|
||||
complete -c borg -f -l 'noflags' -d 'Do not extract/set flags' -n "__fish_seen_subcommand_from extract"
|
||||
complete -c borg -f -l 'stdout' -d 'Write all extracted data to stdout' -n "__fish_seen_subcommand_from extract"
|
||||
complete -c borg -f -l 'sparse' -d 'Create holes in output sparse file' -n "__fish_seen_subcommand_from extract"
|
||||
# Exclusion options
|
||||
|
|
|
@ -101,6 +101,7 @@ _borg() {
|
|||
--noatime'[do not store atime into archive]'\
|
||||
--nobirthtime'[do not store birthtime (creation date) into archive]'\
|
||||
--nobsdflags'[do not read and store bsdflags (e.g. NODUMP, IMMUTABLE) into archive]'\
|
||||
--noflags'[do not read and store flags (e.g. NODUMP, IMMUTABLE) into archive]'\
|
||||
--files-cache'[operate files cache in MODE. default: ctime,size,inode]:mode:(ctime,size,inode mtime,size,inode ctime,size mtime,size rechunk,ctime rechunk,mtime disabled)'\
|
||||
--read-special'[open and read block and char device files as well as FIFOs as if they were regular files.]'\
|
||||
--comment'[add a comment text to the archive]:COMMENT'\
|
||||
|
@ -119,6 +120,7 @@ _borg() {
|
|||
{-n,--dry-run}'[do not actually change any files]'\
|
||||
--numeric-owner'[only obey numeric user and group identifiers]'\
|
||||
--nobsdflags'[do not extract/set bsdflags (e.g. NODUMP, IMMUTABLE)]'\
|
||||
--noflags'[do not extract/set flags (e.g. NODUMP, IMMUTABLE)]'\
|
||||
--stdout'[write all extracted data to stdout]'\
|
||||
--sparse'[create holes in output sparse file from all-zero chunks]'\
|
||||
{-e,--exclude}'[exclude paths matching PATTERN]:PATTERN'\
|
||||
|
|
|
@ -375,7 +375,7 @@ class Archive:
|
|||
"""Failed to encode filename "{}" into file system encoding "{}". Consider configuring the LANG environment variable."""
|
||||
|
||||
def __init__(self, repository, key, manifest, name, cache=None, create=False,
|
||||
checkpoint_interval=1800, numeric_owner=False, noatime=False, noctime=False, nobsdflags=False,
|
||||
checkpoint_interval=1800, numeric_owner=False, noatime=False, noctime=False, noflags=False,
|
||||
progress=False, chunker_params=CHUNKER_PARAMS, start=None, start_monotonic=None, end=None,
|
||||
consider_part_files=False, log_json=False):
|
||||
self.cwd = os.getcwd()
|
||||
|
@ -393,7 +393,7 @@ class Archive:
|
|||
self.numeric_owner = numeric_owner
|
||||
self.noatime = noatime
|
||||
self.noctime = noctime
|
||||
self.nobsdflags = nobsdflags
|
||||
self.noflags = noflags
|
||||
assert (start is None) == (start_monotonic is None), 'Logic error: if start is given, start_monotonic must be given as well and vice versa.'
|
||||
if start is None:
|
||||
start = datetime.utcnow()
|
||||
|
@ -846,7 +846,7 @@ Utilization of max. archive size: {csize_max:.0%}
|
|||
if warning:
|
||||
set_ec(EXIT_WARNING)
|
||||
# bsdflags include the immutable flag and need to be set last:
|
||||
if not self.nobsdflags and 'bsdflags' in item:
|
||||
if not self.noflags and 'bsdflags' in item:
|
||||
try:
|
||||
set_flags(path, item.bsdflags, fd=fd)
|
||||
except OSError:
|
||||
|
@ -1025,11 +1025,11 @@ Utilization of max. archive size: {csize_max:.0%}
|
|||
|
||||
|
||||
class MetadataCollector:
|
||||
def __init__(self, *, noatime, noctime, numeric_owner, nobsdflags, nobirthtime):
|
||||
def __init__(self, *, noatime, noctime, numeric_owner, noflags, nobirthtime):
|
||||
self.noatime = noatime
|
||||
self.noctime = noctime
|
||||
self.numeric_owner = numeric_owner
|
||||
self.nobsdflags = nobsdflags
|
||||
self.noflags = noflags
|
||||
self.nobirthtime = nobirthtime
|
||||
|
||||
def stat_simple_attrs(self, st):
|
||||
|
@ -1058,16 +1058,16 @@ class MetadataCollector:
|
|||
|
||||
def stat_ext_attrs(self, st, path, fd=None):
|
||||
attrs = {}
|
||||
bsdflags = 0
|
||||
flags = 0
|
||||
with backup_io('extended stat'):
|
||||
if not self.nobsdflags:
|
||||
bsdflags = get_flags(path, st, fd=fd)
|
||||
if not self.noflags:
|
||||
flags = get_flags(path, st, fd=fd)
|
||||
xattrs = xattr.get_all(fd or path, follow_symlinks=False)
|
||||
acl_get(path, attrs, st, self.numeric_owner, fd=fd)
|
||||
if xattrs:
|
||||
attrs['xattrs'] = StableDict(xattrs)
|
||||
if bsdflags:
|
||||
attrs['bsdflags'] = bsdflags
|
||||
if flags:
|
||||
attrs['bsdflags'] = flags
|
||||
return attrs
|
||||
|
||||
def stat_attrs(self, st, path, fd=None):
|
||||
|
|
|
@ -175,7 +175,7 @@ def with_archive(method):
|
|||
def wrapper(self, args, repository, key, manifest, **kwargs):
|
||||
archive = Archive(repository, key, manifest, args.location.archive,
|
||||
numeric_owner=getattr(args, 'numeric_owner', False),
|
||||
nobsdflags=getattr(args, 'nobsdflags', False),
|
||||
noflags=getattr(args, 'nobsdflags', False) or getattr(args, 'noflags', False),
|
||||
cache=kwargs.get('cache'),
|
||||
consider_part_files=args.consider_part_files, log_json=args.log_json)
|
||||
return method(self, args, repository=repository, manifest=manifest, key=key, archive=archive, **kwargs)
|
||||
|
@ -557,7 +557,7 @@ class Archiver:
|
|||
|
||||
self.output_filter = args.output_filter
|
||||
self.output_list = args.output_list
|
||||
self.nobsdflags = args.nobsdflags
|
||||
self.noflags = args.nobsdflags or args.noflags
|
||||
self.exclude_nodump = args.exclude_nodump
|
||||
dry_run = args.dry_run
|
||||
t0 = datetime.utcnow()
|
||||
|
@ -574,7 +574,7 @@ class Archiver:
|
|||
chunker_params=args.chunker_params, start=t0, start_monotonic=t0_monotonic,
|
||||
log_json=args.log_json)
|
||||
metadata_collector = MetadataCollector(noatime=not args.atime, noctime=args.noctime,
|
||||
nobsdflags=args.nobsdflags, numeric_owner=args.numeric_owner, nobirthtime=args.nobirthtime)
|
||||
noflags=args.nobsdflags or args.noflags, numeric_owner=args.numeric_owner, nobirthtime=args.nobirthtime)
|
||||
cp = ChunksProcessor(cache=cache, key=key,
|
||||
add_item=archive.add_item, write_checkpoint=archive.write_checkpoint,
|
||||
checkpoint_interval=args.checkpoint_interval, rechunkify=False)
|
||||
|
@ -2370,7 +2370,8 @@ class Archiver:
|
|||
def preprocess_args(self, args):
|
||||
deprecations = [
|
||||
# ('--old', '--new' or None, 'Warning: "--old" has been deprecated. Use "--new" instead.'),
|
||||
('--noatime', None, 'Warning: "--noatime" has been deprecated because it is the default now.')
|
||||
('--noatime', None, 'Warning: "--noatime" has been deprecated because it is the default now.'),
|
||||
('--nobsdflags', None, 'Warning: "--nobsdflags" has been deprecated. Use --noflags instead.')
|
||||
]
|
||||
for i, arg in enumerate(args[:]):
|
||||
for old_name, new_name, warning in deprecations:
|
||||
|
@ -3133,7 +3134,9 @@ class Archiver:
|
|||
fs_group.add_argument('--nobirthtime', dest='nobirthtime', action='store_true',
|
||||
help='do not store birthtime (creation date) into archive')
|
||||
fs_group.add_argument('--nobsdflags', dest='nobsdflags', action='store_true',
|
||||
help='do not read and store bsdflags (e.g. NODUMP, IMMUTABLE) into archive')
|
||||
help='deprecated, use ``--noflags`` instead')
|
||||
fs_group.add_argument('--noflags', dest='noflags', action='store_true',
|
||||
help='do not read and store flags (e.g. NODUMP, IMMUTABLE) into archive')
|
||||
fs_group.add_argument('--files-cache', metavar='MODE', dest='files_cache_mode',
|
||||
type=FilesCacheMode, default=DEFAULT_FILES_CACHE_MODE_UI,
|
||||
help='operate files cache in MODE. default: %s' % DEFAULT_FILES_CACHE_MODE_UI)
|
||||
|
@ -3526,7 +3529,9 @@ class Archiver:
|
|||
subparser.add_argument('--numeric-owner', dest='numeric_owner', action='store_true',
|
||||
help='only obey numeric user and group identifiers')
|
||||
subparser.add_argument('--nobsdflags', dest='nobsdflags', action='store_true',
|
||||
help='do not extract/set bsdflags (e.g. NODUMP, IMMUTABLE)')
|
||||
help='deprecated, use ``--noflags`` instead')
|
||||
subparser.add_argument('--noflags', dest='noflags', action='store_true',
|
||||
help='do not extract/set flags (e.g. NODUMP, IMMUTABLE)')
|
||||
subparser.add_argument('--stdout', dest='stdout', action='store_true',
|
||||
help='write all extracted data to stdout')
|
||||
subparser.add_argument('--sparse', dest='sparse', action='store_true',
|
||||
|
|
|
@ -186,7 +186,7 @@ class BaseTestCase(unittest.TestCase):
|
|||
diff = filecmp.dircmp(dir1, dir2)
|
||||
self._assert_dirs_equal_cmp(diff, **kwargs)
|
||||
|
||||
def _assert_dirs_equal_cmp(self, diff, ignore_bsdflags=False, ignore_xattrs=False, ignore_ns=False):
|
||||
def _assert_dirs_equal_cmp(self, diff, ignore_flags=False, ignore_xattrs=False, ignore_ns=False):
|
||||
self.assert_equal(diff.left_only, [])
|
||||
self.assert_equal(diff.right_only, [])
|
||||
self.assert_equal(diff.diff_files, [])
|
||||
|
@ -206,7 +206,7 @@ class BaseTestCase(unittest.TestCase):
|
|||
d2 = [filename] + [getattr(s2, a) for a in attrs]
|
||||
d1.insert(1, oct(s1.st_mode))
|
||||
d2.insert(1, oct(s2.st_mode))
|
||||
if not ignore_bsdflags:
|
||||
if not ignore_flags:
|
||||
d1.append(get_flags(path1, s1))
|
||||
d2.append(get_flags(path2, s2))
|
||||
# ignore st_rdev if file is not a block/char device, fixes #203
|
||||
|
@ -232,7 +232,7 @@ class BaseTestCase(unittest.TestCase):
|
|||
d2.append(no_selinux(get_all(path2, follow_symlinks=False)))
|
||||
self.assert_equal(d1, d2)
|
||||
for sub_diff in diff.subdirs.values():
|
||||
self._assert_dirs_equal_cmp(sub_diff, ignore_bsdflags=ignore_bsdflags, ignore_xattrs=ignore_xattrs, ignore_ns=ignore_ns)
|
||||
self._assert_dirs_equal_cmp(sub_diff, ignore_flags=ignore_flags, ignore_xattrs=ignore_xattrs, ignore_ns=ignore_ns)
|
||||
|
||||
@contextmanager
|
||||
def fuse_mount(self, location, mountpoint, *options):
|
||||
|
|
|
@ -2182,16 +2182,16 @@ class ArchiverTestCase(ArchiverTestCaseBase):
|
|||
mountpoint = os.path.join(self.tmpdir, 'mountpoint')
|
||||
# mount the whole repository, archive contents shall show up in archivename subdirs of mountpoint:
|
||||
with self.fuse_mount(self.repository_location, mountpoint):
|
||||
# bsdflags are not supported by the FUSE mount
|
||||
# flags are not supported by the FUSE mount
|
||||
# we also ignore xattrs here, they are tested separately
|
||||
self.assert_dirs_equal(self.input_path, os.path.join(mountpoint, 'archive', 'input'),
|
||||
ignore_bsdflags=True, ignore_xattrs=True)
|
||||
ignore_flags=True, ignore_xattrs=True)
|
||||
self.assert_dirs_equal(self.input_path, os.path.join(mountpoint, 'archive2', 'input'),
|
||||
ignore_bsdflags=True, ignore_xattrs=True)
|
||||
ignore_flags=True, ignore_xattrs=True)
|
||||
# mount only 1 archive, its contents shall show up directly in mountpoint:
|
||||
with self.fuse_mount(self.repository_location + '::archive', mountpoint):
|
||||
self.assert_dirs_equal(self.input_path, os.path.join(mountpoint, 'input'),
|
||||
ignore_bsdflags=True, ignore_xattrs=True)
|
||||
ignore_flags=True, ignore_xattrs=True)
|
||||
# regular file
|
||||
in_fn = 'input/file1'
|
||||
out_fn = os.path.join(mountpoint, 'input', 'file1')
|
||||
|
@ -2896,7 +2896,7 @@ id: 2 / e29442 3506da 4e1ea7 / 25f62a 5a3d41 - 02
|
|||
with changedir('output'):
|
||||
# This probably assumes GNU tar. Note -p switch to extract permissions regardless of umask.
|
||||
subprocess.check_call(['tar', 'xpf', '../simple.tar', '--warning=no-timestamp'])
|
||||
self.assert_dirs_equal('input', 'output/input', ignore_bsdflags=True, ignore_xattrs=True, ignore_ns=True)
|
||||
self.assert_dirs_equal('input', 'output/input', ignore_flags=True, ignore_xattrs=True, ignore_ns=True)
|
||||
|
||||
@requires_gnutar
|
||||
@requires_gzip
|
||||
|
@ -2912,7 +2912,7 @@ id: 2 / e29442 3506da 4e1ea7 / 25f62a 5a3d41 - 02
|
|||
assert 'input/dir2\n' in list
|
||||
with changedir('output'):
|
||||
subprocess.check_call(['tar', 'xpf', '../simple.tar.gz', '--warning=no-timestamp'])
|
||||
self.assert_dirs_equal('input', 'output/input', ignore_bsdflags=True, ignore_xattrs=True, ignore_ns=True)
|
||||
self.assert_dirs_equal('input', 'output/input', ignore_flags=True, ignore_xattrs=True, ignore_ns=True)
|
||||
|
||||
@requires_gnutar
|
||||
def test_export_tar_strip_components(self):
|
||||
|
@ -2928,7 +2928,7 @@ id: 2 / e29442 3506da 4e1ea7 / 25f62a 5a3d41 - 02
|
|||
assert 'input/dir2\n' in list
|
||||
with changedir('output'):
|
||||
subprocess.check_call(['tar', 'xpf', '../simple.tar', '--warning=no-timestamp'])
|
||||
self.assert_dirs_equal('input', 'output/', ignore_bsdflags=True, ignore_xattrs=True, ignore_ns=True)
|
||||
self.assert_dirs_equal('input', 'output/', ignore_flags=True, ignore_xattrs=True, ignore_ns=True)
|
||||
|
||||
@requires_hardlinks
|
||||
@requires_gnutar
|
||||
|
|
Loading…
Reference in New Issue