move serve command to archiver.serve

This commit is contained in:
Thomas Waldmann 2022-07-09 00:14:17 +02:00
parent 68772484ce
commit ff411b5d98
3 changed files with 94 additions and 77 deletions

View File

@ -40,7 +40,7 @@ try:
from ..helpers import location_validator, archivename_validator, ChunkerParams, Location from ..helpers import location_validator, archivename_validator, ChunkerParams, Location
from ..helpers import NameSpec, CommentSpec, FilesCacheMode from ..helpers import NameSpec, CommentSpec, FilesCacheMode
from ..helpers import BaseFormatter, ItemFormatter, ArchiveFormatter from ..helpers import BaseFormatter, ItemFormatter, ArchiveFormatter
from ..helpers import format_timedelta, format_file_size, parse_file_size, format_archive from ..helpers import format_timedelta, format_file_size, format_archive, parse_storage_quota
from ..helpers import remove_surrogates, bin_to_hex, eval_escapes from ..helpers import remove_surrogates, bin_to_hex, eval_escapes
from ..helpers import timestamp from ..helpers import timestamp
from ..helpers import get_cache_dir, os_stat from ..helpers import get_cache_dir, os_stat
@ -60,7 +60,7 @@ try:
from ..patterns import PatternMatcher from ..patterns import PatternMatcher
from ..platform import get_flags from ..platform import get_flags
from ..platform import uid2user, gid2group from ..platform import uid2user, gid2group
from ..remote import RepositoryServer, RemoteRepository from ..remote import RemoteRepository
from ..selftest import selftest from ..selftest import selftest
except BaseException: except BaseException:
# an unhandled exception in the try-block would cause the borg cli command to exit with rc 1 due to python's # an unhandled exception in the try-block would cause the borg cli command to exit with rc 1 due to python's
@ -77,13 +77,6 @@ STATS_HEADER = " Original size Deduplicated size"
PURE_PYTHON_MSGPACK_WARNING = "Using a pure-python msgpack! This will result in lower performance." PURE_PYTHON_MSGPACK_WARNING = "Using a pure-python msgpack! This will result in lower performance."
def parse_storage_quota(storage_quota):
parsed = parse_file_size(storage_quota)
if parsed < parse_file_size("10M"):
raise argparse.ArgumentTypeError("quota is too small (%s). At least 10M are required." % storage_quota)
return parsed
def get_func(args): def get_func(args):
# This works around https://bugs.python.org/issue9351 # This works around https://bugs.python.org/issue9351
# func is used at the leaf parsers of the argparse parser tree, # func is used at the leaf parsers of the argparse parser tree,
@ -107,6 +100,7 @@ from .keys import KeysMixIn
from .locks import LocksMixIn from .locks import LocksMixIn
from .mount import MountMixIn from .mount import MountMixIn
from .prune import PruneMixIn from .prune import PruneMixIn
from .serve import ServeMixIn
from .tar import TarMixIn from .tar import TarMixIn
from .transfer import TransferMixIn from .transfer import TransferMixIn
@ -124,6 +118,7 @@ class Archiver(
MountMixIn, MountMixIn,
PruneMixIn, PruneMixIn,
HelpMixIn, HelpMixIn,
ServeMixIn,
TransferMixIn, TransferMixIn,
): ):
def __init__(self, lock_wait=None, prog=None): def __init__(self, lock_wait=None, prog=None):
@ -159,16 +154,6 @@ class Archiver(
matcher.add_includepaths(include_paths) matcher.add_includepaths(include_paths)
return matcher return matcher
def do_serve(self, args):
"""Start in server mode. This command is usually not used manually."""
RepositoryServer(
restrict_to_paths=args.restrict_to_paths,
restrict_to_repositories=args.restrict_to_repositories,
append_only=args.append_only,
storage_quota=args.storage_quota,
).serve()
return EXIT_SUCCESS
@with_repository(create=True, exclusive=True, manifest=False) @with_repository(create=True, exclusive=True, manifest=False)
@with_other_repository(key=True, compatibility=(Manifest.Operation.READ,)) @with_other_repository(key=True, compatibility=(Manifest.Operation.READ,))
def do_rcreate(self, args, repository, *, other_repository=None, other_key=None): def do_rcreate(self, args, repository, *, other_repository=None, other_key=None):
@ -2546,64 +2531,7 @@ class Archiver(
"newname", metavar="NEWNAME", type=archivename_validator(), help="specify the new archive name" "newname", metavar="NEWNAME", type=archivename_validator(), help="specify the new archive name"
) )
# borg serve self.build_parser_serve(subparsers, common_parser, mid_common_parser)
serve_epilog = process_epilog(
"""
This command starts a repository server process. This command is usually not used manually.
"""
)
subparser = subparsers.add_parser(
"serve",
parents=[common_parser],
add_help=False,
description=self.do_serve.__doc__,
epilog=serve_epilog,
formatter_class=argparse.RawDescriptionHelpFormatter,
help="start repository server process",
)
subparser.set_defaults(func=self.do_serve)
subparser.add_argument(
"--restrict-to-path",
metavar="PATH",
dest="restrict_to_paths",
action="append",
help="restrict repository access to PATH. "
"Can be specified multiple times to allow the client access to several directories. "
"Access to all sub-directories is granted implicitly; PATH doesn't need to directly point to a repository.",
)
subparser.add_argument(
"--restrict-to-repository",
metavar="PATH",
dest="restrict_to_repositories",
action="append",
help="restrict repository access. Only the repository located at PATH "
"(no sub-directories are considered) is accessible. "
"Can be specified multiple times to allow the client access to several repositories. "
"Unlike ``--restrict-to-path`` sub-directories are not accessible; "
"PATH needs to directly point at a repository location. "
"PATH may be an empty directory or the last element of PATH may not exist, in which case "
"the client may initialize a repository there.",
)
subparser.add_argument(
"--append-only",
dest="append_only",
action="store_true",
help="only allow appending to repository segment files. Note that this only "
"affects the low level structure of the repository, and running `delete` "
"or `prune` will still be allowed. See :ref:`append_only_mode` in Additional "
"Notes for more details.",
)
subparser.add_argument(
"--storage-quota",
metavar="QUOTA",
dest="storage_quota",
type=parse_storage_quota,
default=None,
help="Override storage quota of the repository (e.g. 5G, 1.5T). "
"When a new repository is initialized, sets the storage quota on the new "
"repository as well. Default: no quota.",
)
self.build_parser_tar(subparsers, common_parser, mid_common_parser) self.build_parser_tar(subparsers, common_parser, mid_common_parser)
self.build_parser_transfer(subparsers, common_parser, mid_common_parser) self.build_parser_transfer(subparsers, common_parser, mid_common_parser)

