Browse Source

Change the default action order to: "create", "prune", "compact", "check" (#304).

Dan Helfman 2 years ago
parent
commit
b343363bb8

+ 3 - 0
NEWS

@@ -1,5 +1,8 @@
 1.7.9.dev0
 1.7.9.dev0
  * #295: Add a SQLite database dump/restore hook.
  * #295: Add a SQLite database dump/restore hook.
+ * #304: Change the default action order when no actions are specified on the command-line to:
+   "create", "prune", "compact", "check". If you'd like to retain the old ordering ("prune" and
+   "compact" first), then specify actions explicitly on the command-line.
  * #304: Run any command-line actions in the order specified instead of using a fixed ordering.
  * #304: Run any command-line actions in the order specified instead of using a fixed ordering.
  * #628: Add a Healthchecks "log" state to send borgmatic logs to Healthchecks without signalling
  * #628: Add a Healthchecks "log" state to send borgmatic logs to Healthchecks without signalling
    success or failure.
    success or failure.

+ 4 - 4
borgmatic/commands/arguments.py

@@ -68,9 +68,9 @@ def parse_subparser_arguments(unparsed_arguments, subparsers):
 
 
         arguments[canonical_name] = parsed
         arguments[canonical_name] = parsed
 
 
-    # If no actions are explicitly requested, assume defaults: prune, compact, create, and check.
+    # If no actions are explicitly requested, assume defaults.
     if not arguments and '--help' not in unparsed_arguments and '-h' not in unparsed_arguments:
     if not arguments and '--help' not in unparsed_arguments and '-h' not in unparsed_arguments:
-        for subparser_name in ('prune', 'compact', 'create', 'check'):
+        for subparser_name in ('create', 'prune', 'compact', 'check'):
             subparser = subparsers[subparser_name]
             subparser = subparsers[subparser_name]
             parsed, unused_remaining = subparser.parse_known_args(unparsed_arguments)
             parsed, unused_remaining = subparser.parse_known_args(unparsed_arguments)
             arguments[subparser_name] = parsed
             arguments[subparser_name] = parsed
