2021-04-08 23:55:10 +00:00
|
|
|
package internal
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"path"
|
|
|
|
"strings"
|
|
|
|
"sync"
|
|
|
|
|
2021-04-12 14:15:17 +00:00
|
|
|
"github.com/cupcakearmy/autorestic/internal/colors"
|
2021-04-08 23:55:10 +00:00
|
|
|
"github.com/mitchellh/go-homedir"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/spf13/viper"
|
|
|
|
)
|
|
|
|
|
2021-04-11 11:04:11 +00:00
|
|
|
const VERSION = "1.0.0"
|
|
|
|
|
2021-04-12 14:15:17 +00:00
|
|
|
var CI bool = false
|
|
|
|
var VERBOSE bool = false
|
|
|
|
|
2021-04-08 23:55:10 +00:00
|
|
|
type Config struct {
|
2021-04-11 15:02:34 +00:00
|
|
|
Locations []Location `mapstructure:"locations"`
|
|
|
|
Backends []Backend `mapstructure:"backends"`
|
2021-04-08 23:55:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var once sync.Once
|
|
|
|
var config *Config
|
|
|
|
|
|
|
|
func GetConfig() *Config {
|
|
|
|
if config == nil {
|
|
|
|
once.Do(func() {
|
2021-04-12 14:15:17 +00:00
|
|
|
if err := viper.ReadInConfig(); err == nil {
|
|
|
|
colors.Faint.Println("Using config file:", viper.ConfigFileUsed())
|
|
|
|
} else {
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-04-08 23:55:10 +00:00
|
|
|
config = &Config{}
|
|
|
|
if err := viper.UnmarshalExact(config); err != nil {
|
2021-04-11 22:02:35 +00:00
|
|
|
panic(err)
|
2021-04-08 23:55:10 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return config
|
|
|
|
}
|
|
|
|
|
2021-04-11 16:17:21 +00:00
|
|
|
func GetPathRelativeToConfig(p string) (string, error) {
|
2021-04-08 23:55:10 +00:00
|
|
|
if path.IsAbs(p) {
|
2021-04-11 16:17:21 +00:00
|
|
|
return p, nil
|
2021-04-08 23:55:10 +00:00
|
|
|
} else if strings.HasPrefix(p, "~") {
|
|
|
|
home, err := homedir.Dir()
|
2021-04-11 16:17:21 +00:00
|
|
|
return path.Join(home, strings.TrimPrefix(p, "~")), err
|
2021-04-08 23:55:10 +00:00
|
|
|
} else {
|
2021-04-11 16:17:21 +00:00
|
|
|
return path.Join(path.Dir(viper.ConfigFileUsed()), p), nil
|
2021-04-08 23:55:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-11 22:02:35 +00:00
|
|
|
func (c *Config) CheckConfig() error {
|
2021-04-12 14:15:17 +00:00
|
|
|
if c == nil {
|
|
|
|
return fmt.Errorf("config could not be loaded/found")
|
|
|
|
}
|
2021-04-12 08:55:57 +00:00
|
|
|
if !CheckIfResticIsCallable() {
|
|
|
|
return fmt.Errorf(`restic was not found. Install either with "autorestic install" or manually`)
|
|
|
|
}
|
2021-04-11 22:02:35 +00:00
|
|
|
found := map[string]bool{}
|
2021-04-11 16:17:21 +00:00
|
|
|
for _, backend := range c.Backends {
|
2021-04-08 23:55:10 +00:00
|
|
|
if err := backend.validate(); err != nil {
|
2021-04-11 22:02:35 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
if _, ok := found[backend.Name]; ok {
|
|
|
|
return fmt.Errorf(`duplicate name for backends "%s"`, backend.Name)
|
|
|
|
} else {
|
|
|
|
found[backend.Name] = true
|
2021-04-08 23:55:10 +00:00
|
|
|
}
|
|
|
|
}
|
2021-04-11 22:02:35 +00:00
|
|
|
found = map[string]bool{}
|
2021-04-11 16:17:21 +00:00
|
|
|
for _, location := range c.Locations {
|
2021-04-08 23:55:10 +00:00
|
|
|
if err := location.validate(c); err != nil {
|
2021-04-11 22:02:35 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
if _, ok := found[location.Name]; ok {
|
|
|
|
return fmt.Errorf(`duplicate name for locations "%s"`, location.Name)
|
|
|
|
} else {
|
|
|
|
found[location.Name] = true
|
2021-04-08 23:55:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-04-11 11:04:11 +00:00
|
|
|
func GetAllOrSelected(cmd *cobra.Command, backends bool) ([]string, error) {
|
2021-04-08 23:55:10 +00:00
|
|
|
var list []string
|
|
|
|
if backends {
|
2021-04-11 15:02:34 +00:00
|
|
|
for _, b := range config.Backends {
|
|
|
|
list = append(list, b.Name)
|
2021-04-08 23:55:10 +00:00
|
|
|
}
|
|
|
|
} else {
|
2021-04-11 15:02:34 +00:00
|
|
|
for _, l := range config.Locations {
|
|
|
|
list = append(list, l.Name)
|
2021-04-08 23:55:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
all, _ := cmd.Flags().GetBool("all")
|
|
|
|
if all {
|
2021-04-11 11:04:11 +00:00
|
|
|
return list, nil
|
2021-04-08 23:55:10 +00:00
|
|
|
} else {
|
|
|
|
var selected []string
|
|
|
|
if backends {
|
|
|
|
tmp, _ := cmd.Flags().GetStringSlice("backend")
|
|
|
|
selected = tmp
|
|
|
|
} else {
|
|
|
|
tmp, _ := cmd.Flags().GetStringSlice("location")
|
|
|
|
selected = tmp
|
|
|
|
}
|
|
|
|
for _, s := range selected {
|
|
|
|
found := false
|
|
|
|
for _, l := range list {
|
|
|
|
if l == s {
|
|
|
|
found = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !found {
|
2021-04-11 11:04:11 +00:00
|
|
|
if backends {
|
|
|
|
return nil, fmt.Errorf("invalid backend \"%s\"", s)
|
|
|
|
} else {
|
|
|
|
return nil, fmt.Errorf("invalid location \"%s\"", s)
|
|
|
|
}
|
2021-04-08 23:55:10 +00:00
|
|
|
}
|
|
|
|
}
|
2021-04-11 12:22:46 +00:00
|
|
|
if len(selected) == 0 {
|
|
|
|
return selected, fmt.Errorf("nothing selected, aborting")
|
|
|
|
}
|
2021-04-11 11:04:11 +00:00
|
|
|
return selected, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func AddFlagsToCommand(cmd *cobra.Command, backend bool) {
|
|
|
|
cmd.PersistentFlags().BoolP("all", "a", false, "Backup all locations")
|
|
|
|
if backend {
|
|
|
|
cmd.PersistentFlags().StringSliceP("backend", "b", []string{}, "backends")
|
|
|
|
} else {
|
|
|
|
cmd.PersistentFlags().StringSliceP("location", "l", []string{}, "Locations")
|
2021-04-08 23:55:10 +00:00
|
|
|
}
|
|
|
|
}
|