Rename repository actions for compatibility with recent Borg 2 changes (#915).
All checks were successful
build / test (push) Successful in 6m23s
build / docs (push) Successful in 1m59s

This commit is contained in:
Dan Helfman 2024-09-09 10:05:32 -07:00
parent 1fe6ae83a8
commit fd4f69f6c3
62 changed files with 666 additions and 579 deletions

2
NEWS
View File

@ -1,5 +1,7 @@
1.8.15.dev0
* #911: Add a "key change-passphrase" action to change the passphrase protecting a repository key.
* #915: Rename repository actions like "rcreate" to more explicit names like "repo-create" for
compatibility with recent Borg 2 changes.
1.8.14
* #896: Fix an error in borgmatic rcreate/init on an empty repository directory with Borg 1.4.

View File

@ -1,7 +1,7 @@
import logging
import borgmatic.borg.borg
import borgmatic.borg.rlist
import borgmatic.borg.repo_list
import borgmatic.config.validate
logger = logging.getLogger(__name__)
@ -25,7 +25,7 @@ def run_borg(
logger.info(
f'{repository.get("label", repository["path"])}: Running arbitrary Borg command'
)
archive_name = borgmatic.borg.rlist.resolve_archive_name(
archive_name = borgmatic.borg.repo_list.resolve_archive_name(
repository['path'],
borg_arguments.archive,
config,

View File

@ -12,7 +12,7 @@ import borgmatic.borg.create
import borgmatic.borg.environment
import borgmatic.borg.extract
import borgmatic.borg.list
import borgmatic.borg.rlist
import borgmatic.borg.repo_list
import borgmatic.borg.state
import borgmatic.config.validate
import borgmatic.execute
@ -559,7 +559,7 @@ def spot_check(
)
logger.debug(f'{log_label}: {len(source_paths)} total source paths for spot check')
archive = borgmatic.borg.rlist.resolve_archive_name(
archive = borgmatic.borg.repo_list.resolve_archive_name(
repository['path'],
'latest',
config,

View File

@ -3,7 +3,7 @@ import logging
import os
import borgmatic.borg.extract
import borgmatic.borg.rlist
import borgmatic.borg.repo_list
import borgmatic.config.validate
import borgmatic.hooks.command
from borgmatic.borg.state import DEFAULT_BORGMATIC_SOURCE_DIRECTORY
@ -33,7 +33,7 @@ def get_config_paths(bootstrap_arguments, global_arguments, local_borg_version):
extract_process = borgmatic.borg.extract.extract_archive(
global_arguments.dry_run,
bootstrap_arguments.repository,
borgmatic.borg.rlist.resolve_archive_name(
borgmatic.borg.repo_list.resolve_archive_name(
bootstrap_arguments.repository,
bootstrap_arguments.archive,
config,
@ -85,7 +85,7 @@ def run_bootstrap(bootstrap_arguments, global_arguments, local_borg_version):
borgmatic.borg.extract.extract_archive(
global_arguments.dry_run,
bootstrap_arguments.repository,
borgmatic.borg.rlist.resolve_archive_name(
borgmatic.borg.repo_list.resolve_archive_name(
bootstrap_arguments.repository,
bootstrap_arguments.archive,
config,

View File

@ -2,8 +2,8 @@ import logging
import borgmatic.actions.arguments
import borgmatic.borg.delete
import borgmatic.borg.rdelete
import borgmatic.borg.rlist
import borgmatic.borg.repo_delete
import borgmatic.borg.repo_list
logger = logging.getLogger(__name__)
@ -26,7 +26,7 @@ def run_delete(
logger.answer(f'{repository.get("label", repository["path"])}: Deleting archives')
archive_name = (
borgmatic.borg.rlist.resolve_archive_name(
borgmatic.borg.repo_list.resolve_archive_name(
repository['path'],
delete_arguments.archive,
config,

View File

@ -1,7 +1,7 @@
import logging
import borgmatic.borg.export_tar
import borgmatic.borg.rlist
import borgmatic.borg.repo_list
import borgmatic.config.validate
logger = logging.getLogger(__name__)
@ -28,7 +28,7 @@ def run_export_tar(
borgmatic.borg.export_tar.export_tar_archive(
global_arguments.dry_run,
repository['path'],
borgmatic.borg.rlist.resolve_archive_name(
borgmatic.borg.repo_list.resolve_archive_name(
repository['path'],
export_tar_arguments.archive,
config,

View File

@ -1,7 +1,7 @@
import logging
import borgmatic.borg.extract
import borgmatic.borg.rlist
import borgmatic.borg.repo_list
import borgmatic.config.validate
import borgmatic.hooks.command
@ -39,7 +39,7 @@ def run_extract(
borgmatic.borg.extract.extract_archive(
global_arguments.dry_run,
repository['path'],
borgmatic.borg.rlist.resolve_archive_name(
borgmatic.borg.repo_list.resolve_archive_name(
repository['path'],
extract_arguments.archive,
config,

View File

@ -3,7 +3,7 @@ import logging
import borgmatic.actions.arguments
import borgmatic.actions.json
import borgmatic.borg.info
import borgmatic.borg.rlist
import borgmatic.borg.repo_list
import borgmatic.config.validate
logger = logging.getLogger(__name__)
@ -30,7 +30,7 @@ def run_info(
logger.answer(
f'{repository.get("label", repository["path"])}: Displaying archive summary information'
)
archive_name = borgmatic.borg.rlist.resolve_archive_name(
archive_name = borgmatic.borg.repo_list.resolve_archive_name(
repository['path'],
info_arguments.archive,
config,

View File

@ -31,7 +31,7 @@ def run_list(
elif not list_arguments.archive: # pragma: no cover
logger.answer(f'{repository.get("label", repository["path"])}: Listing archives')
archive_name = borgmatic.borg.rlist.resolve_archive_name(
archive_name = borgmatic.borg.repo_list.resolve_archive_name(
repository['path'],
list_arguments.archive,
config,

View File

@ -1,7 +1,7 @@
import logging
import borgmatic.borg.mount
import borgmatic.borg.rlist
import borgmatic.borg.repo_list
import borgmatic.config.validate
logger = logging.getLogger(__name__)
@ -31,7 +31,7 @@ def run_mount(
borgmatic.borg.mount.mount_archive(
repository['path'],
borgmatic.borg.rlist.resolve_archive_name(
borgmatic.borg.repo_list.resolve_archive_name(
repository['path'],
mount_arguments.archive,
config,

View File

@ -1,41 +0,0 @@
import logging
import borgmatic.borg.rcreate
import borgmatic.config.validate
logger = logging.getLogger(__name__)
def run_rcreate(
repository,
config,
local_borg_version,
rcreate_arguments,
global_arguments,
local_path,
remote_path,
):
'''
Run the "rcreate" action for the given repository.
'''
if rcreate_arguments.repository and not borgmatic.config.validate.repositories_match(
repository, rcreate_arguments.repository
):
return
logger.info(f'{repository.get("label", repository["path"])}: Creating repository')
borgmatic.borg.rcreate.create_repository(
global_arguments.dry_run,
repository['path'],
config,
local_borg_version,
global_arguments,
rcreate_arguments.encryption_mode,
rcreate_arguments.source_repository,
rcreate_arguments.copy_crypt_key,
rcreate_arguments.append_only,
rcreate_arguments.storage_quota,
rcreate_arguments.make_parent_dirs,
local_path=local_path,
remote_path=remote_path,
)

View File

@ -0,0 +1,41 @@
import logging
import borgmatic.borg.repo_create
import borgmatic.config.validate
logger = logging.getLogger(__name__)
def run_repo_create(
repository,
config,
local_borg_version,
repo_create_arguments,
global_arguments,
local_path,
remote_path,
):
'''
Run the "repo-create" action for the given repository.
'''
if repo_create_arguments.repository and not borgmatic.config.validate.repositories_match(
repository, repo_create_arguments.repository
):
return
logger.info(f'{repository.get("label", repository["path"])}: Creating repository')
borgmatic.borg.repo_create.create_repository(
global_arguments.dry_run,
repository['path'],
config,
local_borg_version,
global_arguments,
repo_create_arguments.encryption_mode,
repo_create_arguments.source_repository,
repo_create_arguments.copy_crypt_key,
repo_create_arguments.append_only,
repo_create_arguments.storage_quota,
repo_create_arguments.make_parent_dirs,
local_path=local_path,
remote_path=remote_path,
)

View File

@ -1,35 +1,35 @@
import logging
import borgmatic.borg.rdelete
import borgmatic.borg.repo_delete
logger = logging.getLogger(__name__)
def run_rdelete(
def run_repo_delete(
repository,
config,
local_borg_version,
rdelete_arguments,
repo_delete_arguments,
global_arguments,
local_path,
remote_path,
):
'''
Run the "rdelete" action for the given repository.
Run the "repo-delete" action for the given repository.
'''
if rdelete_arguments.repository is None or borgmatic.config.validate.repositories_match(
repository, rdelete_arguments.repository
if repo_delete_arguments.repository is None or borgmatic.config.validate.repositories_match(
repository, repo_delete_arguments.repository
):
logger.answer(
f'{repository.get("label", repository["path"])}: Deleting repository'
+ (' cache' if rdelete_arguments.cache_only else '')
+ (' cache' if repo_delete_arguments.cache_only else '')
)
borgmatic.borg.rdelete.delete_repository(
borgmatic.borg.repo_delete.delete_repository(
repository,
config,
local_borg_version,
rdelete_arguments,
repo_delete_arguments,
global_arguments,
local_path,
remote_path,

View File

@ -1,39 +1,39 @@
import logging
import borgmatic.actions.json
import borgmatic.borg.rinfo
import borgmatic.borg.repo_info
import borgmatic.config.validate
logger = logging.getLogger(__name__)
def run_rinfo(
def run_repo_info(
repository,
config,
local_borg_version,
rinfo_arguments,
repo_info_arguments,
global_arguments,
local_path,
remote_path,
):
'''
Run the "rinfo" action for the given repository.
Run the "repo-info" action for the given repository.
If rinfo_arguments.json is True, yield the JSON output from the info for the repository.
If repo_info_arguments.json is True, yield the JSON output from the info for the repository.
'''
if rinfo_arguments.repository is None or borgmatic.config.validate.repositories_match(
repository, rinfo_arguments.repository
if repo_info_arguments.repository is None or borgmatic.config.validate.repositories_match(
repository, repo_info_arguments.repository
):
if not rinfo_arguments.json:
if not repo_info_arguments.json:
logger.answer(
f'{repository.get("label", repository["path"])}: Displaying repository summary information'
)
json_output = borgmatic.borg.rinfo.display_repository_info(
json_output = borgmatic.borg.repo_info.display_repository_info(
repository['path'],
config,
local_borg_version,
rinfo_arguments=rinfo_arguments,
repo_info_arguments=repo_info_arguments,
global_arguments=global_arguments,
local_path=local_path,
remote_path=remote_path,

View File

@ -1,37 +1,37 @@
import logging
import borgmatic.actions.json
import borgmatic.borg.rlist
import borgmatic.borg.repo_list
import borgmatic.config.validate
logger = logging.getLogger(__name__)
def run_rlist(
def run_repo_list(
repository,
config,
local_borg_version,
rlist_arguments,
repo_list_arguments,
global_arguments,
local_path,
remote_path,
):
'''
Run the "rlist" action for the given repository.
Run the "repo-list" action for the given repository.
If rlist_arguments.json is True, yield the JSON output from listing the repository.
If repo_list_arguments.json is True, yield the JSON output from listing the repository.
'''
if rlist_arguments.repository is None or borgmatic.config.validate.repositories_match(
repository, rlist_arguments.repository
if repo_list_arguments.repository is None or borgmatic.config.validate.repositories_match(
repository, repo_list_arguments.repository
):
if not rlist_arguments.json:
if not repo_list_arguments.json:
logger.answer(f'{repository.get("label", repository["path"])}: Listing repository')
json_output = borgmatic.borg.rlist.list_repository(
json_output = borgmatic.borg.repo_list.list_repository(
repository['path'],
config,
local_borg_version,
rlist_arguments=rlist_arguments,
repo_list_arguments=repo_list_arguments,
global_arguments=global_arguments,
local_path=local_path,
remote_path=remote_path,

View File

@ -5,7 +5,7 @@ import os
import borgmatic.borg.extract
import borgmatic.borg.list
import borgmatic.borg.mount
import borgmatic.borg.rlist
import borgmatic.borg.repo_list
import borgmatic.borg.state
import borgmatic.config.validate
import borgmatic.hooks.dispatch
@ -285,7 +285,7 @@ def run_restore(
global_arguments.dry_run,
)
archive_name = borgmatic.borg.rlist.resolve_archive_name(
archive_name = borgmatic.borg.repo_list.resolve_archive_name(
repository['path'],
restore_arguments.archive,
config,

View File

@ -2,7 +2,7 @@ import argparse
import json
import logging
from borgmatic.borg import environment, feature, flags, rinfo
from borgmatic.borg import environment, feature, flags, repo_info
from borgmatic.execute import DO_NOT_CAPTURE, execute_command
logger = logging.getLogger(__name__)
@ -94,7 +94,7 @@ def get_repository_id(
'''
try:
return json.loads(
rinfo.display_repository_info(
repo_info.display_repository_info(
repository_path,
config,
local_borg_version,

View File

@ -4,7 +4,7 @@ import logging
import borgmatic.borg.environment
import borgmatic.borg.feature
import borgmatic.borg.flags
import borgmatic.borg.rdelete
import borgmatic.borg.repo_delete
import borgmatic.execute
logger = logging.getLogger(__name__)
@ -88,24 +88,24 @@ def delete_archives(
for argument_name in ARCHIVE_RELATED_ARGUMENT_NAMES
):
if borgmatic.borg.feature.available(
borgmatic.borg.feature.Feature.RDELETE, local_borg_version
borgmatic.borg.feature.Feature.REPO_DELETE, local_borg_version
):
logger.warning(
'Deleting an entire repository with the delete action is deprecated when using Borg 2.x+. Use the rdelete action instead.'
'Deleting an entire repository with the delete action is deprecated when using Borg 2.x+. Use the repo-delete action instead.'
)
rdelete_arguments = argparse.Namespace(
repo_delete_arguments = argparse.Namespace(
repository=repository['path'],
list_archives=delete_arguments.list_archives,
force=delete_arguments.force,
cache_only=delete_arguments.cache_only,
keep_security_info=delete_arguments.keep_security_info,
)
borgmatic.borg.rdelete.delete_repository(
borgmatic.borg.repo_delete.delete_repository(
repository,
config,
local_borg_version,
rdelete_arguments,
repo_delete_arguments,
global_arguments,
local_path,
remote_path,

View File

@ -3,7 +3,7 @@ import os
import subprocess
import borgmatic.config.validate
from borgmatic.borg import environment, feature, flags, rlist
from borgmatic.borg import environment, feature, flags, repo_list
from borgmatic.execute import DO_NOT_CAPTURE, execute_command
logger = logging.getLogger(__name__)
@ -29,7 +29,7 @@ def extract_last_archive_dry_run(
verbosity_flags = ('--info',)
try:
last_archive_name = rlist.resolve_archive_name(
last_archive_name = repo_list.resolve_archive_name(
repository_path,
'latest',
config,

View File

@ -10,10 +10,10 @@ class Feature(Enum):
NUMERIC_IDS = 4
UPLOAD_RATELIMIT = 5
SEPARATE_REPOSITORY_ARCHIVE = 6
RCREATE = 7
RLIST = 8
RINFO = 9
RDELETE = 10
REPO_CREATE = 7
REPO_LIST = 8
REPO_INFO = 9
REPO_DELETE = 10
MATCH_ARCHIVES = 11
EXCLUDED_FILES_MINUS = 12
@ -25,10 +25,10 @@ FEATURE_TO_MINIMUM_BORG_VERSION = {
Feature.NUMERIC_IDS: parse('1.2.0b3'), # borg create/extract/mount --numeric-ids
Feature.UPLOAD_RATELIMIT: parse('1.2.0b3'), # borg create --upload-ratelimit
Feature.SEPARATE_REPOSITORY_ARCHIVE: parse('2.0.0a2'), # --repo with separate archive
Feature.RCREATE: parse('2.0.0a2'), # borg rcreate
Feature.RLIST: parse('2.0.0a2'), # borg rlist
Feature.RINFO: parse('2.0.0a2'), # borg rinfo
Feature.RDELETE: parse('2.0.0a2'), # borg rdelete
Feature.REPO_CREATE: parse('2.0.0a2'), # borg repo-create
Feature.REPO_LIST: parse('2.0.0a2'), # borg repo-list
Feature.REPO_INFO: parse('2.0.0a2'), # borg repo-info
Feature.REPO_DELETE: parse('2.0.0a2'), # borg repo-delete
Feature.MATCH_ARCHIVES: parse('2.0.0b3'), # borg --match-archives
Feature.EXCLUDED_FILES_MINUS: parse('2.0.0b5'), # --list --filter uses "-" for excludes
}

View File

@ -4,19 +4,19 @@ import logging
import re
import borgmatic.logger
from borgmatic.borg import environment, feature, flags, rlist
from borgmatic.borg import environment, feature, flags, repo_list
from borgmatic.execute import execute_command, execute_command_and_capture_output
logger = logging.getLogger(__name__)
ARCHIVE_FILTER_FLAGS_MOVED_TO_RLIST = ('prefix', 'match_archives', 'sort_by', 'first', 'last')
ARCHIVE_FILTER_FLAGS_MOVED_TO_REPO_LIST = ('prefix', 'match_archives', 'sort_by', 'first', 'last')
MAKE_FLAGS_EXCLUDES = (
'repository',
'archive',
'paths',
'find_paths',
) + ARCHIVE_FILTER_FLAGS_MOVED_TO_RLIST
) + ARCHIVE_FILTER_FLAGS_MOVED_TO_REPO_LIST
def make_list_command(
@ -155,12 +155,12 @@ def list_archive(
borgmatic.logger.add_custom_log_levels()
if not list_arguments.archive and not list_arguments.find_paths:
if feature.available(feature.Feature.RLIST, local_borg_version):
if feature.available(feature.Feature.REPO_LIST, local_borg_version):
logger.warning(
'Omitting the --archive flag on the list action is deprecated when using Borg 2.x+. Use the rlist action instead.'
'Omitting the --archive flag on the list action is deprecated when using Borg 2.x+. Use the repo-list action instead.'
)
rlist_arguments = argparse.Namespace(
repo_list_arguments = argparse.Namespace(
repository=repository_path,
short=list_arguments.short,
format=list_arguments.format,
@ -171,18 +171,18 @@ def list_archive(
first=list_arguments.first,
last=list_arguments.last,
)
return rlist.list_repository(
return repo_list.list_repository(
repository_path,
config,
local_borg_version,
rlist_arguments,
repo_list_arguments,
global_arguments,
local_path,
remote_path,
)
if list_arguments.archive:
for name in ARCHIVE_FILTER_FLAGS_MOVED_TO_RLIST:
for name in ARCHIVE_FILTER_FLAGS_MOVED_TO_REPO_LIST:
if getattr(list_arguments, name, None):
logger.warning(
f"The --{name.replace('_', '-')} flag on the list action is ignored when using the --archive flag."
@ -199,7 +199,7 @@ def list_archive(
# If there are any paths to find (and there's not a single archive already selected), start by
# getting a list of archives to search.
if list_arguments.find_paths and not list_arguments.archive:
rlist_arguments = argparse.Namespace(
repo_list_arguments = argparse.Namespace(
repository=repository_path,
short=True,
format=None,
@ -214,11 +214,11 @@ def list_archive(
# Ask Borg to list archives. Capture its output for use below.
archive_lines = tuple(
execute_command_and_capture_output(
rlist.make_rlist_command(
repo_list.make_repo_list_command(
repository_path,
config,
local_borg_version,
rlist_arguments,
repo_list_arguments,
global_arguments,
local_path,
remote_path,
@ -242,7 +242,7 @@ def list_archive(
# This list call is to show the files in a single archive, not list multiple archives. So
# blank out any archive filtering flags. They'll break anyway in Borg 2.
for name in ARCHIVE_FILTER_FLAGS_MOVED_TO_RLIST:
for name in ARCHIVE_FILTER_FLAGS_MOVED_TO_REPO_LIST:
setattr(archive_arguments, name, None)
main_command = make_list_command(

View File

@ -3,13 +3,13 @@ import json
import logging
import subprocess
from borgmatic.borg import environment, feature, flags, rinfo
from borgmatic.borg import environment, feature, flags, repo_info
from borgmatic.execute import DO_NOT_CAPTURE, execute_command
logger = logging.getLogger(__name__)
RINFO_REPOSITORY_NOT_FOUND_EXIT_CODES = {2, 13, 15}
REPO_INFO_REPOSITORY_NOT_FOUND_EXIT_CODES = {2, 13, 15}
def create_repository(
@ -39,7 +39,7 @@ def create_repository(
'''
try:
info_data = json.loads(
rinfo.display_repository_info(
repo_info.display_repository_info(
repository_path,
config,
local_borg_version,
@ -59,17 +59,17 @@ def create_repository(
logger.info(f'{repository_path}: Repository already exists. Skipping creation.')
return
except subprocess.CalledProcessError as error:
if error.returncode not in RINFO_REPOSITORY_NOT_FOUND_EXIT_CODES:
if error.returncode not in REPO_INFO_REPOSITORY_NOT_FOUND_EXIT_CODES:
raise
lock_wait = config.get('lock_wait')
extra_borg_options = config.get('extra_borg_options', {}).get('rcreate', '')
extra_borg_options = config.get('extra_borg_options', {}).get('repo-create', '')
rcreate_command = (
repo_create_command = (
(local_path,)
+ (
('rcreate',)
if feature.available(feature.Feature.RCREATE, local_borg_version)
('repo-create',)
if feature.available(feature.Feature.REPO_CREATE, local_borg_version)
else ('init',)
)
+ (('--encryption', encryption_mode) if encryption_mode else ())
@ -93,7 +93,7 @@ def create_repository(
# Do not capture output here, so as to support interactive prompts.
execute_command(
rcreate_command,
repo_create_command,
output_file=DO_NOT_CAPTURE,
extra_environment=environment.make_environment(config),
borg_local_path=local_path,

View File

@ -8,26 +8,26 @@ import borgmatic.execute
logger = logging.getLogger(__name__)
def make_rdelete_command(
def make_repo_delete_command(
repository,
config,
local_borg_version,
rdelete_arguments,
repo_delete_arguments,
global_arguments,
local_path,
remote_path,
):
'''
Given a local or remote repository dict, a configuration dict, the local Borg version, the
arguments to the rdelete action as an argparse.Namespace, and global arguments, return a command
as a tuple to rdelete the entire repository.
arguments to the repo_delete action as an argparse.Namespace, and global arguments, return a command
as a tuple to repo_delete the entire repository.
'''
return (
(local_path,)
+ (
('rdelete',)
('repo-delete',)
if borgmatic.borg.feature.available(
borgmatic.borg.feature.Feature.RDELETE, local_borg_version
borgmatic.borg.feature.Feature.REPO_DELETE, local_borg_version
)
else ('delete',)
)
@ -37,14 +37,14 @@ def make_rdelete_command(
+ borgmatic.borg.flags.make_flags('remote-path', remote_path)
+ borgmatic.borg.flags.make_flags('log-json', global_arguments.log_json)
+ borgmatic.borg.flags.make_flags('lock-wait', config.get('lock_wait'))
+ borgmatic.borg.flags.make_flags('list', rdelete_arguments.list_archives)
+ borgmatic.borg.flags.make_flags('list', repo_delete_arguments.list_archives)
+ (
(('--force',) + (('--force',) if rdelete_arguments.force >= 2 else ()))
if rdelete_arguments.force
(('--force',) + (('--force',) if repo_delete_arguments.force >= 2 else ()))
if repo_delete_arguments.force
else ()
)
+ borgmatic.borg.flags.make_flags_from_arguments(
rdelete_arguments, excludes=('list_archives', 'force', 'repository')
repo_delete_arguments, excludes=('list_archives', 'force', 'repository')
)
+ borgmatic.borg.flags.make_repository_flags(repository['path'], local_borg_version)
)
@ -54,23 +54,23 @@ def delete_repository(
repository,
config,
local_borg_version,
rdelete_arguments,
repo_delete_arguments,
global_arguments,
local_path='borg',
remote_path=None,
):
'''
Given a local or remote repository dict, a configuration dict, the local Borg version, the
arguments to the rdelete action as an argparse.Namespace, global arguments as an
argparse.Namespace, and local and remote Borg paths, rdelete the entire repository.
arguments to the repo_delete action as an argparse.Namespace, global arguments as an
argparse.Namespace, and local and remote Borg paths, repo_delete the entire repository.
'''
borgmatic.logger.add_custom_log_levels()
command = make_rdelete_command(
command = make_repo_delete_command(
repository,
config,
local_borg_version,
rdelete_arguments,
repo_delete_arguments,
global_arguments,
local_path,
remote_path,
@ -83,7 +83,7 @@ def delete_repository(
# prompt won't work.
output_file=(
None
if rdelete_arguments.force or rdelete_arguments.cache_only
if repo_delete_arguments.force or repo_delete_arguments.cache_only
else borgmatic.execute.DO_NOT_CAPTURE
),
extra_environment=borgmatic.borg.environment.make_environment(config),

View File

@ -11,14 +11,14 @@ def display_repository_info(
repository_path,
config,
local_borg_version,
rinfo_arguments,
repo_info_arguments,
global_arguments,
local_path='borg',
remote_path=None,
):
'''
Given a local or remote repository path, a configuration dict, the local Borg version, the
arguments to the rinfo action, and global arguments as an argparse.Namespace, display summary
arguments to the repo_info action, and global arguments as an argparse.Namespace, display summary
information for the Borg repository or return JSON summary information.
'''
borgmatic.logger.add_custom_log_levels()
@ -27,31 +27,31 @@ def display_repository_info(
full_command = (
(local_path,)
+ (
('rinfo',)
if feature.available(feature.Feature.RINFO, local_borg_version)
('repo-info',)
if feature.available(feature.Feature.REPO_INFO, local_borg_version)
else ('info',)
)
+ (
('--info',)
if logger.getEffectiveLevel() == logging.INFO and not rinfo_arguments.json
if logger.getEffectiveLevel() == logging.INFO and not repo_info_arguments.json
else ()
)
+ (
('--debug', '--show-rc')
if logger.isEnabledFor(logging.DEBUG) and not rinfo_arguments.json
if logger.isEnabledFor(logging.DEBUG) and not repo_info_arguments.json
else ()
)
+ flags.make_flags('remote-path', remote_path)
+ flags.make_flags('log-json', global_arguments.log_json)
+ flags.make_flags('lock-wait', lock_wait)
+ (('--json',) if rinfo_arguments.json else ())
+ (('--json',) if repo_info_arguments.json else ())
+ flags.make_repository_flags(repository_path, local_borg_version)
)
extra_environment = environment.make_environment(config)
borg_exit_codes = config.get('borg_exit_codes')
if rinfo_arguments.json:
if repo_info_arguments.json:
return execute_command_and_capture_output(
full_command,
extra_environment=extra_environment,

View File

@ -31,7 +31,11 @@ def resolve_archive_name(
full_command = (
(
local_path,
'rlist' if feature.available(feature.Feature.RLIST, local_borg_version) else 'list',
(
'repo-list'
if feature.available(feature.Feature.REPO_LIST, local_borg_version)
else 'list'
),
)
+ flags.make_flags('remote-path', remote_path)
+ flags.make_flags('log-json', global_arguments.log_json)
@ -60,33 +64,37 @@ def resolve_archive_name(
MAKE_FLAGS_EXCLUDES = ('repository', 'prefix', 'match_archives')
def make_rlist_command(
def make_repo_list_command(
repository_path,
config,
local_borg_version,
rlist_arguments,
repo_list_arguments,
global_arguments,
local_path='borg',
remote_path=None,
):
'''
Given a local or remote repository path, a configuration dict, the local Borg version, the
arguments to the rlist action, global arguments as an argparse.Namespace instance, and local and
arguments to the repo_list action, global arguments as an argparse.Namespace instance, and local and
remote Borg paths, return a command as a tuple to list archives with a repository.
'''
return (
(
local_path,
'rlist' if feature.available(feature.Feature.RLIST, local_borg_version) else 'list',
(
'repo-list'
if feature.available(feature.Feature.REPO_LIST, local_borg_version)
else 'list'
),
)
+ (
('--info',)
if logger.getEffectiveLevel() == logging.INFO and not rlist_arguments.json
if logger.getEffectiveLevel() == logging.INFO and not repo_list_arguments.json
else ()
)
+ (
('--debug', '--show-rc')
if logger.isEnabledFor(logging.DEBUG) and not rlist_arguments.json
if logger.isEnabledFor(logging.DEBUG) and not repo_list_arguments.json
else ()
)
+ flags.make_flags('remote-path', remote_path)
@ -94,20 +102,20 @@ def make_rlist_command(
+ flags.make_flags('lock-wait', config.get('lock_wait'))
+ (
(
flags.make_flags('match-archives', f'sh:{rlist_arguments.prefix}*')
flags.make_flags('match-archives', f'sh:{repo_list_arguments.prefix}*')
if feature.available(feature.Feature.MATCH_ARCHIVES, local_borg_version)
else flags.make_flags('glob-archives', f'{rlist_arguments.prefix}*')
else flags.make_flags('glob-archives', f'{repo_list_arguments.prefix}*')
)
if rlist_arguments.prefix
if repo_list_arguments.prefix
else (
flags.make_match_archives_flags(
rlist_arguments.match_archives or config.get('match_archives'),
repo_list_arguments.match_archives or config.get('match_archives'),
config.get('archive_name_format'),
local_borg_version,
)
)
)
+ flags.make_flags_from_arguments(rlist_arguments, excludes=MAKE_FLAGS_EXCLUDES)
+ flags.make_flags_from_arguments(repo_list_arguments, excludes=MAKE_FLAGS_EXCLUDES)
+ flags.make_repository_flags(repository_path, local_borg_version)
)
@ -116,7 +124,7 @@ def list_repository(
repository_path,
config,
local_borg_version,
rlist_arguments,
repo_list_arguments,
global_arguments,
local_path='borg',
remote_path=None,
@ -130,20 +138,20 @@ def list_repository(
borgmatic.logger.add_custom_log_levels()
borg_environment = environment.make_environment(config)
main_command = make_rlist_command(
main_command = make_repo_list_command(
repository_path,
config,
local_borg_version,
rlist_arguments,
repo_list_arguments,
global_arguments,
local_path,
remote_path,
)
json_command = make_rlist_command(
json_command = make_repo_list_command(
repository_path,
config,
local_borg_version,
argparse.Namespace(**dict(rlist_arguments.__dict__, json=True)),
argparse.Namespace(**dict(repo_list_arguments.__dict__, json=True)),
global_arguments,
local_path,
remote_path,
@ -157,7 +165,7 @@ def list_repository(
borg_exit_codes=borg_exit_codes,
)
if rlist_arguments.json:
if repo_list_arguments.json:
return json_listing
flags.warn_for_aggressive_archive_flags(json_command, json_listing)

View File

@ -6,7 +6,7 @@ from argparse import ArgumentParser
from borgmatic.config import collect
ACTION_ALIASES = {
'rcreate': ['init', '-I'],
'repo-create': ['rcreate', 'init', '-I'],
'prune': ['-p'],
'compact': [],
'create': ['-C'],
@ -18,10 +18,10 @@ ACTION_ALIASES = {
'mount': ['-m'],
'umount': ['-u'],
'restore': ['-r'],
'rdelete': [],
'rlist': [],
'repo-delete': ['rdelete'],
'repo-list': ['rlist'],
'list': ['-l'],
'rinfo': [],
'repo-info': ['rinfo'],
'info': ['-i'],
'transfer': [],
'break-lock': [],
@ -402,51 +402,51 @@ def make_parsers():
metavar='',
help='Specify zero or more actions. Defaults to create, prune, compact, and check. Use --help with action for details:',
)
rcreate_parser = action_parsers.add_parser(
'rcreate',
aliases=ACTION_ALIASES['rcreate'],
repo_create_parser = action_parsers.add_parser(
'repo-create',
aliases=ACTION_ALIASES['repo-create'],
help='Create a new, empty Borg repository',
description='Create a new, empty Borg repository',
add_help=False,
)
rcreate_group = rcreate_parser.add_argument_group('rcreate arguments')
rcreate_group.add_argument(
repo_create_group = repo_create_parser.add_argument_group('repo-create arguments')
repo_create_group.add_argument(
'-e',
'--encryption',
dest='encryption_mode',
help='Borg repository encryption mode',
required=True,
)
rcreate_group.add_argument(
repo_create_group.add_argument(
'--source-repository',
'--other-repo',
metavar='KEY_REPOSITORY',
help='Path to an existing Borg repository whose key material should be reused [Borg 2.x+ only]',
)
rcreate_group.add_argument(
repo_create_group.add_argument(
'--repository',
help='Path of the new repository to create (must be already specified in a borgmatic configuration file), defaults to the configured repository if there is only one, quoted globs supported',
)
rcreate_group.add_argument(
repo_create_group.add_argument(
'--copy-crypt-key',
action='store_true',
help='Copy the crypt key used for authenticated encryption from the source repository, defaults to a new random key [Borg 2.x+ only]',
)
rcreate_group.add_argument(
repo_create_group.add_argument(
'--append-only',
action='store_true',
help='Create an append-only repository',
)
rcreate_group.add_argument(
repo_create_group.add_argument(
'--storage-quota',
help='Create a repository with a fixed storage quota',
)
rcreate_group.add_argument(
repo_create_group.add_argument(
'--make-parent-dirs',
action='store_true',
help='Create any missing parent directories of the repository directory',
)
rcreate_group.add_argument(
repo_create_group.add_argument(
'-h', '--help', action='help', help='Show this help message and exit'
)
@ -1070,40 +1070,40 @@ def make_parsers():
)
umount_group.add_argument('-h', '--help', action='help', help='Show this help message and exit')
rdelete_parser = action_parsers.add_parser(
'rdelete',
aliases=ACTION_ALIASES['rdelete'],
repo_delete_parser = action_parsers.add_parser(
'repo-delete',
aliases=ACTION_ALIASES['repo-delete'],
help='Delete an entire repository (with Borg 1.2+, you must run compact afterwards to actually free space)',
description='Delete an entire repository (with Borg 1.2+, you must run compact afterwards to actually free space)',
add_help=False,
)
rdelete_group = rdelete_parser.add_argument_group('delete arguments')
rdelete_group.add_argument(
repo_delete_group = repo_delete_parser.add_argument_group('delete arguments')
repo_delete_group.add_argument(
'--repository',
help='Path of repository to delete, defaults to the configured repository if there is only one, quoted globs supported',
)
rdelete_group.add_argument(
repo_delete_group.add_argument(
'--list',
dest='list_archives',
action='store_true',
help='Show details for the archives in the given repository',
)
rdelete_group.add_argument(
repo_delete_group.add_argument(
'--force',
action='count',
help='Force deletion of corrupted archives, can be given twice if once does not work',
)
rdelete_group.add_argument(
repo_delete_group.add_argument(
'--cache-only',
action='store_true',
help='Delete only the local cache for the given repository',
)
rdelete_group.add_argument(
repo_delete_group.add_argument(
'--keep-security-info',
action='store_true',
help='Do not delete the local security info when deleting a repository',
)
rdelete_group.add_argument(
repo_delete_group.add_argument(
'-h', '--help', action='help', help='Show this help message and exit'
)
@ -1161,65 +1161,67 @@ def make_parsers():
'-h', '--help', action='help', help='Show this help message and exit'
)
rlist_parser = action_parsers.add_parser(
'rlist',
aliases=ACTION_ALIASES['rlist'],
repo_list_parser = action_parsers.add_parser(
'repo-list',
aliases=ACTION_ALIASES['repo-list'],
help='List repository',
description='List the archives in a repository',
add_help=False,
)
rlist_group = rlist_parser.add_argument_group('rlist arguments')
rlist_group.add_argument(
repo_list_group = repo_list_parser.add_argument_group('repo-list arguments')
repo_list_group.add_argument(
'--repository',
help='Path of repository to list, defaults to the configured repositories, quoted globs supported',
)
rlist_group.add_argument(
repo_list_group.add_argument(
'--short', default=False, action='store_true', help='Output only archive names'
)
rlist_group.add_argument('--format', help='Format for archive listing')
rlist_group.add_argument(
repo_list_group.add_argument('--format', help='Format for archive listing')
repo_list_group.add_argument(
'--json', default=False, action='store_true', help='Output results as JSON'
)
rlist_group.add_argument(
repo_list_group.add_argument(
'-P', '--prefix', help='Deprecated. Only list archive names starting with this prefix'
)
rlist_group.add_argument(
repo_list_group.add_argument(
'-a',
'--match-archives',
'--glob-archives',
metavar='PATTERN',
help='Only list archive names matching this pattern',
)
rlist_group.add_argument(
repo_list_group.add_argument(
'--sort-by', metavar='KEYS', help='Comma-separated list of sorting keys'
)
rlist_group.add_argument(
repo_list_group.add_argument(
'--first', metavar='N', help='List first N archives after other filters are applied'
)
rlist_group.add_argument(
repo_list_group.add_argument(
'--last', metavar='N', help='List last N archives after other filters are applied'
)
rlist_group.add_argument(
repo_list_group.add_argument(
'--oldest',
metavar='TIMESPAN',
help='List archives within a specified time range starting from the timestamp of the oldest archive (e.g. 7d or 12m) [Borg 2.x+ only]',
)
rlist_group.add_argument(
repo_list_group.add_argument(
'--newest',
metavar='TIMESPAN',
help='List archives within a time range that ends at timestamp of the newest archive and starts a specified time range ago (e.g. 7d or 12m) [Borg 2.x+ only]',
)
rlist_group.add_argument(
repo_list_group.add_argument(
'--older',
metavar='TIMESPAN',
help='List archives that are older than the specified time range (e.g. 7d or 12m) from the current time [Borg 2.x+ only]',
)
rlist_group.add_argument(
repo_list_group.add_argument(
'--newer',
metavar='TIMESPAN',
help='List archives that are newer than the specified time range (e.g. 7d or 12m) from the current time [Borg 2.x+ only]',
)
rlist_group.add_argument('-h', '--help', action='help', help='Show this help message and exit')
repo_list_group.add_argument(
'-h', '--help', action='help', help='Show this help message and exit'
)
list_parser = action_parsers.add_parser(
'list',
@ -1288,22 +1290,24 @@ def make_parsers():
)
list_group.add_argument('-h', '--help', action='help', help='