1
0
mirror of https://github.com/rancher/os.git synced 2025-06-26 15:01:34 +00:00
os/config/config.go

274 lines
4.9 KiB
Go
Raw Normal View History

2015-02-09 04:38:37 +00:00
package config
import (
"io/ioutil"
2015-02-14 16:29:07 +00:00
"os"
2015-02-09 04:38:37 +00:00
"strings"
log "github.com/Sirupsen/logrus"
2015-02-14 16:29:07 +00:00
"github.com/rancherio/os/util"
2015-02-17 21:31:20 +00:00
"gopkg.in/yaml.v2"
2015-02-09 04:38:37 +00:00
)
2015-03-15 04:27:04 +00:00
func (c *Config) privilegedMerge(newConfig Config) error {
err := c.overlay(newConfig)
if err != nil {
2015-03-15 04:27:04 +00:00
return err
}
toAppend := make([]ContainerConfig, 0, 5)
for _, newContainer := range newConfig.SystemContainers {
found := false
for i, existingContainer := range c.SystemContainers {
if existingContainer.Id != "" && newContainer.Id == existingContainer.Id {
found = true
c.SystemContainers[i] = newContainer
}
}
if !found {
toAppend = append(toAppend, newContainer)
}
}
c.SystemContainers = append(c.SystemContainers, toAppend...)
2015-03-15 04:27:04 +00:00
return nil
}
2015-03-15 04:27:04 +00:00
func (c *Config) overlay(newConfig Config) error {
newConfig.clearReadOnly()
return util.Convert(&newConfig, c)
}
func (c *Config) clearReadOnly() {
c.BootstrapContainers = make([]ContainerConfig, 0)
c.SystemContainers = make([]ContainerConfig, 0)
}
func clearReadOnly(data map[interface{}]interface{}) map[interface{}]interface{} {
newData := make(map[interface{}]interface{})
for k, v := range data {
newData[k] = v
2015-02-18 00:00:30 +00:00
}
2015-03-15 04:27:04 +00:00
delete(newData, "system_container")
delete(newData, "bootstrap_container")
2015-02-20 03:05:43 +00:00
2015-03-15 04:27:04 +00:00
return newData
2015-02-18 00:00:30 +00:00
}
2015-03-15 04:27:04 +00:00
func (c *Config) Import(bytes []byte) error {
data, err := readConfig(bytes, PrivateConfigFile)
if err != nil {
return err
}
if err = saveToDisk(data); err != nil {
return err
}
return c.Reload()
2015-02-17 21:31:20 +00:00
}
2015-03-18 12:38:36 +00:00
// This function only sets "non-empty" values
func (c *Config) SetConfig(newConfig *Config) error {
bytes, err := yaml.Marshal(newConfig)
if err != nil {
return err
}
return c.Merge(bytes)
}
2015-03-15 04:27:04 +00:00
func (c *Config) Merge(bytes []byte) error {
data, err := readSavedConfig(bytes)
2015-02-17 21:31:20 +00:00
if err != nil {
2015-03-15 04:27:04 +00:00
return err
2015-02-14 16:29:07 +00:00
}
2015-02-09 04:38:37 +00:00
2015-03-15 04:27:04 +00:00
err = saveToDisk(data)
2015-02-18 00:00:30 +00:00
if err != nil {
return err
}
2015-03-15 04:27:04 +00:00
return c.Reload()
2015-02-18 00:00:30 +00:00
}
2015-02-09 04:38:37 +00:00
func LoadConfig() (*Config, error) {
cfg := NewConfig()
if err := cfg.Reload(); err != nil {
return nil, err
}
if cfg.Debug {
log.SetLevel(log.DebugLevel)
}
return cfg, nil
}
2015-02-14 16:29:07 +00:00
func (c *Config) readArgs() error {
log.Debug("Reading config args")
2015-02-20 03:05:43 +00:00
parts := make([]string, len(os.Args))
for _, arg := range os.Args[1:] {
if strings.HasPrefix(arg, "--") {
arg = arg[2:]
}
2015-02-23 19:00:24 +00:00
kv := strings.SplitN(arg, "=", 2)
kv[0] = strings.Replace(kv[0], "-", ".", -1)
parts = append(parts, strings.Join(kv, "="))
2015-02-20 03:05:43 +00:00
}
cmdLine := strings.Join(parts, " ")
2015-02-14 16:29:07 +00:00
if len(cmdLine) == 0 {
return nil
2015-02-09 04:38:37 +00:00
}
2015-02-14 16:29:07 +00:00
log.Debugf("Config Args %s", cmdLine)
cmdLineObj := parseCmdline(strings.TrimSpace(cmdLine))
return c.merge(cmdLineObj)
}
2015-02-09 04:38:37 +00:00
2015-03-15 04:27:04 +00:00
func (c *Config) merge(values map[interface{}]interface{}) error {
values = clearReadOnly(values)
return util.Convert(values, c)
2015-02-14 16:29:07 +00:00
}
2015-03-15 04:27:04 +00:00
func (c *Config) readFiles() error {
data, err := readSavedConfig(nil)
2015-02-18 00:00:30 +00:00
if err != nil {
return err
}
return c.merge(data)
}
2015-02-14 16:29:07 +00:00
func (c *Config) readCmdline() error {
log.Debug("Reading config cmdline")
cmdLine, err := ioutil.ReadFile("/proc/cmdline")
2015-02-09 04:38:37 +00:00
if err != nil {
return err
}
2015-02-14 16:29:07 +00:00
if len(cmdLine) == 0 {
return nil
}
log.Debugf("Config cmdline %s", cmdLine)
cmdLineObj := parseCmdline(strings.TrimSpace(string(cmdLine)))
return c.merge(cmdLineObj)
2015-02-09 04:38:37 +00:00
}
2015-03-15 04:27:04 +00:00
func Dump(private, full bool) (string, error) {
2015-03-18 12:38:36 +00:00
files := []string{CloudConfigFile, ConfigFile}
2015-03-15 04:27:04 +00:00
if private {
files = append(files, PrivateConfigFile)
2015-02-09 04:38:37 +00:00
}
2015-03-18 12:38:36 +00:00
c := &Config{}
2015-02-09 04:38:37 +00:00
2015-03-15 04:27:04 +00:00
if full {
2015-03-18 12:38:36 +00:00
c = NewConfig()
2015-03-15 04:27:04 +00:00
}
2015-02-09 04:38:37 +00:00
2015-03-15 04:27:04 +00:00
data, err := readConfig(nil, files...)
if err != nil {
return "", err
}
2015-02-09 04:38:37 +00:00
2015-03-15 04:27:04 +00:00
err = c.merge(data)
if err != nil {
return "", err
}
2015-02-09 04:38:37 +00:00
2015-03-15 04:27:04 +00:00
err = c.readGlobals()
if err != nil {
return "", err
2015-02-09 04:38:37 +00:00
}
2015-03-15 04:27:04 +00:00
bytes, err := yaml.Marshal(c)
return string(bytes), err
2015-02-09 04:38:37 +00:00
}
2015-03-18 12:38:36 +00:00
func (c *Config) configureConsole() error {
if !c.Console.Persistent {
return nil
}
for i := range c.SystemContainers {
// Need to modify original object, not the copy
var container *ContainerConfig = &c.SystemContainers[i]
if container.Id != CONSOLE_CONTAINER {
continue
}
if strings.Contains(container.Cmd, "--rm ") {
container.Cmd = strings.Replace(container.Cmd, "--rm ", "", 1)
}
}
return nil
}
2015-03-15 04:27:04 +00:00
func (c *Config) readGlobals() error {
2015-02-14 16:29:07 +00:00
return util.ShortCircuit(
c.readCmdline,
c.readArgs,
c.mergeAddons,
2015-03-18 12:38:36 +00:00
c.configureConsole,
2015-02-14 16:29:07 +00:00
)
}
2015-03-15 04:27:04 +00:00
func (c *Config) Reload() error {
return util.ShortCircuit(
c.readFiles,
c.readGlobals,
)
}
func (c *Config) mergeAddons() error {
for _, addon := range c.EnabledAddons {
if newConfig, ok := c.Addons[addon]; ok {
log.Debugf("Enabling addon %s", addon)
2015-03-15 04:27:04 +00:00
if err := c.privilegedMerge(newConfig); err != nil {
return err
}
2015-02-14 16:29:07 +00:00
}
}
return nil
2015-02-09 04:38:37 +00:00
}
2015-03-15 04:27:04 +00:00
func (c *Config) Get(key string) (interface{}, error) {
data := make(map[interface{}]interface{})
err := util.Convert(c, &data)
if err != nil {
return nil, err
2015-02-09 04:38:37 +00:00
}
2015-03-15 04:27:04 +00:00
return getOrSetVal(key, data, nil), nil
}
func (c *Config) Set(key string, value interface{}) error {
data, err := readSavedConfig(nil)
if err != nil {
return err
}
getOrSetVal(key, data, value)
err = saveToDisk(data)
if err != nil {
return err
}
return c.Reload()
2015-02-09 04:38:37 +00:00
}