mirror of https://github.com/borgbackup/borg.git
move serve command to archiver.serve
This commit is contained in:
parent
68772484ce
commit
ff411b5d98
|
@ -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)
|
||||||
|
|
|
@ -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.",
|
||||||
|
)
|
|
@ -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}"
|
||||||
|
|
Loading…
Reference in New Issue