aboutsummaryrefslogtreecommitdiff
path: root/config/config.go
blob: ecc679a10981a8b5a77ba7bd1972115501aab1e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Package config provides methods for configuring the petrific binary.
//
// The configuration file is located in `$XDG_CONFIG_HOME/petrific/config.toml`,
// where `$XDG_CONFIG_HOME` is typically `~/.config`.
//
// The configuration file is a TOML file, its main purpose is to define the used
// storage backends, it also defines which GPG key to use for snapshot signing.
//
// Here is an example configuration file:
//
//    # This config key defines the default storage backend, as defined below ([storage.local_compressed])
//    default_storage = "local_compressed"
//
//    # This defines the location of the cache file (can speed up creating backups; can be left out)
//    cache_path = "~/.cache/petrific.cache"
//
//    [signing]
//    # Use this GPG key to sign snapshots
//    key = "0123456789ABCDEF0123456789ABCDEF01234567"
//
//    # The storage.* sections define storage backends.
//    # Every section must contain the key `method`, the other keys depend on the selected method.
//    # For more details see the documentation for ../storage
//
//    [storage.local]
//    method="local"
//    path="~/.local/share/petrific"
//
//    [storage.local_compressed]
//    method="filter"
//    base="local"
//    encode=["zlib-flate", "-compress"]
//    decode=["zlib-flate", "-uncompress"]
package config

import (
	"code.laria.me/petrific/gpg"
	"errors"
	"fmt"
	"github.com/BurntSushi/toml"
	"github.com/adrg/xdg"
	"os"
	"os/user"
	"strings"
)

type StorageConfigErr struct {
	Name string
	Err  error
}

func (sce StorageConfigErr) Error() string {
	return fmt.Sprintf("Could not get configuration for storage %s: %s", sce.Name, sce.Err.Error())
}

var (
	StorageConfigNotFound = errors.New("Not found")
)

type Config struct {
	CachePath      string `toml:"cache_path,omitempty"`
	DefaultStorage string `toml:"default_storage"`
	Signing        struct {
		Key string
	}
	Storage map[string]toml.Primitive
	meta    toml.MetaData `toml:"-"`
}

func LoadConfig(path string) (config Config, err error) {
	if path == "" {
		path, err = xdg.ConfigFile("petrific/config.toml")
		if err != nil {
			return
		}
	}

	meta, err := toml.DecodeFile(path, &config)
	config.meta = meta
	return config, err
}

func (c Config) GPGSigner() gpg.Signer {
	return gpg.Signer{Key: c.Signing.Key}
}

func (c Config) GetStorageMethod(name string) (string, error) {
	prim, ok := c.Storage[name]
	if !ok {
		return "", StorageConfigErr{name, StorageConfigNotFound}
	}

	var method_wrap struct{ Method string }
	err := c.meta.PrimitiveDecode(prim, &method_wrap)
	if err != nil {
		return "", StorageConfigErr{name, err}
	}

	return method_wrap.Method, nil
}

func (c Config) GetStorageConfData(name string, v interface{}) error {
	prim, ok := c.Storage[name]
	if !ok {
		return StorageConfigErr{name, StorageConfigNotFound}
	}

	return c.meta.PrimitiveDecode(prim, v)
}

func ExpandTilde(path string) string {
	home, ok := os.LookupEnv("HOME")
	if !ok {
		u, err := user.Current()
		if err != nil {
			return path
		}
		home = u.HomeDir
	}

	if home == "" {
		return path
	}

	parts := strings.Split(path, string(os.PathSeparator))
	if len(parts) > 0 && parts[0] == "~" {
		parts[0] = home
	}
	return strings.Join(parts, string(os.PathSeparator))
}