forked from canonical/lxd
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.go
More file actions
131 lines (110 loc) · 3.45 KB
/
Copy pathconfig.go
File metadata and controls
131 lines (110 loc) · 3.45 KB
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
131
package lxd
import (
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"strings"
"gopkg.in/yaml.v2"
"github.com/lxc/lxd/shared"
)
// Config holds settings to be used by a client or daemon.
type Config struct {
// DefaultRemote holds the remote daemon name from the Remotes map
// that the client should communicate with by default.
// If empty it defaults to "local".
DefaultRemote string `yaml:"default-remote"`
// Remotes defines a map of remote daemon names to the details for
// communication with the named daemon.
// The implicit "local" remote is always available and communicates
// with the local daemon over a unix socket.
Remotes map[string]RemoteConfig `yaml:"remotes"`
// Command line aliases for `lxc`
Aliases map[string]string `yaml:"aliases"`
// This is the path to the config directory, so the client can find
// previously stored server certs, give good error messages, and save
// new server certs, etc.
//
// We don't need to store it, because of course once we've loaded this
// structure we already know where it is :)
ConfigDir string `yaml:"-"`
}
// RemoteConfig holds details for communication with a remote daemon.
type RemoteConfig struct {
Addr string `yaml:"addr"`
Public bool `yaml:"public"`
}
var LocalRemote = RemoteConfig{
Addr: "unix://",
Public: false}
var defaultRemote = map[string]RemoteConfig{"local": LocalRemote}
var DefaultConfig = Config{
Remotes: defaultRemote,
DefaultRemote: "local",
Aliases: map[string]string{},
}
// LoadConfig reads the configuration from the config path; if the path does
// not exist, it returns a default configuration.
func LoadConfig(path string) (*Config, error) {
data, err := ioutil.ReadFile(path)
if os.IsNotExist(err) {
// A missing file is equivalent to the default configuration.
withPath := DefaultConfig
withPath.ConfigDir = filepath.Dir(path)
return &withPath, nil
}
if err != nil {
return nil, fmt.Errorf("cannot read config file: %v", err)
}
var c Config
err = yaml.Unmarshal(data, &c)
if err != nil {
return nil, fmt.Errorf("cannot parse configuration: %v", err)
}
if c.Remotes == nil {
c.Remotes = make(map[string]RemoteConfig)
}
c.ConfigDir = filepath.Dir(path)
return &c, nil
}
// SaveConfig writes the provided configuration to the config file.
func SaveConfig(c *Config, fname string) error {
// Ignore errors on these two calls. Create will report any problems.
os.Remove(fname + ".new")
os.Mkdir(filepath.Dir(fname), 0700)
f, err := os.Create(fname + ".new")
if err != nil {
return fmt.Errorf("cannot create config file: %v", err)
}
// If there are any errors, do not leave it around.
defer f.Close()
defer os.Remove(fname + ".new")
data, err := yaml.Marshal(c)
_, err = f.Write(data)
if err != nil {
return fmt.Errorf("cannot write configuration: %v", err)
}
f.Close()
err = shared.FileMove(fname+".new", fname)
if err != nil {
return fmt.Errorf("cannot rename temporary config file: %v", err)
}
return nil
}
func (c *Config) ParseRemoteAndContainer(raw string) (string, string) {
result := strings.SplitN(raw, ":", 2)
if len(result) == 1 {
return c.DefaultRemote, result[0]
}
return result[0], result[1]
}
func (c *Config) ParseRemote(raw string) string {
return strings.SplitN(raw, ":", 2)[0]
}
func (c *Config) ConfigPath(file string) string {
return path.Join(c.ConfigDir, file)
}
func (c *Config) ServerCertPath(name string) string {
return path.Join(c.ConfigDir, "servercerts", fmt.Sprintf("%s.crt", name))
}