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:
@@ -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
|
||||||
|
@@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 " +
|
||||||
|
@@ -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)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user