Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add PreValidate hook #359

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Autorestic is a wrapper around the amazing [restic](https://restic.net/). While
- Backup locations to multiple backends
- Snapshot policies and pruning
- Fully encrypted
- Pre/After hooks
- Before/after backup hooks
- Exclude pattern/files
- Cron jobs for automatic backup
- Backup & Restore docker volume
Expand Down
2 changes: 2 additions & 0 deletions docs/pages/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ version: 2

extras:
hooks: &foo
prevalidate:
- echo "Wake up!"
before:
- echo "Hello"
after:
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Autorestic is a wrapper around the amazing [restic](https://restic.net/). While
- Backup locations to multiple backends
- Snapshot policies and pruning
- Fully encrypted
- Pre/After hooks
- Before/after backup hooks
- Exclude pattern/files
- Cron jobs for automatic backup
- Backup & Restore docker volumes
Expand Down
19 changes: 13 additions & 6 deletions docs/pages/location/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,28 @@ They consist of a list of commands that will be executed in the same directory a

The following hooks groups are supported, none are required:

- `prevalidate`
- `before`
- `after`
- `failure`
- `success`

The difference between `prevalidate` and `before` hooks are that `prevalidate` is run before checking the backup location is valid, including checking that the `from` directories exist. This can be useful, for example, to mount the source filesystem that contains the directories listed in `from`.

```yml | .autorestic.yml
locations:
my-location:
from: /data
to: my-backend
hooks:
prevalidate:
- echo "Checks"
before:
- echo "One"
- echo "Two"
- echo "Three"
after:
- echo "Byte"
- echo "Bye"
failure:
- echo "Something went wrong"
success:
Expand All @@ -31,13 +36,15 @@ locations:

## Flowchart

1. `before` hook
2. Run backup
3. `after` hook
4. - `success` hook if no errors were found
1. `prevalidate` hook
2. Check backup location
3. `before` hook
4. Run backup
5. `after` hook
6. - `success` hook if no errors were found
- `failure` hook if at least one error was encountered

If the `before` hook encounters errors the backup and `after` hooks will be skipped and only the `failed` hooks will run.
If either the `prevalidate` or `before` hook encounters errors then the backup and `after` hooks will be skipped and only the `failed` hooks will run.

## Environment variables

Expand Down
9 changes: 5 additions & 4 deletions internal/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,11 @@ func (c *Config) Describe() {

tmp = ""
hooks := map[string][]string{
"Before": l.Hooks.Before,
"After": l.Hooks.After,
"Failure": l.Hooks.Failure,
"Success": l.Hooks.Success,
"PreValidate": l.Hooks.PreValidate,
"Before": l.Hooks.Before,
"After": l.Hooks.After,
"Failure": l.Hooks.Failure,
"Success": l.Hooks.Success,
}
for hook, commands := range hooks {
if len(commands) > 0 {
Expand Down
22 changes: 15 additions & 7 deletions internal/location.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ const (
)

type Hooks struct {
Dir string `mapstructure:"dir"`
Before HookArray `mapstructure:"before,omitempty"`
After HookArray `mapstructure:"after,omitempty"`
Success HookArray `mapstructure:"success,omitempty"`
Failure HookArray `mapstructure:"failure,omitempty"`
Dir string `mapstructure:"dir"`
PreValidate HookArray `mapstructure:"prevalidate,omitempty"`
Before HookArray `mapstructure:"before,omitempty"`
After HookArray `mapstructure:"after,omitempty"`
Success HookArray `mapstructure:"success,omitempty"`
Failure HookArray `mapstructure:"failure,omitempty"`
}

type LocationCopy = map[string][]string
Expand Down Expand Up @@ -184,12 +185,18 @@ func (l Location) Backup(cron bool, specificBackend string) []error {
},
}

// Hooks before location validation
if err := l.ExecuteHooks(l.Hooks.PreValidate, options); err != nil {
errors = append(errors, err)
goto after
}

if err := l.validate(); err != nil {
errors = append(errors, err)
goto after
}

// Hooks
// Hooks after location validation
if err := l.ExecuteHooks(l.Hooks.Before, options); err != nil {
errors = append(errors, err)
goto after
Expand Down Expand Up @@ -289,12 +296,13 @@ func (l Location) Backup(cron bool, specificBackend string) []error {
}
}

// After hooks
// After backup hooks
if err := l.ExecuteHooks(l.Hooks.After, options); err != nil {
errors = append(errors, err)
}

after:
// Success/failure hooks
var commands []string
var isSuccess = len(errors) == 0
if isSuccess {
Expand Down