Browse Source

Fix a traceback when providing an invalid "--override" value for a list option (#814).

Dan Helfman 1 year ago
parent
commit
4d79f582df

+ 1 - 0
NEWS

@@ -3,6 +3,7 @@
    bootstrap" action. Previously, only top-level configuration files were stored.
  * #810: SECURITY: Prevent shell injection attacks within the PostgreSQL hook, the MongoDB hook, the
    SQLite hook, the "borgmatic borg" action, and command hook variable/constant interpolation.
+ * #814: Fix a traceback when providing an invalid "--override" value for a list option.
 
 1.8.6
  * #767: Add an "--ssh-command" flag to the "config bootstrap" action for setting a custom SSH

+ 5 - 0
borgmatic/config/override.py

@@ -13,6 +13,11 @@ def set_values(config, keys, value):
 
     first_key = keys[0]
     if len(keys) == 1:
+        if isinstance(config, list):
+            raise ValueError(
+                'When overriding a list option, the value must use list syntax (e.g., "[foo, bar]" or "[{key: value}]" as appropriate)'
+            )
+
         config[first_key] = value
         return
 

+ 15 - 11
docs/how-to/make-per-application-backups.md

@@ -495,21 +495,29 @@ borgmatic create --override parent_option.option1=value1 --override parent_optio
 forget to specify the section that an option is in. That looks like a prefix
 on the option name, e.g. `location.repositories`.
 
-Note that each value is parsed as an actual YAML string, so you can even set
-list values by using brackets. For instance:
+Note that each value is parsed as an actual YAML string, so you can set list
+values by using brackets. For instance:
 
 ```bash
 borgmatic create --override repositories=[test1.borg,test2.borg]
 ```
 
-Or even a single list element:
+Or a single list element:
 
 ```bash
 borgmatic create --override repositories=[/root/test.borg]
 ```
 
-If your override value contains special YAML characters like colons, then
-you'll need quotes for it to parse correctly:
+Or a single list element that is a key/value pair:
+
+```bash
+borgmatic create --override repositories="[{path: test.borg, label: test}]"
+```
+
+If your override value contains characters like colons or spaces, then you'll
+need to use quotes for it to parse correctly.
+
+Another example:
 
 ```bash
 borgmatic create --override repositories="['user@server:test.borg']"
@@ -518,16 +526,12 @@ borgmatic create --override repositories="['user@server:test.borg']"
 There is not currently a way to override a single element of a list without
 replacing the whole list.
 
-Note that if you override an option of the list type (like
-`location.repositories`), you do need to use the `[ ]` list syntax. See the
-[configuration
+Using the `[ ]` list syntax is required when overriding an option of the list
+type (like `location.repositories`). See the [configuration
 reference](https://torsion.org/borgmatic/docs/reference/configuration/) for
 which options are list types. (YAML list values look like `- this` with an
 indentation and a leading dash.)
 
-Be sure to quote your overrides if they contain spaces or other characters
-that your shell may interpret.
-
 An alternate to command-line overrides is passing in your values via
 [environment
 variables](https://torsion.org/borgmatic/docs/how-to/provide-your-passwords/).

+ 7 - 0
tests/unit/config/test_override.py

@@ -44,6 +44,13 @@ def test_set_values_with_multiple_keys_updates_hierarchy():
     assert config == {'option': {'key': 'value', 'other': 'other_value'}}
 
 
+def test_set_values_with_key_when_list_index_expected_errors():
+    config = {'option': ['foo', 'bar', 'baz']}
+
+    with pytest.raises(ValueError):
+        module.set_values(config, keys=('option', 'key'), value='value')
+
+
 @pytest.mark.parametrize(
     'schema,option_keys,expected_type',
     (