1
0
mirror of https://github.com/rancher/os.git synced 2025-09-04 08:14:21 +00:00

Refactor configuration structure

This commit is contained in:
Darren Shepherd
2015-02-14 09:29:07 -07:00
parent e38e790374
commit bcf66e4c93
2 changed files with 116 additions and 51 deletions

View File

@@ -3,24 +3,29 @@ package config
import ( import (
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"os"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
"github.com/rancherio/os/util"
) )
type InitFunc func(*Config) error type InitFunc func(*Config) error
type ContainerConfig struct { type ContainerConfig struct {
Options []string `json:"options,omitempty"` Id string `json:"id,omitempty"`
Image string `json:"image,omitempty"` Cmd []string `json:"run,omitempty"`
Args []string `json:"args,omitempty"` //Config *runconfig.Config `json:"-"`
//HostConfig *runconfig.HostConfig `json:"-"`
} }
type Config struct { type Config struct {
BootstrapContainers []ContainerConfig `json:"bootstrapContainers,omitempty"` //BootstrapContainers []ContainerConfig `json:"bootstrapContainers,omitempty"`
ConsoleContainer string `json:"consoleContainer,omitempty"`
Debug bool `json:"debug,omitempty"` Debug bool `json:"debug,omitempty"`
Disable []string `json:"disable,omitempty"`
DockerEndpoint string `json:"dockerEndpoint,omitempty"` DockerEndpoint string `json:"dockerEndpoint,omitempty"`
Dns []string `json:"dns,omitempty"` Dns []string `json:"dns,omitempty"`
ImagesPath string `json:"ImagesPath,omitempty"` ImagesPath string `json:"ImagesPath,omitempty"`
@@ -41,6 +46,15 @@ type Config struct {
Respawn []string `json:"respawn,omitempty"` Respawn []string `json:"respawn,omitempty"`
} }
func (c *Config) Dump() string {
content, err := json.MarshalIndent(c, "", " ")
if err == nil {
return string(content)
} else {
return err.Error()
}
}
func LoadConfig() (*Config, error) { func LoadConfig() (*Config, error) {
cfg := NewConfig() cfg := NewConfig()
if err := cfg.Reload(); err != nil { if err := cfg.Reload(); err != nil {
@@ -56,6 +70,7 @@ func LoadConfig() (*Config, error) {
func NewConfig() *Config { func NewConfig() *Config {
return &Config{ return &Config{
ConsoleContainer: "console",
DockerBin: "/usr/bin/docker", DockerBin: "/usr/bin/docker",
Debug: true, Debug: true,
DockerEndpoint: "unix:/var/run/docker.sock", DockerEndpoint: "unix:/var/run/docker.sock",
@@ -75,33 +90,36 @@ func NewConfig() *Config {
ModulesArchive: "/modules.tar", ModulesArchive: "/modules.tar",
SystemContainers: []ContainerConfig{ SystemContainers: []ContainerConfig{
{ {
Options: []string{ Cmd: []string{
"--name", "system-state", "--name", "system-state",
"--net", "none", "--net", "none",
"--read-only", "--read-only",
"state",
}, },
Image: "state",
}, },
{ {
Options: []string{ Cmd: []string{
"--name", "udev",
"--net", "none", "--net", "none",
"--privileged", "--privileged",
"--rm", "--rm",
"--volume", "/dev:/host/dev", "--volume", "/dev:/host/dev",
"--volume", "/lib/modules:/lib/modules:ro", "--volume", "/lib/modules:/lib/modules:ro",
"udev",
}, },
Image: "udev",
}, },
{ {
Options: []string{ Cmd: []string{
"--name", "network",
"--cap-add", "NET_ADMIN", "--cap-add", "NET_ADMIN",
"--net", "host", "--net", "host",
"--rm", "--rm",
"network",
}, },
Image: "network",
}, },
{ {
Options: []string{ Cmd: []string{
"--name", "userdocker",
"-d", "-d",
"--restart", "always", "--restart", "always",
"--net", "host", "--net", "host",
@@ -109,28 +127,32 @@ func NewConfig() *Config {
"--volume", "/lib/modules:/lib/modules:ro", "--volume", "/lib/modules:/lib/modules:ro",
"--volume", "/usr/bin/docker:/usr/bin/docker:ro", "--volume", "/usr/bin/docker:/usr/bin/docker:ro",
"--volumes-from", "system-state", "--volumes-from", "system-state",
"userdocker",
}, },
Image: "userdocker",
}, },
{ {
Options: []string{ Cmd: []string{
"--name", "console",
"-d",
"--rm", "--rm",
"--privileged", "--privileged",
"--volume", "/:/host:ro", "--volume", "/:/host:ro",
"--volume", "/lib/modules:/lib/modules:ro", "--volume", "/lib/modules:/lib/modules:ro",
"--volume", "/usr/bin/docker:/usr/bin/docker:ro", "--volume", "/usr/bin/docker:/usr/bin/docker:ro",
"--volume", "/usr/bin/system-docker:/usr/bin/system-docker:ro", "--volume", "/usr/bin/system-docker:/usr/bin/system-docker:ro",
"--volume", "/init:/usr/bin/respawn:ro",
"--volume", "/var/run/docker.sock:/var/run/system-docker.sock:ro", "--volume", "/var/run/docker.sock:/var/run/system-docker.sock:ro",
"--volumes-from", "system-state", "--volumes-from", "system-state",
"--net", "host", "--net", "host",
"--pid", "host", "--pid", "host",
"-it", "-it",
"console",
}, },
Image: "console",
}, },
}, },
RescueContainer: ContainerConfig{ RescueContainer: ContainerConfig{
Options: []string{ Cmd: []string{
"--name", "rescue",
"--rm", "--rm",
"--privileged", "--privileged",
"--volume", "/:/host", "--volume", "/:/host",
@@ -140,26 +162,50 @@ func NewConfig() *Config {
"--net", "host", "--net", "host",
"--pid", "host", "--pid", "host",
"-it", "-it",
"rescue",
}, },
Image: "rescue",
}, },
} }
} }
func (c *Config) readArgs() error {
log.Debug("Reading config args")
cmdLine := strings.Join(os.Args[1:], " ")
if len(cmdLine) == 0 {
return nil
}
log.Debugf("Config Args %s", cmdLine)
cmdLineObj := parseCmdline(strings.TrimSpace(cmdLine))
return c.merge(cmdLineObj)
}
func (c *Config) merge(values map[string]interface{}) error {
// Lazy way to assign values to *Config
override, err := json.Marshal(values)
if err != nil {
return err
}
return json.Unmarshal(override, c)
}
func (c *Config) readCmdline() error { func (c *Config) readCmdline() error {
log.Debug("Reading config cmdline")
cmdLine, err := ioutil.ReadFile("/proc/cmdline") cmdLine, err := ioutil.ReadFile("/proc/cmdline")
if err != nil { if err != nil {
return err return err
} }
cmdLineObj := parseCmdline(strings.TrimSpace(string(cmdLine))) if len(cmdLine) == 0 {
return nil
// Lazy way to assign values to *Config
b, err := json.Marshal(cmdLineObj)
if err != nil {
return err
} }
return json.Unmarshal(b, c)
log.Debugf("Config cmdline %s", cmdLine)
cmdLineObj := parseCmdline(strings.TrimSpace(string(cmdLine)))
return c.merge(cmdLineObj)
} }
func dummyMarshall(value string) interface{} { func dummyMarshall(value string) interface{} {
@@ -200,7 +246,11 @@ outer:
keys := strings.Split(kv[0], ".")[1:] keys := strings.Split(kv[0], ".")[1:]
for i, key := range keys { for i, key := range keys {
if i == len(keys)-1 { if i == len(keys)-1 {
if strings.HasPrefix(value, "[") && strings.HasSuffix(value, "]") {
current[key] = strings.Split(value[1:len(value)-1], ",")
} else {
current[key] = dummyMarshall(value) current[key] = dummyMarshall(value)
}
} else { } else {
if obj, ok := current[key]; ok { if obj, ok := current[key]; ok {
if newCurrent, ok := obj.(map[string]interface{}); ok { if newCurrent, ok := obj.(map[string]interface{}); ok {
@@ -217,11 +267,25 @@ outer:
} }
} }
log.Debugf("Input obj %s", result)
return result return result
} }
func (c *Config) Reload() error { func (c *Config) Reload() error {
return c.readCmdline() return util.ShortCircuit(
c.readCmdline,
c.readArgs,
)
}
func (c *Config) GetContainerById(id string) *ContainerConfig {
for _, c := range c.SystemContainers {
if c.Id == id {
return &c
}
}
return nil
} }
func RunInitFuncs(cfg *Config, initFuncs []InitFunc) error { func RunInitFuncs(cfg *Config, initFuncs []InitFunc) error {

View File

@@ -11,6 +11,7 @@ func TestParseCmdline(t *testing.T) {
"rescue": true, "rescue": true,
"key1": "value1", "key1": "value1",
"key2": "value2", "key2": "value2",
"keyArray": []string{"1", "2"},
"obj1": map[string]interface{}{ "obj1": map[string]interface{}{
"key3": "3value", "key3": "3value",
"obj2": map[string]interface{}{ "obj2": map[string]interface{}{
@@ -20,7 +21,7 @@ func TestParseCmdline(t *testing.T) {
"key5": 5, "key5": 5,
} }
actual := parseCmdline("a b rancher.rescue rancher.key1=value1 c rancher.key2=value2 rancher.obj1.key3=3value rancher.obj1.obj2.key4 rancher.key5=5") actual := parseCmdline("a b rancher.rescue rancher.keyArray=[1,2] rancher.key1=value1 c rancher.key2=value2 rancher.obj1.key3=3value rancher.obj1.obj2.key4 rancher.key5=5")
ok, err := deepdiff.DeepDiff(actual, expected) ok, err := deepdiff.DeepDiff(actual, expected)
if !ok || err != nil { if !ok || err != nil {