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:
158
config/config.go
158
config/config.go
@@ -3,42 +3,56 @@ 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"`
|
||||||
Debug bool `json:"debug,omitempty"`
|
ConsoleContainer string `json:"consoleContainer,omitempty"`
|
||||||
DockerEndpoint string `json:"dockerEndpoint,omitempty"`
|
Debug bool `json:"debug,omitempty"`
|
||||||
Dns []string `json:"dns,omitempty"`
|
Disable []string `json:"disable,omitempty"`
|
||||||
ImagesPath string `json:"ImagesPath,omitempty"`
|
DockerEndpoint string `json:"dockerEndpoint,omitempty"`
|
||||||
ImagesPattern string `json:"ImagesPattern,omitempty"`
|
Dns []string `json:"dns,omitempty"`
|
||||||
ModulesArchive string `json:"modulesArchive,omitempty"`
|
ImagesPath string `json:"ImagesPath,omitempty"`
|
||||||
Rescue bool `json:"rescue,omitempty"`
|
ImagesPattern string `json:"ImagesPattern,omitempty"`
|
||||||
RescueContainer ContainerConfig `json:"rescueContainer,omitempty"`
|
ModulesArchive string `json:"modulesArchive,omitempty"`
|
||||||
StateDevFSType string `json:"stateDeviceFsType,omitempty"`
|
Rescue bool `json:"rescue,omitempty"`
|
||||||
StateDev string `json:"stateDevice,omitempty"`
|
RescueContainer ContainerConfig `json:"rescueContainer,omitempty"`
|
||||||
StateRequired bool `json:"stateRequired,omitempty"`
|
StateDevFSType string `json:"stateDeviceFsType,omitempty"`
|
||||||
SysInit string `json:"sysInit,omitempty"`
|
StateDev string `json:"stateDevice,omitempty"`
|
||||||
SystemContainers []ContainerConfig `json:"systemContainers,omitempty"`
|
StateRequired bool `json:"stateRequired,omitempty"`
|
||||||
SystemDockerArgs []string `json:"systemDockerArgs,omitempty"`
|
SysInit string `json:"sysInit,omitempty"`
|
||||||
UserContainers []ContainerConfig `json:"userContainser,omitempty"`
|
SystemContainers []ContainerConfig `json:"systemContainers,omitempty"`
|
||||||
UserInit string `json:"userInit,omitempty"`
|
SystemDockerArgs []string `json:"systemDockerArgs,omitempty"`
|
||||||
DockerBin string `json:"dockerBin,omitempty"`
|
UserContainers []ContainerConfig `json:"userContainser,omitempty"`
|
||||||
Modules []string `json:"modules,omitempty"`
|
UserInit string `json:"userInit,omitempty"`
|
||||||
Respawn []string `json:"respawn,omitempty"`
|
DockerBin string `json:"dockerBin,omitempty"`
|
||||||
|
Modules []string `json:"modules,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) {
|
||||||
@@ -56,9 +70,10 @@ func LoadConfig() (*Config, error) {
|
|||||||
|
|
||||||
func NewConfig() *Config {
|
func NewConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
DockerBin: "/usr/bin/docker",
|
ConsoleContainer: "console",
|
||||||
Debug: true,
|
DockerBin: "/usr/bin/docker",
|
||||||
DockerEndpoint: "unix:/var/run/docker.sock",
|
Debug: true,
|
||||||
|
DockerEndpoint: "unix:/var/run/docker.sock",
|
||||||
Dns: []string{
|
Dns: []string{
|
||||||
"8.8.8.8",
|
"8.8.8.8",
|
||||||
"8.8.4.4",
|
"8.8.4.4",
|
||||||
@@ -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 {
|
||||||
current[key] = dummyMarshall(value)
|
if strings.HasPrefix(value, "[") && strings.HasSuffix(value, "]") {
|
||||||
|
current[key] = strings.Split(value[1:len(value)-1], ",")
|
||||||
|
} else {
|
||||||
|
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 {
|
||||||
|
@@ -8,9 +8,10 @@ import (
|
|||||||
|
|
||||||
func TestParseCmdline(t *testing.T) {
|
func TestParseCmdline(t *testing.T) {
|
||||||
expected := map[string]interface{}{
|
expected := map[string]interface{}{
|
||||||
"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 {
|
||||||
|
Reference in New Issue
Block a user