Hooks are all executed at the same time. #473
Labels
No Label
bug
data loss
design finalized
good first issue
new feature area
question / support
security
waiting for response
No Milestone
No Assignees
5 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: borgmatic-collective/borgmatic#473
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Hey,
I am currently trying to measure time using the hooks. For example how much time the checks take in comparison to the backups.
The problem is that the before checks and the after checks are called in two groups at the same time.
1. First the before hooks are called:
2. Then the work happens
backup + checks + prune
3. Then the after hooks are called:
I believe something is programmed wrong. The before and after hook for a piece of work should be executed right before and after it.
Can someone please check and fix it?
Hey there, I just encountered the same Issue.
I'm trying to pause a few containers before creating a backup and unpause them afterwards. But the
after_backup
hook don't run immediately after the backup completes, but only after the integrity checks have completed. I tried using thebefore_check
hook to unpause the containers before the integrity checks start (-> after creating the backup has finished), but that hook runs before the backup job runs.For me this is not really usable like this, since the integrity checks take a few hours, since some of my archives are pretty big. That would mean that my containers are paused for a few hours, which is not necessary, since creating the backup itself only takes a few minutes.
Taking a look at the relevant code it seems like this is the intended behaviour: All
before_{action}
hooks run at the start, next the actions are run, then theafter_{action}
hooks run at the end.I don't think that this is the behaviour most users would expect. I would suggest changing it like @DonRichie suggested:
before_prune
->prune
->after_prune
->before_backup
->backup
->after_backup
->before_check
->check
->after_check
I'm aware that this is probably a breaking change, but I think it is worth it, since it would make borgmatic much more flexible, enabling scenarios like the one I described above.
Or maybe there is another way to achieve what I described above?
Maybe the current behavior could be achieved with an alternate syntax like:
@Nikos410 You are correct that the existing hook behavior is by design. The idea is that
before
andafter
hooks run once per configuration file. So if you have multiple repositories in a single configuration file and run multiple actions on them, the resulting invocations might look something like this:before_backup
hook.before_check
hook.borg create
on repository 1borg check
on repository 1borg create
on repository 2borg check
on repository 2borg create
on repository 3borg check
on repository 3after_check
hook.after_backup
hook.That way, the
before
/after
hooks don't run repeatedly. However, I could see potentially reorganzing things to run more like the following, which would be a fairly major reorganization from the code perspective:before_backup
hook.borg create
on repository 1borg create
on repository 2borg create
on repository 3after_backup
hook.before_check
hook.borg check
on repository 1borg check
on repository 2borg check
on repository 3after_check
hook.However that may still not satisfy the desired use cases, because you're not able to either time a single
create
invocation or, as per the @Nikos410 case, pause/restart containers for a single repository. Still, might be sufficient for most cases?@DonRichie Might it make sense to add action durations to borgmatic logs as an in-built feature?
Need for reorganization
I reread the documentation and feel like currently the three before_* hooks are only useful to find out if a check, prune or backup happened at all. I read the text as for example the prune hook is skipped if no prune action happened.
I would like the regorganization because this still preserves the information mentioned above. At the same time it gives the additional information when exactly the single actions started and added. Thats an improvement!
How to cover all use cases for hooks
Regarding my use case and the healthcheck stuff i am trying: The prune check would still fail since the prune hook won't be executed if there is no prune happening. But I am fine with that behaviour since there might be use cases taking advantage of it.
In a perfect world I would like to have the cartesian product like this:
{success,fail,always}x{before,after}x{everything,backup,check,prune}
Each possible combination as a single hook in the configuration. Thats
3 * 2 * 4 = 24
combinations.Little bit much to be honest. Maybe there is a data structure in the configuration suitable to make that flexible?
But maybe it would be also sufficient to have it documented well, like "if you want success+before+backup hook you need to set success_before_backup_hook = ...".
Durations measurement
Regarding your question @witten: Lets say I want to find out the last checks duration as a user. First I would execute "borg info ..." on my repository. But that isn't providing any information about how much time the last check took. Next step would be calling "journalctl -u backupjob.service" giving your logs. Therefore I want to agree and wish for some duration measurements in the log output.
As I already mentioned in the other issue a statistics hook would be nice. That would require configs settings for http url, http body (with templating) and http headers".
Alternate Syntax
I think we have a conflict between ease of configuration and versatility of the configuration. Maybe this can be resolved with a syntax like this (here for the pausing/unpausing use case that @Nikos410 and I are using):
task
then could becreate | prune | check | extract | everything | any
. Theany
case would be used for hooks that should run before each individual task, but it doesn't matter which one. In the same manner,before | after | before-all | after-all | any
could be used to run a hook before or after each single task, or before or after all of the tasks of this type.before
andbeforeAll
in combination witheverything
in the task option would then do the same. Alternatively, the old syntax style could be used, butbefore-any-any
doesn't quite read as nice.Statistics
To gather statistics data a hook with
task: any
andtiming: any
or a dedicated hook-name could be used. Similar to pre-commit and pre-push hooks in git, addtional information, about the repository, the command, which actions are about to run and the hook name could be passed as parameters into the script. Maybe it would be useful to just be able to pass the path to a bash script to execute to theexecute
param.Evaluation
Advantages:
Disadvantages:
Needs further discussion:
What i forgot: the result.
Could be implemented in a similar fashion to task and timing, but will only be allowed if timing is after or afterAll or any. Possible values:
success | failure | any
Hey, is there any update about this issue? @witten what do you think about the solution @timvahlbrock suggested?
I think it's a cool idea in terms of the syntax, but I don't think it's needed to solve the underlying issue here. Specifically, the problem as I understand it is nicely summarized in the the current ticket title: "Hooks are all executed at the same time." Meaning, in this case,
after_backup
runs after consistency checks along with all otherafter_*
hooks rather than immediately after backups (create
), making container unpausing after backups and before consistency checks difficult. I realize the proposal above includes bothbefore
andbeforeAll
timings to address that, but I don't know that we need both. I think we just need them to run directly before the corresponding action (create
, etc).So I think the solution is to fix that issue, and then the syntax ideas could be discussed on a separate ticket. Personally, I'm not married to any existing borgmatic syntax. If it needs to evolve to satisfy changing requirements, great. I'd also recommend filing the statistics hook ask as a separate issue so it can be implemented on its own.
Let me know your thoughts!
So you're proposing to adapt the current behavior of the hooks? As far as I'm concerned, that would be a breaking change for some existing configurations. Right?
I am proposing that as a fix, yes. It is "breaking" in the sense that this would run the hooks at a different time, but the current timing is "incorrect" as folks here have pointed out (even if it is by design). I would hope there aren't many users relying on that timing. I'd probably have to bump borgmatic's major or minor version to indicate the change.
Came here to log this issue also. Great to see it is already being looked at! Any update on when this is likely to be fixed as some of my checks run for a couple of hours and the service is down until these complete, whereas the backups themselves might only take 15-20 minutes.
This has been implemented in master! Beta testers wanted! See below.
Now, instead of executing "before" command hooks before all borgmatic actions run (and "after" hooks after), borgmatic executes these hooks right before/after the corresponding action. E.g., "before_check" now runs immediately before the "check" action.
Here's an example run with these changes in place and a bunch of
echo
commands configured for the various hooks (The echos are "Starting ...", "Finished ...", etc.):A side effect of these changes: before/after command hooks now run once for each configured repository instead of once per configuration file. This means your hooks may run more than once if you have multiple repositories configured! Additionally, the "repositories" interpolated variable has been changed to "repository", containing the path to the current repository for the hook. This means you can perform appropriate per-repository logic in your hooks if you like.
Since these are some pretty major changes, I'm looking for beta testers to try them out before release. Anyone have a non-production repository or three they'd like to try this on? This is your opportunity to make sure the feature meets your requirements before it's released!
Thanks for all of your ideas and patience with this feature.
Released in borgmatic 1.6.0! Please let me know if you have any problems with this change or have any feedback about it.