View File

@ -0,0 +1,82 @@
import argparse
from ..constants import * # NOQA
from ..helpers import EXIT_SUCCESS
from ..helpers import parse_storage_quota
from ..remote import RepositoryServer
from ..logger import create_logger
logger = create_logger()
class ServeMixIn:
def do_serve(self, args):
"""Start in server mode. This command is usually not used manually."""
RepositoryServer(
restrict_to_paths=args.restrict_to_paths,
restrict_to_repositories=args.restrict_to_repositories,
append_only=args.append_only,
storage_quota=args.storage_quota,
).serve()
return EXIT_SUCCESS
def build_parser_serve(self, subparsers, common_parser, mid_common_parser):
from .common import process_epilog
serve_epilog = process_epilog(
"""
This command starts a repository server process. This command is usually not used manually.
"""
)
subparser = subparsers.add_parser(
"serve",
parents=[common_parser],
add_help=False,
description=self.do_serve.__doc__,
epilog=serve_epilog,
formatter_class=argparse.RawDescriptionHelpFormatter,
help="start repository server process",
)
subparser.set_defaults(func=self.do_serve)
subparser.add_argument(
"--restrict-to-path",
metavar="PATH",
dest="restrict_to_paths",
action="append",
help="restrict repository access to PATH. "
"Can be specified multiple times to allow the client access to several directories. "
"Access to all sub-directories is granted implicitly; PATH doesn't need to directly point to a repository.",
)
subparser.add_argument(
"--restrict-to-repository",
metavar="PATH",
dest="restrict_to_repositories",
action="append",
help="restrict repository access. Only the repository located at PATH "
"(no sub-directories are considered) is accessible. "
"Can be specified multiple times to allow the client access to several repositories. "
"Unlike ``--restrict-to-path`` sub-directories are not accessible; "
"PATH needs to directly point at a repository location. "
"PATH may be an empty directory or the last element of PATH may not exist, in which case "
"the client may initialize a repository there.",
)
subparser.add_argument(
"--append-only",
dest="append_only",
action="store_true",
help="only allow appending to repository segment files. Note that this only "
"affects the low level structure of the repository, and running `delete` "
"or `prune` will still be allowed. See :ref:`append_only_mode` in Additional "
"Notes for more details.",
)
subparser.add_argument(
"--storage-quota",
metavar="QUOTA",
dest="storage_quota",
type=parse_storage_quota,
default=None,
help="Override storage quota of the repository (e.g. 5G, 1.5T). "
"When a new repository is initialized, sets the storage quota on the new "
"repository as well. Default: no quota.",
)

View File

@ -257,6 +257,13 @@ def parse_file_size(s):
return int(float(s) * factor) return int(float(s) * factor)
def parse_storage_quota(storage_quota):
parsed = parse_file_size(storage_quota)
if parsed < parse_file_size("10M"):
raise argparse.ArgumentTypeError("quota is too small (%s). At least 10M are required." % storage_quota)
return parsed
def sizeof_fmt(num, suffix="B", units=None, power=None, sep="", precision=2, sign=False): def sizeof_fmt(num, suffix="B", units=None, power=None, sep="", precision=2, sign=False):
sign = "+" if sign and num > 0 else "" sign = "+" if sign and num > 0 else ""
fmt = "{0:{1}.{2}f}{3}{4}{5}" fmt = "{0:{1}.{2}f}{3}{4}{5}"