Compare commits

..

1 Commits

Author SHA1 Message Date
simonhammes
a33b782c54 Add allowFailure option
Implements #189
2024-11-05 21:32:34 +01:00
6 changed files with 28 additions and 45 deletions

View File

@@ -1,4 +1,4 @@
FROM golang:1.24-alpine as builder FROM golang:1.23-alpine as builder
WORKDIR /app WORKDIR /app
COPY go.* . COPY go.* .
@@ -6,7 +6,7 @@ RUN go mod download
COPY . . COPY . .
RUN go build RUN go build
FROM restic/restic:0.18.0 FROM restic/restic:0.17.2
RUN apk add --no-cache rclone bash curl docker-cli RUN apk add --no-cache rclone bash curl docker-cli
COPY --from=builder /app/autorestic /usr/bin/autorestic COPY --from=builder /app/autorestic /usr/bin/autorestic
ENTRYPOINT [] ENTRYPOINT []

View File

@@ -18,11 +18,9 @@ var backupCmd = &cobra.Command{
err := lock.Lock() err := lock.Lock()
CheckErr(err) CheckErr(err)
defer lock.Unlock() defer lock.Unlock()
dry, _ := cmd.Flags().GetBool("dry-run")
selected, err := internal.GetAllOrSelected(cmd, false) selected, err := internal.GetAllOrSelected(cmd, false)
CheckErr(err) CheckErr(err)
errors := 0 errors := 0
for _, name := range selected { for _, name := range selected {
var splitted = strings.Split(name, "@") var splitted = strings.Split(name, "@")
@@ -31,7 +29,7 @@ var backupCmd = &cobra.Command{
specificBackend = splitted[1] specificBackend = splitted[1]
} }
location, _ := internal.GetLocation(splitted[0]) location, _ := internal.GetLocation(splitted[0])
errs := location.Backup(false, dry, specificBackend) errs := location.Backup(false, specificBackend)
for _, err := range errs { for _, err := range errs {
colors.Error.Printf("%s\n\n", err) colors.Error.Printf("%s\n\n", err)
errors++ errors++
@@ -46,5 +44,4 @@ var backupCmd = &cobra.Command{
func init() { func init() {
rootCmd.AddCommand(backupCmd) rootCmd.AddCommand(backupCmd)
internal.AddFlagsToCommand(backupCmd, false) internal.AddFlagsToCommand(backupCmd, false)
backupCmd.Flags().Bool("dry-run", false, "do not write changes, show what would be affected")
} }

View File

@@ -1,14 +1,11 @@
# Backup # Backup
```bash ```bash
autorestic backup [-l, --location] [-a, --all] [--dry-run] autorestic backup [-l, --location] [-a, --all]
``` ```
Performs a backup of all locations if the `-a` flag is passed. To only backup some locations pass one or more `-l` or `--location` flags. Performs a backup of all locations if the `-a` flag is passed. To only backup some locations pass one or more `-l` or `--location` flags.
The `--dry-run` flag will do a dry run showing what would have been deleted, but won't touch the actual data.
```bash ```bash
# All # All
autorestic backup -a autorestic backup -a

View File

@@ -19,14 +19,15 @@ type BackendRest struct {
} }
type Backend struct { type Backend struct {
name string name string
Type string `mapstructure:"type,omitempty" yaml:"type,omitempty"` Type string `mapstructure:"type,omitempty" yaml:"type,omitempty"`
Path string `mapstructure:"path,omitempty" yaml:"path,omitempty"` Path string `mapstructure:"path,omitempty" yaml:"path,omitempty"`
Key string `mapstructure:"key,omitempty" yaml:"key,omitempty"` Key string `mapstructure:"key,omitempty" yaml:"key,omitempty"`
RequireKey bool `mapstructure:"requireKey,omitempty" yaml:"requireKey,omitempty"` RequireKey bool `mapstructure:"requireKey,omitempty" yaml:"requireKey,omitempty"`
Env map[string]string `mapstructure:"env,omitempty" yaml:"env,omitempty"` AllowFailure bool `mapstructure:"allowFailure,omitempty" yaml:"allowFailure,omitempty"`
Rest BackendRest `mapstructure:"rest,omitempty" yaml:"rest,omitempty"` Env map[string]string `mapstructure:"env,omitempty" yaml:"env,omitempty"`
Options Options `mapstructure:"options,omitempty" yaml:"options,omitempty"` Rest BackendRest `mapstructure:"rest,omitempty" yaml:"rest,omitempty"`
Options Options `mapstructure:"options,omitempty" yaml:"options,omitempty"`
} }
func GetBackend(name string) (Backend, bool) { func GetBackend(name string) (Backend, bool) {

View File

@@ -188,34 +188,18 @@ func CheckConfig() error {
if !CheckIfResticIsCallable() { if !CheckIfResticIsCallable() {
return fmt.Errorf(`%s was not found. Install either with "autorestic install" or manually`, flags.RESTIC_BIN) return fmt.Errorf(`%s was not found. Install either with "autorestic install" or manually`, flags.RESTIC_BIN)
} }
cwd, _ := GetPathRelativeToConfig(".")
for name, location := range c.Locations {
location.name = name
// Hooks before location validation
options := ExecuteOptions{
Command: "bash",
Dir: cwd,
Envs: map[string]string{
"AUTORESTIC_LOCATION": location.name,
},
}
if err := location.ExecuteHooks(location.Hooks.PreValidate, options); err != nil {
return err
}
if err := location.validate(); err != nil {
return err
}
}
for name, backend := range c.Backends { for name, backend := range c.Backends {
backend.name = name backend.name = name
if err := backend.validate(); err != nil { if err := backend.validate(); err != nil {
return err return err
} }
} }
for name, location := range c.Locations {
location.name = name
if err := location.validate(); err != nil {
return err
}
}
return nil return nil
} }

View File

@@ -168,7 +168,7 @@ func (l Location) getLocationTags() string {
return buildTag("location", l.name) return buildTag("location", l.name)
} }
func (l Location) Backup(cron bool, dry bool, specificBackend string) []error { func (l Location) Backup(cron bool, specificBackend string) []error {
var errors []error var errors []error
var backends []string var backends []string
colors.PrimaryPrint(" Backing up location \"%s\" ", l.name) colors.PrimaryPrint(" Backing up location \"%s\" ", l.name)
@@ -228,9 +228,6 @@ func (l Location) Backup(cron bool, dry bool, specificBackend string) []error {
if cron { if cron {
cmd = append(cmd, "--tag", buildTag("cron")) cmd = append(cmd, "--tag", buildTag("cron"))
} }
if dry {
cmd = append(cmd, "--dry-run")
}
cmd = append(cmd, "--tag", l.getLocationTags()) cmd = append(cmd, "--tag", l.getLocationTags())
backupOptions := ExecuteOptions{ backupOptions := ExecuteOptions{
Envs: env, Envs: env,
@@ -270,6 +267,13 @@ func (l Location) Backup(cron bool, dry bool, specificBackend string) []error {
// If error save it and continue // If error save it and continue
if err != nil { if err != nil {
if backend.AllowFailure {
colors.Faint.Printf("skipping backend \"%s\" since allowFailure was set to \"true\"\n", to)
if flags.VERBOSE {
colors.Error.Printf("reason: %s", out)
}
continue
}
colors.Error.Println(out) colors.Error.Println(out)
errors = append(errors, fmt.Errorf("%s@%s:\n%s%s", l.name, backend.name, out, err)) errors = append(errors, fmt.Errorf("%s@%s:\n%s%s", l.name, backend.name, out, err))
continue continue
@@ -450,7 +454,7 @@ func (l Location) RunCron() error {
now := time.Now() now := time.Now()
if now.After(next) { if now.After(next) {
lock.SetCron(l.name, now.Unix()) lock.SetCron(l.name, now.Unix())
errs := l.Backup(true, false, "") errs := l.Backup(true, "")
if len(errs) > 0 { if len(errs) > 0 {
return fmt.Errorf("Failed to backup location \"%s\":\n%w", l.name, errors.Join(errs...)) return fmt.Errorf("Failed to backup location \"%s\":\n%w", l.name, errors.Join(errs...))
} }