1
0
Fork 0
mirror of https://github.com/borgbackup/borg.git synced 2024-12-27 10:18:12 +00:00

Merge pull request #3769 from ThomasWaldmann/fuse-options

FUSE mount options: uid, gid, umask
This commit is contained in:
TW 2018-04-18 12:31:13 +02:00 committed by GitHub
commit 0d01b9ae27
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -214,6 +214,9 @@ class FuseOperations(llfuse.Operations):
# mount options # mount options
allow_damaged_files = False allow_damaged_files = False
versions = False versions = False
uid_forced = None
gid_forced = None
umask = 0
def __init__(self, key, repository, manifest, args, decrypted_repository): def __init__(self, key, repository, manifest, args, decrypted_repository):
super().__init__() super().__init__()
@ -236,7 +239,7 @@ def __init__(self, key, repository, manifest, args, decrypted_repository):
self.contents = defaultdict(dict) self.contents = defaultdict(dict)
self.default_uid = os.getuid() self.default_uid = os.getuid()
self.default_gid = os.getgid() self.default_gid = os.getgid()
self.default_dir = Item(mode=0o40755, mtime=int(time.time() * 1e9), uid=self.default_uid, gid=self.default_gid) self.default_dir = None
self.pending_archives = {} self.pending_archives = {}
self.cache = ItemCache(decrypted_repository) self.cache = ItemCache(decrypted_repository)
data_cache_capacity = int(os.environ.get('BORG_MOUNT_DATA_CACHE_ENTRIES', os.cpu_count() or 1)) data_cache_capacity = int(os.environ.get('BORG_MOUNT_DATA_CACHE_ENTRIES', os.cpu_count() or 1))
@ -276,19 +279,47 @@ def sig_info_handler(self, sig_no, stack):
def mount(self, mountpoint, mount_options, foreground=False): def mount(self, mountpoint, mount_options, foreground=False):
"""Mount filesystem on *mountpoint* with *mount_options*.""" """Mount filesystem on *mountpoint* with *mount_options*."""
def pop_option(options, key, present, not_present, wanted_type, int_base=0):
assert isinstance(options, list) # we mutate this
for idx, option in enumerate(options):
if option == key:
options.pop(idx)
return present
if option.startswith(key + '='):
options.pop(idx)
value = option.split('=', 1)[1]
if wanted_type is bool:
v = value.lower()
if v in ('y', 'yes', 'true', '1'):
return True
if v in ('n', 'no', 'false', '0'):
return False
raise ValueError('unsupported value in option: %s' % option)
if wanted_type is int:
try:
return int(value, base=int_base)
except ValueError:
raise ValueError('unsupported value in option: %s' % option) from None
try:
return wanted_type(value)
except ValueError:
raise ValueError('unsupported value in option: %s' % option) from None
else:
return not_present
options = ['fsname=borgfs', 'ro'] options = ['fsname=borgfs', 'ro']
if mount_options: if mount_options:
options.extend(mount_options.split(',')) options.extend(mount_options.split(','))
try: self.allow_damaged_files = pop_option(options, 'allow_damaged_files', True, False, bool)
options.remove('allow_damaged_files') self.versions = pop_option(options, 'versions', True, False, bool)
self.allow_damaged_files = True self.uid_forced = pop_option(options, 'uid', None, None, int)
except ValueError: self.gid_forced = pop_option(options, 'gid', None, None, int)
pass self.umask = pop_option(options, 'umask', 0, 0, int, int_base=8) # umask is octal, e.g. 222 or 0222
try: dir_uid = self.uid_forced if self.uid_forced is not None else self.default_uid
options.remove('versions') dir_gid = self.gid_forced if self.gid_forced is not None else self.default_gid
self.versions = True dir_mode = 0o40755 & ~self.umask
except ValueError: self.default_dir = Item(mode=dir_mode, mtime=int(time.time() * 1e9), uid=dir_uid, gid=dir_gid)
pass
self._create_filesystem() self._create_filesystem()
llfuse.init(self, mountpoint, options) llfuse.init(self, mountpoint, options)
if not foreground: if not foreground:
@ -485,10 +516,10 @@ def getattr(self, inode, ctx=None):
entry.generation = 0 entry.generation = 0
entry.entry_timeout = 300 entry.entry_timeout = 300
entry.attr_timeout = 300 entry.attr_timeout = 300
entry.st_mode = item.mode entry.st_mode = item.mode & ~self.umask
entry.st_nlink = item.get('nlink', 1) entry.st_nlink = item.get('nlink', 1)
entry.st_uid = item.uid if item.uid >= 0 else self.default_uid entry.st_uid = self.uid_forced if self.uid_forced is not None else item.uid if item.uid >= 0 else self.default_uid
entry.st_gid = item.gid if item.gid >= 0 else self.default_gid entry.st_gid = self.gid_forced if self.gid_forced is not None else item.gid if item.gid >= 0 else self.default_gid
entry.st_rdev = item.get('rdev', 0) entry.st_rdev = item.get('rdev', 0)
entry.st_size = item.get_size() entry.st_size = item.get_size()
entry.st_blksize = 512 entry.st_blksize = 512