mirror of https://github.com/borgbackup/borg.git
Merge pull request #3311 from milkey-mouse/borgfs-man-bp1.1
Generate usage & man page for borgfs (1.1-maint)
This commit is contained in:
commit
9f9cb88a01
|
@ -0,0 +1 @@
|
|||
.. include:: borgfs.rst.inc
|
24
setup.py
24
setup.py
|
@ -238,10 +238,11 @@ class build_usage(Command):
|
|||
# allows us to build docs without the C modules fully loaded during help generation
|
||||
from borg.archiver import Archiver
|
||||
parser = Archiver(prog='borg').build_parser()
|
||||
borgfs_parser = Archiver(prog='borgfs').build_parser()
|
||||
|
||||
self.generate_level("", parser, Archiver)
|
||||
self.generate_level("", parser, Archiver, {'borgfs': borgfs_parser})
|
||||
|
||||
def generate_level(self, prefix, parser, Archiver):
|
||||
def generate_level(self, prefix, parser, Archiver, extra_choices=None):
|
||||
is_subcommand = False
|
||||
choices = {}
|
||||
for action in parser._actions:
|
||||
|
@ -249,6 +250,8 @@ class build_usage(Command):
|
|||
is_subcommand = True
|
||||
for cmd, parser in action.choices.items():
|
||||
choices[prefix + cmd] = parser
|
||||
if extra_choices is not None:
|
||||
choices.update(extra_choices)
|
||||
if prefix and not choices:
|
||||
return
|
||||
print('found commands: %s' % list(choices.keys()))
|
||||
|
@ -501,12 +504,13 @@ class build_man(Command):
|
|||
# allows us to build docs without the C modules fully loaded during help generation
|
||||
from borg.archiver import Archiver
|
||||
parser = Archiver(prog='borg').build_parser()
|
||||
borgfs_parser = Archiver(prog='borgfs').build_parser()
|
||||
|
||||
self.generate_level('', parser, Archiver)
|
||||
self.generate_level('', parser, Archiver, {'borgfs': borgfs_parser})
|
||||
self.build_topic_pages(Archiver)
|
||||
self.build_intro_page()
|
||||
|
||||
def generate_level(self, prefix, parser, Archiver):
|
||||
def generate_level(self, prefix, parser, Archiver, extra_choices=None):
|
||||
is_subcommand = False
|
||||
choices = {}
|
||||
for action in parser._actions:
|
||||
|
@ -514,6 +518,8 @@ class build_man(Command):
|
|||
is_subcommand = True
|
||||
for cmd, parser in action.choices.items():
|
||||
choices[prefix + cmd] = parser
|
||||
if extra_choices is not None:
|
||||
choices.update(extra_choices)
|
||||
if prefix and not choices:
|
||||
return
|
||||
|
||||
|
@ -521,7 +527,10 @@ class build_man(Command):
|
|||
if command.startswith('debug') or command == 'help':
|
||||
continue
|
||||
|
||||
man_title = 'borg-' + command.replace(' ', '-')
|
||||
if command == "borgfs":
|
||||
man_title = command
|
||||
else:
|
||||
man_title = 'borg-' + command.replace(' ', '-')
|
||||
print('building man page', man_title + '(1)', file=sys.stderr)
|
||||
|
||||
is_intermediary = self.generate_level(command + ' ', parser, Archiver)
|
||||
|
@ -536,7 +545,10 @@ class build_man(Command):
|
|||
write('| borg', '[common options]', command, subcommand, '...')
|
||||
self.see_also.setdefault(command, []).append('%s-%s' % (command, subcommand))
|
||||
else:
|
||||
write('borg', '[common options]', command, end='')
|
||||
if command == "borgfs":
|
||||
write(command, end='')
|
||||
else:
|
||||
write('borg', '[common options]', command, end='')
|
||||
self.write_usage(write, parser)
|
||||
write('\n')
|
||||
|
||||
|
|
|
@ -2458,7 +2458,67 @@ class Archiver:
|
|||
mid_common_parser.set_defaults(paths=[], patterns=[])
|
||||
parser.common_options.add_common_group(mid_common_parser, '_midcommand')
|
||||
|
||||
subparsers = parser.add_subparsers(title='required arguments', metavar='<command>')
|
||||
mount_epilog = process_epilog("""
|
||||
This command mounts an archive as a FUSE filesystem. This can be useful for
|
||||
browsing an archive or restoring individual files. Unless the ``--foreground``
|
||||
option is given the command will run in the background until the filesystem
|
||||
is ``umounted``.
|
||||
|
||||
The command ``borgfs`` provides a wrapper for ``borg mount``. This can also be
|
||||
used in fstab entries:
|
||||
``/path/to/repo /mnt/point fuse.borgfs defaults,noauto 0 0``
|
||||
|
||||
To allow a regular user to use fstab entries, add the ``user`` option:
|
||||
``/path/to/repo /mnt/point fuse.borgfs defaults,noauto,user 0 0``
|
||||
|
||||
For mount options, see the fuse(8) manual page. Additional mount options
|
||||
supported by borg:
|
||||
|
||||
- versions: when used with a repository mount, this gives a merged, versioned
|
||||
view of the files in the archives. EXPERIMENTAL, layout may change in future.
|
||||
- allow_damaged_files: by default damaged files (where missing chunks were
|
||||
replaced with runs of zeros by borg check ``--repair``) are not readable and
|
||||
return EIO (I/O error). Set this option to read such files.
|
||||
|
||||
The BORG_MOUNT_DATA_CACHE_ENTRIES environment variable is meant for advanced users
|
||||
to tweak the performance. It sets the number of cached data chunks; additional
|
||||
memory usage can be up to ~8 MiB times this number. The default is the number
|
||||
of CPU cores.
|
||||
|
||||
When the daemonized process receives a signal or crashes, it does not unmount.
|
||||
Unmounting in these cases could cause an active rsync or similar process
|
||||
to unintentionally delete data.
|
||||
|
||||
When running in the foreground ^C/SIGINT unmounts cleanly, but other
|
||||
signals or crashes do not.
|
||||
""")
|
||||
|
||||
if parser.prog == 'borgfs':
|
||||
parser.description = self.do_mount.__doc__
|
||||
parser.epilog = mount_epilog
|
||||
parser.formatter_class = argparse.RawDescriptionHelpFormatter
|
||||
parser.help = 'mount repository'
|
||||
subparser = parser
|
||||
else:
|
||||
subparsers = parser.add_subparsers(title='required arguments', metavar='<command>')
|
||||
subparser = subparsers.add_parser('mount', parents=[common_parser], add_help=False,
|
||||
description=self.do_mount.__doc__,
|
||||
epilog=mount_epilog,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
help='mount repository')
|
||||
subparser.set_defaults(func=self.do_mount)
|
||||
subparser.add_argument('location', metavar='REPOSITORY_OR_ARCHIVE', type=location_validator(),
|
||||
help='repository/archive to mount')
|
||||
subparser.add_argument('mountpoint', metavar='MOUNTPOINT', type=str,
|
||||
help='where to mount filesystem')
|
||||
subparser.add_argument('-f', '--foreground', dest='foreground',
|
||||
action='store_true',
|
||||
help='stay in foreground, do not daemonize')
|
||||
subparser.add_argument('-o', dest='options', type=str,
|
||||
help='Extra mount options')
|
||||
define_archive_filters_group(subparser)
|
||||
if parser.prog == 'borgfs':
|
||||
return parser
|
||||
|
||||
serve_epilog = process_epilog("""
|
||||
This command starts a repository server process. This command is usually not used manually.
|
||||
|
@ -3242,57 +3302,6 @@ class Archiver:
|
|||
define_archive_filters_group(subparser)
|
||||
define_exclusion_group(subparser)
|
||||
|
||||
mount_epilog = process_epilog("""
|
||||
This command mounts an archive as a FUSE filesystem. This can be useful for
|
||||
browsing an archive or restoring individual files. Unless the ``--foreground``
|
||||
option is given the command will run in the background until the filesystem
|
||||
is ``umounted``.
|
||||
|
||||
The command ``borgfs`` provides a wrapper for ``borg mount``. This can also be
|
||||
used in fstab entries:
|
||||
``/path/to/repo /mnt/point fuse.borgfs defaults,noauto 0 0``
|
||||
|
||||
To allow a regular user to use fstab entries, add the ``user`` option:
|
||||
``/path/to/repo /mnt/point fuse.borgfs defaults,noauto,user 0 0``
|
||||
|
||||
For mount options, see the fuse(8) manual page. Additional mount options
|
||||
supported by borg:
|
||||
|
||||
- versions: when used with a repository mount, this gives a merged, versioned
|
||||
view of the files in the archives. EXPERIMENTAL, layout may change in future.
|
||||
- allow_damaged_files: by default damaged files (where missing chunks were
|
||||
replaced with runs of zeros by borg check ``--repair``) are not readable and
|
||||
return EIO (I/O error). Set this option to read such files.
|
||||
|
||||
The BORG_MOUNT_DATA_CACHE_ENTRIES environment variable is meant for advanced users
|
||||
to tweak the performance. It sets the number of cached data chunks; additional
|
||||
memory usage can be up to ~8 MiB times this number. The default is the number
|
||||
of CPU cores.
|
||||
|
||||
When the daemonized process receives a signal or crashes, it does not unmount.
|
||||
Unmounting in these cases could cause an active rsync or similar process
|
||||
to unintentionally delete data.
|
||||
|
||||
When running in the foreground ^C/SIGINT unmounts cleanly, but other
|
||||
signals or crashes do not.
|
||||
""")
|
||||
subparser = subparsers.add_parser('mount', parents=[common_parser], add_help=False,
|
||||
description=self.do_mount.__doc__,
|
||||
epilog=mount_epilog,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
help='mount repository')
|
||||
subparser.set_defaults(func=self.do_mount)
|
||||
subparser.add_argument('location', metavar='REPOSITORY_OR_ARCHIVE', type=location_validator(),
|
||||
help='repository/archive to mount')
|
||||
subparser.add_argument('mountpoint', metavar='MOUNTPOINT', type=str,
|
||||
help='where to mount filesystem')
|
||||
subparser.add_argument('-f', '--foreground', dest='foreground',
|
||||
action='store_true',
|
||||
help='stay in foreground, do not daemonize')
|
||||
subparser.add_argument('-o', dest='options', type=str,
|
||||
help='Extra mount options')
|
||||
define_archive_filters_group(subparser)
|
||||
|
||||
umount_epilog = process_epilog("""
|
||||
This command un-mounts a FUSE filesystem that was mounted with ``borg mount``.
|
||||
|
||||
|
@ -4039,10 +4048,6 @@ def sig_trace_handler(sig_no, stack): # pragma: no cover
|
|||
|
||||
|
||||
def main(): # pragma: no cover
|
||||
# provide 'borg mount' behaviour when the main script/executable is named borgfs
|
||||
if os.path.basename(sys.argv[0]) == "borgfs":
|
||||
sys.argv.insert(1, "mount")
|
||||
|
||||
# Make sure stdout and stderr have errors='replace' to avoid unicode
|
||||
# issues when print()-ing unicode file names
|
||||
sys.stdout = ErrorIgnoringTextIOWrapper(sys.stdout.buffer, sys.stdout.encoding, 'replace', line_buffering=True)
|
||||
|
|
|
@ -3688,14 +3688,17 @@ def get_all_parsers():
|
|||
Return dict mapping command to parser.
|
||||
"""
|
||||
parser = Archiver(prog='borg').build_parser()
|
||||
borgfs_parser = Archiver(prog='borgfs').build_parser()
|
||||
parsers = {}
|
||||
|
||||
def discover_level(prefix, parser, Archiver):
|
||||
def discover_level(prefix, parser, Archiver, extra_choices=None):
|
||||
choices = {}
|
||||
for action in parser._actions:
|
||||
if action.choices is not None and 'SubParsersAction' in str(action.__class__):
|
||||
for cmd, parser in action.choices.items():
|
||||
choices[prefix + cmd] = parser
|
||||
if extra_choices is not None:
|
||||
choices.update(extra_choices)
|
||||
if prefix and not choices:
|
||||
return
|
||||
|
||||
|
@ -3703,7 +3706,7 @@ def get_all_parsers():
|
|||
discover_level(command + " ", parser, Archiver)
|
||||
parsers[command] = parser
|
||||
|
||||
discover_level("", parser, Archiver)
|
||||
discover_level("", parser, Archiver, {'borgfs': borgfs_parser})
|
||||
return parsers
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue