Compare commits

..

7 Commits

Author SHA1 Message Date
ಠ_ಠ
c152eeb652 Merge 0a48d13d6c into 13aa560fda 2024-03-12 15:22:56 +01:00
Stuart Hickinbottom
13aa560fda Add PreValidate hook (#359)
Fix #332.

This adds a new "PreValidate" hook that is executed before checking
the backup location. This allows, for example, mounting a remote
source to make the directories of the location available.

"PreValidate" is added as a new hook to avoid any breakage that might
have been caused by changing the behaviour of the "before" hook.

Documentataion updates included.
2024-03-12 15:22:43 +01:00
rdelaage
bbb1c85cad Fix upgrade command (#259)
fix #191

Co-authored-by: Romain de Laage <romain.delaage@rdelaage.ovh>
2024-02-15 14:27:37 +01:00
Natanel Shitrit
4cc44315ab feat: add docker-cli package (#339)
Co-authored-by: Nicco <hi@nicco.io>
2024-02-15 14:26:26 +01:00
dependabot[bot]
b3440cd87c Bump golang from 1.21-alpine to 1.22-alpine (#355)
Bumps golang from 1.21-alpine to 1.22-alpine.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-15 14:24:17 +01:00
rdelaage
4848702929 Use options on exec command (#253)
Co-authored-by: Romain de Laage <romain.delaage@rdelaage.ovh>
2024-02-15 14:23:43 +01:00
ಠ_ಠ
0a48d13d6c Fix quick installation instruction
The command in the documentation was wrong and didn't run the script with elevated privileges. This one does.
2023-12-28 12:11:47 +01:00
10 changed files with 62 additions and 41 deletions

View File

@@ -1,4 +1,4 @@
FROM golang:1.21-alpine as builder
FROM golang:1.22-alpine as builder
WORKDIR /app
COPY go.* .
@@ -7,7 +7,7 @@ COPY . .
RUN go build
FROM restic/restic:0.16.4
RUN apk add --no-cache rclone bash curl
RUN apk add --no-cache rclone bash curl docker-cli
COPY --from=builder /app/autorestic /usr/bin/autorestic
ENTRYPOINT []
CMD [ "autorestic" ]

View File

@@ -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

View File

@@ -56,6 +56,8 @@ version: 2
extras:
hooks: &foo
prevalidate:
- echo "Wake up!"
before:
- echo "Hello"
after:

View File

@@ -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

View File

@@ -5,7 +5,7 @@ Linux & macOS. Windows is not supported. If you have problems installing please
Autorestic requires `bash`, `wget` and `bzip2` to be installed. For most systems these should be already installed.
```bash
wget -qO - https://raw.githubusercontent.com/cupcakearmy/autorestic/master/install.sh | bash
sudo bash -c "$(wget -qO - https://raw.githubusercontent.com/cupcakearmy/autorestic/master/install.sh)"
```
## Alternatives

View File

@@ -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:
@@ -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

View File

@@ -143,6 +143,7 @@ func (b Backend) Exec(args []string) error {
return err
}
options := ExecuteOptions{Envs: env}
args = append(args, combineBackendOptions("exec", b)...)
_, out, err := ExecuteResticCommand(options, args...)
if err != nil {
colors.Error.Println(out)

View File

@@ -6,7 +6,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"path"
@@ -37,7 +36,7 @@ func dlJSON(url string) (GithubRelease, error) {
return parsed, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
return parsed, err
@@ -73,9 +72,10 @@ func downloadAndInstallAsset(body GithubRelease, name string) error {
// Uncompress
bz := bzip2.NewReader(resp.Body)
// Save to tmp
// Linux does not support overwriting the file that is currently being overwritten, but it can be deleted and a new one moved in its place.
tmp, err := ioutil.TempFile(os.TempDir(), "autorestic-")
// Save to tmp file in the same directory as the install directory
// Linux does not support overwriting the file that is currently being running
// But it can be delete the old one and a new one moved in its place.
tmp, err := os.CreateTemp(INSTALL_PATH, "autorestic-")
if err != nil {
return err
}
@@ -89,24 +89,26 @@ func downloadAndInstallAsset(body GithubRelease, name string) error {
to := path.Join(INSTALL_PATH, name)
defer os.Remove(tmp.Name()) // Cleanup temporary file after thread exits
if err := os.Rename(tmp.Name(), to); err != nil {
colors.Error.Printf("os.Rename() failed (%v), retrying with io.Copy()\n", err.Error())
var src *os.File
var dst *os.File
if src, err = os.Open(tmp.Name()); err != nil {
return err
}
if dst, err = os.Create(to); err != nil {
return err
}
if _, err := io.Copy(dst, src); err != nil {
return err
}
if err := os.Chmod(to, 0755); err != nil {
mode := os.FileMode(0755)
if originalBin, err := os.Lstat(to); err == nil {
mode = originalBin.Mode()
err := os.Remove(to)
if err != nil {
return err
}
}
err = os.Rename(tmp.Name(), to)
if err != nil {
return err
}
err = os.Chmod(to, mode)
if err != nil {
return err
}
colors.Success.Printf("Successfully installed '%s' under %s\n", name, INSTALL_PATH)
return nil
}

View File

@@ -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 {

View File

@@ -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
@@ -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
@@ -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 {