Remove configuration sections entirely (except for deprecated support) #721

Closed
opened 2023-06-29 20:33:07 +00:00 by witten · 11 comments
Owner

What I'm trying to do and why

Here's a common UX annoyance with borgmatic: You want to add a new configuration option to your borgmatic config file because your backup requirements have changed. So you open your config file and uncomment the new option or type it in. Then you run borgmatic, only to get an obnoxious error about unexpected this or that—because you forgot to scroll way up and also uncomment the corresponding section header (location:, storage:, retention:, consistency:, hooks:, etc.). You swear under your breath, uncomment the header, and move on with your task. Or worse, if you're a new user and don't know what the error means, you file a ticket or just stop using borgmatic entirely.

Similarly: Let's say your backup needs change and that option you used to need is no longer necessary. So you open your borgmatic config file, comment out the option, and run borgmatic, only to get an annoying error message about hooks: or whatever section having no values—because you just commented out its last remaining option. You swear, this time not under your breath, comment out hooks:, and move on with your day.

But what if borgmatic could do away with these recurring annoyances and eliminate section headers entirely? Just for context: They were originally added for organization purposes back when borgmatic had way fewer options. But one might argue that any organization they provide now is pretty minimal.

Pop quiz: What section is the lock_wait option in? Do you know? No? Well I don't either, and that's kind of my point. If the section headers aren't really providing much value in the way of organization, maybe they need to go.

I don't propose eliminating other hierarchy besides the section headers in the configuration file. Usually other hierarchy (e.g. postgresql_databases:) is much more localized, and so you're less likely to forget to comment/uncomment it when changing a sub-option.

What this might look like

If this is your current config file ...

location:
    source_directories:
        - /home
        - /etc

    repositories:
        - path: ssh://k8pDxu32@k8pDxu32.repo.borgbase.com/./repo
          label: borgbase
        - path: /var/lib/backups/local.borg
          label: local

retention:
    keep_daily: 7
    keep_weekly: 4
    keep_monthly: 6

consistency:
    checks:
        - name: repository
        - name: archives
          frequency: 2 weeks

hooks:
    before_backup:
        - prepare-for-backup.sh

    postgresql_databases:
        - name: users

    healthchecks: https://hc-ping.com/be067061-cf96-4412-8eae-62b0c50d6a8c

... this might be the same configuration after the proposed changes are implemented:

source_directories:
    - /home
    - /etc

repositories:
    - path: ssh://k8pDxu32@k8pDxu32.repo.borgbase.com/./repo
      label: borgbase
    - path: /var/lib/backups/local.borg
      label: local

keep_daily: 7
keep_weekly: 4
keep_monthly: 6

checks:
    - name: repository
    - name: archives
      frequency: 2 weeks

before_backup:
    - prepare-for-backup.sh

postgresql_databases:
    - name: users

healthchecks: https://hc-ping.com/be067061-cf96-4412-8eae-62b0c50d6a8c

Other notes / implementation ideas

In terms of implementation, I propose deprecating but retaining support for section headers (so, not making a breaking change now) and simply normalizing any old-style configs as they're loaded. Under the hood, normalize() could slurp in any section config and move it to the top-level, effectively merging all the sections together.

There is at least one case where there'd be a collision: retention prefix and consistency prefix. My suggestion there is to silently merge them unless both are set and the values differ, in which case borgmatic could error. (This would technically be a minor breaking change. Oopsie daisy.)

There might also be an option here or there that could do with renaming once it's pulled into global scope. (output color comes to mind.)

Much of the borgmatic code would also need refactoring not to expect to pull options out of sections. This would be a very large and wide-ranging change, but hopefully a mostly mechanical one.

Given that 1.8.0 is the next release, this seems like a natural time to pull off this particular band-aid.

