mirror of
https://github.com/cupcakearmy/autorestic.git
synced 2024-12-23 16:56:25 +00:00
Compare commits
2 Commits
5b46897feb
...
9697e080e6
Author | SHA1 | Date | |
---|---|---|---|
|
9697e080e6 | ||
|
8e24286ca3 |
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
@ -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.7"
|
|
||||||
|
|
||||||
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 {
|
||||||
@ -335,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 {
|
||||||
@ -346,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
|
||||||
}
|
}
|
||||||
|
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"
|
Loading…
Reference in New Issue
Block a user