1
0
mirror of https://github.com/rancher/os.git synced 2025-09-01 14:48:55 +00:00

Support reloading config during system containers start up

This commit is contained in:
Darren Shepherd
2015-02-22 20:57:09 -07:00
parent b0046e8e08
commit 3620db959f
4 changed files with 135 additions and 31 deletions

View File

@@ -115,12 +115,8 @@ func loadImages(cfg *config.Config) error {
return nil return nil
} }
func runContainers(cfg *config.Config) error { func runContainersFrom(startFrom string, cfg *config.Config, containerConfigs []config.ContainerConfig) error {
containerConfigs := cfg.SystemContainers foundStart := false
if cfg.Rescue {
log.Debug("Running rescue container")
containerConfigs = []config.ContainerConfig{*cfg.RescueContainer}
}
for i, containerConfig := range containerConfigs { for i, containerConfig := range containerConfigs {
container := docker.NewContainer(config.DOCKER_SYSTEM_HOST, &containerConfig) container := docker.NewContainer(config.DOCKER_SYSTEM_HOST, &containerConfig)
@@ -130,26 +126,50 @@ func runContainers(cfg *config.Config) error {
continue continue
} }
if containerConfig.Id == config.CONSOLE_CONTAINER { //if containerConfig.Id == config.CONSOLE_CONTAINER {
if util.IsRunningInTty() { // if util.IsRunningInTty() {
container.Config.Tty = true // container.Config.Tty = true
container.Config.AttachStdin = true // container.Config.AttachStdin = true
container.Config.AttachStdout = true // container.Config.AttachStdout = true
container.Config.AttachStderr = true // container.Config.AttachStderr = true
// }
//}
if foundStart || startFrom == "" {
log.Infof("Running [%d/%d] %s", i+1, len(containerConfigs), containerConfig.Id)
container.StartAndWait()
if container.Err != nil {
log.Errorf("Failed to run %v: %v", containerConfig.Id, container.Err)
} }
}
log.Infof("Running [%d/%d] %s", i+1, len(containerConfigs), containerConfig.Id) if containerConfig.ReloadConfig {
container.StartAndWait() log.Info("Reloading configuration")
err := cfg.Reload()
if err != nil {
return err
}
if container.Err != nil { return runContainersFrom(containerConfig.Id, cfg, cfg.SystemContainers)
log.Errorf("Failed to run %v: %v", containerConfig.Id, container.Err) }
} else if startFrom == containerConfig.Id {
foundStart = true
} }
} }
return nil return nil
} }
func runContainers(cfg *config.Config) error {
containerConfigs := cfg.SystemContainers
if cfg.Rescue {
log.Debug("Running rescue container")
containerConfigs = []config.ContainerConfig{*cfg.RescueContainer}
}
return runContainersFrom("", cfg, containerConfigs)
}
func launchConsole(cfg *config.Config) error { func launchConsole(cfg *config.Config) error {
if !util.IsRunningInTty() { if !util.IsRunningInTty() {
return nil return nil

View File

@@ -36,6 +36,7 @@ type ContainerConfig struct {
Id string `yaml:"id,omitempty"` Id string `yaml:"id,omitempty"`
Cmd string `yaml:"run,omitempty"` Cmd string `yaml:"run,omitempty"`
MigrateVolumes bool `yaml:"migrate_volumes,omitempty"` MigrateVolumes bool `yaml:"migrate_volumes,omitempty"`
ReloadConfig bool `yaml:"reload_config,omitempty"`
} }
type Config struct { type Config struct {
@@ -52,6 +53,8 @@ type Config struct {
Modules []string `yaml:"modules,omitempty"` Modules []string `yaml:"modules,omitempty"`
CloudInit CloudInit `yaml:"cloud_init"` CloudInit CloudInit `yaml:"cloud_init"`
SshInfo SshInfo `yaml:"ssh"` SshInfo SshInfo `yaml:"ssh"`
EnabledAddons []string `yaml:"enabledAddons,omitempty"`
Addons map[string]Config `yaml:"addons,omitempty"`
} }
type UserDockerInfo struct { type UserDockerInfo struct {
@@ -75,6 +78,32 @@ type CloudInit struct {
Datasources []string `yaml:"datasources"` Datasources []string `yaml:"datasources"`
} }
func (c *Config) PrivilegedMerge(newConfig Config) (bool, error) {
reboot, err := c.Merge(newConfig)
if err != nil {
return reboot, 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...)
return reboot, nil
}
func (c *Config) Merge(newConfig Config) (bool, error) { func (c *Config) Merge(newConfig Config) (bool, error) {
//Efficient? Nope, but computers are fast //Efficient? Nope, but computers are fast
newConfig.ClearReadOnly() newConfig.ClearReadOnly()
@@ -92,6 +121,9 @@ func (c *Config) Merge(newConfig Config) (bool, error) {
func (c *Config) ClearReadOnly() { func (c *Config) ClearReadOnly() {
c.SystemContainers = []ContainerConfig{} c.SystemContainers = []ContainerConfig{}
c.RescueContainer = nil c.RescueContainer = nil
c.Rescue = false
c.Debug = false
c.Addons = map[string]Config{}
} }
func (c *Config) Dump() (string, error) { func (c *Config) Dump() (string, error) {
@@ -157,7 +189,14 @@ func (c *Config) merge(values map[string]interface{}) error {
if err != nil { if err != nil {
return err return err
} }
return yaml.Unmarshal(override, c) var newConfig Config
err = yaml.Unmarshal(override, &newConfig)
if err != nil {
return nil
}
_, err = c.Merge(newConfig)
return err
} }
func (c *Config) readFile() error { func (c *Config) readFile() error {
@@ -262,13 +301,18 @@ func (c *Config) Reload() error {
c.readFile, c.readFile,
c.readCmdline, c.readCmdline,
c.readArgs, c.readArgs,
c.mergeAddons,
) )
} }
func (c *Config) GetContainerById(id string) *ContainerConfig { func (c *Config) mergeAddons() error {
for _, c := range c.SystemContainers { for _, addon := range c.EnabledAddons {
if c.Id == id { if newConfig, ok := c.Addons[addon]; ok {
return &c log.Debugf("Enabling addon %s", addon)
_, err := c.PrivilegedMerge(newConfig)
if err != nil {
return err
}
} }
} }

View File

@@ -19,15 +19,18 @@ func NewConfig() *Config {
}, },
SystemContainers: []ContainerConfig{ SystemContainers: []ContainerConfig{
{ {
Id: "system-volumes",
Cmd: "--name=system-volumes " + Cmd: "--name=system-volumes " +
"--net=none " + "--net=none " +
"--read-only " + "--read-only " +
"-v=/var/lib/rancher/conf:/var/lib/rancher/conf " + "-v=/var/lib/rancher/conf:/var/lib/rancher/conf " +
"-v=/lib/modules:/lib/modules:ro " + "-v=/lib/modules:/lib/modules:ro " +
"-v=/var/run:/var/run " + "-v=/var/run:/var/run " +
"-v=/var/log:/var/log " +
"state", "state",
}, },
{ {
Id: "command-volumes",
Cmd: "--name=command-volumes " + Cmd: "--name=command-volumes " +
"--net=none " + "--net=none " +
"--read-only " + "--read-only " +
@@ -44,6 +47,7 @@ func NewConfig() *Config {
"state", "state",
}, },
{ {
Id: "user-volumes",
Cmd: "--name=user-volumes " + Cmd: "--name=user-volumes " +
"--net=none " + "--net=none " +
"--read-only " + "--read-only " +
@@ -52,6 +56,7 @@ func NewConfig() *Config {
"state", "state",
}, },
{ {
Id: "udev",
Cmd: "--name=udev " + Cmd: "--name=udev " +
"--net=none " + "--net=none " +
"--privileged " + "--privileged " +
@@ -61,13 +66,16 @@ func NewConfig() *Config {
"udev", "udev",
}, },
{ {
Id: "cloud-init",
Cmd: "--name=cloud-init " + Cmd: "--name=cloud-init " +
"--rm " + "--rm " +
"--net=host " + "--net=host " +
"--volumes-from=command-volumes " + "--volumes-from=command-volumes " +
"cloudinit", "cloudinit",
ReloadConfig: true,
}, },
{ {
Id: "network",
Cmd: "--name=network " + Cmd: "--name=network " +
"--cap-add=NET_ADMIN " + "--cap-add=NET_ADMIN " +
"--net=host " + "--net=host " +
@@ -75,6 +83,7 @@ func NewConfig() *Config {
"network", "network",
}, },
{ {
Id: "ntp",
Cmd: "--name=ntp " + Cmd: "--name=ntp " +
"--rm " + "--rm " +
"-d " + "-d " +
@@ -83,14 +92,19 @@ func NewConfig() *Config {
"ntp", "ntp",
}, },
{ {
Id: "syslog",
Cmd: "--name=syslog " + Cmd: "--name=syslog " +
"-d " + "-d " +
"--rm " + "--rm " +
"--privileged " + "--privileged " +
"--net=host " + "--net=host " +
"--ipc=host " +
"--pid=host " +
"--volumes-from=system-volumes " +
"syslog", "syslog",
}, },
{ {
Id: "userdocker",
Cmd: "--name=userdocker " + Cmd: "--name=userdocker " +
"-d " + "-d " +
"--rm " + "--rm " +
@@ -106,6 +120,7 @@ func NewConfig() *Config {
"userdocker", "userdocker",
}, },
{ {
Id: "console",
Cmd: "--name=console " + Cmd: "--name=console " +
"-d " + "-d " +
"--rm " + "--rm " +
@@ -113,13 +128,37 @@ func NewConfig() *Config {
"--volumes-from=command-volumes " + "--volumes-from=command-volumes " +
"--volumes-from=user-volumes " + "--volumes-from=user-volumes " +
"--volumes-from=system-volumes " + "--volumes-from=system-volumes " +
"--restart=always " +
"--ipc=host " + "--ipc=host " +
"--net=host " + "--net=host " +
"--pid=host " + "--pid=host " +
"console", "console",
}, },
}, },
EnabledAddons: []string{},
Addons: map[string]Config{
"ubuntu-console": {
SystemContainers: []ContainerConfig{
{
Id: "console",
Cmd: "--name=ubuntu-console " +
"-d " +
"--rm " +
"--privileged " +
"--volumes-from=command-volumes " +
"--volumes-from=user-volumes " +
"--volumes-from=system-volumes " +
"--restart=always " +
"--ipc=host " +
"--net=host " +
"--pid=host " +
"rancher/ubuntuconsole",
},
},
},
},
RescueContainer: &ContainerConfig{ RescueContainer: &ContainerConfig{
Id: "console",
Cmd: "--name=rescue " + Cmd: "--name=rescue " +
"-d " + "-d " +
"--rm " + "--rm " +
@@ -127,6 +166,7 @@ func NewConfig() *Config {
"--volumes-from=console-volumes " + "--volumes-from=console-volumes " +
"--volumes-from=user-volumes " + "--volumes-from=user-volumes " +
"--volumes-from=system-volumes " + "--volumes-from=system-volumes " +
"--restart=always " +
"--ipc=host " + "--ipc=host " +
"--net=host " + "--net=host " +
"--pid=host " + "--pid=host " +

View File

@@ -34,7 +34,7 @@ type Container struct {
HostConfig *runconfig.HostConfig HostConfig *runconfig.HostConfig
dockerHost string dockerHost string
Container *dockerClient.Container Container *dockerClient.Container
containerCfg *config.ContainerConfig ContainerCfg *config.ContainerConfig
} }
type ByCreated []dockerClient.APIContainers type ByCreated []dockerClient.APIContainers
@@ -65,7 +65,7 @@ func StartAndWait(dockerHost string, containerCfg *config.ContainerConfig) error
func NewContainer(dockerHost string, containerCfg *config.ContainerConfig) *Container { func NewContainer(dockerHost string, containerCfg *config.ContainerConfig) *Container {
c := &Container{ c := &Container{
dockerHost: dockerHost, dockerHost: dockerHost,
containerCfg: containerCfg, ContainerCfg: containerCfg,
} }
return c.Parse() return c.Parse()
} }
@@ -102,7 +102,7 @@ func (c *Container) Lookup() *Container {
return c return c
} }
hash, err := getHash(c.containerCfg) hash, err := getHash(c.ContainerCfg)
if err != nil { if err != nil {
return c.returnErr(err) return c.returnErr(err)
} }
@@ -169,7 +169,7 @@ func (c *Container) Parse() *Container {
flDetach := flags.Bool([]string{"d", "-detach"}, false, "") flDetach := flags.Bool([]string{"d", "-detach"}, false, "")
flName := flags.String([]string{"#name", "-name"}, "", "") flName := flags.String([]string{"#name", "-name"}, "", "")
args, err := shlex.Split(c.containerCfg.Cmd) args, err := shlex.Split(c.ContainerCfg.Cmd)
if err != nil { if err != nil {
return c.returnErr(err) return c.returnErr(err)
} }
@@ -181,8 +181,8 @@ func (c *Container) Parse() *Container {
c.detach = *flDetach c.detach = *flDetach
c.remove = *flRemove c.remove = *flRemove
if c.containerCfg.Id == "" { if c.ContainerCfg.Id == "" {
c.containerCfg.Id = c.Name c.ContainerCfg.Id = c.Name
} }
return c return c
@@ -327,13 +327,13 @@ func (c *Container) getCreateOpts(client *dockerClient.Client) (*dockerClient.Cr
opts.Config.Labels = make(map[string]string) opts.Config.Labels = make(map[string]string)
} }
hash, err := getHash(c.containerCfg) hash, err := getHash(c.ContainerCfg)
if err != nil { if err != nil {
return nil, err return nil, err
} }
opts.Config.Labels[HASH] = hash opts.Config.Labels[HASH] = hash
opts.Config.Labels[ID] = c.containerCfg.Id opts.Config.Labels[ID] = c.ContainerCfg.Id
return &opts, nil return &opts, nil
} }
@@ -398,7 +398,7 @@ func (c *Container) start(wait bool) *Container {
return c.returnErr(err) return c.returnErr(err)
} }
err := appendVolumesFrom(client, c.containerCfg, opts) err := appendVolumesFrom(client, c.ContainerCfg, opts)
if err != nil { if err != nil {
return c.returnErr(err) return c.returnErr(err)
} }