mirror of
https://github.com/cupcakearmy/autorestic.git
synced 2025-09-08 11:30:40 +00:00
Compare commits
29 Commits
v1.7.3
...
9697e080e6
Author | SHA1 | Date | |
---|---|---|---|
|
9697e080e6 | ||
|
3b57602fe8 | ||
|
045513234f | ||
|
8e24286ca3 | ||
|
78b0db50e0 | ||
|
62dd371d51 | ||
|
08766b75db | ||
b3b7c8df95 | |||
2c5266c9a0 | |||
087b293c39 | |||
|
112a69d743 | ||
|
37d55c691f | ||
|
715b6f791c | ||
|
38b38c6805 | ||
c82db56069 | |||
27821dc3ef | |||
866975d32d | |||
|
955ac0e323 | ||
|
1512db5b55 | ||
|
046331748c | ||
72a40eaaa2 | |||
ec61effe22 | |||
d6acab94a5 | |||
|
d0d2fcf0f2 | ||
58fd41fafb | |||
|
d0c4a32879 | ||
74979e9a2a | |||
|
3732dcf6ff | ||
|
874ed52e3b |
8
.github/dependabot.yml
vendored
Normal file
8
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "docker"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
21
.github/workflows/build.yml
vendored
21
.github/workflows/build.yml
vendored
@@ -10,12 +10,12 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v1
|
uses: docker/setup-qemu-action@v2
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v1
|
uses: docker/setup-buildx-action@v2
|
||||||
- name: Docker Labels
|
- name: Docker Labels
|
||||||
id: meta
|
id: meta
|
||||||
uses: crazy-max/ghaction-docker-meta@v2
|
uses: crazy-max/ghaction-docker-meta@v4
|
||||||
with:
|
with:
|
||||||
images: cupcakearmy/autorestic
|
images: cupcakearmy/autorestic
|
||||||
tags: |
|
tags: |
|
||||||
@@ -23,12 +23,12 @@ jobs:
|
|||||||
type=semver,pattern={{major}}.{{minor}}
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
type=semver,pattern={{major}}
|
type=semver,pattern={{major}}
|
||||||
- name: Login to DockerHub
|
- name: Login to DockerHub
|
||||||
uses: docker/login-action@v1
|
uses: docker/login-action@v2
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
uses: docker/build-push-action@v2
|
uses: docker/build-push-action@v3
|
||||||
with:
|
with:
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: true
|
push: true
|
||||||
@@ -37,17 +37,12 @@ jobs:
|
|||||||
release:
|
release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-go@v2
|
- uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: "^1.16.3"
|
go-version: "^1.20"
|
||||||
- name: Build
|
- name: Build
|
||||||
run: go run build/build.go
|
run: go run build/build.go
|
||||||
|
|
||||||
- name: Sign
|
|
||||||
uses: tristan-weil/ghaction-checksum-sign-artifact@v1.0.1
|
|
||||||
with:
|
|
||||||
path: dist/*
|
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
|
11
CHANGELOG.md
11
CHANGELOG.md
@@ -5,6 +5,17 @@ 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/),
|
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).
|
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
|
## [1.7.1] - 2022-04-27
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.18-alpine as builder
|
FROM golang:1.20-alpine as builder
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY go.* .
|
COPY go.* .
|
||||||
@@ -6,7 +6,8 @@ RUN go mod download
|
|||||||
COPY . .
|
COPY . .
|
||||||
RUN go build
|
RUN go build
|
||||||
|
|
||||||
FROM alpine
|
FROM restic/restic:0.15.1
|
||||||
RUN apk add --no-cache restic rclone bash openssh
|
RUN apk add --no-cache rclone bash
|
||||||
COPY --from=builder /app/autorestic /usr/bin/autorestic
|
COPY --from=builder /app/autorestic /usr/bin/autorestic
|
||||||
|
ENTRYPOINT []
|
||||||
CMD [ "autorestic" ]
|
CMD [ "autorestic" ]
|
||||||
|
@@ -4,7 +4,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
@@ -17,23 +21,51 @@ import (
|
|||||||
var DIR, _ = filepath.Abs("./dist")
|
var DIR, _ = filepath.Abs("./dist")
|
||||||
|
|
||||||
var targets = map[string][]string{
|
var targets = map[string][]string{
|
||||||
|
// "aix": {"ppc64"}, // Not supported by fsnotify
|
||||||
"darwin": {"amd64", "arm64"},
|
"darwin": {"amd64", "arm64"},
|
||||||
"freebsd": {"386", "amd64", "arm"},
|
"freebsd": {"386", "amd64", "arm"},
|
||||||
"linux": {"386", "amd64", "arm", "arm64"},
|
"linux": {"386", "amd64", "arm", "arm64", "ppc64le", "mips", "mipsle", "mips64", "mips64le", "s390x"},
|
||||||
"netbsd": {"386", "amd64"},
|
"netbsd": {"386", "amd64"},
|
||||||
"openbsd": {"386", "amd64"},
|
"openbsd": {"386", "amd64"},
|
||||||
|
// "windows": {"386", "amd64"}, // Not supported by autorestic
|
||||||
|
"solaris": {"amd64"},
|
||||||
}
|
}
|
||||||
|
|
||||||
type buildOptions struct {
|
type buildOptions struct {
|
||||||
Target, Arch, Version string
|
Target, Arch, Version string
|
||||||
}
|
}
|
||||||
|
|
||||||
func build(options buildOptions, wg *sync.WaitGroup) {
|
const (
|
||||||
fmt.Printf("Building %s %s\n", options.Target, options.Arch)
|
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)
|
||||||
out := fmt.Sprintf("autorestic_%s_%s_%s", options.Version, options.Target, options.Arch)
|
out := fmt.Sprintf("autorestic_%s_%s_%s", options.Version, options.Target, options.Arch)
|
||||||
out = path.Join(DIR, out)
|
out = path.Join(DIR, out)
|
||||||
out, _ = filepath.Abs(out)
|
|
||||||
fmt.Println(out)
|
|
||||||
|
|
||||||
// Build
|
// Build
|
||||||
{
|
{
|
||||||
@@ -62,22 +94,39 @@ func build(options buildOptions, wg *sync.WaitGroup) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wg.Done()
|
|
||||||
|
// 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))
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
os.RemoveAll(DIR)
|
os.RemoveAll(DIR)
|
||||||
v := internal.VERSION
|
v := internal.VERSION
|
||||||
|
checksums := []Checksums{}
|
||||||
|
|
||||||
|
// Build async
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
for target, archs := range targets {
|
for target, archs := range targets {
|
||||||
for _, arch := range archs {
|
for _, arch := range archs {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
build(buildOptions{
|
go build(buildOptions{
|
||||||
Target: target,
|
Target: target,
|
||||||
Arch: arch,
|
Arch: arch,
|
||||||
Version: v,
|
Version: v,
|
||||||
}, &wg)
|
}, &wg, &checksums)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
writeChecksums(&checksums)
|
||||||
}
|
}
|
||||||
|
@@ -5,10 +5,10 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/cupcakearmy/autorestic/internal"
|
|
||||||
"github.com/cupcakearmy/autorestic/internal/colors"
|
"github.com/cupcakearmy/autorestic/internal/colors"
|
||||||
"github.com/cupcakearmy/autorestic/internal/flags"
|
"github.com/cupcakearmy/autorestic/internal/flags"
|
||||||
"github.com/cupcakearmy/autorestic/internal/lock"
|
"github.com/cupcakearmy/autorestic/internal/lock"
|
||||||
|
"github.com/cupcakearmy/autorestic/internal/version"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
homedir "github.com/mitchellh/go-homedir"
|
homedir "github.com/mitchellh/go-homedir"
|
||||||
@@ -26,7 +26,7 @@ func CheckErr(err error) {
|
|||||||
var cfgFile string
|
var cfgFile string
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Version: internal.VERSION,
|
Version: version.VERSION,
|
||||||
Use: "autorestic",
|
Use: "autorestic",
|
||||||
Short: "CLI Wrapper for restic",
|
Short: "CLI Wrapper for restic",
|
||||||
Long: "Documentation:\thttps://autorestic.vercel.app\nSupport:\thttps://discord.gg/wS7RpYTYd2",
|
Long: "Documentation:\thttps://autorestic.vercel.app\nSupport:\thttps://discord.gg/wS7RpYTYd2",
|
||||||
@@ -41,7 +41,7 @@ func init() {
|
|||||||
rootCmd.PersistentFlags().BoolVar(&flags.CI, "ci", false, "CI mode disabled interactive mode and colors and enables verbosity")
|
rootCmd.PersistentFlags().BoolVar(&flags.CI, "ci", false, "CI mode disabled interactive mode and colors and enables verbosity")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&flags.VERBOSE, "verbose", "v", false, "verbose mode")
|
rootCmd.PersistentFlags().BoolVarP(&flags.VERBOSE, "verbose", "v", false, "verbose mode")
|
||||||
rootCmd.PersistentFlags().StringVar(&flags.RESTIC_BIN, "restic-bin", "restic", "specify custom restic binary")
|
rootCmd.PersistentFlags().StringVar(&flags.RESTIC_BIN, "restic-bin", "restic", "specify custom restic binary")
|
||||||
rootCmd.PersistentFlags().StringVar(&flags.DOCKER_IMAGE, "docker-image", "cupcakearmy/autorestic:"+internal.VERSION, "specify a custom docker image")
|
rootCmd.PersistentFlags().StringVar(&flags.DOCKER_IMAGE, "docker-image", "cupcakearmy/autorestic:"+version.VERSION, "specify a custom docker image")
|
||||||
cobra.OnInitialize(initConfig)
|
cobra.OnInitialize(initConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ func initConfig() {
|
|||||||
viper.SetConfigFile(cfgFile)
|
viper.SetConfigFile(cfgFile)
|
||||||
viper.AutomaticEnv()
|
viper.AutomaticEnv()
|
||||||
if viper.ConfigFileUsed() == "" {
|
if viper.ConfigFileUsed() == "" {
|
||||||
colors.Error.Println("cannot read config file %s\n", cfgFile)
|
colors.Error.Printf("cannot read config file %s\n", cfgFile)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
9755
docs/.codedoc/package-lock.json
generated
9755
docs/.codedoc/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codedoc/core": "^0.2.24"
|
"@codedoc/core": "^0.3.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,5 +8,6 @@ A list of community driven projects. (No official affiliation)
|
|||||||
- Ansible Role: <https://github.com/ItsNotGoodName/ansible-role-autorestic>
|
- Ansible Role: <https://github.com/ItsNotGoodName/ansible-role-autorestic>
|
||||||
- Ansible Role: <https://github.com/FuzzyMistborn/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://0xacab.org/varac-projects/ansible-role-autorestic>
|
||||||
|
- Ansible Role: <https://github.com/dbrennand/ansible-role-autorestic>
|
||||||
|
|
||||||
> :ToCPrevNext
|
> :ToCPrevNext
|
||||||
|
@@ -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.
|
Autorestic requires `bash`, `wget` and `bzip2` to be installed. For most systems these should be already installed.
|
||||||
|
|
||||||
```bash
|
```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
|
## Alternatives
|
||||||
@@ -24,6 +24,10 @@ 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`.
|
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
|
### AUR
|
||||||
|
|
||||||
~~If you are on Arch there is an [AUR Package](https://aur.archlinux.org/packages/autorestic-bin/) (looking for maintainers).~~ - Deprecated
|
~~If you are on Arch there is an [AUR Package](https://aur.archlinux.org/packages/autorestic-bin/) (looking for maintainers).~~ - Deprecated
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```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.
|
See [installation](/installation) for alternative options.
|
||||||
|
1872
docs/package-lock.json
generated
1872
docs/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,6 @@
|
|||||||
"dev": "codedoc serve"
|
"dev": "codedoc serve"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codedoc/cli": "^0.2.8"
|
"@codedoc/cli": "^0.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
go.mod
6
go.mod
@@ -1,6 +1,6 @@
|
|||||||
module github.com/cupcakearmy/autorestic
|
module github.com/cupcakearmy/autorestic
|
||||||
|
|
||||||
go 1.18
|
go 1.20
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/blang/semver/v4 v4.0.0
|
github.com/blang/semver/v4 v4.0.0
|
||||||
@@ -28,8 +28,8 @@ require (
|
|||||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/subosito/gotenv v1.2.0 // indirect
|
github.com/subosito/gotenv v1.2.0 // indirect
|
||||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
|
||||||
golang.org/x/text v0.3.7 // indirect
|
golang.org/x/text v0.3.8 // indirect
|
||||||
gopkg.in/ini.v1 v1.66.4 // indirect
|
gopkg.in/ini.v1 v1.66.4 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||||
|
8
go.sum
8
go.sum
@@ -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-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-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-20210927094055-39ccf1dd6fa6/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-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
|
||||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
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.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/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.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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
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-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
@@ -31,6 +31,11 @@ else
|
|||||||
fi
|
fi
|
||||||
echo $ARCH
|
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 \
|
wget -qO - https://api.github.com/repos/cupcakearmy/autorestic/releases/latest \
|
||||||
| grep "browser_download_url.*_${OS}_${ARCH}" \
|
| grep "browser_download_url.*_${OS}_${ARCH}" \
|
||||||
| cut -d : -f 2,3 \
|
| cut -d : -f 2,3 \
|
||||||
|
@@ -10,6 +10,8 @@ import (
|
|||||||
|
|
||||||
"github.com/cupcakearmy/autorestic/internal/colors"
|
"github.com/cupcakearmy/autorestic/internal/colors"
|
||||||
"github.com/cupcakearmy/autorestic/internal/flags"
|
"github.com/cupcakearmy/autorestic/internal/flags"
|
||||||
|
"github.com/cupcakearmy/autorestic/internal/options"
|
||||||
|
"github.com/cupcakearmy/autorestic/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BackendRest struct {
|
type BackendRest struct {
|
||||||
@@ -24,7 +26,7 @@ type Backend struct {
|
|||||||
Key string `mapstructure:"key,omitempty"`
|
Key string `mapstructure:"key,omitempty"`
|
||||||
Env map[string]string `mapstructure:"env,omitempty"`
|
Env map[string]string `mapstructure:"env,omitempty"`
|
||||||
Rest BackendRest `mapstructure:"rest,omitempty"`
|
Rest BackendRest `mapstructure:"rest,omitempty"`
|
||||||
Options Options `mapstructure:"options,omitempty"`
|
Options options.Options `mapstructure:"options,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetBackend(name string) (Backend, bool) {
|
func GetBackend(name string) (Backend, bool) {
|
||||||
@@ -38,7 +40,7 @@ func (b Backend) generateRepo() (string, error) {
|
|||||||
case "local":
|
case "local":
|
||||||
return GetPathRelativeToConfig(b.Path)
|
return GetPathRelativeToConfig(b.Path)
|
||||||
case "rest":
|
case "rest":
|
||||||
parsed, err := url.Parse(b.Path)
|
parsed, err := url.Parse(os.ExpandEnv(b.Path))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -120,11 +122,15 @@ func (b Backend) validate() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
options := ExecuteOptions{Envs: env, Silent: true}
|
options := utils.ExecuteOptions{
|
||||||
|
Envs: env,
|
||||||
|
Silent: true,
|
||||||
|
Global: GetConfig().Global,
|
||||||
|
}
|
||||||
// Check if already initialized
|
// Check if already initialized
|
||||||
cmd := []string{"check"}
|
cmd := []string{"check"}
|
||||||
cmd = append(cmd, combineBackendOptions("check", b)...)
|
cmd = append(cmd, combineBackendOptions("check", b)...)
|
||||||
_, _, err = ExecuteResticCommand(options, cmd...)
|
_, _, err = utils.ExecuteResticCommand(options, cmd...)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
@@ -132,7 +138,7 @@ func (b Backend) validate() error {
|
|||||||
colors.Body.Printf("Initializing backend \"%s\"...\n", b.name)
|
colors.Body.Printf("Initializing backend \"%s\"...\n", b.name)
|
||||||
cmd := []string{"init"}
|
cmd := []string{"init"}
|
||||||
cmd = append(cmd, combineBackendOptions("init", b)...)
|
cmd = append(cmd, combineBackendOptions("init", b)...)
|
||||||
_, _, err := ExecuteResticCommand(options, cmd...)
|
_, _, err := utils.ExecuteResticCommand(options, cmd...)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,8 +148,11 @@ func (b Backend) Exec(args []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
options := ExecuteOptions{Envs: env}
|
options := utils.ExecuteOptions{
|
||||||
_, out, err := ExecuteResticCommand(options, args...)
|
Envs: env,
|
||||||
|
Global: GetConfig().Global,
|
||||||
|
}
|
||||||
|
_, out, err := utils.ExecuteResticCommand(options, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
colors.Error.Println(out)
|
colors.Error.Println(out)
|
||||||
return err
|
return err
|
||||||
@@ -157,7 +166,7 @@ func (b Backend) ExecDocker(l Location, args []string) (int, string, error) {
|
|||||||
return -1, "", err
|
return -1, "", err
|
||||||
}
|
}
|
||||||
volume := l.From[0]
|
volume := l.From[0]
|
||||||
options := ExecuteOptions{
|
options := utils.ExecuteOptions{
|
||||||
Command: "docker",
|
Command: "docker",
|
||||||
Envs: env,
|
Envs: env,
|
||||||
}
|
}
|
||||||
@@ -185,7 +194,7 @@ func (b Backend) ExecDocker(l Location, args []string) (int, string, error) {
|
|||||||
// No additional setup needed
|
// No additional setup needed
|
||||||
case "rclone":
|
case "rclone":
|
||||||
// Read host rclone config and mount it into the container
|
// Read host rclone config and mount it into the container
|
||||||
code, configFile, err := ExecuteCommand(ExecuteOptions{Command: "rclone"}, "config", "file")
|
code, configFile, err := utils.ExecuteCommand(utils.ExecuteOptions{Command: "rclone"}, "config", "file")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return code, "", err
|
return code, "", err
|
||||||
}
|
}
|
||||||
@@ -200,5 +209,5 @@ func (b Backend) ExecDocker(l Location, args []string) (int, string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
docker = append(docker, flags.DOCKER_IMAGE, "-c", strings.Join(args, " "))
|
docker = append(docker, flags.DOCKER_IMAGE, "-c", strings.Join(args, " "))
|
||||||
return ExecuteCommand(options, docker...)
|
return utils.ExecuteCommand(options, docker...)
|
||||||
}
|
}
|
||||||
|
@@ -14,9 +14,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/blang/semver/v4"
|
"github.com/blang/semver/v4"
|
||||||
"github.com/cupcakearmy/autorestic/internal"
|
|
||||||
"github.com/cupcakearmy/autorestic/internal/colors"
|
"github.com/cupcakearmy/autorestic/internal/colors"
|
||||||
"github.com/cupcakearmy/autorestic/internal/flags"
|
"github.com/cupcakearmy/autorestic/internal/flags"
|
||||||
|
"github.com/cupcakearmy/autorestic/internal/utils"
|
||||||
|
"github.com/cupcakearmy/autorestic/internal/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
const INSTALL_PATH = "/usr/local/bin"
|
const INSTALL_PATH = "/usr/local/bin"
|
||||||
@@ -115,7 +116,7 @@ func downloadAndInstallAsset(body GithubRelease, name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func InstallRestic() error {
|
func InstallRestic() error {
|
||||||
installed := internal.CheckIfCommandIsCallable("restic")
|
installed := utils.CheckIfCommandIsCallable("restic")
|
||||||
if installed {
|
if installed {
|
||||||
colors.Body.Println("restic already installed")
|
colors.Body.Println("restic already installed")
|
||||||
return nil
|
return nil
|
||||||
@@ -129,7 +130,7 @@ func InstallRestic() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func upgradeRestic() error {
|
func upgradeRestic() error {
|
||||||
_, _, err := internal.ExecuteCommand(internal.ExecuteOptions{
|
_, _, err := utils.ExecuteCommand(utils.ExecuteOptions{
|
||||||
Command: flags.RESTIC_BIN,
|
Command: flags.RESTIC_BIN,
|
||||||
}, "self-update")
|
}, "self-update")
|
||||||
return err
|
return err
|
||||||
@@ -147,7 +148,7 @@ func Upgrade(restic bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Upgrade self
|
// Upgrade self
|
||||||
current, err := semver.ParseTolerant(internal.VERSION)
|
current, err := semver.ParseTolerant(version.VERSION)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -11,23 +11,20 @@ import (
|
|||||||
"github.com/cupcakearmy/autorestic/internal/colors"
|
"github.com/cupcakearmy/autorestic/internal/colors"
|
||||||
"github.com/cupcakearmy/autorestic/internal/flags"
|
"github.com/cupcakearmy/autorestic/internal/flags"
|
||||||
"github.com/cupcakearmy/autorestic/internal/lock"
|
"github.com/cupcakearmy/autorestic/internal/lock"
|
||||||
|
"github.com/cupcakearmy/autorestic/internal/options"
|
||||||
|
"github.com/cupcakearmy/autorestic/internal/utils"
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
const VERSION = "1.7.3"
|
|
||||||
|
|
||||||
type OptionMap map[string][]interface{}
|
|
||||||
type Options map[string]OptionMap
|
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Version string `mapstructure:"version"`
|
Version string `mapstructure:"version"`
|
||||||
Extras interface{} `mapstructure:"extras"`
|
Extras interface{} `mapstructure:"extras"`
|
||||||
Locations map[string]Location `mapstructure:"locations"`
|
Locations map[string]Location `mapstructure:"locations"`
|
||||||
Backends map[string]Backend `mapstructure:"backends"`
|
Backends map[string]Backend `mapstructure:"backends"`
|
||||||
Global Options `mapstructure:"global"`
|
Global options.Options `mapstructure:"global"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var once sync.Once
|
var once sync.Once
|
||||||
@@ -184,7 +181,7 @@ func CheckConfig() error {
|
|||||||
if c == nil {
|
if c == nil {
|
||||||
return fmt.Errorf("config could not be loaded/found")
|
return fmt.Errorf("config could not be loaded/found")
|
||||||
}
|
}
|
||||||
if !CheckIfResticIsCallable() {
|
if !utils.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 {
|
for name, backend := range c.Backends {
|
||||||
@@ -263,7 +260,7 @@ func AddFlagsToCommand(cmd *cobra.Command, backend bool) {
|
|||||||
|
|
||||||
func (c *Config) SaveConfig() error {
|
func (c *Config) SaveConfig() error {
|
||||||
file := viper.ConfigFileUsed()
|
file := viper.ConfigFileUsed()
|
||||||
if err := CopyFile(file, file+".old"); err != nil {
|
if err := utils.CopyFile(file, file+".old"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
colors.Secondary.Println("Saved a backup copy of your file next to the original.")
|
colors.Secondary.Println("Saved a backup copy of your file next to the original.")
|
||||||
@@ -274,40 +271,11 @@ func (c *Config) SaveConfig() error {
|
|||||||
return viper.WriteConfig()
|
return viper.WriteConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
func optionToString(option string) string {
|
|
||||||
if !strings.HasPrefix(option, "-") {
|
|
||||||
return "--" + option
|
|
||||||
}
|
|
||||||
return option
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendOptionsToSlice(str *[]string, options OptionMap) {
|
|
||||||
for key, values := range options {
|
|
||||||
for _, value := range values {
|
|
||||||
// Bool
|
|
||||||
asBool, ok := value.(bool)
|
|
||||||
if ok && asBool {
|
|
||||||
*str = append(*str, optionToString(key))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
*str = append(*str, optionToString(key), fmt.Sprint(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getOptions(options Options, keys []string) []string {
|
|
||||||
var selected []string
|
|
||||||
for _, key := range keys {
|
|
||||||
appendOptionsToSlice(&selected, options[key])
|
|
||||||
}
|
|
||||||
return selected
|
|
||||||
}
|
|
||||||
|
|
||||||
func combineBackendOptions(key string, b Backend) []string {
|
func combineBackendOptions(key string, b Backend) []string {
|
||||||
// Priority: backend > global
|
// Priority: backend > global
|
||||||
var options []string
|
var options []string
|
||||||
gFlags := getOptions(GetConfig().Global, []string{key})
|
gFlags := GetConfig().Global.GetOptions([]string{key})
|
||||||
bFlags := getOptions(b.Options, []string{"all", key})
|
bFlags := b.Options.GetOptions([]string{"all", key})
|
||||||
options = append(options, gFlags...)
|
options = append(options, gFlags...)
|
||||||
options = append(options, bFlags...)
|
options = append(options, bFlags...)
|
||||||
return options
|
return options
|
||||||
@@ -316,9 +284,9 @@ func combineBackendOptions(key string, b Backend) []string {
|
|||||||
func combineAllOptions(key string, l Location, b Backend) []string {
|
func combineAllOptions(key string, l Location, b Backend) []string {
|
||||||
// Priority: location > backend > global
|
// Priority: location > backend > global
|
||||||
var options []string
|
var options []string
|
||||||
gFlags := getOptions(GetConfig().Global, []string{key})
|
gFlags := GetConfig().Global.GetOptions([]string{key})
|
||||||
bFlags := getOptions(b.Options, []string{"all", key})
|
bFlags := b.Options.GetOptions([]string{"all", key})
|
||||||
lFlags := getOptions(l.Options, []string{"all", key})
|
lFlags := l.Options.GetOptions([]string{"all", key})
|
||||||
options = append(options, gFlags...)
|
options = append(options, gFlags...)
|
||||||
options = append(options, bFlags...)
|
options = append(options, bFlags...)
|
||||||
options = append(options, lFlags...)
|
options = append(options, lFlags...)
|
||||||
|
@@ -12,6 +12,8 @@ import (
|
|||||||
"github.com/cupcakearmy/autorestic/internal/flags"
|
"github.com/cupcakearmy/autorestic/internal/flags"
|
||||||
"github.com/cupcakearmy/autorestic/internal/lock"
|
"github.com/cupcakearmy/autorestic/internal/lock"
|
||||||
"github.com/cupcakearmy/autorestic/internal/metadata"
|
"github.com/cupcakearmy/autorestic/internal/metadata"
|
||||||
|
"github.com/cupcakearmy/autorestic/internal/utils"
|
||||||
|
"github.com/cupcakearmy/autorestic/internal/options"
|
||||||
"github.com/robfig/cron"
|
"github.com/robfig/cron"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -49,7 +51,7 @@ type Location struct {
|
|||||||
To []string `mapstructure:"to,omitempty"`
|
To []string `mapstructure:"to,omitempty"`
|
||||||
Hooks Hooks `mapstructure:"hooks,omitempty"`
|
Hooks Hooks `mapstructure:"hooks,omitempty"`
|
||||||
Cron string `mapstructure:"cron,omitempty"`
|
Cron string `mapstructure:"cron,omitempty"`
|
||||||
Options Options `mapstructure:"options,omitempty"`
|
Options options.Options `mapstructure:"options,omitempty"`
|
||||||
ForgetOption LocationForgetOption `mapstructure:"forget,omitempty"`
|
ForgetOption LocationForgetOption `mapstructure:"forget,omitempty"`
|
||||||
CopyOption LocationCopy `mapstructure:"copy,omitempty"`
|
CopyOption LocationCopy `mapstructure:"copy,omitempty"`
|
||||||
}
|
}
|
||||||
@@ -101,14 +103,14 @@ func (l Location) validate() error {
|
|||||||
if _, ok := GetBackend(copyFrom); !ok {
|
if _, ok := GetBackend(copyFrom); !ok {
|
||||||
return fmt.Errorf(`location "%s" has an invalid backend "%s" in copy option`, l.name, copyFrom)
|
return fmt.Errorf(`location "%s" has an invalid backend "%s" in copy option`, l.name, copyFrom)
|
||||||
}
|
}
|
||||||
if !ArrayContains(l.To, copyFrom) {
|
if !utils.ArrayContains(l.To, copyFrom) {
|
||||||
return fmt.Errorf(`location "%s" has an invalid copy from "%s"`, l.name, copyFrom)
|
return fmt.Errorf(`location "%s" has an invalid copy from "%s"`, l.name, copyFrom)
|
||||||
}
|
}
|
||||||
for _, copyToTarget := range copyTo {
|
for _, copyToTarget := range copyTo {
|
||||||
if _, ok := GetBackend(copyToTarget); !ok {
|
if _, ok := GetBackend(copyToTarget); !ok {
|
||||||
return fmt.Errorf(`location "%s" has an invalid backend "%s" in copy option`, l.name, copyToTarget)
|
return fmt.Errorf(`location "%s" has an invalid backend "%s" in copy option`, l.name, copyToTarget)
|
||||||
}
|
}
|
||||||
if ArrayContains(l.To, copyToTarget) {
|
if utils.ArrayContains(l.To, copyToTarget) {
|
||||||
return fmt.Errorf(`location "%s" cannot copy to "%s" as it's already a target`, l.name, copyToTarget)
|
return fmt.Errorf(`location "%s" cannot copy to "%s" as it's already a target`, l.name, copyToTarget)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,7 +125,7 @@ func (l Location) validate() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l Location) ExecuteHooks(commands []string, options ExecuteOptions) error {
|
func (l Location) ExecuteHooks(commands []string, options utils.ExecuteOptions) error {
|
||||||
if len(commands) == 0 {
|
if len(commands) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -137,7 +139,7 @@ func (l Location) ExecuteHooks(commands []string, options ExecuteOptions) error
|
|||||||
colors.Secondary.Println("\nRunning hooks")
|
colors.Secondary.Println("\nRunning hooks")
|
||||||
for _, command := range commands {
|
for _, command := range commands {
|
||||||
colors.Body.Println("> " + command)
|
colors.Body.Println("> " + command)
|
||||||
_, out, err := ExecuteCommand(options, "-c", command)
|
_, out, err := utils.ExecuteCommand(options, "-c", command)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
colors.Error.Println(out)
|
colors.Error.Println(out)
|
||||||
return err
|
return err
|
||||||
@@ -176,7 +178,7 @@ func (l Location) Backup(cron bool, specificBackend string) []error {
|
|||||||
return errors
|
return errors
|
||||||
}
|
}
|
||||||
cwd, _ := GetPathRelativeToConfig(".")
|
cwd, _ := GetPathRelativeToConfig(".")
|
||||||
options := ExecuteOptions{
|
options := utils.ExecuteOptions{
|
||||||
Command: "bash",
|
Command: "bash",
|
||||||
Dir: cwd,
|
Dir: cwd,
|
||||||
Envs: map[string]string{
|
Envs: map[string]string{
|
||||||
@@ -221,8 +223,9 @@ func (l Location) Backup(cron bool, specificBackend string) []error {
|
|||||||
cmd = append(cmd, "--tag", buildTag("cron"))
|
cmd = append(cmd, "--tag", buildTag("cron"))
|
||||||
}
|
}
|
||||||
cmd = append(cmd, "--tag", l.getLocationTags())
|
cmd = append(cmd, "--tag", l.getLocationTags())
|
||||||
backupOptions := ExecuteOptions{
|
backupOptions := utils.ExecuteOptions{
|
||||||
Envs: env,
|
Envs: env,
|
||||||
|
Global: GetConfig().Global,
|
||||||
}
|
}
|
||||||
|
|
||||||
var code int = 0
|
var code int = 0
|
||||||
@@ -237,9 +240,9 @@ func (l Location) Backup(cron bool, specificBackend string) []error {
|
|||||||
}
|
}
|
||||||
cmd = append(cmd, path)
|
cmd = append(cmd, path)
|
||||||
}
|
}
|
||||||
code, out, err = ExecuteResticCommand(backupOptions, cmd...)
|
code, out, err = utils.ExecuteResticCommand(backupOptions, cmd...)
|
||||||
case TypeVolume:
|
case TypeVolume:
|
||||||
ok := CheckIfVolumeExists(l.From[0])
|
ok := utils.CheckIfVolumeExists(l.From[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
errors = append(errors, fmt.Errorf("volume \"%s\" does not exist", l.From[0]))
|
errors = append(errors, fmt.Errorf("volume \"%s\" does not exist", l.From[0]))
|
||||||
continue
|
continue
|
||||||
@@ -277,8 +280,9 @@ func (l Location) Backup(cron bool, specificBackend string) []error {
|
|||||||
for k, v := range env2 {
|
for k, v := range env2 {
|
||||||
env[k+"2"] = v
|
env[k+"2"] = v
|
||||||
}
|
}
|
||||||
_, _, err := ExecuteResticCommand(ExecuteOptions{
|
_, _, err := utils.ExecuteResticCommand(utils.ExecuteOptions{
|
||||||
Envs: env,
|
Envs: env,
|
||||||
|
Global: GetConfig().Global,
|
||||||
}, "copy", md.SnapshotID)
|
}, "copy", md.SnapshotID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -308,7 +312,10 @@ after:
|
|||||||
|
|
||||||
// Forget and optionally prune
|
// Forget and optionally prune
|
||||||
if isSuccess && l.ForgetOption != "" && l.ForgetOption != LocationForgetNo {
|
if isSuccess && l.ForgetOption != "" && l.ForgetOption != LocationForgetNo {
|
||||||
l.Forget(l.ForgetOption == LocationForgetPrune, false)
|
err := l.Forget(l.ForgetOption == LocationForgetPrune, false)
|
||||||
|
if err != nil {
|
||||||
|
errors = append(errors, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errors) == 0 {
|
if len(errors) == 0 {
|
||||||
@@ -332,8 +339,9 @@ func (l Location) Forget(prune bool, dry bool) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
options := ExecuteOptions{
|
options := utils.ExecuteOptions{
|
||||||
Envs: env,
|
Envs: env,
|
||||||
|
Global: GetConfig().Global,
|
||||||
}
|
}
|
||||||
cmd := []string{"forget", "--tag", l.getLocationTags()}
|
cmd := []string{"forget", "--tag", l.getLocationTags()}
|
||||||
if prune {
|
if prune {
|
||||||
@@ -343,7 +351,7 @@ func (l Location) Forget(prune bool, dry bool) error {
|
|||||||
cmd = append(cmd, "--dry-run")
|
cmd = append(cmd, "--dry-run")
|
||||||
}
|
}
|
||||||
cmd = append(cmd, combineAllOptions("forget", l, backend)...)
|
cmd = append(cmd, combineAllOptions("forget", l, backend)...)
|
||||||
_, _, err = ExecuteResticCommand(options, cmd...)
|
_, _, err = utils.ExecuteResticCommand(options, cmd...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -14,9 +14,9 @@ func (e addedExtractor) Matches(line string) bool {
|
|||||||
}
|
}
|
||||||
func (e addedExtractor) Extract(metadata *BackupLogMetadata, line string) {
|
func (e addedExtractor) Extract(metadata *BackupLogMetadata, line string) {
|
||||||
// Sample line: "Added to the repo: 0 B"
|
// Sample line: "Added to the repo: 0 B"
|
||||||
metadata.AddedSize = strings.TrimSpace(e.re.ReplaceAllString(line, ""))
|
metadata.AddedSize = strings.TrimSpace(e.re.ReplaceAllString(line, "$2"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAddedExtractor() MetadatExtractor {
|
func NewAddedExtractor() MetadatExtractor {
|
||||||
return addedExtractor{regexp.MustCompile(`(?i)^Added to the repo:`)}
|
return addedExtractor{regexp.MustCompile(`(?i)^Added to the repo(sitory)?: ([\d\.]+ \w+)( \([\d\.]+[\w\s]+\))?`)}
|
||||||
}
|
}
|
||||||
|
38
internal/options/options.go
Normal file
38
internal/options/options.go
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package options
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OptionMap map[string][]interface{}
|
||||||
|
type Options map[string]OptionMap
|
||||||
|
|
||||||
|
func (o Options) GetOptions(keys []string) []string {
|
||||||
|
var selected []string
|
||||||
|
for _, key := range keys {
|
||||||
|
o[key].AppendOptionsToSlice(&selected)
|
||||||
|
}
|
||||||
|
return selected
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m OptionMap) AppendOptionsToSlice(str *[]string) {
|
||||||
|
for key, values := range m {
|
||||||
|
for _, value := range values {
|
||||||
|
// Bool
|
||||||
|
asBool, ok := value.(bool)
|
||||||
|
if ok && asBool {
|
||||||
|
*str = append(*str, optionToString(key))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
*str = append(*str, optionToString(key), fmt.Sprint(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func optionToString(option string) string {
|
||||||
|
if !strings.HasPrefix(option, "-") {
|
||||||
|
return "--" + option
|
||||||
|
}
|
||||||
|
return option
|
||||||
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
package internal
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/cupcakearmy/autorestic/internal/colors"
|
"github.com/cupcakearmy/autorestic/internal/colors"
|
||||||
"github.com/cupcakearmy/autorestic/internal/flags"
|
"github.com/cupcakearmy/autorestic/internal/flags"
|
||||||
|
"github.com/cupcakearmy/autorestic/internal/options"
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -26,6 +27,7 @@ type ExecuteOptions struct {
|
|||||||
Envs map[string]string
|
Envs map[string]string
|
||||||
Dir string
|
Dir string
|
||||||
Silent bool
|
Silent bool
|
||||||
|
Global options.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
type ColoredWriter struct {
|
type ColoredWriter struct {
|
||||||
@@ -78,8 +80,7 @@ func ExecuteCommand(options ExecuteOptions, args ...string) (int, string, error)
|
|||||||
|
|
||||||
func ExecuteResticCommand(options ExecuteOptions, args ...string) (int, string, error) {
|
func ExecuteResticCommand(options ExecuteOptions, args ...string) (int, string, error) {
|
||||||
options.Command = flags.RESTIC_BIN
|
options.Command = flags.RESTIC_BIN
|
||||||
var c = GetConfig()
|
var optionsAsString = options.Global.GetOptions([]string{"all"})
|
||||||
var optionsAsString = getOptions(c.Global, []string{"all"})
|
|
||||||
args = append(optionsAsString, args...)
|
args = append(optionsAsString, args...)
|
||||||
return ExecuteCommand(options, args...)
|
return ExecuteCommand(options, args...)
|
||||||
}
|
}
|
3
internal/version/version.go
Normal file
3
internal/version/version.go
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
package version
|
||||||
|
|
||||||
|
const VERSION = "1.7.7"
|
Reference in New Issue
Block a user