@@ -216,7 +216,7 @@ def make_parsers():
     top_level_parser = ArgumentParser(
     top_level_parser = ArgumentParser(
         description='''
         description='''
             Simple, configuration-driven backup software for servers and workstations. If none of
             Simple, configuration-driven backup software for servers and workstations. If none of
-            the action options are given, then borgmatic defaults to: prune, compact, create, and
+            the action options are given, then borgmatic defaults to: create, prune, compact, and
             check.
             check.
             ''',
             ''',
         parents=[global_parser],
         parents=[global_parser],
@@ -225,7 +225,7 @@ def make_parsers():
     subparsers = top_level_parser.add_subparsers(
     subparsers = top_level_parser.add_subparsers(
         title='actions',
         title='actions',
         metavar='',
         metavar='',
-        help='Specify zero or more actions. Defaults to prune, compact, create, and check. Use --help with action for details:',
+        help='Specify zero or more actions. Defaults to creat, prune, compact, and check. Use --help with action for details:',
     )
     )
     rcreate_parser = subparsers.add_parser(
     rcreate_parser = subparsers.add_parser(
         'rcreate',
         'rcreate',

+ 11 - 11
borgmatic/commands/borgmatic.py

@@ -44,8 +44,8 @@ LEGACY_CONFIG_PATH = '/etc/borgmatic/config'
 def run_configuration(config_filename, config, arguments):
 def run_configuration(config_filename, config, arguments):
     '''
     '''
     Given a config filename, the corresponding parsed config dict, and command-line arguments as a
     Given a config filename, the corresponding parsed config dict, and command-line arguments as a
-    dict from subparser name to a namespace of parsed arguments, execute the defined prune, compact,
-    create, check, and/or other actions.
+    dict from subparser name to a namespace of parsed arguments, execute the defined create, prune,
+    compact, check, and/or other actions.
 
 
     Yield a combination of:
     Yield a combination of:
 
 
@@ -64,7 +64,7 @@ def run_configuration(config_filename, config, arguments):
     retry_wait = storage.get('retry_wait', 0)
     retry_wait = storage.get('retry_wait', 0)
     encountered_error = None
     encountered_error = None
     error_repository = ''
     error_repository = ''
-    using_primary_action = {'prune', 'compact', 'create', 'check'}.intersection(arguments)
+    using_primary_action = {'create', 'prune', 'compact', 'check'}.intersection(arguments)
     monitoring_log_level = verbosity_to_log_level(global_arguments.monitoring_verbosity)
     monitoring_log_level = verbosity_to_log_level(global_arguments.monitoring_verbosity)
 
 
     try:
     try:
@@ -302,12 +302,12 @@ def run_actions(
                 local_path,
                 local_path,
                 remote_path,
                 remote_path,
             )
             )
-        elif action_name == 'prune':
-            borgmatic.actions.prune.run_prune(
+        elif action_name == 'create':
+            yield from borgmatic.actions.create.run_create(
                 config_filename,
                 config_filename,
                 repository,
                 repository,
+                location,
                 storage,
                 storage,
-                retention,
                 hooks,
                 hooks,
                 hook_context,
                 hook_context,
                 local_borg_version,
                 local_borg_version,
@@ -317,8 +317,8 @@ def run_actions(
                 local_path,
                 local_path,
                 remote_path,
                 remote_path,
             )
             )
-        elif action_name == 'compact':
-            borgmatic.actions.compact.run_compact(
+        elif action_name == 'prune':
+            borgmatic.actions.prune.run_prune(
                 config_filename,
                 config_filename,
                 repository,
                 repository,
                 storage,
                 storage,
@@ -332,12 +332,12 @@ def run_actions(
                 local_path,
                 local_path,
                 remote_path,
                 remote_path,
             )
             )
-        elif action_name == 'create':
-            yield from borgmatic.actions.create.run_create(
+        elif action_name == 'compact':
+            borgmatic.actions.compact.run_compact(
                 config_filename,
                 config_filename,
                 repository,
                 repository,
-                location,
                 storage,
                 storage,
+                retention,
                 hooks,
                 hooks,
                 hook_context,
                 hook_context,
                 local_borg_version,
                 local_borg_version,

+ 8 - 8
borgmatic/config/schema.yaml

@@ -369,6 +369,11 @@ properties:
                         description: |
                         description: |
                           Extra command-line options to pass to "borg init".
                           Extra command-line options to pass to "borg init".
                         example: "--extra-option"
                         example: "--extra-option"
+                    create:
+                        type: string
+                        description: |
+                          Extra command-line options to pass to "borg create".
+                        example: "--extra-option"
                     prune:
                     prune:
                         type: string
                         type: string
                         description: |
                         description: |
@@ -379,11 +384,6 @@ properties:
                         description: |
                         description: |
                           Extra command-line options to pass to "borg compact".
                           Extra command-line options to pass to "borg compact".
                         example: "--extra-option"
                         example: "--extra-option"
-                    create:
-                        type: string
-                        description: |
-                          Extra command-line options to pass to "borg create".
-                        example: "--extra-option"
                     check:
                     check:
                         type: string
                         type: string
                         description: |
                         description: |
@@ -663,11 +663,11 @@ properties:
                     type: string
                     type: string
                 description: |
                 description: |
                     List of one or more shell commands or scripts to execute
                     List of one or more shell commands or scripts to execute
-                    when an exception occurs during a "prune", "compact",
-                    "create", or "check" action or an associated before/after
+                    when an exception occurs during a "create", "prune",
+                    "compact", or "check" action or an associated before/after
                     hook.
                     hook.
                 example:
                 example:
-                    - echo "Error during prune/compact/create/check."
+                    - echo "Error during create/prune/compact/check."
             before_everything:
             before_everything:
                 type: array
                 type: array
                 items:
                 items:

+ 16 - 12
docs/how-to/deal-with-very-large-backups.md

@@ -9,28 +9,32 @@ eleventyNavigation:
 
 
 Borg itself is great for efficiently de-duplicating data across successive
 Borg itself is great for efficiently de-duplicating data across successive
 backup archives, even when dealing with very large repositories. But you may
 backup archives, even when dealing with very large repositories. But you may
-find that while borgmatic's default mode of `prune`, `compact`, `create`, and
-`check` works well on small repositories, it's not so great on larger ones.
-That's because running the default pruning, compact, and consistency checks
-take a long time on large repositories.
+find that while borgmatic's default actions of `create`, `prune`, `compact`,
+and `check` works well on small repositories, it's not so great on larger
+ones. That's because running the default pruning, compact, and consistency
+checks take a long time on large repositories.
+
+<span class="minilink minilink-addedin">Prior to version 1.7.9</span> The
+default action ordering was `prune`, `compact`, `create`, and `check`.
 
 
 ### A la carte actions
 ### A la carte actions
 
 
-If you find yourself in this situation, you have some options. First, you can
-run borgmatic's `prune`, `compact`, `create`, or `check` actions separately.
-For instance, the following optional actions are available:
+If you find yourself wanting to customize the actions, you have some options.
+First, you can run borgmatic's `prune`, `compact`, `create`, or `check`
+actions separately. For instance, the following optional actions are
+available (among others):
 
 
 ```bash
 ```bash
+borgmatic create
 borgmatic prune
 borgmatic prune
 borgmatic compact
 borgmatic compact
-borgmatic create
 borgmatic check
 borgmatic check
 ```
 ```
 
 
-You can run with only one of these actions provided, or you can mix and match
-any number of them in a single borgmatic run. This supports approaches like
-skipping certain actions while running others. For instance, this skips
-`prune` and `compact` and only runs `create` and `check`:
+You can run borgmatic with only one of these actions provided, or you can mix
+and match any number of them in a single borgmatic run. This supports
+approaches like skipping certain actions while running others. For instance,
+this skips `prune` and `compact` and only runs `create` and `check`:
 
 
 ```bash
 ```bash
 borgmatic create check
 borgmatic create check

+ 6 - 6
docs/how-to/monitor-your-backups.md

@@ -83,7 +83,7 @@ tests](https://torsion.org/borgmatic/docs/how-to/extract-a-backup/).
 
 
 ## Error hooks
 ## Error hooks
 
 
-When an error occurs during a `prune`, `compact`, `create`, or `check` action,
+When an error occurs during a `create`, `prune`, `compact`, or `check` action,
 borgmatic can run configurable shell commands to fire off custom error
 borgmatic can run configurable shell commands to fire off custom error
 notifications or take other actions, so you can get alerted as soon as
 notifications or take other actions, so you can get alerted as soon as
 something goes wrong. Here's a not-so-useful example:
 something goes wrong. Here's a not-so-useful example:
@@ -116,8 +116,8 @@ the repository. Here's the full set of supported variables you can use here:
  * `output`: output of the command that failed (may be blank if an error
  * `output`: output of the command that failed (may be blank if an error
    occurred without running a command)
    occurred without running a command)
 
 
-Note that borgmatic runs the `on_error` hooks only for `prune`, `compact`,
-`create`, or `check` actions or hooks in which an error occurs, and not other
+Note that borgmatic runs the `on_error` hooks only for `create`, `prune`,
+`compact`, or `check` actions or hooks in which an error occurs, and not other
 actions. borgmatic does not run `on_error` hooks if an error occurs within a
 actions. borgmatic does not run `on_error` hooks if an error occurs within a
 `before_everything` or `after_everything` hook. For more about hooks, see the
 `before_everything` or `after_everything` hook. For more about hooks, see the
 [borgmatic hooks
 [borgmatic hooks
@@ -144,7 +144,7 @@ With this hook in place, borgmatic pings your Healthchecks project when a
 backup begins, ends, or errors. Specifically, after the <a
 backup begins, ends, or errors. Specifically, after the <a
 href="https://torsion.org/borgmatic/docs/how-to/add-preparation-and-cleanup-steps-to-backups/">`before_backup`
 href="https://torsion.org/borgmatic/docs/how-to/add-preparation-and-cleanup-steps-to-backups/">`before_backup`
 hooks</a> run, borgmatic lets Healthchecks know that it has started if any of
 hooks</a> run, borgmatic lets Healthchecks know that it has started if any of
-the `prune`, `compact`, `create`, or `check` actions are run.
+the `create`, `prune`, `compact`, or `check` actions are run.
 
 
 Then, if the actions complete successfully, borgmatic notifies Healthchecks of
 Then, if the actions complete successfully, borgmatic notifies Healthchecks of
 the success after the `after_backup` hooks run, and includes borgmatic logs in
 the success after the `after_backup` hooks run, and includes borgmatic logs in
@@ -154,8 +154,8 @@ in the Healthchecks UI, although be aware that Healthchecks currently has a
 
 
 If an error occurs during any action or hook, borgmatic notifies Healthchecks
 If an error occurs during any action or hook, borgmatic notifies Healthchecks
 after the `on_error` hooks run, also tacking on logs including the error
 after the `on_error` hooks run, also tacking on logs including the error
-itself. But the logs are only included for errors that occur when a `prune`,
-`compact`, `create`, or `check` action is run.
+itself. But the logs are only included for errors that occur when a `create`,
+`prune`, `compact`, or `check` action is run.
 
 
 You can customize the verbosity of the logs that are sent to Healthchecks with
 You can customize the verbosity of the logs that are sent to Healthchecks with
 borgmatic's `--monitoring-verbosity` flag. The `--list` and `--stats` flags
 borgmatic's `--monitoring-verbosity` flag. The `--list` and `--stats` flags

+ 13 - 13
tests/unit/commands/test_borgmatic.py

@@ -436,14 +436,15 @@ def test_run_actions_runs_transfer():
     )
     )
 
 
 
 
-def test_run_actions_runs_prune():
+def test_run_actions_runs_create():
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module.command).should_receive('execute_hook')
     flexmock(module.command).should_receive('execute_hook')
-    flexmock(borgmatic.actions.prune).should_receive('run_prune').once()
+    expected = flexmock()
+    flexmock(borgmatic.actions.create).should_receive('run_create').and_yield(expected).once()
 
 
-    tuple(
+    result = tuple(
         module.run_actions(
         module.run_actions(
-            arguments={'global': flexmock(dry_run=False), 'prune': flexmock()},
+            arguments={'global': flexmock(dry_run=False), 'create': flexmock()},
             config_filename=flexmock(),
             config_filename=flexmock(),
             location={'repositories': []},
             location={'repositories': []},
             storage=flexmock(),
             storage=flexmock(),
@@ -456,16 +457,17 @@ def test_run_actions_runs_prune():
             repository_path='repo',
             repository_path='repo',
         )
         )
     )
     )
+    assert result == (expected,)
 
 
 
 
-def test_run_actions_runs_compact():
+def test_run_actions_runs_prune():
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module.command).should_receive('execute_hook')
     flexmock(module.command).should_receive('execute_hook')
-    flexmock(borgmatic.actions.compact).should_receive('run_compact').once()
+    flexmock(borgmatic.actions.prune).should_receive('run_prune').once()
 
 
     tuple(
     tuple(
         module.run_actions(
         module.run_actions(
-            arguments={'global': flexmock(dry_run=False), 'compact': flexmock()},
+            arguments={'global': flexmock(dry_run=False), 'prune': flexmock()},
             config_filename=flexmock(),
             config_filename=flexmock(),
             location={'repositories': []},
             location={'repositories': []},
             storage=flexmock(),
             storage=flexmock(),
@@ -480,15 +482,14 @@ def test_run_actions_runs_compact():
     )
     )
 
 
 
 
-def test_run_actions_runs_create():
+def test_run_actions_runs_compact():
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module.command).should_receive('execute_hook')
     flexmock(module.command).should_receive('execute_hook')
-    expected = flexmock()
-    flexmock(borgmatic.actions.create).should_receive('run_create').and_yield(expected).once()
+    flexmock(borgmatic.actions.compact).should_receive('run_compact').once()
 
 
-    result = tuple(
+    tuple(
         module.run_actions(
         module.run_actions(
-            arguments={'global': flexmock(dry_run=False), 'create': flexmock()},
+            arguments={'global': flexmock(dry_run=False), 'compact': flexmock()},
             config_filename=flexmock(),
             config_filename=flexmock(),
             location={'repositories': []},
             location={'repositories': []},
             storage=flexmock(),
             storage=flexmock(),
@@ -501,7 +502,6 @@ def test_run_actions_runs_create():
             repository_path='repo',
             repository_path='repo',
         )
         )
     )
     )
-    assert result == (expected,)
 
 
 
 
 def test_run_actions_runs_check_when_repository_enabled_for_checks():
 def test_run_actions_runs_check_when_repository_enabled_for_checks():