Compare commits

..

1 Commits

Author SHA1 Message Date
Andreas Wagner
4e3ae6403b add more architectures for linux build process
equivalent to 7d665fa1f4/helpers/build-release-binaries/main.go
2022-10-06 12:06:20 +03:00
27 changed files with 8076 additions and 3967 deletions

View File

@@ -1,8 +0,0 @@
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"

View File

@@ -10,12 +10,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v1
- name: Docker Labels
id: meta
uses: crazy-max/ghaction-docker-meta@v4
uses: crazy-max/ghaction-docker-meta@v2
with:
images: cupcakearmy/autorestic
tags: |
@@ -23,12 +23,12 @@ jobs:
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
- name: Login to DockerHub
uses: docker/login-action@v2
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v3
uses: docker/build-push-action@v2
with:
platforms: linux/amd64,linux/arm64
push: true
@@ -37,12 +37,17 @@ jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
with:
go-version: "^1.20"
go-version: "^1.16.3"
- name: Build
run: go run build/build.go
- name: Sign
uses: tristan-weil/ghaction-checksum-sign-artifact@v1.0.1
with:
path: dist/*
- name: Release
uses: softprops/action-gh-release@v1
with:

View File

@@ -5,17 +5,6 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.7.4] - 2023-01-18
### Fixed
- Transformer for extracting information. @11mariom
### Changed
- Bump docker restic version.
- Docs dependencies updated.
## [1.7.1] - 2022-04-27
### Fixed

View File

@@ -1,4 +1,4 @@
FROM golang:1.20-alpine as builder
FROM golang:1.18-alpine as builder
WORKDIR /app
COPY go.* .
@@ -6,8 +6,7 @@ RUN go mod download
COPY . .
RUN go build
FROM restic/restic:0.15.1
RUN apk add --no-cache rclone bash
FROM alpine
RUN apk add --no-cache restic rclone bash openssh
COPY --from=builder /app/autorestic /usr/bin/autorestic
ENTRYPOINT []
CMD [ "autorestic" ]

View File

@@ -4,11 +4,7 @@
package main
import (
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
@@ -21,51 +17,23 @@ import (
var DIR, _ = filepath.Abs("./dist")
var targets = map[string][]string{
// "aix": {"ppc64"}, // Not supported by fsnotify
"darwin": {"amd64", "arm64"},
"freebsd": {"386", "amd64", "arm"},
"linux": {"386", "amd64", "arm", "arm64", "ppc64le", "mips", "mipsle", "mips64", "mips64le", "s390x"},
"linux": {"386", "amd64", "arm", "arm64", "ppc64le", "mips", "mipsle", "mips64", "mips64le"},
"netbsd": {"386", "amd64"},
"openbsd": {"386", "amd64"},
// "windows": {"386", "amd64"}, // Not supported by autorestic
"solaris": {"amd64"},
}
type buildOptions struct {
Target, Arch, Version string
}
const (
CHECKSUM_MD5 = "MD5SUMS"
CHECKSUM_SHA_1 = "SHA1SUMS"
CHECKSUM_SHA_256 = "SHA256SUMS"
)
type Checksums struct {
filename, md5, sha1, sha256 string
}
func writeChecksums(checksums *[]Checksums) {
FILE_MD5, _ := os.OpenFile(path.Join(DIR, CHECKSUM_MD5), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
defer FILE_MD5.Close()
FILE_SHA1, _ := os.OpenFile(path.Join(DIR, CHECKSUM_SHA_1), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
defer FILE_SHA1.Close()
FILE_SHA256, _ := os.OpenFile(path.Join(DIR, CHECKSUM_SHA_256), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
defer FILE_SHA256.Close()
for _, checksum := range *checksums {
fmt.Fprintf(FILE_MD5, "%s %s\n", checksum.md5, checksum.filename)
fmt.Fprintf(FILE_SHA1, "%s %s\n", checksum.sha1, checksum.filename)
fmt.Fprintf(FILE_SHA256, "%s %s\n", checksum.sha256, checksum.filename)
}
}
func build(options buildOptions, wg *sync.WaitGroup, checksums *[]Checksums) {
defer wg.Done()
fmt.Printf("Building: %s %s\n", options.Target, options.Arch)
func build(options buildOptions, wg *sync.WaitGroup) {
fmt.Printf("Building %s %s\n", options.Target, options.Arch)
out := fmt.Sprintf("autorestic_%s_%s_%s", options.Version, options.Target, options.Arch)
out = path.Join(DIR, out)
out, _ = filepath.Abs(out)
fmt.Println(out)
// Build
{
@@ -94,39 +62,22 @@ func build(options buildOptions, wg *sync.WaitGroup, checksums *[]Checksums) {
panic(err)
}
}
// Checksum
{
file := out + ".bz2"
content, _ := ioutil.ReadFile(file)
*checksums = append(*checksums, Checksums{
filename: path.Base(file),
md5: fmt.Sprintf("%x", md5.Sum(content)),
sha1: fmt.Sprintf("%x", sha1.Sum(content)),
sha256: fmt.Sprintf("%x", sha256.Sum256(content)),
})
}
fmt.Printf("Built: %s\n", path.Base(out))
wg.Done()
}
func main() {
os.RemoveAll(DIR)
v := internal.VERSION
checksums := []Checksums{}
// Build async
var wg sync.WaitGroup
for target, archs := range targets {
for _, arch := range archs {
wg.Add(1)
go build(buildOptions{
build(buildOptions{
Target: target,
Arch: arch,
Version: v,
}, &wg, &checksums)
}, &wg)
}
}
wg.Wait()
writeChecksums(&checksums)
}

View File

@@ -4,7 +4,6 @@ import (
"fmt"
"github.com/cupcakearmy/autorestic/internal"
"github.com/cupcakearmy/autorestic/internal/colors"
"github.com/cupcakearmy/autorestic/internal/lock"
"github.com/spf13/cobra"
)
@@ -43,13 +42,8 @@ var restoreCmd = &cobra.Command{
}
}
errs := l.Restore(target, from, force, snapshot, optional)
for _, err := range errs {
colors.Error.Printf("%s\n\n", err)
}
if len(errs) > 0 {
CheckErr(fmt.Errorf("%d errors were found", len(errs)))
}
err = l.Restore(target, from, force, snapshot, optional)
CheckErr(err)
},
}

View File

@@ -55,7 +55,7 @@ func initConfig() {
viper.SetConfigFile(cfgFile)
viper.AutomaticEnv()
if viper.ConfigFileUsed() == "" {
colors.Error.Printf("cannot read config file %s\n", cfgFile)
colors.Error.Println("cannot read config file %s\n", cfgFile)
os.Exit(1)
}
} else {

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
{
"dependencies": {
"@codedoc/core": "^0.3.2"
"@codedoc/core": "^0.2.24"
}
}

View File

@@ -45,7 +45,6 @@
>
> [0.x → 1.0](/migration/0.x_1.0)
> [1.4 → 1.5](/migration/1.4_1.5)
> [1.7 → 1.8](/migration/1.7_1.8)
[Examples](/examples)
[Docker](/docker)

View File

@@ -8,6 +8,5 @@ A list of community driven projects. (No official affiliation)
- Ansible Role: <https://github.com/ItsNotGoodName/ansible-role-autorestic>
- Ansible Role: <https://github.com/FuzzyMistborn/ansible-role-autorestic>
- Ansible Role: <https://0xacab.org/varac-projects/ansible-role-autorestic>
- Ansible Role: <https://github.com/dbrennand/ansible-role-autorestic>
> :ToCPrevNext

View File

@@ -55,11 +55,10 @@ version: 2
extras:
hooks: &foo
backup:
before:
- echo "Hello"
after:
- echo "kthxbye"
before:
- echo "Hello"
after:
- echo "kthxbye"
policies: &bar
keep-daily: 14
keep-weekly: 52

View File

@@ -22,13 +22,12 @@ autorestic exec -b my-backend -- unlock
extras:
healthchecks: &healthchecks
hooks:
backup:
before:
- 'curl -m 10 --retry 5 -X POST -H "Content-Type: text/plain" --data "Starting backup for location: ${AUTORESTIC_LOCATION}" https://<healthchecks-url>/ping/<uid>/start'
failure:
- 'curl -m 10 --retry 5 -X POST -H "Content-Type: text/plain" --data "Backup failed for location: ${AUTORESTIC_LOCATION}" https://<healthchecks-url>/ping/<uid>/fail'
success:
- 'curl -m 10 --retry 5 -X POST -H "Content-Type: text/plain" --data "Backup successful for location: ${AUTORESTIC_LOCATION}" https://<healthchecks-url>/ping/<uid>'
before:
- 'curl -m 10 --retry 5 -X POST -H "Content-Type: text/plain" --data "Starting backup for location: ${AUTORESTIC_LOCATION}" https://<healthchecks-url>/ping/<uid>/start'
failure:
- 'curl -m 10 --retry 5 -X POST -H "Content-Type: text/plain" --data "Backup failed for location: ${AUTORESTIC_LOCATION}" https://<healthchecks-url>/ping/<uid>/fail'
success:
- 'curl -m 10 --retry 5 -X POST -H "Content-Type: text/plain" --data "Backup successful for location: ${AUTORESTIC_LOCATION}" https://<healthchecks-url>/ping/<uid>'
locations:
something:

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
wget -qO - https://raw.githubusercontent.com/CupCakeArmy/autorestic/master/install.sh | bash
```
## Alternatives
@@ -24,10 +24,6 @@ You can download the right binary from the release page and simply copy it to `/
If you are on macOS you can install through brew: `brew install autorestic`.
### Fedora
Fedora users can install the [autorestic](https://src.fedoraproject.org/rpms/autorestic/) package with `dnf install autorestic`.
### AUR
~~If you are on Arch there is an [AUR Package](https://aur.archlinux.org/packages/autorestic-bin/) (looking for maintainers).~~ - Deprecated

View File

@@ -1,8 +1,8 @@
# Hooks
If you want to perform some commands before and/or after a backup or restore, you can use hooks.
If you want to perform some commands before and/or after a backup, you can use hooks.
They consist of a list of commands that will be executed in the same directory as the config file or in the `dir` directory if configured.
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:
@@ -17,27 +17,16 @@ locations:
from: /data
to: my-backend
hooks:
backup:
before:
- echo "One"
- echo "Two"
- echo "Three"
after:
- echo "Byte"
failure:
- echo "Something went wrong"
success:
- echo "Well done!"
restore:
dir: /var/www/html
before:
- echo "Let's restore this backup!"
after:
- echo "Finished to restore"
failure:
- echo "A problem has been encountered :("
success:
- echo "Successfully restored!"
before:
- echo "One"
- echo "Two"
- echo "Three"
after:
- echo "Byte"
failure:
- echo "Something went wrong"
success:
- echo "Well done!"
```
## Flowchart

View File

@@ -1,45 +0,0 @@
# Migration from `1.7` to `1.8`
## Config files
- The config version have been changed
- You can now configure restore hooks
See detailed instructions below.
## Config Version
The version field of the config file has been changed from `2` to `3`.
## Hooks
Since `1.8` both backup and restore hooks are possible.
For this reason, backup hooks have been moved one layer deeper, you have to move them in a `backup` object.
Before:
```yaml
locations:
l1:
# ...
from: /foo/bar
hooks:
before:
- pwd
```
After:
```yaml
locations:
l1:
# ...
from: /foo/bar
hooks:
backup:
before:
- pwd
restore:
after:
- echo "My super restore hook"
```

View File

@@ -2,4 +2,3 @@
- [From 0.x to 1.0](/migration/0.x_1.0)
- [From 1.4 to 1.5](/migration/1.4_1.5)
- [From 1.7 to 1.8](/migration/1.7_1.8)

View File

@@ -3,7 +3,7 @@
## Installation
```bash
wget -qO - https://raw.githubusercontent.com/cupcakearmy/autorestic/master/install.sh | bash
wget -qO - https://raw.githubusercontent.com/CupCakeArmy/autorestic/master/install.sh | bash
```
See [installation](/installation) for alternative options.

1870
docs/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,6 +5,6 @@
"dev": "codedoc serve"
},
"dependencies": {
"@codedoc/cli": "^0.3.0"
"@codedoc/cli": "^0.2.8"
}
}

6
go.mod
View File

@@ -1,6 +1,6 @@
module github.com/cupcakearmy/autorestic
go 1.20
go 1.18
require (
github.com/blang/semver/v4 v4.0.0
@@ -28,8 +28,8 @@ require (
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
golang.org/x/text v0.3.8 // indirect
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/ini.v1 v1.66.4 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect

8
go.sum
View File

@@ -324,8 +324,8 @@ golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -333,8 +333,8 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

View File

@@ -31,11 +31,6 @@ else
fi
echo $ARCH
if ! command -v bzip2 &>/dev/null; then
echo "Missing bzip2 command. Please install the bzip2 package for your system."
exit 1
fi
wget -qO - https://api.github.com/repos/cupcakearmy/autorestic/releases/latest \
| grep "browser_download_url.*_${OS}_${ARCH}" \
| cut -d : -f 2,3 \

View File

@@ -38,7 +38,7 @@ func (b Backend) generateRepo() (string, error) {
case "local":
return GetPathRelativeToConfig(b.Path)
case "rest":
parsed, err := url.Parse(os.ExpandEnv(b.Path))
parsed, err := url.Parse(b.Path)
if err != nil {
return "", err
}

View File

@@ -17,7 +17,7 @@ import (
"github.com/spf13/viper"
)
const VERSION = "1.7.7"
const VERSION = "1.7.3"
type OptionMap map[string][]interface{}
type Options map[string]OptionMap
@@ -83,7 +83,7 @@ func GetConfig() *Config {
exitConfig(nil, "version specified in config file is not an int")
} else {
// Check for version
if version != 3 {
if version != 2 {
exitConfig(nil, "unsupported config version number. please check the docs for migration\nhttps://autorestic.vercel.app/migration/")
}
}
@@ -132,14 +132,10 @@ func (c *Config) Describe() {
tmp = ""
hooks := map[string][]string{
"Before backup": l.Hooks.BackupOption.Before,
"After backup": l.Hooks.BackupOption.After,
"Failure backup": l.Hooks.BackupOption.Failure,
"Success backup": l.Hooks.BackupOption.Success,
"Before restore": l.Hooks.RestoreOption.Before,
"After restore": l.Hooks.RestoreOption.After,
"Failure restore": l.Hooks.RestoreOption.Failure,
"Success restore": l.Hooks.RestoreOption.Success,
"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,13 +33,6 @@ const (
)
type Hooks struct {
RestoreOption HooksList `mapstructure:"restore,omitempty"`
BackupOption HooksList `mapstructure:"backup,omitempty"`
}
type LocationCopy = map[string][]string
type HooksList struct {
Dir string `mapstructure:"dir"`
Before HookArray `mapstructure:"before,omitempty"`
After HookArray `mapstructure:"after,omitempty"`
@@ -47,16 +40,18 @@ type HooksList struct {
Failure HookArray `mapstructure:"failure,omitempty"`
}
type LocationCopy = map[string][]string
type Location struct {
name string `mapstructure:",omitempty"`
From []string `mapstructure:"from,omitempty"`
Type string `mapstructure:"type,omitempty"`
To []string `mapstructure:"to,omitempty"`
Hooks Hooks `mapstructure:"hooks,omitempty"`
Cron string `mapstructure:"cron,omitempty"`
Options Options `mapstructure:"options,omitempty"`
ForgetOption LocationForgetOption `mapstructure:"forget,omitempty"`
CopyOption LocationCopy `mapstructure:"copy,omitempty"`
name string `mapstructure:",omitempty"`
From []string `mapstructure:"from,omitempty"`
Type string `mapstructure:"type,omitempty"`
To []string `mapstructure:"to,omitempty"`
Hooks Hooks `mapstructure:"hooks,omitempty"`
Cron string `mapstructure:"cron,omitempty"`
Options Options `mapstructure:"options,omitempty"`
ForgetOption LocationForgetOption `mapstructure:"forget,omitempty"`
CopyOption LocationCopy `mapstructure:"copy,omitempty"`
}
func GetLocation(name string) (Location, bool) {
@@ -128,12 +123,12 @@ func (l Location) validate() error {
return nil
}
func (l Location) ExecuteHooks(commands []string, directory string, options ExecuteOptions) error {
func (l Location) ExecuteHooks(commands []string, options ExecuteOptions) error {
if len(commands) == 0 {
return nil
}
if directory != "" {
if dir, err := GetPathRelativeToConfig(directory); err != nil {
if l.Hooks.Dir != "" {
if dir, err := GetPathRelativeToConfig(l.Hooks.Dir); err != nil {
return err
} else {
options.Dir = dir
@@ -195,7 +190,7 @@ func (l Location) Backup(cron bool, specificBackend string) []error {
}
// Hooks
if err := l.ExecuteHooks(l.Hooks.BackupOption.Before, l.Hooks.BackupOption.Dir, options); err != nil {
if err := l.ExecuteHooks(l.Hooks.Before, options); err != nil {
errors = append(errors, err)
goto after
}
@@ -295,7 +290,7 @@ func (l Location) Backup(cron bool, specificBackend string) []error {
}
// After hooks
if err := l.ExecuteHooks(l.Hooks.BackupOption.After, l.Hooks.BackupOption.Dir, options); err != nil {
if err := l.ExecuteHooks(l.Hooks.After, options); err != nil {
errors = append(errors, err)
}
@@ -303,20 +298,17 @@ after:
var commands []string
var isSuccess = len(errors) == 0
if isSuccess {
commands = l.Hooks.BackupOption.Success
commands = l.Hooks.Success
} else {
commands = l.Hooks.BackupOption.Failure
commands = l.Hooks.Failure
}
if err := l.ExecuteHooks(commands, l.Hooks.BackupOption.Dir, options); err != nil {
if err := l.ExecuteHooks(commands, options); err != nil {
errors = append(errors, err)
}
// Forget and optionally prune
if isSuccess && l.ForgetOption != "" && l.ForgetOption != LocationForgetNo {
err := l.Forget(l.ForgetOption == LocationForgetPrune, false)
if err != nil {
errors = append(errors, err)
}
l.Forget(l.ForgetOption == LocationForgetPrune, false)
}
if len(errors) == 0 {
@@ -375,35 +367,11 @@ func buildRestoreCommand(l Location, to string, snapshot string, options []strin
return base
}
func (l Location) Restore(to, from string, force bool, snapshot string, options []string) (errors []error) {
cwd, _ := GetPathRelativeToConfig(".")
hooksOptions := ExecuteOptions{
Command: "bash",
Dir: cwd,
Envs: map[string]string{
"AUTORESTIC_LOCATION": l.name,
},
}
defer func() {
var commands []string
var isSuccess = len(errors) == 0
if isSuccess {
commands = l.Hooks.RestoreOption.Success
} else {
commands = l.Hooks.RestoreOption.Failure
}
if err := l.ExecuteHooks(commands, l.Hooks.RestoreOption.Dir, hooksOptions); err != nil {
errors = append(errors, err)
}
colors.Success.Println("Done")
}()
func (l Location) Restore(to, from string, force bool, snapshot string, options []string) error {
if from == "" {
from = l.To[0]
} else if !l.hasBackend(from) {
errors = append(errors, fmt.Errorf("invalid backend: \"%s\"", from))
return fmt.Errorf("invalid backend: \"%s\"", from)
}
if snapshot == "" {
@@ -414,23 +382,15 @@ func (l Location) Restore(to, from string, force bool, snapshot string, options
backend, _ := GetBackend(from)
colors.Secondary.Printf("Restoring %s@%s → %s\n", snapshot, backend.name, to)
// Before Hooks for restore
if err := l.ExecuteHooks(l.Hooks.RestoreOption.Before, l.Hooks.RestoreOption.Dir, hooksOptions); err != nil {
errors = append(errors, err)
return
}
t, err := l.getType()
if err != nil {
errors = append(errors, err)
return
return err
}
switch t {
case TypeLocal:
to, err = filepath.Abs(to)
if err != nil {
errors = append(errors, err)
return
return err
}
// Check if target is empty
if !force {
@@ -439,17 +399,14 @@ func (l Location) Restore(to, from string, force bool, snapshot string, options
if err == nil {
files, err := ioutil.ReadDir(to)
if err != nil {
errors = append(errors, err)
return
return err
}
if len(files) > 0 {
errors = append(errors, notEmptyError)
return
return notEmptyError
}
} else {
if !os.IsNotExist(err) {
errors = append(errors, err)
return
return err
}
}
}
@@ -458,17 +415,10 @@ func (l Location) Restore(to, from string, force bool, snapshot string, options
_, _, err = backend.ExecDocker(l, buildRestoreCommand(l, "/", snapshot, options))
}
if err != nil {
errors = append(errors, err)
return
return err
}
// After Hooks for restore
if err := l.ExecuteHooks(l.Hooks.RestoreOption.After, l.Hooks.RestoreOption.Dir, hooksOptions); err != nil {
errors = append(errors, err)
return
}
return
colors.Success.Println("Done")
return nil
}
func (l Location) RunCron() error {

View File

@@ -14,9 +14,9 @@ func (e addedExtractor) Matches(line string) bool {
}
func (e addedExtractor) Extract(metadata *BackupLogMetadata, line string) {
// Sample line: "Added to the repo: 0 B"
metadata.AddedSize = strings.TrimSpace(e.re.ReplaceAllString(line, "$2"))
metadata.AddedSize = strings.TrimSpace(e.re.ReplaceAllString(line, ""))
}
func NewAddedExtractor() MetadatExtractor {
return addedExtractor{regexp.MustCompile(`(?i)^Added to the repo(sitory)?: ([\d\.]+ \w+)( \([\d\.]+[\w\s]+\))?`)}
return addedExtractor{regexp.MustCompile(`(?i)^Added to the repo:`)}
}