mirror of
https://github.com/rancher/os.git
synced 2025-09-13 05:33:34 +00:00
Reshuffle cloud-config
Read files cloud-config.d in alphanumeric order, then cloud-config.yml `ros config` writes to cloud-config.yml (and cloud-config.d/private.yml - only private keys) Add (c *CloudConfig) Save() method, use it to save the changed config Read and apply metadata as part of LoadConfig() Simplify ros config export logic
This commit is contained in:
226
config/config.go
226
config/config.go
@@ -1,212 +1,116 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/docker/libcompose/project"
|
||||
"github.com/rancherio/os/util"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
func (c *CloudConfig) Import(bytes []byte) error {
|
||||
data, err := readConfig(bytes, PrivateConfigFile)
|
||||
func (c *CloudConfig) Import(bytes []byte) (*CloudConfig, error) {
|
||||
data, err := readConfig(bytes, false, CloudConfigPrivateFile)
|
||||
if err != nil {
|
||||
return err
|
||||
return c, err
|
||||
}
|
||||
|
||||
if err := saveToDisk(data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Reload()
|
||||
}
|
||||
|
||||
// This function only sets "non-empty" values
|
||||
func (c *CloudConfig) SetConfig(newConfig *CloudConfig) error {
|
||||
bytes, err := yaml.Marshal(newConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Merge(bytes)
|
||||
}
|
||||
|
||||
func (c *CloudConfig) Merge(bytes []byte) error {
|
||||
data, err := readConfig(bytes, LocalConfigFile, PrivateConfigFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := saveToDisk(data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Reload()
|
||||
}
|
||||
|
||||
func LoadConfig() (*CloudConfig, error) {
|
||||
cfg := NewConfig()
|
||||
if err := cfg.Reload(); err != nil {
|
||||
log.WithFields(log.Fields{"cfg": cfg, "err": err}).Error("Failed to reload config")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cfg.Rancher.Debug {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
if !util.Contains(cfg.Rancher.Docker.Args, "-D") {
|
||||
cfg.Rancher.Docker.Args = append(cfg.Rancher.Docker.Args, "-D")
|
||||
}
|
||||
if !util.Contains(cfg.Rancher.SystemDocker.Args, "-D") {
|
||||
cfg.Rancher.SystemDocker.Args = append(cfg.Rancher.SystemDocker.Args, "-D")
|
||||
}
|
||||
if err := util.Convert(data, cfg); err != nil {
|
||||
return c, err
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func (c *CloudConfig) merge(values map[interface{}]interface{}) error {
|
||||
t := &CloudConfig{}
|
||||
if err := util.Convert(values, t); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.Convert(values, c)
|
||||
}
|
||||
|
||||
func (c *CloudConfig) readFiles() error {
|
||||
data, err := readConfig(nil, CloudConfigFile, LocalConfigFile, PrivateConfigFile)
|
||||
func (c *CloudConfig) MergeBytes(bytes []byte) (*CloudConfig, error) {
|
||||
data, err := readConfig(bytes, false)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{"err": err}).Error("Error reading config files")
|
||||
return err
|
||||
return c, err
|
||||
}
|
||||
|
||||
if err := c.merge(data); err != nil {
|
||||
log.WithFields(log.Fields{"cfg": c, "data": data, "err": err}).Error("Error merging config data")
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return c.Merge(data)
|
||||
}
|
||||
|
||||
func (c *CloudConfig) readCmdline() error {
|
||||
log.Debug("Reading config cmdline")
|
||||
cmdLine, err := ioutil.ReadFile("/proc/cmdline")
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{"err": err}).Error("Failed to read kernel params")
|
||||
return err
|
||||
func (c *CloudConfig) Merge(values map[interface{}]interface{}) (*CloudConfig, error) {
|
||||
t := *c
|
||||
if err := util.Convert(values, &t); err != nil {
|
||||
return c, err
|
||||
}
|
||||
|
||||
if len(cmdLine) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Debugf("Config cmdline %s", cmdLine)
|
||||
|
||||
cmdLineObj := parseCmdline(strings.TrimSpace(string(cmdLine)))
|
||||
|
||||
if err := c.merge(cmdLineObj); err != nil {
|
||||
log.WithFields(log.Fields{"cfg": c, "cmdLine": cmdLine, "data": cmdLineObj, "err": err}).Warn("Error adding kernel params to config")
|
||||
}
|
||||
return nil
|
||||
return &t, nil
|
||||
}
|
||||
|
||||
func Dump(private, full bool) (string, error) {
|
||||
files := []string{CloudConfigFile, LocalConfigFile}
|
||||
if private {
|
||||
files = append(files, PrivateConfigFile)
|
||||
}
|
||||
|
||||
c := &CloudConfig{}
|
||||
func Dump(boot, private, full bool) (string, error) {
|
||||
var cfg *CloudConfig
|
||||
var err error
|
||||
|
||||
if full {
|
||||
c = NewConfig()
|
||||
cfg, err = LoadConfig()
|
||||
} else {
|
||||
files := []string{CloudConfigBootFile, CloudConfigPrivateFile, CloudConfigFile}
|
||||
if !private {
|
||||
files = util.FilterStrings(files, func(x string) bool { return x != CloudConfigPrivateFile })
|
||||
}
|
||||
if !boot {
|
||||
files = util.FilterStrings(files, func(x string) bool { return x != CloudConfigBootFile })
|
||||
}
|
||||
cfg, err = ChainCfgFuncs(nil,
|
||||
func(_ *CloudConfig) (*CloudConfig, error) { return ReadConfig(nil, true, files...) },
|
||||
amendNils,
|
||||
)
|
||||
}
|
||||
|
||||
data, err := readConfig(nil, files...)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := c.merge(data); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := c.readCmdline(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
c.amendNils()
|
||||
|
||||
bytes, err := yaml.Marshal(c)
|
||||
bytes, err := yaml.Marshal(*cfg)
|
||||
return string(bytes), err
|
||||
}
|
||||
|
||||
func (c *CloudConfig) amendNils() error {
|
||||
if c.Rancher.Environment == nil {
|
||||
c.Rancher.Environment = map[string]string{}
|
||||
}
|
||||
if c.Rancher.Autoformat == nil {
|
||||
c.Rancher.Autoformat = map[string]*project.ServiceConfig{}
|
||||
}
|
||||
if c.Rancher.BootstrapContainers == nil {
|
||||
c.Rancher.BootstrapContainers = map[string]*project.ServiceConfig{}
|
||||
}
|
||||
if c.Rancher.Services == nil {
|
||||
c.Rancher.Services = map[string]*project.ServiceConfig{}
|
||||
}
|
||||
if c.Rancher.ServicesInclude == nil {
|
||||
c.Rancher.ServicesInclude = map[string]bool{}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CloudConfig) Reload() error {
|
||||
return util.ShortCircuit(
|
||||
c.readFiles,
|
||||
c.readCmdline,
|
||||
c.amendNils,
|
||||
)
|
||||
}
|
||||
|
||||
func (c *CloudConfig) Get(key string) (interface{}, error) {
|
||||
data := make(map[interface{}]interface{})
|
||||
err := util.Convert(c, &data)
|
||||
if err != nil {
|
||||
data := map[interface{}]interface{}{}
|
||||
if err := util.Convert(c, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return getOrSetVal(key, data, nil), nil
|
||||
v, _ := getOrSetVal(key, data, nil)
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (c *CloudConfig) Set(key string, value interface{}) error {
|
||||
data, err := readConfig(nil, LocalConfigFile, PrivateConfigFile)
|
||||
func (c *CloudConfig) Set(key string, value interface{}) (*CloudConfig, error) {
|
||||
data := map[interface{}]interface{}{}
|
||||
if err := util.Convert(c, &data); err != nil {
|
||||
return c, err
|
||||
}
|
||||
|
||||
_, data = getOrSetVal(key, data, value)
|
||||
|
||||
return c.Merge(data)
|
||||
}
|
||||
|
||||
func (c *CloudConfig) Save() error {
|
||||
files := append([]string{OsConfigFile}, CloudConfigDirFiles()...)
|
||||
files = util.FilterStrings(files, func(x string) bool { return x != CloudConfigPrivateFile })
|
||||
exCfg, err := ChainCfgFuncs(nil,
|
||||
func(_ *CloudConfig) (*CloudConfig, error) {
|
||||
return ReadConfig(nil, true, files...)
|
||||
},
|
||||
readCmdline,
|
||||
amendNils)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
getOrSetVal(key, data, value)
|
||||
|
||||
cfg := NewConfig()
|
||||
|
||||
if err := util.Convert(data, cfg); err != nil {
|
||||
exData := map[interface{}]interface{}{}
|
||||
if err := util.Convert(exCfg, &exData); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data := map[interface{}]interface{}{}
|
||||
if err := util.Convert(c, &data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data = util.MapsDifference(data, exData)
|
||||
log.WithFields(log.Fields{"diff": data}).Debug("The diff we're about to save")
|
||||
if err := saveToDisk(data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Reload()
|
||||
}
|
||||
|
||||
func (r Repositories) ToArray() []string {
|
||||
result := make([]string, 0, len(r))
|
||||
for _, repo := range r {
|
||||
if repo.Url != "" {
|
||||
result = append(result, repo.Url)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user