#### What I'm trying to do and why Here's a common UX annoyance with borgmatic: You want to add a new configuration option to your borgmatic config file because your backup requirements have changed. So you open your config file and uncomment the new option or type it in. Then you run borgmatic, only to get an obnoxious error about unexpected this or that—because you forgot to scroll way up and also uncomment the corresponding section header (`location:`, `storage:`, `retention:`, `consistency:`, `hooks:`, etc.). You swear under your breath, uncomment the header, and move on with your task. Or worse, if you're a new user and don't know what the error means, you file a ticket or just stop using borgmatic entirely. Similarly: Let's say your backup needs change and that option you *used* to need is no longer necessary. So you open your borgmatic config file, comment out the option, and run borgmatic, only to get an annoying error message about `hooks:` or whatever section having no values—because you just commented out its last remaining option. You swear, this time not under your breath, comment out `hooks:`, and move on with your day. But what if borgmatic could do away with these recurring annoyances and eliminate section headers entirely? Just for context: They were originally added for organization purposes back when borgmatic had way fewer options. But one might argue that any organization they provide now is pretty minimal. Pop quiz: What section is the `lock_wait` option in? Do you know? *No?* Well I don't either, and that's kind of my point. If the section headers aren't really providing much value in the way of organization, maybe they need to go. I *don't* propose eliminating other hierarchy besides the section headers in the configuration file. Usually other hierarchy (e.g. `postgresql_databases:`) is much more localized, and so you're less likely to forget to comment/uncomment it when changing a sub-option. #### What this might look like If this is your current config file ... ```yaml location: source_directories: - /home - /etc repositories: - path: ssh://k8pDxu32@k8pDxu32.repo.borgbase.com/./repo label: borgbase - path: /var/lib/backups/local.borg label: local retention: keep_daily: 7 keep_weekly: 4 keep_monthly: 6 consistency: checks: - name: repository - name: archives frequency: 2 weeks hooks: before_backup: - prepare-for-backup.sh postgresql_databases: - name: users healthchecks: https://hc-ping.com/be067061-cf96-4412-8eae-62b0c50d6a8c ``` ... this might be the same configuration after the proposed changes are implemented: ```yaml source_directories: - /home - /etc repositories: - path: ssh://k8pDxu32@k8pDxu32.repo.borgbase.com/./repo label: borgbase - path: /var/lib/backups/local.borg label: local keep_daily: 7 keep_weekly: 4 keep_monthly: 6 checks: - name: repository - name: archives frequency: 2 weeks before_backup: - prepare-for-backup.sh postgresql_databases: - name: users healthchecks: https://hc-ping.com/be067061-cf96-4412-8eae-62b0c50d6a8c ``` #### Other notes / implementation ideas In terms of implementation, I propose deprecating but retaining support for section headers (so, *not* making a breaking change now) and simply normalizing any old-style configs as they're loaded. Under the hood, `normalize()` could slurp in any section config and move it to the top-level, effectively merging all the sections together. There is at least one case where there'd be a collision: `retention` `prefix` and `consistency` `prefix`. My suggestion there is to silently merge them unless both are set and the values differ, in which case borgmatic could error. (This would technically be a minor breaking change. Oopsie daisy.) There might also be an option here or there that could do with renaming once it's pulled into global scope. (`output` `color` comes to mind.) Much of the borgmatic code would also need refactoring not to expect to pull options out of sections. This would be a very large and wide-ranging change, but hopefully a mostly mechanical one. Given that 1.8.0 is the next release, this seems like a natural time to pull off this particular band-aid.
witten changed title from Remove configuration sections entirely to Remove configuration sections entirely (except for deprecated support) 2023-06-29 20:43:10 +00:00
witten referenced this issue from a commit 2023-07-09 06:14:57 +00:00
Author
Owner

Merged into main and will be part of the next release.

Merged into main and will be part of the next release.
Author
Owner

Released in borgmatic 1.8.0!

Released in borgmatic 1.8.0!

Hi, I think this is a troublesome change for people like me that rely on those sections to be able to use multiple << include merges in a single configuration file (e.g. to have separate different combinations of retention options and hooks).

Is there any possibility to make them permanently optional instead of deprecating them? Just wondering.

Hi, I think this is a troublesome change for people like me that rely on those sections to be able to use multiple << include merges in a single configuration file (e.g. to have separate different combinations of retention options and hooks). Is there any possibility to make them permanently optional instead of deprecating them? Just wondering.
Author
Owner

Thanks for chiming in with your experience here! Honestly I was a little worried about this use case with the changes in this ticket, so it's good to hear from someone who actually has this need. As an alternative to the sections for multiple << includes, what do you think of borgmatic actually supporting an include that pulls in multiple files? Something like this (although I haven't vetted the feasibility):

<<: !include common1.yaml common2.yaml common3.yaml

Thoughts? Other ideas?

Thanks for chiming in with your experience here! Honestly I was a little worried about this use case with the changes in this ticket, so it's good to hear from someone who actually has this need. As an alternative to the sections for multiple << includes, what do you think of borgmatic actually supporting an include that pulls in multiple files? Something like this (although I haven't vetted the feasibility): ```python <<: !include common1.yaml common2.yaml common3.yaml ``` Thoughts? Other ideas?

Oh wow, that idea actually sounds great to me, I was thinking of working around the issue by using yq in a similar fashion (although in a way that would require me to do some preprocessing to get the actual final configuration files, not that great).

If I were able to do what you just described (and in a way where changes are applied in listed order like I assume is the case), I think many of my configuration files could simply contain a single include line and that would be amazing.

Oh wow, that idea actually sounds great to me, I was thinking of working around the issue by using [yq](https://github.com/mikefarah/yq) in a similar fashion (although in a way that would require me to do some preprocessing to get the actual final configuration files, not that great). If I were able to do what you just described (and in a way where changes are applied in listed order like I assume is the case), I think many of my configuration files could simply contain a single include line and that would be amazing.
Author
Owner

Great! I broke off that feature into #732, which you are welcome to follow! (Also.. TIL I learned about yq! 😄)

Great! I broke off that feature into #732, which you are welcome to follow! (Also.. TIL I learned about yq! 😄)

Thank you so much, definitely looking forward to it! 🙂

Thank you so much, definitely looking forward to it! 🙂
Author
Owner

That multiple include feature in #732 is now implemented in main and will be part of the next release! Documentation here: https://torsion.org/borgmatic/docs/how-to/make-per-application-backups/#multiple-merge-includes

That multiple include feature in #732 is now implemented in main and will be part of the next release! Documentation here: https://torsion.org/borgmatic/docs/how-to/make-per-application-backups/#multiple-merge-includes
Author
Owner

And #732 (multiple includes) has just been released in borgmatic 1.8.1! Let me know how it works out for you.

And #732 (multiple includes) has just been released in borgmatic 1.8.1! Let me know how it works out for you.

Sorry for the very late reply, but I was able to update all of my configuration just recently, making use of the new multi-include feature, and it indeed works pretty well. Thanks a lot!

Sorry for the very late reply, but I was able to update all of my configuration just recently, making use of the new multi-include feature, and it indeed works pretty well. Thanks a lot!
Author
Owner

Awesome, glad to hear it!

Awesome, glad to hear it!
Sign in to join this conversation.
No Milestone
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: borgmatic-collective/borgmatic#721
No description provided.