mirror of
https://github.com/cupcakearmy/autorestic.git
synced 2025-09-06 10:30:39 +00:00
Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
a4b54f9f64 | |||
c2e88193cd | |||
a2ef69d96d | |||
|
d45949b028 | ||
77d47cc697 | |||
a3239c0f3b | |||
90cd3171e5 | |||
61673bd88b | |||
41736ea3c4 | |||
a7779e04bd | |||
|
1326e7e53c | ||
478e193d78 | |||
11d4c67dce | |||
1643309957 | |||
e05386b0b5 | |||
aebaf0a225 | |||
c090013bf5 | |||
88c6949208 |
23
CHANGELOG.md
23
CHANGELOG.md
@@ -5,6 +5,29 @@ 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.1.2] - 2021-07-11
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
Don't check all backend when running `forget` or `exec` commands.
|
||||||
|
|
||||||
|
## [1.1.1] - 2021-05-17
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Options for backends
|
||||||
|
|
||||||
|
## [1.1.0] - 2021-05-06
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- use custom restic binary
|
||||||
|
- success & failure hooks
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- don't skip other locations on failure
|
||||||
|
|
||||||
## [1.0.9] - 2021-05-01
|
## [1.0.9] - 2021-05-01
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
@@ -24,6 +24,7 @@ Releases are automatically built by the github workflow and uploaded to the rele
|
|||||||
|
|
||||||
### Brew
|
### Brew
|
||||||
|
|
||||||
1. Check the checksum with `shasum -a 256 autorestic-1.2.3.tar.gz`
|
1. Download the latest release.
|
||||||
2. Update `url` and `sha256` in the brew repo.
|
2. Check the checksum with `shasum -a 256 autorestic-1.2.3.tar.gz`
|
||||||
3. Submit PR
|
3. Update `url` and `sha256` in the brew repo.
|
||||||
|
4. Submit PR
|
||||||
|
@@ -13,6 +13,9 @@
|
|||||||
<br><br>
|
<br><br>
|
||||||
<a target="_blank" href="https://discord.gg/wS7RpYTYd2">
|
<a target="_blank" href="https://discord.gg/wS7RpYTYd2">
|
||||||
<img src="https://img.shields.io/discord/252403122348097536" alt="discord badge" />
|
<img src="https://img.shields.io/discord/252403122348097536" alt="discord badge" />
|
||||||
|
<img src="https://img.shields.io/github/contributors/cupcakearmy/autorestic" alt="contributor badge" />
|
||||||
|
<img src="https://img.shields.io/github/downloads/cupcakearmy/autorestic/total" alt="downloads badge" />
|
||||||
|
<img src="https://img.shields.io/github/v/release/cupcakearmy/autorestic" alt="version badge" />
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</p>
|
</p>
|
||||||
|
@@ -17,15 +17,15 @@ var backupCmd = &cobra.Command{
|
|||||||
CheckErr(err)
|
CheckErr(err)
|
||||||
defer lock.Unlock()
|
defer lock.Unlock()
|
||||||
|
|
||||||
CheckErr(internal.CheckConfig())
|
internal.GetConfig()
|
||||||
|
|
||||||
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 {
|
||||||
location, _ := internal.GetLocation(name)
|
location, _ := internal.GetLocation(name)
|
||||||
err := location.Backup(false)
|
errs := location.Backup(false)
|
||||||
if err != nil {
|
for err := range errs {
|
||||||
colors.Error.Println(err)
|
colors.Error.Println(err)
|
||||||
errors++
|
errors++
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,7 @@ var execCmd = &cobra.Command{
|
|||||||
CheckErr(err)
|
CheckErr(err)
|
||||||
defer lock.Unlock()
|
defer lock.Unlock()
|
||||||
|
|
||||||
CheckErr(internal.CheckConfig())
|
internal.GetConfig()
|
||||||
|
|
||||||
selected, err := internal.GetAllOrSelected(cmd, true)
|
selected, err := internal.GetAllOrSelected(cmd, true)
|
||||||
CheckErr(err)
|
CheckErr(err)
|
||||||
|
@@ -14,7 +14,7 @@ var forgetCmd = &cobra.Command{
|
|||||||
CheckErr(err)
|
CheckErr(err)
|
||||||
defer lock.Unlock()
|
defer lock.Unlock()
|
||||||
|
|
||||||
CheckErr(internal.CheckConfig())
|
internal.GetConfig()
|
||||||
|
|
||||||
selected, err := internal.GetAllOrSelected(cmd, false)
|
selected, err := internal.GetAllOrSelected(cmd, false)
|
||||||
CheckErr(err)
|
CheckErr(err)
|
||||||
|
@@ -37,6 +37,7 @@ func init() {
|
|||||||
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file (default is $HOME/.autorestic.yml or ./.autorestic.yml)")
|
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file (default is $HOME/.autorestic.yml or ./.autorestic.yml)")
|
||||||
rootCmd.PersistentFlags().BoolVar(&internal.CI, "ci", false, "CI mode disabled interactive mode and colors and enables verbosity")
|
rootCmd.PersistentFlags().BoolVar(&internal.CI, "ci", false, "CI mode disabled interactive mode and colors and enables verbosity")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&internal.VERBOSE, "verbose", "v", false, "verbose mode")
|
rootCmd.PersistentFlags().BoolVarP(&internal.VERBOSE, "verbose", "v", false, "verbose mode")
|
||||||
|
rootCmd.PersistentFlags().StringVar(&internal.RESTIC_BIN, "restic-bin", "restic", "specify custom restic binary")
|
||||||
cobra.OnInitialize(initConfig)
|
cobra.OnInitialize(initConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
>
|
>
|
||||||
> [Overview](/backend/overview)
|
> [Overview](/backend/overview)
|
||||||
> [Available Backends](/backend/available)
|
> [Available Backends](/backend/available)
|
||||||
|
> [Options](/backend/options)
|
||||||
|
|
||||||
> :Collapse label=CLI
|
> :Collapse label=CLI
|
||||||
>
|
>
|
||||||
@@ -36,7 +37,7 @@
|
|||||||
> [Exec](/cli/exec)
|
> [Exec](/cli/exec)
|
||||||
> [Install](/cli/install)
|
> [Install](/cli/install)
|
||||||
> [Uninstall](/cli/uninstall)
|
> [Uninstall](/cli/uninstall)
|
||||||
> [Update](/cli/update)
|
> [Upgrade](/cli/upgrade)
|
||||||
|
|
||||||
[Examples](/examples)
|
[Examples](/examples)
|
||||||
|
|
||||||
|
23
docs/markdown/backend/options.md
Normal file
23
docs/markdown/backend/options.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Options
|
||||||
|
|
||||||
|
For the `backup` and `forget` commands you can pass any native flags to `restic`.
|
||||||
|
|
||||||
|
> It is also possible to set options for an [a specific location](/location/options).
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
backend:
|
||||||
|
foo:
|
||||||
|
type: ...
|
||||||
|
path: ...
|
||||||
|
options:
|
||||||
|
backup:
|
||||||
|
tag:
|
||||||
|
- foo
|
||||||
|
- bar
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example, whenever `autorestic` runs `restic backup` it will append a `--tag abc --tag` to the native command.
|
||||||
|
|
||||||
|
For more detail see the [location docs](/location/options) for options, as they are the same
|
||||||
|
|
||||||
|
> :ToCPrevNext
|
@@ -4,7 +4,7 @@
|
|||||||
autorestic forget [-l, --location] [-a, --all] [--dry-run] [--prune]
|
autorestic forget [-l, --location] [-a, --all] [--dry-run] [--prune]
|
||||||
```
|
```
|
||||||
|
|
||||||
This will prune and remove old data form the backends according to the [keep policy you have specified for the location](/location/forget)
|
This will prune and remove old data form the backends according to the [keep policy you have specified for the location](/location/forget).
|
||||||
|
|
||||||
The `--dry-run` flag will do a dry run showing what would have been deleted, but won't touch the actual data.
|
The `--dry-run` flag will do a dry run showing what would have been deleted, but won't touch the actual data.
|
||||||
|
|
||||||
|
@@ -27,4 +27,12 @@ Verbose mode will show the output of the native restic commands that are otherwi
|
|||||||
autorestic --verbose backup -a
|
autorestic --verbose backup -a
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## `--restic-bin`
|
||||||
|
|
||||||
|
With `--restic-bin` you can specify to run a specific restic binary. This can be useful if you want to [create a custom binary with root access that can be executed by any user](https://restic.readthedocs.io/en/stable/080_examples.html#full-backup-without-root).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
autorestic --restic-bin /some/path/to/my/custom/restic/binary
|
||||||
|
```
|
||||||
|
|
||||||
> :ToCPrevNext
|
> :ToCPrevNext
|
||||||
|
@@ -1,11 +0,0 @@
|
|||||||
# Update
|
|
||||||
|
|
||||||
Autorestic can update itself! Super handy right? Simply run autorestic update and we will check for you if there are updates for restic and autorestic and install them if necessary.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
autorestic update
|
|
||||||
```
|
|
||||||
|
|
||||||
Updates both restic and autorestic automagically.
|
|
||||||
|
|
||||||
> :ToCPrevNext
|
|
11
docs/markdown/cli/upgrade.md
Normal file
11
docs/markdown/cli/upgrade.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Upgrade
|
||||||
|
|
||||||
|
Autorestic can upgrade itself! Super handy right? Simply run autorestic upgrade and we will check for you if there are updates for restic and autorestic and install them if necessary.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
autorestic upgrade
|
||||||
|
```
|
||||||
|
|
||||||
|
Updates both restic and autorestic automagically.
|
||||||
|
|
||||||
|
> :ToCPrevNext
|
@@ -31,6 +31,7 @@ backends:
|
|||||||
remote:
|
remote:
|
||||||
type: b2
|
type: b2
|
||||||
path: 'myBucket:backup/home'
|
path: 'myBucket:backup/home'
|
||||||
|
env:
|
||||||
B2_ACCOUNT_ID: account_id
|
B2_ACCOUNT_ID: account_id
|
||||||
B2_ACCOUNT_KEY: account_key
|
B2_ACCOUNT_KEY: account_key
|
||||||
|
|
||||||
|
@@ -12,5 +12,6 @@ This amazing people helped the project!
|
|||||||
- @ChanceM - Typos
|
- @ChanceM - Typos
|
||||||
- @TheForcer - Typos
|
- @TheForcer - Typos
|
||||||
- @themorlan - Typos
|
- @themorlan - Typos
|
||||||
|
- @somebox - Typos
|
||||||
|
|
||||||
> :ToCPrevNext
|
> :ToCPrevNext
|
||||||
|
@@ -2,7 +2,14 @@
|
|||||||
|
|
||||||
If you want to perform some commands before and/or after a backup, 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 `before`/`after` commands that will be executed in the same directory as the target `from`.
|
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:
|
||||||
|
|
||||||
|
- `before`
|
||||||
|
- `after`
|
||||||
|
- `failure`
|
||||||
|
- `success`
|
||||||
|
|
||||||
```yml | .autorestic.yml
|
```yml | .autorestic.yml
|
||||||
locations:
|
locations:
|
||||||
@@ -11,10 +18,25 @@ locations:
|
|||||||
to: my-backend
|
to: my-backend
|
||||||
hooks:
|
hooks:
|
||||||
before:
|
before:
|
||||||
- echo "Hello"
|
- echo "One"
|
||||||
- echo "Human"
|
- echo "Two"
|
||||||
|
- echo "Three"
|
||||||
after:
|
after:
|
||||||
- echo "kthxbye"
|
- echo "Byte"
|
||||||
|
failure:
|
||||||
|
- echo "Something went wrong"
|
||||||
|
success:
|
||||||
|
- echo "Well done!"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Flowchart
|
||||||
|
|
||||||
|
1. `before` hook
|
||||||
|
2. Run backup
|
||||||
|
3. `after` hook
|
||||||
|
4. - `success` hook if no errors were found
|
||||||
|
- `failure` hook if at least error was encountered
|
||||||
|
|
||||||
|
If the `before` hook encounters errors the backup and `after` hooks will be skipped and only the `failed` hooks will run.
|
||||||
|
|
||||||
> :ToCPrevNext
|
> :ToCPrevNext
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
For the `backup` and `forget` commands you can pass any native flags to `restic`.
|
For the `backup` and `forget` commands you can pass any native flags to `restic`.
|
||||||
|
|
||||||
|
> It is also possible to set options for an [entire backend](/backend/options).
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
locations:
|
locations:
|
||||||
foo:
|
foo:
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# Update
|
# Upgrade
|
||||||
|
|
||||||
## From `0.x` to `1.0`
|
## From `0.x` to `1.0`
|
||||||
|
|
||||||
|
@@ -23,6 +23,8 @@ elif [[ $NATIVE_ARCH == *"arm64"* || $NATIVE_ARCH == *"aarch64"* ]]; then
|
|||||||
ARCH=arm64
|
ARCH=arm64
|
||||||
elif [[ $NATIVE_ARCH == *"x86"* ]]; then
|
elif [[ $NATIVE_ARCH == *"x86"* ]]; then
|
||||||
ARCH=386
|
ARCH=386
|
||||||
|
elif [[ $NATIVE_ARCH == *"armv7"* ]]; then
|
||||||
|
ARCH=arm
|
||||||
else
|
else
|
||||||
echo "Could not determine Architecure automatically, please check the release page manually: https://github.com/cupcakearmy/autorestic/releases"
|
echo "Could not determine Architecure automatically, please check the release page manually: https://github.com/cupcakearmy/autorestic/releases"
|
||||||
exit 1
|
exit 1
|
||||||
|
@@ -23,6 +23,7 @@ type Backend struct {
|
|||||||
Key string `yaml:"key,omitempty"`
|
Key string `yaml:"key,omitempty"`
|
||||||
Env map[string]string `yaml:"env,omitempty"`
|
Env map[string]string `yaml:"env,omitempty"`
|
||||||
Rest BackendRest `yaml:"rest,omitempty"`
|
Rest BackendRest `yaml:"rest,omitempty"`
|
||||||
|
Options Options `yaml:"options,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetBackend(name string) (Backend, bool) {
|
func GetBackend(name string) (Backend, bool) {
|
||||||
|
@@ -12,7 +12,7 @@ import (
|
|||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
const VERSION = "1.0.9"
|
const VERSION = "1.1.2"
|
||||||
|
|
||||||
var CI bool = false
|
var CI bool = false
|
||||||
var VERBOSE bool = false
|
var VERBOSE bool = false
|
||||||
@@ -75,21 +75,22 @@ func (c *Config) Describe() {
|
|||||||
colors.PrintDescription("Cron", l.Cron)
|
colors.PrintDescription("Cron", l.Cron)
|
||||||
}
|
}
|
||||||
|
|
||||||
after, before := len(l.Hooks.After), len(l.Hooks.Before)
|
|
||||||
if after+before > 0 {
|
|
||||||
tmp = ""
|
tmp = ""
|
||||||
if before > 0 {
|
hooks := map[string][]string{
|
||||||
tmp += "\tBefore"
|
"Before": l.Hooks.Before,
|
||||||
for _, cmd := range l.Hooks.Before {
|
"After": l.Hooks.After,
|
||||||
|
"Failure": l.Hooks.Failure,
|
||||||
|
"Success": l.Hooks.Success,
|
||||||
|
}
|
||||||
|
for hook, commands := range hooks {
|
||||||
|
if len(commands) > 0 {
|
||||||
|
tmp += "\n\t" + hook
|
||||||
|
for _, cmd := range commands {
|
||||||
tmp += colors.Faint.Sprintf("\n\t ▶ %s", cmd)
|
tmp += colors.Faint.Sprintf("\n\t ▶ %s", cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if after > 0 {
|
|
||||||
tmp += "\n\tAfter"
|
|
||||||
for _, cmd := range l.Hooks.After {
|
|
||||||
tmp += colors.Faint.Sprintf("\n\t ▶ %s", cmd)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if tmp != "" {
|
||||||
colors.PrintDescription("Hooks", tmp)
|
colors.PrintDescription("Hooks", tmp)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +130,7 @@ func CheckConfig() error {
|
|||||||
return fmt.Errorf("config could not be loaded/found")
|
return fmt.Errorf("config could not be loaded/found")
|
||||||
}
|
}
|
||||||
if !CheckIfResticIsCallable() {
|
if !CheckIfResticIsCallable() {
|
||||||
return fmt.Errorf(`restic was not found. Install either with "autorestic install" or manually`)
|
return fmt.Errorf(`%s was not found. Install either with "autorestic install" or manually`, RESTIC_BIN)
|
||||||
}
|
}
|
||||||
for name, backend := range c.Backends {
|
for name, backend := range c.Backends {
|
||||||
backend.name = name
|
backend.name = name
|
||||||
@@ -139,7 +140,7 @@ func CheckConfig() error {
|
|||||||
}
|
}
|
||||||
for name, location := range c.Locations {
|
for name, location := range c.Locations {
|
||||||
location.name = name
|
location.name = name
|
||||||
if err := location.validate(c); err != nil {
|
if err := location.validate(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,3 +220,13 @@ func (c *Config) SaveConfig() error {
|
|||||||
|
|
||||||
return viper.WriteConfig()
|
return viper.WriteConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getOptions(options Options, key string) []string {
|
||||||
|
var selected []string
|
||||||
|
for k, values := range options[key] {
|
||||||
|
for _, value := range values {
|
||||||
|
selected = append(selected, fmt.Sprintf("--%s", k), value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return selected
|
||||||
|
}
|
||||||
|
@@ -24,8 +24,10 @@ const (
|
|||||||
type HookArray = []string
|
type HookArray = []string
|
||||||
|
|
||||||
type Hooks struct {
|
type Hooks struct {
|
||||||
Before HookArray `yaml:"before"`
|
Before HookArray `yaml:"before,omitempty"`
|
||||||
After HookArray `yaml:"after"`
|
After HookArray `yaml:"after,omitempty"`
|
||||||
|
Success HookArray `yaml:"success,omitempty"`
|
||||||
|
Failure HookArray `yaml:"failure,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Options map[string]map[string][]string
|
type Options map[string]map[string][]string
|
||||||
@@ -45,7 +47,7 @@ func GetLocation(name string) (Location, bool) {
|
|||||||
return l, ok
|
return l, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l Location) validate(c *Config) error {
|
func (l Location) validate() error {
|
||||||
if l.From == "" {
|
if l.From == "" {
|
||||||
return fmt.Errorf(`Location "%s" is missing "from" key`, l.name)
|
return fmt.Errorf(`Location "%s" is missing "from" key`, l.name)
|
||||||
}
|
}
|
||||||
@@ -76,17 +78,6 @@ func (l Location) validate(c *Config) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l Location) getOptions(key string) []string {
|
|
||||||
var options []string
|
|
||||||
saved := l.Options[key]
|
|
||||||
for k, values := range saved {
|
|
||||||
for _, value := range values {
|
|
||||||
options = append(options, fmt.Sprintf("--%s", k), value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return options
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExecuteHooks(commands []string, options ExecuteOptions) error {
|
func ExecuteHooks(commands []string, options ExecuteOptions) error {
|
||||||
if len(commands) == 0 {
|
if len(commands) == 0 {
|
||||||
return nil
|
return nil
|
||||||
@@ -133,7 +124,8 @@ func (l Location) getPath() (string, error) {
|
|||||||
return "", fmt.Errorf("could not get path for location \"%s\"", l.name)
|
return "", fmt.Errorf("could not get path for location \"%s\"", l.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l Location) Backup(cron bool) error {
|
func (l Location) Backup(cron bool) []error {
|
||||||
|
var errors []error
|
||||||
colors.PrimaryPrint(" Backing up location \"%s\" ", l.name)
|
colors.PrimaryPrint(" Backing up location \"%s\" ", l.name)
|
||||||
t := l.getType()
|
t := l.getType()
|
||||||
options := ExecuteOptions{
|
options := ExecuteOptions{
|
||||||
@@ -147,7 +139,8 @@ func (l Location) Backup(cron bool) error {
|
|||||||
|
|
||||||
// Hooks
|
// Hooks
|
||||||
if err := ExecuteHooks(l.Hooks.Before, options); err != nil {
|
if err := ExecuteHooks(l.Hooks.Before, options); err != nil {
|
||||||
return err
|
errors = append(errors, err)
|
||||||
|
goto after
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backup
|
// Backup
|
||||||
@@ -156,12 +149,15 @@ func (l Location) Backup(cron bool) error {
|
|||||||
colors.Secondary.Printf("Backend: %s\n", backend.name)
|
colors.Secondary.Printf("Backend: %s\n", backend.name)
|
||||||
env, err := backend.getEnv()
|
env, err := backend.getEnv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
errors = append(errors, err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
flags := l.getOptions("backup")
|
lFlags := getOptions(l.Options, "backup")
|
||||||
|
bFlags := getOptions(backend.Options, "backup")
|
||||||
cmd := []string{"backup"}
|
cmd := []string{"backup"}
|
||||||
cmd = append(cmd, flags...)
|
cmd = append(cmd, lFlags...)
|
||||||
|
cmd = append(cmd, bFlags...)
|
||||||
if cron {
|
if cron {
|
||||||
cmd = append(cmd, "--tag", "cron")
|
cmd = append(cmd, "--tag", "cron")
|
||||||
}
|
}
|
||||||
@@ -181,7 +177,8 @@ func (l Location) Backup(cron bool) error {
|
|||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
colors.Error.Println(out)
|
colors.Error.Println(out)
|
||||||
return err
|
errors = append(errors, err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
if VERBOSE {
|
if VERBOSE {
|
||||||
colors.Faint.Println(out)
|
colors.Faint.Println(out)
|
||||||
@@ -190,10 +187,22 @@ func (l Location) Backup(cron bool) error {
|
|||||||
|
|
||||||
// After hooks
|
// After hooks
|
||||||
if err := ExecuteHooks(l.Hooks.After, options); err != nil {
|
if err := ExecuteHooks(l.Hooks.After, options); err != nil {
|
||||||
return err
|
errors = append(errors, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
after:
|
||||||
|
var commands []string
|
||||||
|
if len(errors) > 0 {
|
||||||
|
commands = l.Hooks.Failure
|
||||||
|
} else {
|
||||||
|
commands = l.Hooks.Success
|
||||||
|
}
|
||||||
|
if err := ExecuteHooks(commands, options); err != nil {
|
||||||
|
errors = append(errors, err)
|
||||||
|
}
|
||||||
|
|
||||||
colors.Success.Println("Done")
|
colors.Success.Println("Done")
|
||||||
return nil
|
return errors
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l Location) Forget(prune bool, dry bool) error {
|
func (l Location) Forget(prune bool, dry bool) error {
|
||||||
@@ -214,7 +223,8 @@ func (l Location) Forget(prune bool, dry bool) error {
|
|||||||
options := ExecuteOptions{
|
options := ExecuteOptions{
|
||||||
Envs: env,
|
Envs: env,
|
||||||
}
|
}
|
||||||
flags := l.getOptions("forget")
|
lFlags := getOptions(l.Options, "forget")
|
||||||
|
bFlags := getOptions(backend.Options, "forget")
|
||||||
cmd := []string{"forget", "--path", path}
|
cmd := []string{"forget", "--path", path}
|
||||||
if prune {
|
if prune {
|
||||||
cmd = append(cmd, "--prune")
|
cmd = append(cmd, "--prune")
|
||||||
@@ -222,7 +232,8 @@ func (l Location) Forget(prune bool, dry bool) error {
|
|||||||
if dry {
|
if dry {
|
||||||
cmd = append(cmd, "--dry-run")
|
cmd = append(cmd, "--dry-run")
|
||||||
}
|
}
|
||||||
cmd = append(cmd, flags...)
|
cmd = append(cmd, lFlags...)
|
||||||
|
cmd = append(cmd, bFlags...)
|
||||||
out, err := ExecuteResticCommand(options, cmd...)
|
out, err := ExecuteResticCommand(options, cmd...)
|
||||||
if VERBOSE {
|
if VERBOSE {
|
||||||
colors.Faint.Println(out)
|
colors.Faint.Println(out)
|
||||||
|
@@ -10,13 +10,15 @@ import (
|
|||||||
"github.com/cupcakearmy/autorestic/internal/colors"
|
"github.com/cupcakearmy/autorestic/internal/colors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var RESTIC_BIN string
|
||||||
|
|
||||||
func CheckIfCommandIsCallable(cmd string) bool {
|
func CheckIfCommandIsCallable(cmd string) bool {
|
||||||
_, err := exec.LookPath(cmd)
|
_, err := exec.LookPath(cmd)
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckIfResticIsCallable() bool {
|
func CheckIfResticIsCallable() bool {
|
||||||
return CheckIfCommandIsCallable("restic")
|
return CheckIfCommandIsCallable(RESTIC_BIN)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExecuteOptions struct {
|
type ExecuteOptions struct {
|
||||||
@@ -50,7 +52,7 @@ func ExecuteCommand(options ExecuteOptions, args ...string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ExecuteResticCommand(options ExecuteOptions, args ...string) (string, error) {
|
func ExecuteResticCommand(options ExecuteOptions, args ...string) (string, error) {
|
||||||
options.Command = "restic"
|
options.Command = RESTIC_BIN
|
||||||
return ExecuteCommand(options, args...)
|
return ExecuteCommand(options, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user