|
@@ -315,7 +315,8 @@ 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, nobirthtime=False, nobsdflags=False,
|
|
|
+ checkpoint_interval=1800, numeric_owner=False, noatime=False, noctime=False, nobirthtime=False,
|
|
|
+ nobsdflags=False, noacls=False, noxattrs=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()
|
|
@@ -335,6 +336,8 @@ class Archive:
|
|
|
self.noctime = noctime
|
|
|
self.nobirthtime = nobirthtime
|
|
|
self.nobsdflags = nobsdflags
|
|
|
+ self.noacls = noacls
|
|
|
+ self.noxattrs = noxattrs
|
|
|
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()
|
|
@@ -762,31 +765,33 @@ Utilization of max. archive size: {csize_max:.0%}
|
|
|
except OSError:
|
|
|
# some systems don't support calling utime on a symlink
|
|
|
pass
|
|
|
- acl_set(path, item, self.numeric_owner)
|
|
|
- # chown removes Linux capabilities, so set the extended attributes at the end, after chown, since they include
|
|
|
- # the Linux capabilities in the "security.capability" attribute.
|
|
|
- xattrs = item.get('xattrs', {})
|
|
|
- for k, v in xattrs.items():
|
|
|
- try:
|
|
|
- xattr.setxattr(fd or path, k, v, follow_symlinks=False)
|
|
|
- except OSError as e:
|
|
|
- msg_format = '%s: when setting extended attribute %s: %%s' % (path, k.decode())
|
|
|
- if e.errno == errno.E2BIG:
|
|
|
- err_str = 'too big for this filesystem'
|
|
|
- elif e.errno == errno.ENOTSUP:
|
|
|
- err_str = 'xattrs not supported on this filesystem'
|
|
|
- elif e.errno == errno.ENOSPC:
|
|
|
- # no space left on device while setting this specific xattr
|
|
|
- # ext4 reports ENOSPC when trying to set an xattr with >4kiB while ext4 can only support 4kiB xattrs
|
|
|
- # (in this case, this is NOT a "disk full" error, just a ext4 limitation).
|
|
|
- err_str = 'no space left on device [xattr len = %d]' % (len(v), )
|
|
|
- else:
|
|
|
- # generic handler
|
|
|
- # EACCES: permission denied to set this specific xattr (this may happen related to security.* keys)
|
|
|
- # EPERM: operation not permitted
|
|
|
- err_str = os.strerror(e.errno)
|
|
|
- logger.warning(msg_format % err_str)
|
|
|
- set_ec(EXIT_WARNING)
|
|
|
+ if not self.noacls:
|
|
|
+ acl_set(path, item, self.numeric_owner)
|
|
|
+ if not self.noxattrs:
|
|
|
+ # chown removes Linux capabilities, so set the extended attributes at the end, after chown, since they include
|
|
|
+ # the Linux capabilities in the "security.capability" attribute.
|
|
|
+ xattrs = item.get('xattrs', {})
|
|
|
+ for k, v in xattrs.items():
|
|
|
+ try:
|
|
|
+ xattr.setxattr(fd or path, k, v, follow_symlinks=False)
|
|
|
+ except OSError as e:
|
|
|
+ msg_format = '%s: when setting extended attribute %s: %%s' % (path, k.decode())
|
|
|
+ if e.errno == errno.E2BIG:
|
|
|
+ err_str = 'too big for this filesystem'
|
|
|
+ elif e.errno == errno.ENOTSUP:
|
|
|
+ err_str = 'xattrs not supported on this filesystem'
|
|
|
+ elif e.errno == errno.ENOSPC:
|
|
|
+ # no space left on device while setting this specific xattr
|
|
|
+ # ext4 reports ENOSPC when trying to set an xattr with >4kiB while ext4 can only support 4kiB xattrs
|
|
|
+ # (in this case, this is NOT a "disk full" error, just a ext4 limitation).
|
|
|
+ err_str = 'no space left on device [xattr len = %d]' % (len(v), )
|
|
|
+ else:
|
|
|
+ # generic handler
|
|
|
+ # EACCES: permission denied to set this specific xattr (this may happen related to security.* keys)
|
|
|
+ # EPERM: operation not permitted
|
|
|
+ err_str = os.strerror(e.errno)
|
|
|
+ logger.warning(msg_format % err_str)
|
|
|
+ set_ec(EXIT_WARNING)
|
|
|
# bsdflags include the immutable flag and need to be set last:
|
|
|
if not self.nobsdflags and 'bsdflags' in item:
|
|
|
try:
|
|
@@ -907,12 +912,11 @@ Utilization of max. archive size: {csize_max:.0%}
|
|
|
|
|
|
def stat_ext_attrs(self, st, path):
|
|
|
attrs = {}
|
|
|
- bsdflags = 0
|
|
|
with backup_io('extended stat'):
|
|
|
- xattrs = xattr.get_all(path, follow_symlinks=False)
|
|
|
- if not self.nobsdflags:
|
|
|
- bsdflags = get_flags(path, st)
|
|
|
- acl_get(path, attrs, st, self.numeric_owner)
|
|
|
+ xattrs = {} if self.noxattrs else xattr.get_all(path, follow_symlinks=False)
|
|
|
+ bsdflags = 0 if self.nobsdflags else get_flags(path, st)
|
|
|
+ if not self.noacls:
|
|
|
+ acl_get(path, attrs, st, self.numeric_owner)
|
|
|
if xattrs:
|
|
|
attrs['xattrs'] = StableDict(xattrs)
|
|
|
if bsdflags:
|