mirror of https://github.com/borgbackup/borg.git
move rdelete command to archiver.rdelete
This commit is contained in:
parent
94aec46a01
commit
a31332ddb5
|
@ -125,6 +125,7 @@ per_file_ignores =
|
|||
src/borg/archiver/help.py:E501,F405
|
||||
src/borg/archiver/keys.py:F405
|
||||
src/borg/archiver/prune.py:F405
|
||||
src/borg/archiver/rdelete.py:F405
|
||||
src/borg/archiver/tar.py:F405
|
||||
src/borg/cache.py:E127,E128,E402,E501,E722,W504
|
||||
src/borg/fuse.py:E402,E501,E722,W504
|
||||
|
|
|
@ -31,11 +31,11 @@ try:
|
|||
from ..archive import Archive, ArchiveRecreater, Statistics, is_special
|
||||
from ..archive import BackupError, BackupOSError, backup_io, OsOpen, stat_update_check
|
||||
from ..archive import FilesystemObjectProcessors, MetadataCollector, ChunksProcessor
|
||||
from ..cache import Cache, SecurityManager
|
||||
from ..cache import Cache
|
||||
from ..constants import * # NOQA
|
||||
from ..compress import CompressionSpec
|
||||
from ..helpers import EXIT_SUCCESS, EXIT_WARNING, EXIT_ERROR, EXIT_SIGNAL_BASE
|
||||
from ..helpers import Error, NoManifestError, set_ec
|
||||
from ..helpers import Error, set_ec
|
||||
from ..helpers import location_validator, archivename_validator, ChunkerParams, Location
|
||||
from ..helpers import NameSpec, CommentSpec, FilesCacheMode
|
||||
from ..helpers import BaseFormatter, ItemFormatter, ArchiveFormatter
|
||||
|
@ -46,7 +46,7 @@ try:
|
|||
from ..helpers import Manifest
|
||||
from ..helpers import HardLinkManager
|
||||
from ..helpers import check_python, check_extension_modules
|
||||
from ..helpers import dir_is_tagged, is_slow_msgpack, is_supported_msgpack, yes, sysinfo
|
||||
from ..helpers import dir_is_tagged, is_slow_msgpack, is_supported_msgpack, sysinfo
|
||||
from ..helpers import log_multi
|
||||
from ..helpers import signal_handler, raising_signal_handler, SigHup, SigTerm
|
||||
from ..helpers import ErrorIgnoringTextIOWrapper
|
||||
|
@ -100,6 +100,7 @@ from .locks import LocksMixIn
|
|||
from .mount import MountMixIn
|
||||
from .prune import PruneMixIn
|
||||
from .rcreate import RCreateMixIn
|
||||
from .rdelete import RDeleteMixIn
|
||||
from .serve import ServeMixIn
|
||||
from .tar import TarMixIn
|
||||
from .transfer import TransferMixIn
|
||||
|
@ -119,6 +120,7 @@ class Archiver(
|
|||
PruneMixIn,
|
||||
HelpMixIn,
|
||||
RCreateMixIn,
|
||||
RDeleteMixIn,
|
||||
ServeMixIn,
|
||||
TransferMixIn,
|
||||
):
|
||||
|
@ -703,80 +705,6 @@ class Archiver(
|
|||
cache.commit()
|
||||
return self.exit_code
|
||||
|
||||
@with_repository(exclusive=True, manifest=False)
|
||||
def do_rdelete(self, args, repository):
|
||||
"""Delete a repository"""
|
||||
self.output_list = args.output_list
|
||||
dry_run = args.dry_run
|
||||
keep_security_info = args.keep_security_info
|
||||
|
||||
if not args.cache_only:
|
||||
if args.forced == 0: # without --force, we let the user see the archives list and confirm.
|
||||
id = bin_to_hex(repository.id)
|
||||
location = repository._location.canonical_path()
|
||||
msg = []
|
||||
try:
|
||||
manifest, key = Manifest.load(repository, Manifest.NO_OPERATION_CHECK)
|
||||
n_archives = len(manifest.archives)
|
||||
msg.append(
|
||||
f"You requested to completely DELETE the following repository "
|
||||
f"*including* {n_archives} archives it contains:"
|
||||
)
|
||||
except NoManifestError:
|
||||
n_archives = None
|
||||
msg.append(
|
||||
"You requested to completely DELETE the following repository "
|
||||
"*including* all archives it may contain:"
|
||||
)
|
||||
|
||||
msg.append(DASHES)
|
||||
msg.append(f"Repository ID: {id}")
|
||||
msg.append(f"Location: {location}")
|
||||
|
||||
if self.output_list:
|
||||
msg.append("")
|
||||
msg.append("Archives:")
|
||||
|
||||
if n_archives is not None:
|
||||
if n_archives > 0:
|
||||
for archive_info in manifest.archives.list(sort_by=["ts"]):
|
||||
msg.append(format_archive(archive_info))
|
||||
else:
|
||||
msg.append("This repository seems to not have any archives.")
|
||||
else:
|
||||
msg.append(
|
||||
"This repository seems to have no manifest, so we can't "
|
||||
"tell anything about its contents."
|
||||
)
|
||||
|
||||
msg.append(DASHES)
|
||||
msg.append("Type 'YES' if you understand this and want to continue: ")
|
||||
msg = "\n".join(msg)
|
||||
if not yes(
|
||||
msg,
|
||||
false_msg="Aborting.",
|
||||
invalid_msg="Invalid answer, aborting.",
|
||||
truish=("YES",),
|
||||
retry=False,
|
||||
env_var_override="BORG_DELETE_I_KNOW_WHAT_I_AM_DOING",
|
||||
):
|
||||
self.exit_code = EXIT_ERROR
|
||||
return self.exit_code
|
||||
if not dry_run:
|
||||
repository.destroy()
|
||||
logger.info("Repository deleted.")
|
||||
if not keep_security_info:
|
||||
SecurityManager.destroy(repository)
|
||||
else:
|
||||
logger.info("Would delete repository.")
|
||||
logger.info("Would %s security info." % ("keep" if keep_security_info else "delete"))
|
||||
if not dry_run:
|
||||
Cache.destroy(repository)
|
||||
logger.info("Cache deleted.")
|
||||
else:
|
||||
logger.info("Would delete cache.")
|
||||
return self.exit_code
|
||||
|
||||
@with_repository(exclusive=True, manifest=False)
|
||||
def do_delete(self, args, repository):
|
||||
"""Delete archives"""
|
||||
|
@ -1753,53 +1681,7 @@ class Archiver(
|
|||
self.build_parser_config(subparsers, common_parser, mid_common_parser)
|
||||
self.build_parser_debug(subparsers, common_parser, mid_common_parser)
|
||||
self.build_parser_help(subparsers, common_parser, mid_common_parser, parser)
|
||||
|
||||
# borg rdelete
|
||||
rdelete_epilog = process_epilog(
|
||||
"""
|
||||
This command deletes the complete repository.
|
||||
|
||||
When you delete a complete repository, the security info and local cache for it
|
||||
(if any) are also deleted. Alternatively, you can delete just the local cache
|
||||
with the ``--cache-only`` option, or keep the security info with the
|
||||
``--keep-security-info`` option.
|
||||
|
||||
Always first use ``--dry-run --list`` to see what would be deleted.
|
||||
"""
|
||||
)
|
||||
subparser = subparsers.add_parser(
|
||||
"rdelete",
|
||||
parents=[common_parser],
|
||||
add_help=False,
|
||||
description=self.do_rdelete.__doc__,
|
||||
epilog=rdelete_epilog,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
help="delete repository",
|
||||
)
|
||||
subparser.set_defaults(func=self.do_rdelete)
|
||||
subparser.add_argument("-n", "--dry-run", dest="dry_run", action="store_true", help="do not change repository")
|
||||
subparser.add_argument(
|
||||
"--list", dest="output_list", action="store_true", help="output verbose list of archives"
|
||||
)
|
||||
subparser.add_argument(
|
||||
"--force",
|
||||
dest="forced",
|
||||
action="count",
|
||||
default=0,
|
||||
help="force deletion of corrupted archives, " "use ``--force --force`` in case ``--force`` does not work.",
|
||||
)
|
||||
subparser.add_argument(
|
||||
"--cache-only",
|
||||
dest="cache_only",
|
||||
action="store_true",
|
||||
help="delete only the local cache for the given repository",
|
||||
)
|
||||
subparser.add_argument(
|
||||
"--keep-security-info",
|
||||
dest="keep_security_info",
|
||||
action="store_true",
|
||||
help="keep the local security info when deleting a repository",
|
||||
)
|
||||
self.build_parser_rdelete(subparsers, common_parser, mid_common_parser, parser)
|
||||
|
||||
# borg delete
|
||||
delete_epilog = process_epilog(
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
import argparse
|
||||
|
||||
from .common import with_repository
|
||||
from ..cache import Cache, SecurityManager
|
||||
from ..constants import * # NOQA
|
||||
from ..helpers import EXIT_ERROR
|
||||
from ..helpers import NoManifestError
|
||||
from ..helpers import format_archive
|
||||
from ..helpers import bin_to_hex
|
||||
from ..helpers import Manifest
|
||||
from ..helpers import yes
|
||||
|
||||
from ..logger import create_logger
|
||||
|
||||
logger = create_logger()
|
||||
|
||||
|
||||
class RDeleteMixIn:
|
||||
@with_repository(exclusive=True, manifest=False)
|
||||
def do_rdelete(self, args, repository):
|
||||
"""Delete a repository"""
|
||||
self.output_list = args.output_list
|
||||
dry_run = args.dry_run
|
||||
keep_security_info = args.keep_security_info
|
||||
|
||||
if not args.cache_only:
|
||||
if args.forced == 0: # without --force, we let the user see the archives list and confirm.
|
||||
id = bin_to_hex(repository.id)
|
||||
location = repository._location.canonical_path()
|
||||
msg = []
|
||||
try:
|
||||
manifest, key = Manifest.load(repository, Manifest.NO_OPERATION_CHECK)
|
||||
n_archives = len(manifest.archives)
|
||||
msg.append(
|
||||
f"You requested to completely DELETE the following repository "
|
||||
f"*including* {n_archives} archives it contains:"
|
||||
)
|
||||
except NoManifestError:
|
||||
n_archives = None
|
||||
msg.append(
|
||||
"You requested to completely DELETE the following repository "
|
||||
"*including* all archives it may contain:"
|
||||
)
|
||||
|
||||
msg.append(DASHES)
|
||||
msg.append(f"Repository ID: {id}")
|
||||
msg.append(f"Location: {location}")
|
||||
|
||||
if self.output_list:
|
||||
msg.append("")
|
||||
msg.append("Archives:")
|
||||
|
||||
if n_archives is not None:
|
||||
if n_archives > 0:
|
||||
for archive_info in manifest.archives.list(sort_by=["ts"]):
|
||||
msg.append(format_archive(archive_info))
|
||||
else:
|
||||
msg.append("This repository seems to not have any archives.")
|
||||
else:
|
||||
msg.append(
|
||||
"This repository seems to have no manifest, so we can't "
|
||||
"tell anything about its contents."
|
||||
)
|
||||
|
||||
msg.append(DASHES)
|
||||
msg.append("Type 'YES' if you understand this and want to continue: ")
|
||||
msg = "\n".join(msg)
|
||||
if not yes(
|
||||
msg,
|
||||
false_msg="Aborting.",
|
||||
invalid_msg="Invalid answer, aborting.",
|
||||
truish=("YES",),
|
||||
retry=False,
|
||||
env_var_override="BORG_DELETE_I_KNOW_WHAT_I_AM_DOING",
|
||||
):
|
||||
self.exit_code = EXIT_ERROR
|
||||
return self.exit_code
|
||||
if not dry_run:
|
||||
repository.destroy()
|
||||
logger.info("Repository deleted.")
|
||||
if not keep_security_info:
|
||||
SecurityManager.destroy(repository)
|
||||
else:
|
||||
logger.info("Would delete repository.")
|
||||
logger.info("Would %s security info." % ("keep" if keep_security_info else "delete"))
|
||||
if not dry_run:
|
||||
Cache.destroy(repository)
|
||||
logger.info("Cache deleted.")
|
||||
else:
|
||||
logger.info("Would delete cache.")
|
||||
return self.exit_code
|
||||
|
||||
def build_parser_rdelete(self, subparsers, common_parser, mid_common_parser, parser):
|
||||
|
||||
from .common import process_epilog
|
||||
|
||||
rdelete_epilog = process_epilog(
|
||||
"""
|
||||
This command deletes the complete repository.
|
||||
|
||||
When you delete a complete repository, the security info and local cache for it
|
||||
(if any) are also deleted. Alternatively, you can delete just the local cache
|
||||
with the ``--cache-only`` option, or keep the security info with the
|
||||
``--keep-security-info`` option.
|
||||
|
||||
Always first use ``--dry-run --list`` to see what would be deleted.
|
||||
"""
|
||||
)
|
||||
subparser = subparsers.add_parser(
|
||||
"rdelete",
|
||||
parents=[common_parser],
|
||||
add_help=False,
|
||||
description=self.do_rdelete.__doc__,
|
||||
epilog=rdelete_epilog,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
help="delete repository",
|
||||
)
|
||||
subparser.set_defaults(func=self.do_rdelete)
|
||||
subparser.add_argument("-n", "--dry-run", dest="dry_run", action="store_true", help="do not change repository")
|
||||
subparser.add_argument(
|
||||
"--list", dest="output_list", action="store_true", help="output verbose list of archives"
|
||||
)
|
||||
subparser.add_argument(
|
||||
"--force",
|
||||
dest="forced",
|
||||
action="count",
|
||||
default=0,
|
||||
help="force deletion of corrupted archives, " "use ``--force --force`` in case ``--force`` does not work.",
|
||||
)
|
||||
subparser.add_argument(
|
||||
"--cache-only",
|
||||
dest="cache_only",
|
||||
action="store_true",
|
||||
help="delete only the local cache for the given repository",
|
||||
)
|
||||
subparser.add_argument(
|
||||
"--keep-security-info",
|
||||
dest="keep_security_info",
|
||||
action="store_true",
|
||||
help="keep the local security info when deleting a repository",
|
||||
)
|
Loading…
Reference in New Issue