From 249d24a8b9c50fc599f9ce8868f8e4272034d9fc Mon Sep 17 00:00:00 2001 From: Robert McQueen Date: Wed, 11 Mar 2026 20:36:18 +0000 Subject: [PATCH 1/2] Add test for to_nice_yaml scalar corruption in hooks (issue #117) Add a healthchecks scalar URL to the molecule converge playbook and a verify assertion that checks the rendered borgmatic config doesn't contain '...' (YAML document end marker) in the healthchecks value. This catches the bug where to_nice_yaml on a scalar produces "value\n...\n" which corrupts the config. Co-Authored-By: Claude Opus 4.6 --- molecule/default/converge.yml | 1 + molecule/default/verify.yml | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index e0108e3..6d8f105 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -49,6 +49,7 @@ borgmatic_hooks: before_backup: - echo "`date` - Starting backup." + healthchecks: https://hc-ping.com/12345678-1234-1234-1234-123456789012 postgresql_databases: - name: users hostname: database1.example.org diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index f816e3f..f5d90a5 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -11,3 +11,20 @@ - name: Ensure produced YAML is valid command: | yamllint -d "{extends: relaxed, rules: {line-length: {max: 120}}}" /etc/borgmatic/config.yaml + + - name: Read borgmatic config + ansible.builtin.slurp: + src: /etc/borgmatic/config.yaml + register: borgmatic_config + + - name: Parse borgmatic config as YAML + ansible.builtin.set_fact: + borgmatic_config_parsed: "{{ borgmatic_config.content | b64decode | from_yaml }}" + + - name: Verify healthchecks URL is not corrupted by to_nice_yaml scalar bug + ansible.builtin.assert: + that: + - >- + '...' not in (borgmatic_config_parsed.healthchecks | + default(borgmatic_config_parsed.hooks.healthchecks | default(''))) + fail_msg: "healthchecks URL corrupted by to_nice_yaml scalar bug (contains '...')" From 58452cb09d988028a37d19158c2d9702af8d1cee Mon Sep 17 00:00:00 2001 From: Robert McQueen Date: Wed, 11 Mar 2026 23:33:25 +0000 Subject: [PATCH 2/2] Fix to_nice_yaml scalar corruption in borgmatic hooks (fixes #117) Invoking to_nice_yaml on a scalar value generates a two-line YAML document "value\n...\n" which corrupts the value of a hook such as healthchecks which is just a single string URL. Instead of looping over each of the hooks, apply to_nice_yaml to the entire hooks dict in a single invocation. Add width=1000 to prevent PyYAML from wrapping long strings (like URLs) at 80 chars. Fix both config.yaml.j2 (borgmatic >= 1.8) and config_1.7.yaml.j2 (borgmatic < 1.8). Co-Authored-By: Claude Opus 4.6 --- templates/config.yaml.j2 | 6 +----- templates/config_1.7.yaml.j2 | 5 +---- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/templates/config.yaml.j2 b/templates/config.yaml.j2 index d6efc51..bfa89eb 100644 --- a/templates/config.yaml.j2 +++ b/templates/config.yaml.j2 @@ -193,13 +193,9 @@ check_last: {{ borgmatic_check_last }} # IMPORTANT: All provided commands and scripts are executed with user permissions of borgmatic. # Do not forget to set secure permissions on this file as well as on any script listed (chmod 0700) to # prevent potential shell injection or privilege escalation. -{% for hook in borgmatic_hooks %} -{{ hook }}: -{{ borgmatic_hooks[hook] | to_nice_yaml(indent=4) | indent(4, first=true) }} -{% endfor %} +{{ borgmatic_hooks | to_nice_yaml(indent=4, width=1000) }} {% if borgmatic_custom_config is defined and borgmatic_custom_config %} # Custom configuration {{ borgmatic_custom_config | to_nice_yaml(indent=4) }} {% endif %} - diff --git a/templates/config_1.7.yaml.j2 b/templates/config_1.7.yaml.j2 index ed784db..9fc7548 100644 --- a/templates/config_1.7.yaml.j2 +++ b/templates/config_1.7.yaml.j2 @@ -200,7 +200,4 @@ consistency: # Do not forget to set secure permissions on this file as well as on any script listed (chmod 0700) to # prevent potential shell injection or privilege escalation. hooks: -{% for hook in borgmatic_hooks %} - {{ hook }}: -{{ borgmatic_hooks[hook] | to_nice_yaml(indent=4) | indent(8, first=true) }} -{% endfor %} +{{ borgmatic_hooks | to_nice_yaml(indent=4, width=1000) | indent(4) }}