mirror of
https://github.com/cupcakearmy/autorestic.git
synced 2025-09-06 10:30:39 +00:00
Compare commits
4 Commits
c66bce9728
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
9cf919b42b | ||
|
bb29a98614 | ||
|
39f4f87ce3 | ||
|
bd36bbe429 |
@@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.23-alpine as builder
|
FROM golang:1.25-alpine as builder
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY go.* .
|
COPY go.* .
|
||||||
|
@@ -18,9 +18,11 @@ 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, "@")
|
||||||
@@ -29,7 +31,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, specificBackend)
|
errs := location.Backup(false, dry, 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++
|
||||||
@@ -44,4 +46,5 @@ 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")
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,14 @@
|
|||||||
# Backup
|
# Backup
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
autorestic backup [-l, --location] [-a, --all]
|
autorestic backup [-l, --location] [-a, --all] [--dry-run]
|
||||||
```
|
```
|
||||||
|
|
||||||
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
|
||||||
|
@@ -24,7 +24,6 @@ type Backend struct {
|
|||||||
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"`
|
||||||
AllowFailure bool `mapstructure:"allowFailure,omitempty" yaml:"allowFailure,omitempty"`
|
|
||||||
Env map[string]string `mapstructure:"env,omitempty" yaml:"env,omitempty"`
|
Env map[string]string `mapstructure:"env,omitempty" yaml:"env,omitempty"`
|
||||||
Rest BackendRest `mapstructure:"rest,omitempty" yaml:"rest,omitempty"`
|
Rest BackendRest `mapstructure:"rest,omitempty" yaml:"rest,omitempty"`
|
||||||
Options Options `mapstructure:"options,omitempty" yaml:"options,omitempty"`
|
Options Options `mapstructure:"options,omitempty" yaml:"options,omitempty"`
|
||||||
|
@@ -188,15 +188,31 @@ 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)
|
||||||
}
|
}
|
||||||
for name, backend := range c.Backends {
|
|
||||||
backend.name = name
|
cwd, _ := GetPathRelativeToConfig(".")
|
||||||
if err := backend.validate(); err != nil {
|
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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for name, location := range c.Locations {
|
|
||||||
location.name = name
|
for name, backend := range c.Backends {
|
||||||
if err := location.validate(); err != nil {
|
backend.name = name
|
||||||
|
if err := backend.validate(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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, specificBackend string) []error {
|
func (l Location) Backup(cron bool, dry 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,6 +228,9 @@ func (l Location) Backup(cron 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,
|
||||||
@@ -267,13 +270,6 @@ func (l Location) Backup(cron 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
|
||||||
@@ -454,7 +450,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, "")
|
errs := l.Backup(true, false, "")
|
||||||
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...))
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user