2019-06-23 04:32:27 +00:00
import collections
2023-06-06 18:07:09 +00:00
import itertools
2023-06-19 23:18:47 +00:00
import sys
2023-07-14 02:25:14 +00:00
from argparse import ArgumentParser
2019-06-23 04:32:27 +00:00
from borgmatic . config import collect
2023-06-19 23:18:47 +00:00
ACTION_ALIASES = {
2022-08-21 21:25:16 +00:00
' rcreate ' : [ ' init ' , ' -I ' ] ,
' prune ' : [ ' -p ' ] ,
2022-02-08 07:29:44 +00:00
' compact ' : [ ] ,
2022-08-21 21:25:16 +00:00
' create ' : [ ' -C ' ] ,
' check ' : [ ' -k ' ] ,
2023-05-25 18:56:13 +00:00
' config ' : [ ] ,
2022-08-21 21:25:16 +00:00
' extract ' : [ ' -x ' ] ,
' export-tar ' : [ ] ,
' mount ' : [ ' -m ' ] ,
' umount ' : [ ' -u ' ] ,
' restore ' : [ ' -r ' ] ,
2022-08-15 22:04:40 +00:00
' rlist ' : [ ] ,
2022-08-21 21:25:16 +00:00
' list ' : [ ' -l ' ] ,
2022-08-13 06:06:56 +00:00
' rinfo ' : [ ] ,
2022-08-21 21:25:16 +00:00
' info ' : [ ' -i ' ] ,
2022-08-18 21:28:12 +00:00
' transfer ' : [ ] ,
2022-10-04 20:42:18 +00:00
' break-lock ' : [ ] ,
2021-06-18 03:41:44 +00:00
' borg ' : [ ] ,
2019-06-23 04:32:27 +00:00
}
2023-06-19 23:18:47 +00:00
def get_subaction_parsers ( action_parser ) :
2023-06-09 12:01:57 +00:00
'''
2023-06-19 23:18:47 +00:00
Given an argparse . ArgumentParser instance , lookup the subactions in it and return a dict from
subaction name to subaction parser .
2023-06-09 12:01:57 +00:00
'''
2023-06-19 23:18:47 +00:00
if not action_parser . _subparsers :
return { }
2023-06-07 19:32:43 +00:00
2023-06-19 23:18:47 +00:00
return {
subaction_name : subaction_parser
for group_action in action_parser . _subparsers . _group_actions
for subaction_name , subaction_parser in group_action . choices . items ( )
}
2023-06-07 19:32:43 +00:00
2023-06-19 23:18:47 +00:00
def get_subactions_for_actions ( action_parsers ) :
2019-06-23 04:32:27 +00:00
'''
2023-06-19 23:18:47 +00:00
Given a dict from action name to an argparse . ArgumentParser instance , make a map from action
name to the names of contained sub - actions .
2019-06-23 04:32:27 +00:00
'''
2023-06-19 23:18:47 +00:00
return {
action : tuple (
subaction_name
for group_action in action_parser . _subparsers . _group_actions
for subaction_name in group_action . choices . keys ( )
)
for action , action_parser in action_parsers . items ( )
if action_parser . _subparsers
2023-05-26 17:14:31 +00:00
}
2019-06-23 04:32:27 +00:00
2021-06-18 03:41:44 +00:00
2023-06-19 23:18:47 +00:00
def omit_values_colliding_with_action_names ( unparsed_arguments , parsed_arguments ) :
'''
Given a sequence of string arguments and a dict from action name to parsed argparse . Namespace
arguments , return the string arguments with any values omitted that happen to be the same as
the name of a borgmatic action .
2019-06-23 04:32:27 +00:00
2023-06-19 23:18:47 +00:00
This prevents , for instance , " check --only extract " from triggering the " extract " action .
'''
remaining_arguments = list ( unparsed_arguments )
2019-06-23 04:32:27 +00:00
2023-06-19 23:18:47 +00:00
for action_name , parsed in parsed_arguments . items ( ) :
2019-09-20 18:43:27 +00:00
for value in vars ( parsed ) . values ( ) :
if isinstance ( value , str ) :
2023-06-19 23:18:47 +00:00
if value in ACTION_ALIASES . keys ( ) :
2019-09-20 18:43:27 +00:00
remaining_arguments . remove ( value )
elif isinstance ( value , list ) :
for item in value :
2023-06-19 23:18:47 +00:00
if item in ACTION_ALIASES . keys ( ) :
2019-09-20 18:43:27 +00:00
remaining_arguments . remove ( item )
2023-06-19 23:18:47 +00:00
return tuple ( remaining_arguments )
2023-06-06 18:07:09 +00:00
2019-06-23 04:32:27 +00:00
2023-06-19 23:18:47 +00:00
def parse_and_record_action_arguments (
unparsed_arguments , parsed_arguments , action_parser , action_name , canonical_name = None
) :
'''
Given unparsed arguments as a sequence of strings , parsed arguments as a dict from action name
to parsed argparse . Namespace , a parser to parse with , an action name , and an optional canonical
action name ( in case this the action name is an alias ) , parse the arguments and return a list of
any remaining string arguments that were not parsed . Also record the parsed argparse . Namespace
by setting it into the given parsed arguments . Return None if no parsing occurs because the
given action doesn ' t apply to the given unparsed arguments.
'''
filtered_arguments = omit_values_colliding_with_action_names (
unparsed_arguments , parsed_arguments
)
2019-06-23 04:32:27 +00:00
2023-06-19 23:18:47 +00:00
if action_name not in filtered_arguments :
return tuple ( unparsed_arguments )
parsed , remaining = action_parser . parse_known_args ( filtered_arguments )
parsed_arguments [ canonical_name or action_name ] = parsed
# Special case: If this is a "borg" action, greedily consume all arguments after (+1) the "borg"
# argument.
if action_name == ' borg ' :
borg_options_index = remaining . index ( ' borg ' ) + 1
parsed_arguments [ ' borg ' ] . options = remaining [ borg_options_index : ]
remaining = remaining [ : borg_options_index ]
return tuple ( argument for argument in remaining if argument != action_name )
def get_unparsable_arguments ( remaining_action_arguments ) :
'''
2023-06-24 21:10:47 +00:00
Given a sequence of argument tuples ( one per action parser that parsed arguments ) , determine the
remaining arguments that no action parsers have consumed .
2023-06-19 23:18:47 +00:00
'''
if not remaining_action_arguments :
return ( )
return tuple (
argument
for argument in dict . fromkeys (
itertools . chain . from_iterable ( remaining_action_arguments )
) . keys ( )
if all ( argument in action_arguments for action_arguments in remaining_action_arguments )
)
2019-06-23 04:32:27 +00:00
2023-06-08 18:51:41 +00:00
2023-06-24 21:10:47 +00:00
def parse_arguments_for_actions ( unparsed_arguments , action_parsers , global_parser ) :
2023-06-19 23:18:47 +00:00
'''
2023-06-24 21:10:47 +00:00
Given a sequence of arguments , a dict from action name to argparse . ArgumentParser instance ,
and the global parser as a argparse . ArgumentParser instance , give each requested action ' s
parser a shot at parsing all arguments . This allows common arguments like " --repository " to be
shared across multiple action parsers .
2023-06-19 23:18:47 +00:00
Return the result as a tuple of : ( a dict mapping from action name to an argparse . Namespace of
2023-06-24 21:10:47 +00:00
parsed arguments , a tuple of argument tuples where each is the remaining arguments not claimed
by any action parser ) .
2023-06-19 23:18:47 +00:00
'''
arguments = collections . OrderedDict ( )
help_requested = bool ( ' --help ' in unparsed_arguments or ' -h ' in unparsed_arguments )
remaining_action_arguments = [ ]
alias_to_action_name = {
alias : action_name for action_name , aliases in ACTION_ALIASES . items ( ) for alias in aliases
}
# If the "borg" action is used, skip all other action parsers. This avoids confusion like
# "borg list" triggering borgmatic's own list action.
if ' borg ' in unparsed_arguments :
action_parsers = { ' borg ' : action_parsers [ ' borg ' ] }
# Ask each action parser, one by one, to parse arguments.
for argument in unparsed_arguments :
action_name = argument
canonical_name = alias_to_action_name . get ( action_name , action_name )
action_parser = action_parsers . get ( action_name )
if not action_parser :
2019-09-20 18:43:27 +00:00
continue
2019-06-23 04:32:27 +00:00
2023-06-19 23:18:47 +00:00
subaction_parsers = get_subaction_parsers ( action_parser )
2023-06-08 18:51:41 +00:00
2023-06-21 17:41:32 +00:00
# But first parse with subaction parsers, if any.
2023-06-19 23:18:47 +00:00
if subaction_parsers :
subactions_parsed = False
2019-09-20 18:43:27 +00:00
2023-06-19 23:18:47 +00:00
for subaction_name , subaction_parser in subaction_parsers . items ( ) :
remaining_action_arguments . append (
2023-06-21 17:41:32 +00:00
tuple (
argument
for argument in parse_and_record_action_arguments (
unparsed_arguments ,
arguments ,
subaction_parser ,
subaction_name ,
)
if argument != action_name
2023-06-19 23:18:47 +00:00
)
)
2019-09-22 18:30:58 +00:00
2023-06-19 23:18:47 +00:00
if subaction_name in arguments :
subactions_parsed = True
if not subactions_parsed :
if help_requested :
action_parser . print_help ( )
sys . exit ( 0 )
else :
raise ValueError (
f " Missing sub-action after { action_name } action. Expected one of: { ' , ' . join ( get_subactions_for_actions ( action_parsers ) [ action_name ] ) } "
)
# Otherwise, parse with the main action parser.
else :
remaining_action_arguments . append (
parse_and_record_action_arguments (
unparsed_arguments , arguments , action_parser , action_name , canonical_name
)
)
2019-09-20 18:43:27 +00:00
2023-06-19 23:18:47 +00:00
# If no actions were explicitly requested, assume defaults.
if not arguments and not help_requested :
for default_action_name in ( ' create ' , ' prune ' , ' compact ' , ' check ' ) :
default_action_parser = action_parsers [ default_action_name ]
remaining_action_arguments . append (
parse_and_record_action_arguments (
tuple ( unparsed_arguments ) + ( default_action_name , ) ,
arguments ,
default_action_parser ,
default_action_name ,
)
)
2023-06-24 21:10:47 +00:00
arguments [ ' global ' ] , remaining = global_parser . parse_known_args ( unparsed_arguments )
remaining_action_arguments . append ( remaining )
2023-06-19 23:18:47 +00:00
return (
arguments ,
2023-06-24 21:10:47 +00:00
tuple ( remaining_action_arguments ) if arguments else unparsed_arguments ,
2023-06-19 23:18:47 +00:00
)
2019-06-23 04:32:27 +00:00
2022-05-26 17:27:53 +00:00
def make_parsers ( ) :
2019-06-23 04:32:27 +00:00
'''
2023-06-24 21:10:47 +00:00
Build a global arguments parser , individual action parsers , and a combined parser containing
both . Return them as a tuple . The global parser is useful for parsing just global arguments
while ignoring actions , and the combined parser is handy for displaying help that includes
everything : global flags , a list of actions , etc .
2019-06-23 04:32:27 +00:00
'''
2020-01-02 18:37:31 +00:00
config_paths = collect . get_default_config_paths ( expand_home = True )
unexpanded_config_paths = collect . get_default_config_paths ( expand_home = False )
2019-06-23 04:32:27 +00:00
global_parser = ArgumentParser ( add_help = False )
global_group = global_parser . add_argument_group ( ' global arguments ' )
global_group . add_argument (
' -c ' ,
' --config ' ,
dest = ' config_paths ' ,
2023-07-14 02:25:14 +00:00
action = ' append ' ,
help = f " Configuration filename or directory, can specify flag multiple times, defaults to: { ' ' . join ( unexpanded_config_paths ) } " ,
2019-06-23 04:32:27 +00:00
)
global_group . add_argument (
' -n ' ,
' --dry-run ' ,
dest = ' dry_run ' ,
action = ' store_true ' ,
help = ' Go through the motions, but do not actually write to any repositories ' ,
)
global_group . add_argument (
' -nc ' , ' --no-color ' , dest = ' no_color ' , action = ' store_true ' , help = ' Disable colored output '
)
global_group . add_argument (
' -v ' ,
' --verbosity ' ,
type = int ,
2023-04-30 22:01:45 +00:00
choices = range ( - 2 , 3 ) ,
2019-06-23 04:32:27 +00:00
default = 0 ,
2023-05-28 19:39:00 +00:00
help = ' Display verbose progress to the console (disabled, errors only, default, some, or lots: -2, -1, 0, 1, or 2) ' ,
2019-06-23 04:32:27 +00:00
)
global_group . add_argument (
' --syslog-verbosity ' ,
type = int ,
2023-04-30 22:01:45 +00:00
choices = range ( - 2 , 3 ) ,
2019-06-23 04:32:27 +00:00
default = 0 ,
2023-05-28 19:39:00 +00:00
help = ' Log verbose progress to syslog (disabled, errors only, default, some, or lots: -2, -1, 0, 1, or 2). Ignored when console is interactive or --log-file is given ' ,
2019-11-02 18:23:18 +00:00
)
global_group . add_argument (
' --log-file-verbosity ' ,
type = int ,
2023-04-30 22:01:45 +00:00
choices = range ( - 2 , 3 ) ,
2019-11-03 08:55:19 +00:00
default = 0 ,
2023-05-28 19:39:00 +00:00
help = ' Log verbose progress to log file (disabled, errors only, default, some, or lots: -2, -1, 0, 1, or 2). Only used when --log-file is given ' ,
2019-06-23 04:32:27 +00:00
)
2020-01-22 23:10:47 +00:00
global_group . add_argument (
' --monitoring-verbosity ' ,
type = int ,
2023-04-30 22:01:45 +00:00
choices = range ( - 2 , 3 ) ,
2020-01-31 18:23:36 +00:00
default = 0 ,
2023-05-08 12:24:04 +00:00
help = ' Log verbose progress to monitoring integrations that support logging (from disabled, errors only, default, some, or lots: -2, -1, 0, 1, or 2) ' ,
2020-01-22 23:10:47 +00:00
)
2019-10-31 09:44:22 +00:00
global_group . add_argument (
' --log-file ' ,
type = str ,
2019-11-02 18:23:18 +00:00
help = ' Write log messages to this file instead of syslog ' ,
2019-10-31 09:44:22 +00:00
)
2023-04-03 06:06:36 +00:00
global_group . add_argument (
' --log-file-format ' ,
2019-10-31 09:44:22 +00:00
type = str ,
2023-04-03 06:06:36 +00:00
help = ' Log format string used for log messages written to the log file ' ,
2019-10-31 09:44:22 +00:00
)
2023-05-09 06:00:49 +00:00
global_group . add_argument (
' --log-json ' ,
action = ' store_true ' ,
help = ' Write log messages and console output as one JSON object per log line instead of formatted text ' ,
)
2019-12-17 19:46:27 +00:00
global_group . add_argument (
' --override ' ,
2023-07-09 06:14:30 +00:00
metavar = ' OPTION.SUBOPTION=VALUE ' ,
2019-12-17 19:46:27 +00:00
dest = ' overrides ' ,
2023-07-14 02:25:14 +00:00
action = ' append ' ,
help = ' Configuration file option to override with specified value, can specify flag multiple times ' ,
2019-12-17 19:46:27 +00:00
)
2022-06-16 16:52:54 +00:00
global_group . add_argument (
2022-06-16 18:35:24 +00:00
' --no-environment-interpolation ' ,
2022-06-16 16:52:54 +00:00
dest = ' resolve_env ' ,
action = ' store_false ' ,
help = ' Do not resolve environment variables in configuration file ' ,
)
2022-05-26 17:27:53 +00:00
global_group . add_argument (
' --bash-completion ' ,
default = False ,
action = ' store_true ' ,
help = ' Show bash completion script and exit ' ,
)
2023-04-28 01:46:13 +00:00
global_group . add_argument (
' --fish-completion ' ,
default = False ,
action = ' store_true ' ,
help = ' Show fish completion script and exit ' ,
)
2019-06-23 04:32:27 +00:00
global_group . add_argument (
' --version ' ,
dest = ' version ' ,
default = False ,
action = ' store_true ' ,
help = ' Display installed version number of borgmatic and exit ' ,
)
2023-06-24 21:10:47 +00:00
global_plus_action_parser = ArgumentParser (
2019-06-23 04:32:27 +00:00
description = '''
2019-11-18 06:49:16 +00:00
Simple , configuration - driven backup software for servers and workstations . If none of
2023-03-08 22:05:06 +00:00
the action options are given , then borgmatic defaults to : create , prune , compact , and
2022-02-09 22:33:12 +00:00
check .
2019-06-23 04:32:27 +00:00
''' ,
parents = [ global_parser ] ,
)
2023-06-24 21:10:47 +00:00
action_parsers = global_plus_action_parser . add_subparsers (
2019-06-23 16:46:22 +00:00
title = ' actions ' ,
metavar = ' ' ,
2023-03-24 21:14:56 +00:00
help = ' Specify zero or more actions. Defaults to create, prune, compact, and check. Use --help with action for details: ' ,
2019-06-23 16:46:22 +00:00
)
2023-06-19 23:18:47 +00:00
rcreate_parser = action_parsers . add_parser (
2022-08-12 21:53:20 +00:00
' rcreate ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' rcreate ' ] ,
2022-08-12 21:53:20 +00:00
help = ' Create a new, empty Borg repository ' ,
description = ' Create a new, empty Borg repository ' ,
2019-06-23 04:32:27 +00:00
add_help = False ,
)
2022-08-12 21:53:20 +00:00
rcreate_group = rcreate_parser . add_argument_group ( ' rcreate arguments ' )
rcreate_group . add_argument (
2019-06-23 04:32:27 +00:00
' -e ' ,
' --encryption ' ,
dest = ' encryption_mode ' ,
help = ' Borg repository encryption mode ' ,
required = True ,
)
2022-08-18 00:33:09 +00:00
rcreate_group . add_argument (
2022-08-19 06:06:51 +00:00
' --source-repository ' ,
2022-08-18 00:33:09 +00:00
' --other-repo ' ,
2022-08-19 06:06:51 +00:00
metavar = ' KEY_REPOSITORY ' ,
2023-03-28 12:45:49 +00:00
help = ' Path to an existing Borg repository whose key material should be reused [Borg 2.x+ only] ' ,
2022-08-18 00:33:09 +00:00
)
2023-02-27 07:22:23 +00:00
rcreate_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 ' ,
)
2022-08-12 21:53:20 +00:00
rcreate_group . add_argument (
2022-08-18 21:28:12 +00:00
' --copy-crypt-key ' ,
2019-06-23 04:32:27 +00:00
action = ' store_true ' ,
2023-03-28 12:45:49 +00:00
help = ' Copy the crypt key used for authenticated encryption from the source repository, defaults to a new random key [Borg 2.x+ only] ' ,
2019-06-23 04:32:27 +00:00
)
2022-08-12 21:53:20 +00:00
rcreate_group . add_argument (
2023-04-15 02:35:24 +00:00
' --append-only ' ,
action = ' store_true ' ,
help = ' Create an append-only repository ' ,
2022-08-18 21:28:12 +00:00
)
rcreate_group . add_argument (
2023-04-15 02:35:24 +00:00
' --storage-quota ' ,
help = ' Create a repository with a fixed storage quota ' ,
2022-08-18 21:28:12 +00:00
)
rcreate_group . add_argument (
' --make-parent-dirs ' ,
action = ' store_true ' ,
help = ' Create any missing parent directories of the repository directory ' ,
2019-06-23 04:32:27 +00:00
)
2022-08-12 21:53:20 +00:00
rcreate_group . add_argument (
' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit '
)
2019-06-23 04:32:27 +00:00
2023-06-19 23:18:47 +00:00
transfer_parser = action_parsers . add_parser (
2022-08-19 06:06:51 +00:00
' transfer ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' transfer ' ] ,
2023-03-28 12:45:49 +00:00
help = ' Transfer archives from one repository to another, optionally upgrading the transferred data [Borg 2.0+ only] ' ,
description = ' Transfer archives from one repository to another, optionally upgrading the transferred data [Borg 2.0+ only] ' ,
2022-08-19 06:06:51 +00:00
add_help = False ,
)
transfer_group = transfer_parser . add_argument_group ( ' transfer arguments ' )
transfer_group . add_argument (
' --repository ' ,
help = ' Path of existing destination repository to transfer archives to, defaults to the configured repository if there is only one ' ,
)
transfer_group . add_argument (
' --source-repository ' ,
help = ' Path of existing source repository to transfer archives from ' ,
required = True ,
)
transfer_group . add_argument (
' --archive ' ,
help = ' Name of single archive to transfer (or " latest " ), defaults to transferring all archives ' ,
)
transfer_group . add_argument (
' --upgrader ' ,
2023-04-01 16:40:32 +00:00
help = ' Upgrader type used to convert the transferred data, e.g. " From12To20 " to upgrade data from Borg 1.2 to 2.0 format, defaults to no conversion ' ,
2022-08-19 06:06:51 +00:00
)
2023-02-27 07:22:23 +00:00
transfer_group . add_argument (
' --progress ' ,
default = False ,
action = ' store_true ' ,
help = ' Display progress as each archive is transferred ' ,
)
2022-08-19 06:06:51 +00:00
transfer_group . add_argument (
' -a ' ,
2022-10-04 05:50:37 +00:00
' --match-archives ' ,
2022-08-19 06:06:51 +00:00
' --glob-archives ' ,
2022-10-04 05:50:37 +00:00
metavar = ' PATTERN ' ,
help = ' Only transfer archives with names matching this pattern ' ,
2022-08-19 06:06:51 +00:00
)
transfer_group . add_argument (
' --sort-by ' , metavar = ' KEYS ' , help = ' Comma-separated list of sorting keys '
)
transfer_group . add_argument (
' --first ' ,
metavar = ' N ' ,
help = ' Only transfer first N archives after other filters are applied ' ,
)
transfer_group . add_argument (
' --last ' , metavar = ' N ' , help = ' Only transfer last N archives after other filters are applied '
)
2023-03-25 20:28:03 +00:00
transfer_group . add_argument (
2023-04-27 16:57:23 +00:00
' --oldest ' ,
metavar = ' TIMESPAN ' ,
help = ' Transfer archives within a specified time range starting from the timestamp of the oldest archive (e.g. 7d or 12m) [Borg 2.x+ only] ' ,
2023-03-25 20:28:03 +00:00
)
transfer_group . add_argument (
2023-04-27 16:57:23 +00:00
' --newest ' ,
metavar = ' TIMESPAN ' ,
help = ' Transfer 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] ' ,
2023-03-25 20:28:03 +00:00
)
transfer_group . add_argument (
2023-04-27 16:57:23 +00:00
' --older ' ,
metavar = ' TIMESPAN ' ,
help = ' Transfer archives that are older than the specified time range (e.g. 7d or 12m) from the current time [Borg 2.x+ only] ' ,
2023-03-25 20:28:03 +00:00
)
transfer_group . add_argument (
2023-04-27 16:57:23 +00:00
' --newer ' ,
metavar = ' TIMESPAN ' ,
help = ' Transfer archives that are newer than the specified time range (e.g. 7d or 12m) from the current time [Borg 2.x+ only] ' ,
2023-03-25 20:28:03 +00:00
)
2022-08-19 06:06:51 +00:00
transfer_group . add_argument (
' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit '
)
2023-06-19 23:18:47 +00:00
prune_parser = action_parsers . add_parser (
2019-06-23 04:32:27 +00:00
' prune ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' prune ' ] ,
2022-02-09 22:33:12 +00:00
help = ' Prune archives according to the retention policy (with Borg 1.2+, run compact afterwards to actually free space) ' ,
description = ' Prune archives according to the retention policy (with Borg 1.2+, run compact afterwards to actually free space) ' ,
2019-06-23 04:32:27 +00:00
add_help = False ,
)
prune_group = prune_parser . add_argument_group ( ' prune arguments ' )
2023-03-15 16:39:54 +00:00
prune_group . add_argument (
' --repository ' ,
help = ' Path of specific existing repository to prune (must be already specified in a borgmatic configuration file) ' ,
)
2019-06-23 04:32:27 +00:00
prune_group . add_argument (
' --stats ' ,
dest = ' stats ' ,
default = False ,
action = ' store_true ' ,
help = ' Display statistics of archive ' ,
)
2020-01-11 15:38:07 +00:00
prune_group . add_argument (
2022-08-21 21:25:16 +00:00
' --list ' , dest = ' list_archives ' , action = ' store_true ' , help = ' List archives kept/pruned '
2020-01-11 15:38:07 +00:00
)
2023-03-25 20:28:03 +00:00
prune_group . add_argument (
2023-04-27 16:57:23 +00:00
' --oldest ' ,
metavar = ' TIMESPAN ' ,
help = ' Prune archives within a specified time range starting from the timestamp of the oldest archive (e.g. 7d or 12m) [Borg 2.x+ only] ' ,
2023-03-25 20:28:03 +00:00
)
prune_group . add_argument (
2023-04-27 16:57:23 +00:00
' --newest ' ,
metavar = ' TIMESPAN ' ,
help = ' Prune 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] ' ,
2023-03-25 20:28:03 +00:00
)
prune_group . add_argument (
2023-04-27 16:57:23 +00:00
' --older ' ,
metavar = ' TIMESPAN ' ,
help = ' Prune archives that are older than the specified time range (e.g. 7d or 12m) from the current time [Borg 2.x+ only] ' ,
2023-03-25 20:28:03 +00:00
)
prune_group . add_argument (
2023-04-27 16:57:23 +00:00
' --newer ' ,
metavar = ' TIMESPAN ' ,
help = ' Prune archives that are newer than the specified time range (e.g. 7d or 12m) from the current time [Borg 2.x+ only] ' ,
2023-03-25 20:28:03 +00:00
)
2019-06-23 04:32:27 +00:00
prune_group . add_argument ( ' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit ' )
2023-06-19 23:18:47 +00:00
compact_parser = action_parsers . add_parser (
2022-02-08 07:29:44 +00:00
' compact ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' compact ' ] ,
2023-03-28 12:45:49 +00:00
help = ' Compact segments to free space [Borg 1.2+, borgmatic 1.5.23+ only] ' ,
description = ' Compact segments to free space [Borg 1.2+, borgmatic 1.5.23+ only] ' ,
2022-02-08 07:29:44 +00:00
add_help = False ,
)
compact_group = compact_parser . add_argument_group ( ' compact arguments ' )
2023-03-16 15:13:45 +00:00
compact_group . add_argument (
' --repository ' ,
help = ' Path of specific existing repository to compact (must be already specified in a borgmatic configuration file) ' ,
)
2022-02-08 07:29:44 +00:00
compact_group . add_argument (
' --progress ' ,
dest = ' progress ' ,
default = False ,
action = ' store_true ' ,
help = ' Display progress as each segment is compacted ' ,
)
compact_group . add_argument (
' --cleanup-commits ' ,
dest = ' cleanup_commits ' ,
default = False ,
action = ' store_true ' ,
2023-03-28 12:45:49 +00:00
help = ' Cleanup commit-only 17-byte segment files left behind by Borg 1.1 [flag in Borg 1.2 only] ' ,
2022-02-08 07:29:44 +00:00
)
compact_group . add_argument (
' --threshold ' ,
type = int ,
dest = ' threshold ' ,
help = ' Minimum saved space percentage threshold for compacting a segment, defaults to 10 ' ,
)
2022-02-08 20:05:02 +00:00
compact_group . add_argument (
' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit '
)
2022-02-08 07:29:44 +00:00
2023-06-19 23:18:47 +00:00
create_parser = action_parsers . add_parser (
2019-06-23 04:32:27 +00:00
' create ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' create ' ] ,
2022-08-18 04:14:58 +00:00
help = ' Create an archive (actually perform a backup) ' ,
description = ' Create an archive (actually perform a backup) ' ,
2019-06-23 04:32:27 +00:00
add_help = False ,
)
create_group = create_parser . add_argument_group ( ' create arguments ' )
2023-03-16 17:15:49 +00:00
create_group . add_argument (
' --repository ' ,
help = ' Path of specific existing repository to backup to (must be already specified in a borgmatic configuration file) ' ,
)
2019-06-23 04:32:27 +00:00
create_group . add_argument (
' --progress ' ,
dest = ' progress ' ,
default = False ,
action = ' store_true ' ,
2020-01-24 19:27:16 +00:00
help = ' Display progress for each file as it is backed up ' ,
2019-06-23 04:32:27 +00:00
)
create_group . add_argument (
' --stats ' ,
dest = ' stats ' ,
default = False ,
action = ' store_true ' ,
help = ' Display statistics of archive ' ,
)
2020-01-11 15:38:07 +00:00
create_group . add_argument (
2022-08-21 21:25:16 +00:00
' --list ' , ' --files ' , dest = ' list_files ' , action = ' store_true ' , help = ' Show per-file details '
2020-01-11 15:38:07 +00:00
)
2019-06-23 04:32:27 +00:00
create_group . add_argument (
' --json ' , dest = ' json ' , default = False , action = ' store_true ' , help = ' Output results as JSON '
)
create_group . add_argument ( ' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit ' )
2023-06-19 23:18:47 +00:00
check_parser = action_parsers . add_parser (
2019-06-23 04:32:27 +00:00
' check ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' check ' ] ,
2019-06-23 04:32:27 +00:00
help = ' Check archives for consistency ' ,
description = ' Check archives for consistency ' ,
add_help = False ,
)
check_group = check_parser . add_argument_group ( ' check arguments ' )
2023-03-16 12:34:52 +00:00
check_group . add_argument (
' --repository ' ,
help = ' Path of specific existing repository to check (must be already specified in a borgmatic configuration file) ' ,
)
2020-01-24 19:27:16 +00:00
check_group . add_argument (
' --progress ' ,
dest = ' progress ' ,
default = False ,
action = ' store_true ' ,
help = ' Display progress for each file as it is checked ' ,
)
2019-12-05 00:07:00 +00:00
check_group . add_argument (
' --repair ' ,
dest = ' repair ' ,
default = False ,
action = ' store_true ' ,
2022-05-29 02:29:33 +00:00
help = ' Attempt to repair any inconsistencies found (for interactive use) ' ,
2019-12-05 00:07:00 +00:00
)
2019-09-19 18:43:53 +00:00
check_group . add_argument (
' --only ' ,
metavar = ' CHECK ' ,
choices = ( ' repository ' , ' archives ' , ' data ' , ' extract ' ) ,
dest = ' only ' ,
action = ' append ' ,
2022-05-28 21:42:19 +00:00
help = ' Run a particular consistency check (repository, archives, data, or extract) instead of configured checks (subject to configured frequency, can specify flag multiple times) ' ,
2019-09-19 18:43:53 +00:00
)
2022-05-29 02:29:33 +00:00
check_group . add_argument (
' --force ' ,
default = False ,
action = ' store_true ' ,
help = ' Ignore configured check frequencies and run checks unconditionally ' ,
)
2019-06-23 04:32:27 +00:00
check_group . add_argument ( ' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit ' )
2023-06-19 23:18:47 +00:00
extract_parser = action_parsers . add_parser (
2019-06-23 04:32:27 +00:00
' extract ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' extract ' ] ,
2019-10-31 19:57:36 +00:00
help = ' Extract files from a named archive to the current directory ' ,
2019-06-23 04:32:27 +00:00
description = ' Extract a named archive to the current directory ' ,
add_help = False ,
)
extract_group = extract_parser . add_argument_group ( ' extract arguments ' )
extract_group . add_argument (
' --repository ' ,
2019-06-25 17:46:55 +00:00
help = ' Path of repository to extract, defaults to the configured repository if there is only one ' ,
2019-06-23 04:32:27 +00:00
)
2020-01-30 00:59:02 +00:00
extract_group . add_argument (
' --archive ' , help = ' Name of archive to extract (or " latest " ) ' , required = True
)
2019-06-23 04:32:27 +00:00
extract_group . add_argument (
2019-11-01 17:00:26 +00:00
' --path ' ,
2019-06-23 04:32:27 +00:00
' --restore-path ' ,
2019-10-31 19:57:36 +00:00
metavar = ' PATH ' ,
2019-11-01 17:00:26 +00:00
dest = ' paths ' ,
2023-07-14 02:25:14 +00:00
action = ' append ' ,
help = ' Path to extract from archive, can specify flag multiple times, defaults to the entire archive ' ,
2019-11-01 17:00:26 +00:00
)
extract_group . add_argument (
' --destination ' ,
metavar = ' PATH ' ,
dest = ' destination ' ,
help = ' Directory to extract files into, defaults to the current directory ' ,
2019-06-23 04:32:27 +00:00
)
2020-06-06 21:57:14 +00:00
extract_group . add_argument (
' --strip-components ' ,
2023-03-09 18:09:16 +00:00
type = lambda number : number if number == ' all ' else int ( number ) ,
2020-06-06 21:57:14 +00:00
metavar = ' NUMBER ' ,
2023-03-09 18:09:16 +00:00
help = ' Number of leading path components to remove from each extracted path or " all " to strip all leading path components. Skip paths with fewer elements ' ,
2020-06-06 21:57:14 +00:00
)
2019-06-23 04:32:27 +00:00
extract_group . add_argument (
' --progress ' ,
dest = ' progress ' ,
default = False ,
action = ' store_true ' ,
2020-01-24 19:27:16 +00:00
help = ' Display progress for each file as it is extracted ' ,
2019-06-23 04:32:27 +00:00
)
extract_group . add_argument (
' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit '
)
2023-06-19 23:18:47 +00:00
config_parser = action_parsers . add_parser (
2023-05-25 18:56:13 +00:00
' config ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' config ' ] ,
2023-05-25 18:56:13 +00:00
help = ' Perform configuration file related operations ' ,
description = ' Perform configuration file related operations ' ,
add_help = False ,
2023-05-25 19:37:11 +00:00
)
config_group = config_parser . add_argument_group ( ' config arguments ' )
2023-06-06 18:07:09 +00:00
config_group . add_argument ( ' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit ' )
2023-05-25 18:56:13 +00:00
2023-06-19 23:18:47 +00:00
config_parsers = config_parser . add_subparsers (
title = ' config sub-actions ' ,
2023-05-25 18:56:13 +00:00
)
2023-06-19 23:18:47 +00:00
config_bootstrap_parser = config_parsers . add_parser (
2023-05-25 18:56:13 +00:00
' bootstrap ' ,
2023-06-23 17:11:41 +00:00
help = ' Extract the borgmatic configuration files from a named archive ' ,
description = ' Extract the borgmatic configuration files from a named archive ' ,
2023-05-25 18:56:13 +00:00
add_help = False ,
)
2023-06-06 18:07:09 +00:00
config_bootstrap_group = config_bootstrap_parser . add_argument_group (
' config bootstrap arguments '
)
2023-05-25 18:56:13 +00:00
config_bootstrap_group . add_argument (
' --repository ' ,
2023-06-05 14:35:10 +00:00
help = ' Path of repository to extract config files from ' ,
2023-05-25 18:56:13 +00:00
required = True ,
)
config_bootstrap_group . add_argument (
2023-06-01 11:23:34 +00:00
' --borgmatic-source-directory ' ,
2023-06-09 12:01:57 +00:00
help = ' Path that stores the config files used to create an archive and additional source files used for temporary internal state like borgmatic database dumps. Defaults to ~/.borgmatic ' ,
2023-05-25 18:56:13 +00:00
)
config_bootstrap_group . add_argument (
2023-06-06 18:07:09 +00:00
' --archive ' ,
help = ' Name of archive to extract config files from, defaults to " latest " ' ,
default = ' latest ' ,
2023-05-25 18:56:13 +00:00
)
config_bootstrap_group . add_argument (
' --destination ' ,
metavar = ' PATH ' ,
dest = ' destination ' ,
2023-06-05 14:35:10 +00:00
help = ' Directory to extract config files into, defaults to / ' ,
default = ' / ' ,
2023-05-25 18:56:13 +00:00
)
config_bootstrap_group . add_argument (
' --strip-components ' ,
type = lambda number : number if number == ' all ' else int ( number ) ,
metavar = ' NUMBER ' ,
help = ' Number of leading path components to remove from each extracted path or " all " to strip all leading path components. Skip paths with fewer elements ' ,
)
config_bootstrap_group . add_argument (
' --progress ' ,
dest = ' progress ' ,
default = False ,
action = ' store_true ' ,
help = ' Display progress for each file as it is extracted ' ,
)
2023-05-25 19:37:11 +00:00
config_bootstrap_group . add_argument (
' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit '
)
2023-05-25 18:56:13 +00:00
2023-06-21 19:19:49 +00:00
config_generate_parser = config_parsers . add_parser (
' generate ' ,
help = ' Generate a sample borgmatic configuration file ' ,
description = ' Generate a sample borgmatic configuration file ' ,
add_help = False ,
)
config_generate_group = config_generate_parser . add_argument_group ( ' config generate arguments ' )
config_generate_group . add_argument (
' -s ' ,
' --source ' ,
dest = ' source_filename ' ,
help = ' Optional configuration file to merge into the generated configuration, useful for upgrading your configuration ' ,
)
config_generate_group . add_argument (
' -d ' ,
' --destination ' ,
dest = ' destination_filename ' ,
default = config_paths [ 0 ] ,
help = f ' Destination configuration file, default: { unexpanded_config_paths [ 0 ] } ' ,
)
config_generate_group . add_argument (
' --overwrite ' ,
default = False ,
action = ' store_true ' ,
help = ' Whether to overwrite any existing destination file, defaults to false ' ,
)
config_generate_group . add_argument (
' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit '
)
2023-06-23 17:11:41 +00:00
config_validate_parser = config_parsers . add_parser (
' validate ' ,
2023-06-24 21:10:47 +00:00
help = ' Validate borgmatic configuration files specified with --config (see borgmatic --help) ' ,
2023-06-23 17:11:41 +00:00
description = ' Validate borgmatic configuration files specified with --config (see borgmatic --help) ' ,
add_help = False ,
)
config_validate_group = config_validate_parser . add_argument_group ( ' config validate arguments ' )
config_validate_group . add_argument (
' -s ' ,
' --show ' ,
action = ' store_true ' ,
help = ' Show the validated configuration after all include merging has occurred ' ,
)
config_validate_group . add_argument (
' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit '
)
2023-06-19 23:18:47 +00:00
export_tar_parser = action_parsers . add_parser (
2020-07-23 04:53:55 +00:00
' export-tar ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' export-tar ' ] ,
2020-07-23 04:53:55 +00:00
help = ' Export an archive to a tar-formatted file or stream ' ,
description = ' Export an archive to a tar-formatted file or stream ' ,
add_help = False ,
)
export_tar_group = export_tar_parser . add_argument_group ( ' export-tar arguments ' )
export_tar_group . add_argument (
' --repository ' ,
help = ' Path of repository to export from, defaults to the configured repository if there is only one ' ,
)
export_tar_group . add_argument (
' --archive ' , help = ' Name of archive to export (or " latest " ) ' , required = True
)
export_tar_group . add_argument (
' --path ' ,
metavar = ' PATH ' ,
dest = ' paths ' ,
2023-07-14 02:25:14 +00:00
action = ' append ' ,
help = ' Path to export from archive, can specify flag multiple times, defaults to the entire archive ' ,
2020-07-23 04:53:55 +00:00
)
export_tar_group . add_argument (
' --destination ' ,
metavar = ' PATH ' ,
dest = ' destination ' ,
2022-08-21 21:25:16 +00:00
help = ' Path to destination export tar file, or " - " for stdout (but be careful about dirtying output with --verbosity or --list) ' ,
2020-07-23 04:53:55 +00:00
required = True ,
)
export_tar_group . add_argument (
' --tar-filter ' , help = ' Name of filter program to pipe data through '
)
export_tar_group . add_argument (
2022-08-21 21:25:16 +00:00
' --list ' , ' --files ' , dest = ' list_files ' , action = ' store_true ' , help = ' Show per-file details '
2020-07-23 04:53:55 +00:00
)
export_tar_group . add_argument (
' --strip-components ' ,
type = int ,
metavar = ' NUMBER ' ,
dest = ' strip_components ' ,
help = ' Number of leading path components to remove from each exported path. Skip paths with fewer elements ' ,
)
export_tar_group . add_argument (
' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit '
)
2023-06-19 23:18:47 +00:00
mount_parser = action_parsers . add_parser (
2019-11-25 22:56:20 +00:00
' mount ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' mount ' ] ,
2019-11-25 22:56:20 +00:00
help = ' Mount files from a named archive as a FUSE filesystem ' ,
description = ' Mount a named archive as a FUSE filesystem ' ,
add_help = False ,
)
mount_group = mount_parser . add_argument_group ( ' mount arguments ' )
mount_group . add_argument (
' --repository ' ,
help = ' Path of repository to use, defaults to the configured repository if there is only one ' ,
)
2020-01-30 00:59:02 +00:00
mount_group . add_argument ( ' --archive ' , help = ' Name of archive to mount (or " latest " ) ' )
2019-11-25 22:56:20 +00:00
mount_group . add_argument (
' --mount-point ' ,
metavar = ' PATH ' ,
dest = ' mount_point ' ,
help = ' Path where filesystem is to be mounted ' ,
required = True ,
)
mount_group . add_argument (
' --path ' ,
metavar = ' PATH ' ,
dest = ' paths ' ,
2023-07-14 02:25:14 +00:00
action = ' append ' ,
help = ' Path to mount from archive, can specify multiple times, defaults to the entire archive ' ,
2019-11-25 22:56:20 +00:00
)
mount_group . add_argument (
' --foreground ' ,
dest = ' foreground ' ,
default = False ,
action = ' store_true ' ,
help = ' Stay in foreground until ctrl-C is pressed ' ,
)
2023-03-25 20:28:03 +00:00
mount_group . add_argument (
' --first ' ,
metavar = ' N ' ,
help = ' Mount first N archives after other filters are applied ' ,
)
mount_group . add_argument (
' --last ' , metavar = ' N ' , help = ' Mount last N archives after other filters are applied '
)
mount_group . add_argument (
2023-04-27 16:57:23 +00:00
' --oldest ' ,
metavar = ' TIMESPAN ' ,
help = ' Mount archives within a specified time range starting from the timestamp of the oldest archive (e.g. 7d or 12m) [Borg 2.x+ only] ' ,
2023-03-25 20:28:03 +00:00
)
mount_group . add_argument (
2023-04-27 16:57:23 +00:00
' --newest ' ,
metavar = ' TIMESPAN ' ,
help = ' Mount 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] ' ,
2023-03-25 20:28:03 +00:00
)
mount_group . add_argument (
2023-04-27 16:57:23 +00:00
' --older ' ,
metavar = ' TIMESPAN ' ,
help = ' Mount archives that are older than the specified time range (e.g. 7d or 12m) from the current time [Borg 2.x+ only] ' ,
2023-03-25 20:28:03 +00:00
)
mount_group . add_argument (
2023-04-27 16:57:23 +00:00
' --newer ' ,
metavar = ' TIMESPAN ' ,
help = ' Mount archives that are newer than the specified time range (e.g. 7d or 12m) from the current time [Borg 2.x+ only] ' ,
2023-03-25 20:28:03 +00:00
)
2019-11-25 22:56:20 +00:00
mount_group . add_argument ( ' --options ' , dest = ' options ' , help = ' Extra Borg mount options ' )
mount_group . add_argument ( ' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit ' )
2023-06-19 23:18:47 +00:00
umount_parser = action_parsers . add_parser (
2019-11-25 22:56:20 +00:00
' umount ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' umount ' ] ,
2019-11-25 22:56:20 +00:00
help = ' Unmount a FUSE filesystem that was mounted with " borgmatic mount " ' ,
description = ' Unmount a mounted FUSE filesystem ' ,
add_help = False ,
)
umount_group = umount_parser . add_argument_group ( ' umount arguments ' )
umount_group . add_argument (
' --mount-point ' ,
metavar = ' PATH ' ,
dest = ' mount_point ' ,
help = ' Path of filesystem to unmount ' ,
required = True ,
)
umount_group . add_argument ( ' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit ' )
2023-06-19 23:18:47 +00:00
restore_parser = action_parsers . add_parser (
2019-10-31 19:57:36 +00:00
' restore ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' restore ' ] ,
2019-10-31 19:57:36 +00:00
help = ' Restore database dumps from a named archive ' ,
description = ' Restore database dumps from a named archive. (To extract files instead, use " borgmatic extract " .) ' ,
add_help = False ,
)
restore_group = restore_parser . add_argument_group ( ' restore arguments ' )
restore_group . add_argument (
' --repository ' ,
help = ' Path of repository to restore from, defaults to the configured repository if there is only one ' ,
)
2020-01-30 00:59:02 +00:00
restore_group . add_argument (
' --archive ' , help = ' Name of archive to restore from (or " latest " ) ' , required = True
)
2019-10-31 19:57:36 +00:00
restore_group . add_argument (
' --database ' ,
metavar = ' NAME ' ,
dest = ' databases ' ,
2023-07-14 02:25:14 +00:00
action = ' append ' ,
help = " Name of database to restore from archive, must be defined in borgmatic ' s configuration, can specify flag multiple times, defaults to all databases " ,
2019-10-31 19:57:36 +00:00
)
2023-04-05 20:40:36 +00:00
restore_group . add_argument (
' --schema ' ,
metavar = ' NAME ' ,
dest = ' schemas ' ,
2023-07-14 02:25:14 +00:00
action = ' append ' ,
help = ' Name of schema to restore from the database, can specify flag multiple times, defaults to all schemas. Schemas are only supported for PostgreSQL and MongoDB databases ' ,
2023-04-05 20:40:36 +00:00
)
2023-06-13 18:41:19 +00:00
restore_group . add_argument (
' --hostname ' ,
help = ' Database hostname to restore to. Defaults to the " restore_hostname " option in borgmatic \' s configuration ' ,
)
restore_group . add_argument (
2023-06-16 09:44:00 +00:00
' --port ' ,
help = ' Port to restore to. Defaults to the " restore_port " option in borgmatic \' s configuration ' ,
2023-06-13 18:41:19 +00:00
)
restore_group . add_argument (
' --username ' ,
help = ' Username with which to connect to the database. Defaults to the " restore_username " option in borgmatic \' s configuration ' ,
)
restore_group . add_argument (
' --password ' ,
help = ' Password with which to connect to the restore database. Defaults to the " restore_password " option in borgmatic \' s configuration ' ,
)
2023-06-15 17:35:53 +00:00
restore_group . add_argument (
' --restore-path ' ,
help = ' Path to restore SQLite database dumps to. Defaults to the " restore_path " option in borgmatic \' s configuration ' ,
)
2019-10-31 19:57:36 +00:00
restore_group . add_argument (
' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit '
)
2023-06-19 23:18:47 +00:00
rlist_parser = action_parsers . add_parser (
2022-08-15 22:04:40 +00:00
' rlist ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' rlist ' ] ,
2022-08-15 22:04:40 +00:00
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 (
2023-04-15 02:35:24 +00:00
' --repository ' ,
help = ' Path of repository to list, defaults to the configured repositories ' ,
2022-08-15 22:04:40 +00:00
)
rlist_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 (
' --json ' , default = False , action = ' store_true ' , help = ' Output results as JSON '
)
rlist_group . add_argument (
2023-04-05 04:25:10 +00:00
' -P ' , ' --prefix ' , help = ' Deprecated. Only list archive names starting with this prefix '
2022-08-15 22:04:40 +00:00
)
rlist_group . add_argument (
2022-10-04 05:50:37 +00:00
' -a ' ,
' --match-archives ' ,
' --glob-archives ' ,
metavar = ' PATTERN ' ,
help = ' Only list archive names matching this pattern ' ,
2022-08-15 22:04:40 +00:00
)
rlist_group . add_argument (
' --sort-by ' , metavar = ' KEYS ' , help = ' Comma-separated list of sorting keys '
)
rlist_group . add_argument (
' --first ' , metavar = ' N ' , help = ' List first N archives after other filters are applied '
)
rlist_group . add_argument (
' --last ' , metavar = ' N ' , help = ' List last N archives after other filters are applied '
)
2023-03-25 20:28:03 +00:00
rlist_group . add_argument (
2023-04-27 16:57:23 +00:00
' --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] ' ,
2023-03-25 20:28:03 +00:00
)
rlist_group . add_argument (
2023-04-27 16:57:23 +00:00
' --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] ' ,
2023-03-25 20:28:03 +00:00
)
rlist_group . add_argument (
2023-04-27 16:57:23 +00:00
' --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] ' ,
2023-03-25 20:28:03 +00:00
)
rlist_group . add_argument (
2023-04-27 16:57:23 +00:00
' --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] ' ,
2023-03-25 20:28:03 +00:00
)
2022-08-15 22:04:40 +00:00
rlist_group . add_argument ( ' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit ' )
2023-06-19 23:18:47 +00:00
list_parser = action_parsers . add_parser (
2019-06-23 04:32:27 +00:00
' list ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' list ' ] ,
2022-08-15 22:04:40 +00:00
help = ' List archive ' ,
description = ' List the files in an archive or search for a file across archives ' ,
2019-06-23 04:32:27 +00:00
add_help = False ,
)
list_group = list_parser . add_argument_group ( ' list arguments ' )
list_group . add_argument (
2022-08-15 22:04:40 +00:00
' --repository ' ,
help = ' Path of repository containing archive to list, defaults to the configured repositories ' ,
2019-06-23 04:32:27 +00:00
)
2022-08-15 22:04:40 +00:00
list_group . add_argument ( ' --archive ' , help = ' Name of the archive to list (or " latest " ) ' )
2019-12-08 22:07:02 +00:00
list_group . add_argument (
' --path ' ,
metavar = ' PATH ' ,
dest = ' paths ' ,
2023-07-14 02:25:14 +00:00
action = ' append ' ,
help = ' Path or pattern to list from a single selected archive (via " --archive " ), can specify flag multiple times, defaults to listing the entire archive ' ,
2022-06-03 22:12:14 +00:00
)
list_group . add_argument (
' --find ' ,
metavar = ' PATH ' ,
dest = ' find_paths ' ,
2023-07-14 02:25:14 +00:00
action = ' append ' ,
help = ' Partial path or pattern to search for and list across multiple archives, can specify flag multiple times ' ,
2019-12-08 22:07:02 +00:00
)
2019-06-23 04:32:27 +00:00
list_group . add_argument (
2022-08-15 22:04:40 +00:00
' --short ' , default = False , action = ' store_true ' , help = ' Output only path names '
2019-06-25 17:18:30 +00:00
)
list_group . add_argument ( ' --format ' , help = ' Format for file listing ' )
list_group . add_argument (
' --json ' , default = False , action = ' store_true ' , help = ' Output results as JSON '
)
list_group . add_argument (
2023-04-05 04:25:10 +00:00
' -P ' , ' --prefix ' , help = ' Deprecated. Only list archive names starting with this prefix '
2019-06-25 17:18:30 +00:00
)
list_group . add_argument (
2022-10-04 05:50:37 +00:00
' -a ' ,
' --match-archives ' ,
' --glob-archives ' ,
metavar = ' PATTERN ' ,
help = ' Only list archive names matching this pattern ' ,
2019-06-25 17:18:30 +00:00
)
list_group . add_argument (
' --sort-by ' , metavar = ' KEYS ' , help = ' Comma-separated list of sorting keys '
)
list_group . add_argument (
' --first ' , metavar = ' N ' , help = ' List first N archives after other filters are applied '
)
list_group . add_argument (
2019-10-13 21:46:28 +00:00
' --last ' , metavar = ' N ' , help = ' List last N archives after other filters are applied '
2019-06-25 17:18:30 +00:00
)
list_group . add_argument (
' -e ' , ' --exclude ' , metavar = ' PATTERN ' , help = ' Exclude paths matching the pattern '
)
list_group . add_argument (
' --exclude-from ' , metavar = ' FILENAME ' , help = ' Exclude paths from exclude file, one per line '
)
list_group . add_argument ( ' --pattern ' , help = ' Include or exclude paths matching a pattern ' )
list_group . add_argument (
2019-10-23 05:42:36 +00:00
' --patterns-from ' ,
2019-06-25 17:18:30 +00:00
metavar = ' FILENAME ' ,
help = ' Include or exclude paths matching patterns from pattern file, one per line ' ,
2019-06-23 04:32:27 +00:00
)
list_group . add_argument ( ' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit ' )
2023-06-19 23:18:47 +00:00
rinfo_parser = action_parsers . add_parser (
2022-08-13 06:06:56 +00:00
' rinfo ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' rinfo ' ] ,
2022-08-13 06:06:56 +00:00
help = ' Show repository summary information such as disk space used ' ,
description = ' Show repository summary information such as disk space used ' ,
add_help = False ,
)
rinfo_group = rinfo_parser . add_argument_group ( ' rinfo arguments ' )
rinfo_group . add_argument (
' --repository ' ,
help = ' Path of repository to show info for, defaults to the configured repository if there is only one ' ,
)
rinfo_group . add_argument (
' --json ' , dest = ' json ' , default = False , action = ' store_true ' , help = ' Output results as JSON '
)
rinfo_group . add_argument ( ' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit ' )
2023-06-19 23:18:47 +00:00
info_parser = action_parsers . add_parser (
2019-06-23 04:32:27 +00:00
' info ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' info ' ] ,
2022-08-13 06:06:56 +00:00
help = ' Show archive summary information such as disk space used ' ,
description = ' Show archive summary information such as disk space used ' ,
2019-06-23 04:32:27 +00:00
add_help = False ,
)
info_group = info_parser . add_argument_group ( ' info arguments ' )
2019-06-25 17:46:55 +00:00
info_group . add_argument (
' --repository ' ,
2022-08-13 06:06:56 +00:00
help = ' Path of repository containing archive to show info for, defaults to the configured repository if there is only one ' ,
2019-06-25 17:46:55 +00:00
)
2020-01-30 00:59:02 +00:00
info_group . add_argument ( ' --archive ' , help = ' Name of archive to show info for (or " latest " ) ' )
2019-06-23 04:32:27 +00:00
info_group . add_argument (
' --json ' , dest = ' json ' , default = False , action = ' store_true ' , help = ' Output results as JSON '
)
2019-06-25 17:46:55 +00:00
info_group . add_argument (
2023-04-05 04:25:10 +00:00
' -P ' ,
' --prefix ' ,
help = ' Deprecated. Only show info for archive names starting with this prefix ' ,
2019-06-25 17:46:55 +00:00
)
info_group . add_argument (
' -a ' ,
2022-10-04 05:50:37 +00:00
' --match-archives ' ,
2019-06-25 17:46:55 +00:00
' --glob-archives ' ,
2022-10-04 05:50:37 +00:00
metavar = ' PATTERN ' ,
help = ' Only show info for archive names matching this pattern ' ,
2019-06-25 17:46:55 +00:00
)
info_group . add_argument (
' --sort-by ' , metavar = ' KEYS ' , help = ' Comma-separated list of sorting keys '
)
info_group . add_argument (
' --first ' ,
metavar = ' N ' ,
help = ' Show info for first N archives after other filters are applied ' ,
)
info_group . add_argument (
2020-10-11 22:04:15 +00:00
' --last ' , metavar = ' N ' , help = ' Show info for last N archives after other filters are applied '
2019-06-25 17:46:55 +00:00
)
2023-03-25 20:28:03 +00:00
info_group . add_argument (
2023-04-27 16:57:23 +00:00
' --oldest ' ,
metavar = ' TIMESPAN ' ,
help = ' Show info for archives within a specified time range starting from the timestamp of the oldest archive (e.g. 7d or 12m) [Borg 2.x+ only] ' ,
2023-03-25 20:28:03 +00:00
)
info_group . add_argument (
2023-04-27 16:57:23 +00:00
' --newest ' ,
metavar = ' TIMESPAN ' ,
help = ' Show info for 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] ' ,
2023-03-25 20:28:03 +00:00
)
info_group . add_argument (
2023-04-27 16:57:23 +00:00
' --older ' ,
metavar = ' TIMESPAN ' ,
help = ' Show info for archives that are older than the specified time range (e.g. 7d or 12m) from the current time [Borg 2.x+ only] ' ,
2023-03-25 20:28:03 +00:00
)
info_group . add_argument (
2023-04-27 16:57:23 +00:00
' --newer ' ,
metavar = ' TIMESPAN ' ,
help = ' Show info for archives that are newer than the specified time range (e.g. 7d or 12m) from the current time [Borg 2.x+ only] ' ,
2023-03-25 20:28:03 +00:00
)
2019-06-23 04:32:27 +00:00
info_group . add_argument ( ' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit ' )
2023-06-19 23:18:47 +00:00
break_lock_parser = action_parsers . add_parser (
2022-10-04 20:42:18 +00:00
' break-lock ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' break-lock ' ] ,
2022-10-04 20:42:18 +00:00
help = ' Break the repository and cache locks left behind by Borg aborting ' ,
description = ' Break Borg repository and cache locks left behind by Borg aborting ' ,
add_help = False ,
)
break_lock_group = break_lock_parser . add_argument_group ( ' break-lock arguments ' )
break_lock_group . add_argument (
' --repository ' ,
help = ' Path of repository to break the lock for, defaults to the configured repository if there is only one ' ,
)
2022-10-12 17:52:32 +00:00
break_lock_group . add_argument (
' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit '
)
2022-10-04 20:42:18 +00:00
2023-06-19 23:18:47 +00:00
borg_parser = action_parsers . add_parser (
2021-06-18 03:41:44 +00:00
' borg ' ,
2023-06-19 23:18:47 +00:00
aliases = ACTION_ALIASES [ ' borg ' ] ,
2021-06-18 03:41:44 +00:00
help = ' Run an arbitrary Borg command ' ,
2023-03-07 22:08:35 +00:00
description = " Run an arbitrary Borg command based on borgmatic ' s configuration " ,
2021-06-18 03:41:44 +00:00
add_help = False ,
)
borg_group = borg_parser . add_argument_group ( ' borg arguments ' )
borg_group . add_argument (
' --repository ' ,
help = ' Path of repository to pass to Borg, defaults to the configured repositories ' ,
)
borg_group . add_argument ( ' --archive ' , help = ' Name of archive to pass to Borg (or " latest " ) ' )
borg_group . add_argument (
' -- ' ,
metavar = ' OPTION ' ,
dest = ' options ' ,
nargs = ' + ' ,
help = ' Options to pass to Borg, command first ( " create " , " list " , etc). " -- " is optional. To specify the repository or the archive, you must use --repository or --archive instead of providing them here. ' ,
)
borg_group . add_argument ( ' -h ' , ' --help ' , action = ' help ' , help = ' Show this help message and exit ' )
2023-06-24 21:10:47 +00:00
return global_parser , action_parsers , global_plus_action_parser
2022-05-26 17:27:53 +00:00
def parse_arguments ( * unparsed_arguments ) :
'''
Given command - line arguments with which this script was invoked , parse the arguments and return
2023-06-19 23:18:47 +00:00
them as a dict mapping from action name ( or " global " ) to an argparse . Namespace instance .
2022-05-26 17:27:53 +00:00
2023-06-24 21:10:47 +00:00
Raise ValueError if the arguments cannot be parsed .
Raise SystemExit with an error code of 0 if " --help " was requested .
'''
global_parser , action_parsers , global_plus_action_parser = make_parsers ( )
arguments , remaining_action_arguments = parse_arguments_for_actions (
unparsed_arguments , action_parsers . choices , global_parser
2021-06-18 03:41:44 +00:00
)
2023-06-01 20:34:35 +00:00
2023-07-14 02:25:14 +00:00
if not arguments [ ' global ' ] . config_paths :
arguments [ ' global ' ] . config_paths = collect . get_default_config_paths ( expand_home = True )
2023-06-21 19:19:49 +00:00
for action_name in ( ' bootstrap ' , ' generate ' , ' validate ' ) :
2023-06-24 21:10:47 +00:00
if (
action_name in arguments . keys ( ) and len ( arguments . keys ( ) ) > 2
) : # 2 = 1 for 'global' + 1 for the action
2023-06-21 19:19:49 +00:00
raise ValueError (
2023-06-24 21:10:47 +00:00
f ' The { action_name } action cannot be combined with other actions. Please run it separately. '
2023-06-21 19:19:49 +00:00
)
2023-06-01 20:34:35 +00:00
2023-06-24 21:10:47 +00:00
unknown_arguments = get_unparsable_arguments ( remaining_action_arguments )
if unknown_arguments :
if ' --help ' in unknown_arguments or ' -h ' in unknown_arguments :
global_plus_action_parser . print_help ( )
sys . exit ( 0 )
global_plus_action_parser . print_usage ( )
raise ValueError (
f " Unrecognized argument { ' s ' if len ( unknown_arguments ) > 1 else ' ' } : { ' ' . join ( unknown_arguments ) } "
)
2023-02-27 01:05:56 +00:00
if ' create ' in arguments and arguments [ ' create ' ] . list_files and arguments [ ' create ' ] . progress :
raise ValueError (
' With the create action, only one of --list (--files) and --progress flags can be used. '
)
2023-05-04 00:16:36 +00:00
if ' create ' in arguments and arguments [ ' create ' ] . list_files and arguments [ ' create ' ] . json :
raise ValueError (
' With the create action, only one of --list (--files) and --json flags can be used. '
)
2023-02-27 01:05:56 +00:00
2019-06-23 04:32:27 +00:00
if (
2022-08-13 06:06:56 +00:00
( ' list ' in arguments and ' rinfo ' in arguments and arguments [ ' list ' ] . json )
or ( ' list ' in arguments and ' info ' in arguments and arguments [ ' list ' ] . json )
or ( ' rinfo ' in arguments and ' info ' in arguments and arguments [ ' rinfo ' ] . json )
2019-06-23 04:32:27 +00:00
) :
2022-08-17 22:36:19 +00:00
raise ValueError ( ' With the --json flag, multiple actions cannot be used together. ' )
2022-08-12 21:53:20 +00:00
2022-08-19 06:06:51 +00:00
if (
' transfer ' in arguments
and arguments [ ' transfer ' ] . archive
2022-10-04 05:50:37 +00:00
and arguments [ ' transfer ' ] . match_archives
2022-08-19 06:06:51 +00:00
) :
raise ValueError (
2023-04-05 04:25:10 +00:00
' With the transfer action, only one of --archive and --match-archives flags can be used. '
)
if ' list ' in arguments and ( arguments [ ' list ' ] . prefix and arguments [ ' list ' ] . match_archives ) :
raise ValueError (
' With the list action, only one of --prefix or --match-archives flags can be used. '
)
if ' rlist ' in arguments and ( arguments [ ' rlist ' ] . prefix and arguments [ ' rlist ' ] . match_archives ) :
raise ValueError (
' With the rlist action, only one of --prefix or --match-archives flags can be used. '
2022-08-19 06:06:51 +00:00
)
2022-08-17 22:36:19 +00:00
if ' info ' in arguments and (
( arguments [ ' info ' ] . archive and arguments [ ' info ' ] . prefix )
2022-10-04 05:50:37 +00:00
or ( arguments [ ' info ' ] . archive and arguments [ ' info ' ] . match_archives )
or ( arguments [ ' info ' ] . prefix and arguments [ ' info ' ] . match_archives )
2022-08-17 22:36:19 +00:00
) :
2022-08-12 21:53:20 +00:00
raise ValueError (
2022-10-04 05:50:37 +00:00
' With the info action, only one of --archive, --prefix, or --match-archives flags can be used. '
2022-08-12 21:53:20 +00:00
)
2019-06-23 04:32:27 +00:00
return arguments