mirror of
https://github.com/cupcakearmy/autorestic.git
synced 2025-09-06 10:30:39 +00:00
Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
12adeb2b06 | |||
37b26dfc31 | |||
c1795b2acc | |||
b8d12e518c | |||
50060cf539 | |||
c33aac42dc | |||
c359053e0e | |||
c16340ab26 | |||
edc85c4ac3 | |||
68682777f2 | |||
|
b6c7922df5 | ||
|
991b8bec22 | ||
bbc32568ad | |||
f3c038c716 | |||
59612a97b6 | |||
33319a00ef | |||
8eb14ea14f |
17
CHANGELOG.md
17
CHANGELOG.md
@@ -5,6 +5,23 @@ 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.0.8] - 2021-04-28
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- `--lean` flag to cron command for less output about skipping backups.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- consistent lower casing in usage descriptions.
|
||||||
|
|
||||||
|
## [1.0.7] - 2021-04-26
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Support for `darwin/arm64` aka Apple Silicon.
|
||||||
|
- Added support for `arm64` and `aarch64` in install scripts.
|
||||||
|
|
||||||
## [1.0.6] - 2021-04-24
|
## [1.0.6] - 2021-04-24
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@@ -9,6 +9,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/cupcakearmy/autorestic/internal"
|
"github.com/cupcakearmy/autorestic/internal"
|
||||||
)
|
)
|
||||||
@@ -16,7 +17,7 @@ import (
|
|||||||
var DIR, _ = filepath.Abs("./dist")
|
var DIR, _ = filepath.Abs("./dist")
|
||||||
|
|
||||||
var targets = map[string][]string{
|
var targets = map[string][]string{
|
||||||
"darwin": {"amd64"},
|
"darwin": {"amd64", "arm64"},
|
||||||
"freebsd": {"386", "amd64", "arm"},
|
"freebsd": {"386", "amd64", "arm"},
|
||||||
"linux": {"386", "amd64", "arm", "arm64"},
|
"linux": {"386", "amd64", "arm", "arm64"},
|
||||||
"netbsd": {"386", "amd64"},
|
"netbsd": {"386", "amd64"},
|
||||||
@@ -27,7 +28,7 @@ type buildOptions struct {
|
|||||||
Target, Arch, Version string
|
Target, Arch, Version string
|
||||||
}
|
}
|
||||||
|
|
||||||
func build(options buildOptions) error {
|
func build(options buildOptions, wg *sync.WaitGroup) {
|
||||||
fmt.Printf("Building %s %s\n", options.Target, options.Arch)
|
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)
|
||||||
@@ -46,7 +47,7 @@ func build(options buildOptions) error {
|
|||||||
)
|
)
|
||||||
err := c.Run()
|
err := c.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,26 +59,25 @@ func build(options buildOptions) error {
|
|||||||
c.Stderr = os.Stderr
|
c.Stderr = os.Stderr
|
||||||
err := c.Run()
|
err := c.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
wg.Done()
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
os.RemoveAll(DIR)
|
os.RemoveAll(DIR)
|
||||||
v := internal.VERSION
|
v := internal.VERSION
|
||||||
|
var wg sync.WaitGroup
|
||||||
for target, archs := range targets {
|
for target, archs := range targets {
|
||||||
for _, arch := range archs {
|
for _, arch := range archs {
|
||||||
err := build(buildOptions{
|
wg.Add(1)
|
||||||
|
build(buildOptions{
|
||||||
Target: target,
|
Target: target,
|
||||||
Arch: arch,
|
Arch: arch,
|
||||||
Version: v,
|
Version: v,
|
||||||
})
|
}, &wg)
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,7 @@ var cronCmd = &cobra.Command{
|
|||||||
Short: "Run cron job for automated backups",
|
Short: "Run cron job for automated backups",
|
||||||
Long: `Intended to be mainly triggered by an automated system like systemd or crontab. For each location checks if a cron backup is due and runs it.`,
|
Long: `Intended to be mainly triggered by an automated system like systemd or crontab. For each location checks if a cron backup is due and runs it.`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
internal.CRON_LEAN, _ = cmd.Flags().GetBool("lean")
|
||||||
err := lock.Lock()
|
err := lock.Lock()
|
||||||
CheckErr(err)
|
CheckErr(err)
|
||||||
defer lock.Unlock()
|
defer lock.Unlock()
|
||||||
@@ -22,4 +23,5 @@ var cronCmd = &cobra.Command{
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(cronCmd)
|
rootCmd.AddCommand(cronCmd)
|
||||||
|
cronCmd.Flags().Bool("lean", false, "only output information about actual backups")
|
||||||
}
|
}
|
||||||
|
@@ -31,6 +31,6 @@ var forgetCmd = &cobra.Command{
|
|||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(forgetCmd)
|
rootCmd.AddCommand(forgetCmd)
|
||||||
internal.AddFlagsToCommand(forgetCmd, false)
|
internal.AddFlagsToCommand(forgetCmd, false)
|
||||||
forgetCmd.Flags().Bool("prune", false, "Also prune repository")
|
forgetCmd.Flags().Bool("prune", false, "also prune repository")
|
||||||
forgetCmd.Flags().Bool("dry-run", false, "Do not write changes, show what would be affected")
|
forgetCmd.Flags().Bool("dry-run", false, "do not write changes, show what would be affected")
|
||||||
}
|
}
|
||||||
|
@@ -57,5 +57,4 @@ func initConfig() {
|
|||||||
viper.SetConfigName(".autorestic")
|
viper.SetConfigName(".autorestic")
|
||||||
}
|
}
|
||||||
viper.AutomaticEnv()
|
viper.AutomaticEnv()
|
||||||
internal.GetConfig()
|
|
||||||
}
|
}
|
||||||
|
@@ -16,5 +16,5 @@ var uninstallCmd = &cobra.Command{
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(uninstallCmd)
|
rootCmd.AddCommand(uninstallCmd)
|
||||||
uninstallCmd.Flags().Bool("no-restic", false, "Do not uninstall restic.")
|
uninstallCmd.Flags().Bool("no-restic", false, "do not uninstall restic.")
|
||||||
}
|
}
|
||||||
|
@@ -17,5 +17,5 @@ var upgradeCmd = &cobra.Command{
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(upgradeCmd)
|
rootCmd.AddCommand(upgradeCmd)
|
||||||
upgradeCmd.Flags().Bool("no-restic", false, "Also update restic. Default: true")
|
upgradeCmd.Flags().Bool("no-restic", false, "also update restic")
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
> [General](/cli/general)
|
> [General](/cli/general)
|
||||||
> [Info](/cli/info)
|
> [Info](/cli/info)
|
||||||
> [Check](/cli/check)
|
> [Check](/cli/check)
|
||||||
|
> [Completion](/cli/completion)
|
||||||
> [Backup](/cli/backup)
|
> [Backup](/cli/backup)
|
||||||
> [Restore](/cli/restore)
|
> [Restore](/cli/restore)
|
||||||
> [Forget](/cli/forget)
|
> [Forget](/cli/forget)
|
||||||
|
@@ -19,16 +19,17 @@ backends:
|
|||||||
backends:
|
backends:
|
||||||
name-of-backend:
|
name-of-backend:
|
||||||
type: b2
|
type: b2
|
||||||
path: 'myAccount:myBucket/my/path'
|
path: 'backblaze_bucketID'
|
||||||
|
# Or With a path
|
||||||
|
# path: 'backblaze_bucketID:/some/path'
|
||||||
env:
|
env:
|
||||||
B2_ACCOUNT_ID: backblaze_account_id
|
B2_ACCOUNT_ID: 'backblaze_keyID'
|
||||||
B2_ACCOUNT_KEY: backblaze_account_key
|
B2_ACCOUNT_KEY: 'backblaze_applicationKey'
|
||||||
```
|
```
|
||||||
|
|
||||||
#### API Keys gotcha
|
#### API Keys gotcha
|
||||||
|
|
||||||
When creating API make sure you check _Allow List All Bucket Names_ if you allow access to a single bucket only.
|
If you use a _File name prefix_ when making the application key, do not include a leading slash. Make sure to include this prefix in the path (e.g. `path: 'backblaze_bucketID:my/path'`).
|
||||||
Also make sure that the _File name prefix_ (if used) does not includes a leading slash.
|
|
||||||
|
|
||||||
## S3 / Minio
|
## S3 / Minio
|
||||||
|
|
||||||
|
17
docs/markdown/cli/completion.md
Normal file
17
docs/markdown/cli/completion.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Completion
|
||||||
|
|
||||||
|
```bash
|
||||||
|
autorestic completion [bash|zsh|fish|powershell]
|
||||||
|
```
|
||||||
|
|
||||||
|
Autorestic can generate shell completions automatically to make the experience even easier.
|
||||||
|
Supported shells are
|
||||||
|
|
||||||
|
- bash
|
||||||
|
- zsh
|
||||||
|
- fish
|
||||||
|
- powershell
|
||||||
|
|
||||||
|
To see how to install run `autorestic help completion` and follow the instructions for your specific shell
|
||||||
|
|
||||||
|
> :ToCPrevNext
|
@@ -1,11 +1,13 @@
|
|||||||
# Cron
|
# Cron
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
autorestic cron
|
autorestic cron [--lean]
|
||||||
```
|
```
|
||||||
|
|
||||||
This command is mostly intended to be triggered by an automated system like systemd or crontab.
|
This command is mostly intended to be triggered by an automated system like systemd or crontab.
|
||||||
|
|
||||||
It will run cron jobs as [specified in the cron section](/location/cron) of a specific location.
|
It will run cron jobs as [specified in the cron section](/location/cron) of a specific location.
|
||||||
|
|
||||||
|
The `--lean` flag will omit output like _skipping location x: not due yet_. This can be useful if you are dumping the output of the cron job to a log file and don't want to be overwhelmed by the output log.
|
||||||
|
|
||||||
> :ToCPrevNext
|
> :ToCPrevNext
|
||||||
|
@@ -4,10 +4,10 @@
|
|||||||
autorestic exec [-b, --backend] [-a, --all] <command> -- [native options]
|
autorestic exec [-b, --backend] [-a, --all] <command> -- [native options]
|
||||||
```
|
```
|
||||||
|
|
||||||
This is avery handy command which enables you to run any native restic command on desired backends. An example would be listing all the snapshots of all your backends:
|
This is avery handy command which enables you to run any native restic command on desired backends. Generally will want to include the verbose flag `-v, --verbose` to see the output. An example would be listing all the snapshots of all your backends:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
autorestic exec -a -- snapshots
|
autorestic exec -av -- snapshots
|
||||||
```
|
```
|
||||||
|
|
||||||
With `exec` you can basically run every cli command that you would be able to run with the restic cli. It only pre-fills path, key, etc.
|
With `exec` you can basically run every cli command that you would be able to run with the restic cli. It only pre-fills path, key, etc.
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
This amazing people helped the project!
|
This amazing people helped the project!
|
||||||
|
|
||||||
- @agateblue - Docs, Pruning, S3
|
- @agateblue - Docs, Pruning, S3
|
||||||
|
- @david-boles - Docs
|
||||||
- @jin-park-dev - Typos
|
- @jin-park-dev - Typos
|
||||||
- @sumnerboy12 - Typos
|
- @sumnerboy12 - Typos
|
||||||
- @FuzzyMistborn - Typos
|
- @FuzzyMistborn - Typos
|
||||||
|
@@ -30,14 +30,14 @@ First, open your crontab in edit mode
|
|||||||
crontab -e
|
crontab -e
|
||||||
```
|
```
|
||||||
|
|
||||||
Then paste this at the bottom of the file and save it. Note that in this specific example the `.autorestic.yml` is located in `/srv/`. You need to modify that part of course to fit your config file.
|
Then paste this at the bottom of the file and save it. Note that in this specific example the config file is located at one of the default locations (e.g. `~/.autorestic.yml`). If your config is somewhere else you'll need to specify it using the `-c` option.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# This is required, as it otherwise cannot find restic as a command.
|
# This is required, as it otherwise cannot find restic as a command.
|
||||||
PATH="/usr/local/bin:/usr/bin:/bin"
|
PATH="/usr/local/bin:/usr/bin:/bin"
|
||||||
|
|
||||||
# Example running every 5 minutes
|
# Example running every 5 minutes
|
||||||
*/5 * * * * autorestic -c /srv/.autorestic.yml --ci cron
|
*/5 * * * * autorestic --ci cron
|
||||||
```
|
```
|
||||||
|
|
||||||
> The `--ci` option is not required, but recommended
|
> The `--ci` option is not required, but recommended
|
||||||
|
@@ -9,7 +9,7 @@ curl -s https://raw.githubusercontent.com/CupCakeArmy/autorestic/master/install.
|
|||||||
## Write a simple config file
|
## Write a simple config file
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
vim .autorestic.yml
|
vim ~/.autorestic.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
For a quick overview:
|
For a quick overview:
|
||||||
@@ -35,7 +35,7 @@ locations:
|
|||||||
- hdd
|
- hdd
|
||||||
|
|
||||||
backends:
|
backends:
|
||||||
- name: remote
|
remote:
|
||||||
type: s3
|
type: s3
|
||||||
path: 's3.amazonaws.com/bucket_name'
|
path: 's3.amazonaws.com/bucket_name'
|
||||||
key: some-random-password-198rc79r8y1029c8yfewj8f1u0ef87yh198uoieufy
|
key: some-random-password-198rc79r8y1029c8yfewj8f1u0ef87yh198uoieufy
|
||||||
@@ -43,7 +43,7 @@ backends:
|
|||||||
AWS_ACCESS_KEY_ID: account_id
|
AWS_ACCESS_KEY_ID: account_id
|
||||||
AWS_SECRET_ACCESS_KEY: account_key
|
AWS_SECRET_ACCESS_KEY: account_key
|
||||||
|
|
||||||
- name: hdd
|
hdd:
|
||||||
type: local
|
type: local
|
||||||
path: /mnt/my_external_storage
|
path: /mnt/my_external_storage
|
||||||
key: 'if not key is set it will be generated for you'
|
key: 'if not key is set it will be generated for you'
|
||||||
@@ -52,7 +52,7 @@ backends:
|
|||||||
## Check
|
## Check
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
autorestic check -a
|
autorestic check
|
||||||
```
|
```
|
||||||
|
|
||||||
This checks if the config file has any issues. If this is the first time this can take longer as autorestic will setup the backends.
|
This checks if the config file has any issues. If this is the first time this can take longer as autorestic will setup the backends.
|
||||||
|
@@ -16,9 +16,11 @@ else
|
|||||||
fi
|
fi
|
||||||
echo $OS
|
echo $OS
|
||||||
|
|
||||||
NATIVE_ARCH=$(uname -m)
|
NATIVE_ARCH=$(uname -m | tr '[:upper:]' '[:lower:]')
|
||||||
if [[ $NATIVE_ARCH == *"x86_64"* ]]; then
|
if [[ $NATIVE_ARCH == *"x86_64"* ]]; then
|
||||||
ARCH=amd64
|
ARCH=amd64
|
||||||
|
elif [[ $NATIVE_ARCH == *"arm64"* || $NATIVE_ARCH == *"aarch64"* ]]; then
|
||||||
|
ARCH=arm64
|
||||||
elif [[ $NATIVE_ARCH == *"x86"* ]]; then
|
elif [[ $NATIVE_ARCH == *"x86"* ]]; then
|
||||||
ARCH=386
|
ARCH=386
|
||||||
else
|
else
|
||||||
|
@@ -120,7 +120,9 @@ func upgradeRestic() error {
|
|||||||
func Upgrade(restic bool) error {
|
func Upgrade(restic bool) error {
|
||||||
// Upgrade restic
|
// Upgrade restic
|
||||||
if restic {
|
if restic {
|
||||||
InstallRestic()
|
if err := InstallRestic(); err != nil {
|
||||||
|
colors.Error.Println(err)
|
||||||
|
}
|
||||||
upgradeRestic()
|
upgradeRestic()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -12,10 +12,11 @@ import (
|
|||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
const VERSION = "1.0.6"
|
const VERSION = "1.0.8"
|
||||||
|
|
||||||
var CI bool = false
|
var CI bool = false
|
||||||
var VERBOSE bool = false
|
var VERBOSE bool = false
|
||||||
|
var CRON_LEAN bool = false
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Locations map[string]Location `yaml:"locations"`
|
Locations map[string]Location `yaml:"locations"`
|
||||||
@@ -29,7 +30,9 @@ func GetConfig() *Config {
|
|||||||
if config == nil {
|
if config == nil {
|
||||||
once.Do(func() {
|
once.Do(func() {
|
||||||
if err := viper.ReadInConfig(); err == nil {
|
if err := viper.ReadInConfig(); err == nil {
|
||||||
colors.Faint.Println("Using config file:", viper.ConfigFileUsed())
|
if !CRON_LEAN {
|
||||||
|
colors.Faint.Println("Using config file:", viper.ConfigFileUsed())
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -190,11 +193,17 @@ func GetAllOrSelected(cmd *cobra.Command, backends bool) ([]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func AddFlagsToCommand(cmd *cobra.Command, backend bool) {
|
func AddFlagsToCommand(cmd *cobra.Command, backend bool) {
|
||||||
cmd.PersistentFlags().BoolP("all", "a", false, "Backup all locations")
|
var usage string
|
||||||
if backend {
|
if backend {
|
||||||
cmd.PersistentFlags().StringSliceP("backend", "b", []string{}, "backends")
|
usage = "all backends"
|
||||||
} else {
|
} else {
|
||||||
cmd.PersistentFlags().StringSliceP("location", "l", []string{}, "Locations")
|
usage = "all locations"
|
||||||
|
}
|
||||||
|
cmd.PersistentFlags().BoolP("all", "a", false, usage)
|
||||||
|
if backend {
|
||||||
|
cmd.PersistentFlags().StringSliceP("backend", "b", []string{}, "select backends")
|
||||||
|
} else {
|
||||||
|
cmd.PersistentFlags().StringSliceP("location", "l", []string{}, "select locations")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -309,7 +309,9 @@ func (l Location) RunCron() error {
|
|||||||
lock.SetCron(l.name, now.Unix())
|
lock.SetCron(l.name, now.Unix())
|
||||||
l.Backup(true)
|
l.Backup(true)
|
||||||
} else {
|
} else {
|
||||||
colors.Body.Printf("Skipping \"%s\", not due yet.\n", l.name)
|
if !CRON_LEAN {
|
||||||
|
colors.Body.Printf("Skipping \"%s\", not due yet.\n", l.name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user