add failure and success hooks

This commit is contained in:
cupcakearmy 2021-05-06 15:55:32 +02:00
parent aebaf0a225
commit e05386b0b5
No known key found for this signature in database
GPG Key ID: D28129AE5654D9D9
4 changed files with 68 additions and 27 deletions

View File

@ -17,15 +17,15 @@ var backupCmd = &cobra.Command{
CheckErr(err)
defer lock.Unlock()
CheckErr(internal.CheckConfig())
internal.GetConfig()
selected, err := internal.GetAllOrSelected(cmd, false)
CheckErr(err)
errors := 0
for _, name := range selected {
location, _ := internal.GetLocation(name)
err := location.Backup(false)
if err != nil {
errs := location.Backup(false)
for err := range errs {
colors.Error.Println(err)
errors++
}

View File

@ -2,7 +2,14 @@
If you want to perform some commands before and/or after a backup, you can use hooks.
They consist of a list of `before`/`after` commands that will be executed in the same directory as the target `from`.
They consist of a list of commands that will be executed in the same directory as the target `from`.
The following hooks groups are supported, none are required:
- `before`
- `after`
- `failure`
- `success`
```yml | .autorestic.yml
locations:
@ -11,10 +18,25 @@ locations:
to: my-backend
hooks:
before:
- echo "Hello"
- echo "Human"
- echo "One"
- echo "Two"
- echo "Three"
after:
- echo "kthxbye"
- echo "Byte"
failure:
- echo "Something went wrong"
success:
- echo "Well done!"
```
## Flowchart
1. `before` hook
2. Run backup
3. `after` hook
4. - `success` hook if no errors were found
- `failure` hook if at least error was encountered
If the `before` hook encounters errors the backup and `after` hooks will be skipped and only the `failed` hooks will run.
> :ToCPrevNext

View File

@ -75,21 +75,22 @@ func (c *Config) Describe() {
colors.PrintDescription("Cron", l.Cron)
}
after, before := len(l.Hooks.After), len(l.Hooks.Before)
if after+before > 0 {
tmp = ""
if before > 0 {
tmp += "\tBefore"
for _, cmd := range l.Hooks.Before {
hooks := map[string][]string{
"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 {
tmp += "\n\t" + hook
for _, cmd := range commands {
tmp += colors.Faint.Sprintf("\n\t ▶ %s", cmd)
}
}
if after > 0 {
tmp += "\n\tAfter"
for _, cmd := range l.Hooks.After {
tmp += colors.Faint.Sprintf("\n\t ▶ %s", cmd)
}
}
if tmp != "" {
colors.PrintDescription("Hooks", tmp)
}

View File

@ -24,8 +24,10 @@ const (
type HookArray = []string
type Hooks struct {
Before HookArray `yaml:"before"`
After HookArray `yaml:"after"`
Before HookArray `yaml:"before,omitempty"`
After HookArray `yaml:"after,omitempty"`
Success HookArray `yaml:"success,omitempty"`
Failure HookArray `yaml:"failure,omitempty"`
}
type Options map[string]map[string][]string
@ -133,7 +135,8 @@ func (l Location) getPath() (string, error) {
return "", fmt.Errorf("could not get path for location \"%s\"", l.name)
}
func (l Location) Backup(cron bool) error {
func (l Location) Backup(cron bool) []error {
var errors []error
colors.PrimaryPrint(" Backing up location \"%s\" ", l.name)
t := l.getType()
options := ExecuteOptions{
@ -147,7 +150,8 @@ func (l Location) Backup(cron bool) error {
// Hooks
if err := ExecuteHooks(l.Hooks.Before, options); err != nil {
return err
errors = append(errors, err)
goto after
}
// Backup
@ -156,7 +160,8 @@ func (l Location) Backup(cron bool) error {
colors.Secondary.Printf("Backend: %s\n", backend.name)
env, err := backend.getEnv()
if err != nil {
return nil
errors = append(errors, err)
continue
}
flags := l.getOptions("backup")
@ -181,7 +186,8 @@ func (l Location) Backup(cron bool) error {
}
if err != nil {
colors.Error.Println(out)
return err
errors = append(errors, err)
continue
}
if VERBOSE {
colors.Faint.Println(out)
@ -190,10 +196,22 @@ func (l Location) Backup(cron bool) error {
// After hooks
if err := ExecuteHooks(l.Hooks.After, options); err != nil {
return err
errors = append(errors, err)
}
after:
var commands []string
if len(errors) > 0 {
commands = l.Hooks.Failure
} else {
commands = l.Hooks.Success
}
if err := ExecuteHooks(commands, options); err != nil {
errors = append(errors, err)
}
colors.Success.Println("Done")
return nil
return errors
}
func (l Location) Forget(prune bool, dry bool) error {