mirror of
https://github.com/cupcakearmy/autorestic.git
synced 2024-12-22 16:26:25 +00:00
make back compatible
This commit is contained in:
parent
aa0b81023f
commit
1bbd3879fe
@ -30,9 +30,7 @@ var backupCmd = &cobra.Command{
|
|||||||
CheckErr(err)
|
CheckErr(err)
|
||||||
defer lock.Unlock()
|
defer lock.Unlock()
|
||||||
|
|
||||||
config := internal.GetConfig()
|
CheckErr(internal.CheckConfig())
|
||||||
err = config.CheckConfig()
|
|
||||||
CheckErr(err)
|
|
||||||
|
|
||||||
selected, err := internal.GetAllOrSelected(cmd, false)
|
selected, err := internal.GetAllOrSelected(cmd, false)
|
||||||
CheckErr(err)
|
CheckErr(err)
|
||||||
|
@ -31,9 +31,8 @@ var checkCmd = &cobra.Command{
|
|||||||
CheckErr(err)
|
CheckErr(err)
|
||||||
defer lock.Unlock()
|
defer lock.Unlock()
|
||||||
|
|
||||||
config := internal.GetConfig()
|
CheckErr(internal.CheckConfig())
|
||||||
err = config.CheckConfig()
|
|
||||||
CheckErr(err)
|
|
||||||
colors.Success.Println("Everyting is fine.")
|
colors.Success.Println("Everyting is fine.")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,7 @@ var execCmd = &cobra.Command{
|
|||||||
CheckErr(err)
|
CheckErr(err)
|
||||||
defer lock.Unlock()
|
defer lock.Unlock()
|
||||||
|
|
||||||
config := internal.GetConfig()
|
CheckErr(internal.CheckConfig())
|
||||||
err = config.CheckConfig()
|
|
||||||
CheckErr(err)
|
|
||||||
|
|
||||||
selected, err := internal.GetAllOrSelected(cmd, true)
|
selected, err := internal.GetAllOrSelected(cmd, true)
|
||||||
CheckErr(err)
|
CheckErr(err)
|
||||||
|
@ -30,8 +30,7 @@ var forgetCmd = &cobra.Command{
|
|||||||
CheckErr(err)
|
CheckErr(err)
|
||||||
defer lock.Unlock()
|
defer lock.Unlock()
|
||||||
|
|
||||||
config := internal.GetConfig()
|
CheckErr(internal.CheckConfig())
|
||||||
CheckErr(config.CheckConfig())
|
|
||||||
|
|
||||||
selected, err := internal.GetAllOrSelected(cmd, false)
|
selected, err := internal.GetAllOrSelected(cmd, false)
|
||||||
CheckErr(err)
|
CheckErr(err)
|
||||||
|
@ -12,21 +12,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Backend struct {
|
type Backend struct {
|
||||||
Name string `mapstructure:"name"`
|
name string
|
||||||
Type string `mapstructure:"type"`
|
Type string `mapstructure:"type,omitempty"`
|
||||||
Path string `mapstructure:"path"`
|
Path string `mapstructure:"path,omitempty"`
|
||||||
Key string `mapstructure:"key"`
|
Key string `mapstructure:"key,omitempty"`
|
||||||
Env map[string]string `mapstructure:"env"`
|
Env map[string]string `mapstructure:"env,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetBackend(name string) (Backend, bool) {
|
func GetBackend(name string) (Backend, bool) {
|
||||||
c := GetConfig()
|
b, ok := GetConfig().Backends[name]
|
||||||
for _, b := range c.Backends {
|
b.name = name
|
||||||
if b.Name == name {
|
return b, ok
|
||||||
return b, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Backend{}, false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Backend) generateRepo() (string, error) {
|
func (b Backend) generateRepo() (string, error) {
|
||||||
@ -59,25 +55,20 @@ func generateRandomKey() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b Backend) validate() error {
|
func (b Backend) validate() error {
|
||||||
if b.Name == "" {
|
|
||||||
return fmt.Errorf(`Backend has no "name"`)
|
|
||||||
}
|
|
||||||
if b.Type == "" {
|
if b.Type == "" {
|
||||||
return fmt.Errorf(`Backend "%s" has no "type"`, b.Name)
|
return fmt.Errorf(`Backend "%s" has no "type"`, b.name)
|
||||||
}
|
}
|
||||||
if b.Path == "" {
|
if b.Path == "" {
|
||||||
return fmt.Errorf(`Backend "%s" has no "path"`, b.Name)
|
return fmt.Errorf(`Backend "%s" has no "path"`, b.name)
|
||||||
}
|
}
|
||||||
if b.Key == "" {
|
if b.Key == "" {
|
||||||
key := generateRandomKey()
|
key := generateRandomKey()
|
||||||
b.Key = key
|
b.Key = key
|
||||||
c := GetConfig()
|
c := GetConfig()
|
||||||
for i, backend := range c.Backends {
|
tmp := c.Backends[b.name]
|
||||||
if backend.Name == b.Name {
|
tmp.Key = key
|
||||||
c.Backends[i].Key = key
|
tmp.name = ""
|
||||||
break
|
c.Backends[b.name] = tmp
|
||||||
}
|
|
||||||
}
|
|
||||||
file := viper.ConfigFileUsed()
|
file := viper.ConfigFileUsed()
|
||||||
if err := CopyFile(file, file+".old"); err != nil {
|
if err := CopyFile(file, file+".old"); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -18,8 +18,8 @@ var CI bool = false
|
|||||||
var VERBOSE bool = false
|
var VERBOSE bool = false
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Locations []Location `mapstructure:"locations"`
|
Locations map[string]Location `mapstructure:"locations"`
|
||||||
Backends []Backend `mapstructure:"backends"`
|
Backends map[string]Backend `mapstructure:"backends"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var once sync.Once
|
var once sync.Once
|
||||||
@ -31,7 +31,6 @@ func GetConfig() *Config {
|
|||||||
if err := viper.ReadInConfig(); err == nil {
|
if err := viper.ReadInConfig(); err == nil {
|
||||||
colors.Faint.Println("Using config file:", viper.ConfigFileUsed())
|
colors.Faint.Println("Using config file:", viper.ConfigFileUsed())
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,34 +54,25 @@ func GetPathRelativeToConfig(p string) (string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) CheckConfig() error {
|
func CheckConfig() error {
|
||||||
|
c := GetConfig()
|
||||||
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 !CheckIfResticIsCallable() {
|
||||||
return fmt.Errorf(`restic was not found. Install either with "autorestic install" or manually`)
|
return fmt.Errorf(`restic was not found. Install either with "autorestic install" or manually`)
|
||||||
}
|
}
|
||||||
found := map[string]bool{}
|
for name, backend := range c.Backends {
|
||||||
for _, backend := range c.Backends {
|
backend.name = name
|
||||||
if err := backend.validate(); err != nil {
|
if err := backend.validate(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, ok := found[backend.Name]; ok {
|
|
||||||
return fmt.Errorf(`duplicate name for backends "%s"`, backend.Name)
|
|
||||||
} else {
|
|
||||||
found[backend.Name] = true
|
|
||||||
}
|
}
|
||||||
}
|
for name, location := range c.Locations {
|
||||||
found = map[string]bool{}
|
location.name = name
|
||||||
for _, location := range c.Locations {
|
|
||||||
if err := location.validate(c); err != nil {
|
if err := location.validate(c); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, ok := found[location.Name]; ok {
|
|
||||||
return fmt.Errorf(`duplicate name for locations "%s"`, location.Name)
|
|
||||||
} else {
|
|
||||||
found[location.Name] = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -90,25 +80,25 @@ func (c *Config) CheckConfig() error {
|
|||||||
func GetAllOrSelected(cmd *cobra.Command, backends bool) ([]string, error) {
|
func GetAllOrSelected(cmd *cobra.Command, backends bool) ([]string, error) {
|
||||||
var list []string
|
var list []string
|
||||||
if backends {
|
if backends {
|
||||||
for _, b := range config.Backends {
|
for name := range config.Backends {
|
||||||
list = append(list, b.Name)
|
list = append(list, name)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, l := range config.Locations {
|
for name := range config.Locations {
|
||||||
list = append(list, l.Name)
|
list = append(list, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
all, _ := cmd.Flags().GetBool("all")
|
all, _ := cmd.Flags().GetBool("all")
|
||||||
if all {
|
if all {
|
||||||
return list, nil
|
return list, nil
|
||||||
} else {
|
}
|
||||||
|
|
||||||
var selected []string
|
var selected []string
|
||||||
if backends {
|
if backends {
|
||||||
tmp, _ := cmd.Flags().GetStringSlice("backend")
|
selected, _ = cmd.Flags().GetStringSlice("backend")
|
||||||
selected = tmp
|
|
||||||
} else {
|
} else {
|
||||||
tmp, _ := cmd.Flags().GetStringSlice("location")
|
selected, _ = cmd.Flags().GetStringSlice("location")
|
||||||
selected = tmp
|
|
||||||
}
|
}
|
||||||
for _, s := range selected {
|
for _, s := range selected {
|
||||||
found := false
|
found := false
|
||||||
@ -126,11 +116,11 @@ func GetAllOrSelected(cmd *cobra.Command, backends bool) ([]string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(selected) == 0 {
|
if len(selected) == 0 {
|
||||||
return selected, fmt.Errorf("nothing selected, aborting")
|
return selected, fmt.Errorf("nothing selected, aborting")
|
||||||
}
|
}
|
||||||
return selected, nil
|
return selected, nil
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddFlagsToCommand(cmd *cobra.Command, backend bool) {
|
func AddFlagsToCommand(cmd *cobra.Command, backend bool) {
|
||||||
|
@ -2,7 +2,8 @@ package internal
|
|||||||
|
|
||||||
func RunCron() error {
|
func RunCron() error {
|
||||||
c := GetConfig()
|
c := GetConfig()
|
||||||
for _, l := range c.Locations {
|
for name, l := range c.Locations {
|
||||||
|
l.name = name
|
||||||
if err := l.RunCron(); err != nil {
|
if err := l.RunCron(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -31,33 +31,26 @@ type Hooks struct {
|
|||||||
type Options map[string]map[string][]string
|
type Options map[string]map[string][]string
|
||||||
|
|
||||||
type Location struct {
|
type Location struct {
|
||||||
Name string `mapstructure:"name"`
|
name string `mapstructure:",omitempty"`
|
||||||
From string `mapstructure:"from"`
|
From string `mapstructure:"from,omitempty"`
|
||||||
To []string `mapstructure:"to"`
|
To []string `mapstructure:"to,omitempty"`
|
||||||
Hooks Hooks `mapstructure:"hooks"`
|
Hooks Hooks `mapstructure:"hooks,omitempty"`
|
||||||
Cron string `mapstructure:"cron"`
|
Cron string `mapstructure:"cron,omitempty"`
|
||||||
Options Options `mapstructure:"options"`
|
Options Options `mapstructure:"options,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetLocation(name string) (Location, bool) {
|
func GetLocation(name string) (Location, bool) {
|
||||||
c := GetConfig()
|
l, ok := GetConfig().Locations[name]
|
||||||
for _, b := range c.Locations {
|
l.name = name
|
||||||
if b.Name == name {
|
return l, ok
|
||||||
return b, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Location{}, false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l Location) validate(c *Config) error {
|
func (l Location) validate(c *Config) error {
|
||||||
if l.Name == "" {
|
|
||||||
return fmt.Errorf(`Location is missing name`)
|
|
||||||
}
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
if len(l.To) == 0 {
|
if len(l.To) == 0 {
|
||||||
return fmt.Errorf(`Location "%s" has no "to" targets`, l.Name)
|
return fmt.Errorf(`Location "%s" has no "to" targets`, l.name)
|
||||||
}
|
}
|
||||||
// Check if backends are all valid
|
// Check if backends are all valid
|
||||||
for _, to := range l.To {
|
for _, to := range l.To {
|
||||||
@ -120,13 +113,13 @@ func (l Location) getPath() (string, error) {
|
|||||||
return path, nil
|
return path, nil
|
||||||
}
|
}
|
||||||
case TypeVolume:
|
case TypeVolume:
|
||||||
return "/volume/" + l.Name + "/" + l.getVolumeName(), nil
|
return "/volume/" + l.name + "/" + l.getVolumeName(), nil
|
||||||
}
|
}
|
||||||
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() error {
|
func (l Location) Backup() 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{
|
||||||
Command: "bash",
|
Command: "bash",
|
||||||
@ -145,7 +138,7 @@ func (l Location) Backup() error {
|
|||||||
// Backup
|
// Backup
|
||||||
for _, to := range l.To {
|
for _, to := range l.To {
|
||||||
backend, _ := GetBackend(to)
|
backend, _ := GetBackend(to)
|
||||||
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
|
return nil
|
||||||
@ -186,7 +179,7 @@ func (l Location) Backup() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l Location) Forget(prune bool, dry bool) error {
|
func (l Location) Forget(prune bool, dry bool) error {
|
||||||
colors.PrimaryPrint("Forgetting for location \"%s\"", l.Name)
|
colors.PrimaryPrint("Forgetting for location \"%s\"", l.name)
|
||||||
|
|
||||||
path, err := l.getPath()
|
path, err := l.getPath()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -195,7 +188,7 @@ func (l Location) Forget(prune bool, dry bool) error {
|
|||||||
|
|
||||||
for _, to := range l.To {
|
for _, to := range l.To {
|
||||||
backend, _ := GetBackend(to)
|
backend, _ := GetBackend(to)
|
||||||
colors.Secondary.Printf("For backend \"%s\"\n", backend.Name)
|
colors.Secondary.Printf("For backend \"%s\"\n", backend.name)
|
||||||
env, err := backend.getEnv()
|
env, err := backend.getEnv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
@ -244,7 +237,7 @@ func (l Location) Restore(to, from string, force bool) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
colors.PrimaryPrint("Restoring location \"%s\"", l.Name)
|
colors.PrimaryPrint("Restoring location \"%s\"", l.name)
|
||||||
|
|
||||||
backend, _ := GetBackend(from)
|
backend, _ := GetBackend(from)
|
||||||
path, err := l.getPath()
|
path, err := l.getPath()
|
||||||
@ -293,14 +286,14 @@ func (l Location) RunCron() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
last := time.Unix(lock.GetCron(l.Name), 0)
|
last := time.Unix(lock.GetCron(l.name), 0)
|
||||||
next := schedule.Next(last)
|
next := schedule.Next(last)
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
if now.After(next) {
|
if now.After(next) {
|
||||||
lock.SetCron(l.Name, now.Unix())
|
lock.SetCron(l.name, now.Unix())
|
||||||
l.Backup()
|
l.Backup()
|
||||||
} else {
|
} else {
|
||||||
colors.Body.Printf("Skipping \"%s\", not due yet.\n", l.Name)
|
colors.Body.Printf("Skipping \"%s\", not due yet.\n", l.name)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user