mirror of
https://github.com/rancher/os.git
synced 2025-06-30 00:31:49 +00:00
Refactor configuration to compose syntax
This commit is contained in:
parent
38389b1f8e
commit
c7ae14cc13
@ -8,26 +8,26 @@ import (
|
|||||||
"github.com/rancherio/os/docker"
|
"github.com/rancherio/os/docker"
|
||||||
)
|
)
|
||||||
|
|
||||||
func parseContainers(cfg *config.Config) map[string]*docker.Container {
|
//func parseContainers(cfg *config.Config) map[string]*docker.Container {
|
||||||
result := map[string]*docker.Container{}
|
// result := map[string]*docker.Container{}
|
||||||
|
//
|
||||||
for _, containerConfig := range cfg.SystemContainers {
|
// for _, containerConfig := range cfg.SystemContainers {
|
||||||
container := docker.NewContainer(config.DOCKER_SYSTEM_HOST, &containerConfig)
|
// container := docker.NewContainer(config.DOCKER_SYSTEM_HOST, &containerConfig)
|
||||||
if containerConfig.Id != "" {
|
// if containerConfig.Id != "" {
|
||||||
result[containerConfig.Id] = container
|
// result[containerConfig.Id] = container
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return result
|
// return result
|
||||||
}
|
//}
|
||||||
|
|
||||||
func reload(c *cli.Context) {
|
func reload(c *cli.Context) {
|
||||||
cfg, err := config.LoadConfig()
|
_, err := config.LoadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
containers := parseContainers(cfg)
|
containers := map[string]*docker.Container{} //parseContainers(cfg)
|
||||||
toStart := make([]*docker.Container, 0, len(c.Args()))
|
toStart := make([]*docker.Container, 0, len(c.Args()))
|
||||||
|
|
||||||
for _, id := range c.Args() {
|
for _, id := range c.Args() {
|
||||||
|
@ -27,10 +27,10 @@ func Main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
applyNetworkConfigs(cfg)
|
ApplyNetworkConfigs(&cfg.Network)
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyNetworkConfigs(cfg *config.Config) error {
|
func ApplyNetworkConfigs(netCfg *config.NetworkConfig) error {
|
||||||
links, err := netlink.LinkList()
|
links, err := netlink.LinkList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -41,7 +41,7 @@ func applyNetworkConfigs(cfg *config.Config) error {
|
|||||||
linkName := link.Attrs().Name
|
linkName := link.Attrs().Name
|
||||||
var match config.InterfaceConfig
|
var match config.InterfaceConfig
|
||||||
|
|
||||||
for key, netConf := range cfg.Network.Interfaces {
|
for key, netConf := range netCfg.Interfaces {
|
||||||
if netConf.Match == "" {
|
if netConf.Match == "" {
|
||||||
netConf.Match = key
|
netConf.Match = key
|
||||||
}
|
}
|
||||||
@ -86,8 +86,8 @@ func applyNetworkConfigs(cfg *config.Config) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//post run
|
//post run
|
||||||
if cfg.Network.PostRun != nil {
|
if netCfg.PostRun != nil {
|
||||||
return docker.StartAndWait(config.DOCKER_SYSTEM_HOST, cfg.Network.PostRun)
|
return docker.StartAndWait(config.DOCKER_SYSTEM_HOST, netCfg.PostRun)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/rancherio/rancher-compose/project"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/rancherio/os/util"
|
"github.com/rancherio/os/util"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
@ -16,23 +18,10 @@ func (c *Config) privilegedMerge(newConfig Config) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
toAppend := make([]ContainerConfig, 0, 5)
|
for k, v := range newConfig.SystemContainers {
|
||||||
|
c.SystemContainers[k] = v
|
||||||
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 nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,8 +31,8 @@ func (c *Config) overlay(newConfig Config) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) clearReadOnly() {
|
func (c *Config) clearReadOnly() {
|
||||||
c.BootstrapContainers = make([]ContainerConfig, 0)
|
c.BootstrapContainers = make(map[string]*project.ServiceConfig, 0)
|
||||||
c.SystemContainers = make([]ContainerConfig, 0)
|
c.SystemContainers = make(map[string]*project.ServiceConfig, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func clearReadOnly(data map[interface{}]interface{}) map[interface{}]interface{} {
|
func clearReadOnly(data map[interface{}]interface{}) map[interface{}]interface{} {
|
||||||
@ -103,6 +92,12 @@ func LoadConfig() (*Config, error) {
|
|||||||
|
|
||||||
if cfg.Debug {
|
if cfg.Debug {
|
||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
|
if !util.Contains(cfg.UserDocker.Args, "-D") {
|
||||||
|
cfg.UserDocker.Args = append(cfg.UserDocker.Args, "-D")
|
||||||
|
}
|
||||||
|
if !util.Contains(cfg.SystemDocker.Args, "-D") {
|
||||||
|
cfg.SystemDocker.Args = append(cfg.SystemDocker.Args, "-D")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cfg, nil
|
return cfg, nil
|
||||||
@ -197,20 +192,11 @@ func Dump(private, full bool) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) configureConsole() error {
|
func (c *Config) configureConsole() error {
|
||||||
if !c.Console.Persistent {
|
if console, ok := c.SystemContainers[CONSOLE_CONTAINER]; ok {
|
||||||
return nil
|
if c.Console.Persistent {
|
||||||
}
|
console.Labels = append(console.Labels, REMOVE+"=false")
|
||||||
|
} else {
|
||||||
for i := range c.SystemContainers {
|
console.Labels = append(console.Labels, REMOVE+"=true")
|
||||||
// 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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +207,6 @@ func (c *Config) readGlobals() error {
|
|||||||
return util.ShortCircuit(
|
return util.ShortCircuit(
|
||||||
c.readCmdline,
|
c.readCmdline,
|
||||||
c.readArgs,
|
c.readArgs,
|
||||||
c.mergeAddons,
|
|
||||||
c.configureConsole,
|
c.configureConsole,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -233,19 +218,6 @@ func (c *Config) Reload() error {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) mergeAddons() error {
|
|
||||||
for _, addon := range c.EnabledAddons {
|
|
||||||
if newConfig, ok := c.Addons[addon]; ok {
|
|
||||||
log.Debugf("Enabling addon %s", addon)
|
|
||||||
if err := c.privilegedMerge(newConfig); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) Get(key string) (interface{}, error) {
|
func (c *Config) Get(key string) (interface{}, error) {
|
||||||
data := make(map[interface{}]interface{})
|
data := make(map[interface{}]interface{})
|
||||||
err := util.Convert(c, &data)
|
err := util.Convert(c, &data)
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/rancherio/rancher-compose/project"
|
||||||
|
)
|
||||||
|
|
||||||
func NewConfig() *Config {
|
func NewConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
Debug: DEBUG,
|
Debug: DEBUG,
|
||||||
@ -43,7 +47,7 @@ func NewConfig() *Config {
|
|||||||
Nameservers: []string{"8.8.8.8", "8.8.4.4"},
|
Nameservers: []string{"8.8.8.8", "8.8.4.4"},
|
||||||
},
|
},
|
||||||
Interfaces: map[string]InterfaceConfig{
|
Interfaces: map[string]InterfaceConfig{
|
||||||
"eth*": {
|
"eth0": {
|
||||||
DHCP: true,
|
DHCP: true,
|
||||||
},
|
},
|
||||||
"lo": {
|
"lo": {
|
||||||
@ -58,193 +62,238 @@ func NewConfig() *Config {
|
|||||||
Url: "https://releases.rancher.com/os/versions.yml",
|
Url: "https://releases.rancher.com/os/versions.yml",
|
||||||
Image: "rancher/os",
|
Image: "rancher/os",
|
||||||
},
|
},
|
||||||
BootstrapContainers: []ContainerConfig{
|
BootstrapContainers: map[string]*project.ServiceConfig{
|
||||||
{
|
"udev": {
|
||||||
Id: "udev",
|
Net: "host",
|
||||||
Cmd: "--name=udev " +
|
Privileged: true,
|
||||||
"--net=none " +
|
Labels: []string{
|
||||||
"--privileged " +
|
DETACH + "=false",
|
||||||
"--rm " +
|
},
|
||||||
"-v=/dev:/host/dev " +
|
Volumes: []string{
|
||||||
"-v=/lib/modules:/lib/modules:ro " +
|
"/dev:/host/dev",
|
||||||
"udev",
|
"/lib/modules:/lib/modules:ro",
|
||||||
|
"/lib/firmware:/lib/firmware:ro",
|
||||||
|
},
|
||||||
|
Image: "udev",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
SystemContainers: []ContainerConfig{
|
SystemContainers: map[string]*project.ServiceConfig{
|
||||||
{
|
"udev": {
|
||||||
Id: "udev",
|
Image: "udev",
|
||||||
Cmd: "--name=udev " +
|
Net: "host",
|
||||||
"--net=none " +
|
Privileged: true,
|
||||||
"--privileged " +
|
Labels: []string{
|
||||||
"--rm " +
|
DETACH + "=true",
|
||||||
"-v=/dev:/host/dev " +
|
},
|
||||||
"-v=/lib/modules:/lib/modules:ro " +
|
Environment: []string{
|
||||||
"udev",
|
"DAEMON=true",
|
||||||
CreateOnly: true,
|
},
|
||||||
|
Volumes: []string{
|
||||||
|
"/dev:/host/dev",
|
||||||
|
"/lib/modules:/lib/modules:ro",
|
||||||
|
"/lib/firmware:/lib/firmware:ro",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
"system-volumes": {
|
||||||
Id: "system-volumes",
|
Image: "state",
|
||||||
Cmd: "--name=system-volumes " +
|
Net: "none",
|
||||||
"--net=none " +
|
ReadOnly: true,
|
||||||
"--read-only " +
|
Privileged: true,
|
||||||
"-v=/etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt " +
|
Labels: []string{
|
||||||
"-v=/var/lib/rancher/conf:/var/lib/rancher/conf " +
|
CREATE_ONLY + "=true",
|
||||||
"-v=/lib/modules:/lib/modules:ro " +
|
},
|
||||||
"-v=/var/run:/var/run " +
|
Volumes: []string{
|
||||||
"-v=/var/log:/var/log " +
|
"/etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt",
|
||||||
"state",
|
"/var/lib/rancher/conf:/var/lib/rancher/conf",
|
||||||
CreateOnly: true,
|
"/lib/modules:/lib/modules:ro",
|
||||||
|
"/lib/firmware:/lib/firmware:ro",
|
||||||
|
"/var/run:/var/run",
|
||||||
|
"/var/log:/var/log",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
"command-volumes": {
|
||||||
Id: "command-volumes",
|
Image: "state",
|
||||||
Cmd: "--name=command-volumes " +
|
Net: "none",
|
||||||
"--net=none " +
|
ReadOnly: true,
|
||||||
"--read-only " +
|
Privileged: true,
|
||||||
"-v=/init:/sbin/halt:ro " +
|
Labels: []string{
|
||||||
"-v=/init:/sbin/poweroff:ro " +
|
CREATE_ONLY + "=true",
|
||||||
"-v=/init:/sbin/reboot:ro " +
|
},
|
||||||
"-v=/init:/sbin/shutdown:ro " +
|
Volumes: []string{
|
||||||
"-v=/init:/sbin/netconf:ro " +
|
"/init:/sbin/halt:ro",
|
||||||
"-v=/init:/usr/bin/cloud-init:ro " +
|
"/init:/sbin/poweroff:ro",
|
||||||
"-v=/init:/usr/bin/rancherctl:ro " +
|
"/init:/sbin/reboot:ro",
|
||||||
"-v=/init:/usr/bin/respawn:ro " +
|
"/init:/sbin/shutdown:ro",
|
||||||
"-v=/init:/usr/bin/system-docker:ro " +
|
"/init:/sbin/netconf:ro",
|
||||||
"-v=/lib/modules:/lib/modules:ro " +
|
"/init:/usr/bin/cloud-init:ro",
|
||||||
"-v=/usr/bin/docker:/usr/bin/docker:ro " +
|
"/init:/usr/bin/rancherctl:ro",
|
||||||
"state",
|
"/init:/usr/bin/respawn:ro",
|
||||||
CreateOnly: true,
|
"/init:/usr/bin/system-docker:ro",
|
||||||
|
"/lib/modules:/lib/modules:ro",
|
||||||
|
"/usr/bin/docker:/usr/bin/docker:ro",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
"user-volumes": {
|
||||||
Id: "user-volumes",
|
Image: "state",
|
||||||
Cmd: "--name=user-volumes " +
|
Net: "none",
|
||||||
"--net=none " +
|
ReadOnly: true,
|
||||||
"--read-only " +
|
Privileged: true,
|
||||||
"-v=/home:/home " +
|
Labels: []string{
|
||||||
"-v=/opt:/opt " +
|
CREATE_ONLY + "=true",
|
||||||
"state",
|
},
|
||||||
CreateOnly: true,
|
Volumes: []string{
|
||||||
|
"/home:/home",
|
||||||
|
"/opt:/opt",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
"docker-volumes": {
|
||||||
Id: "docker-volumes",
|
Image: "state",
|
||||||
Cmd: "--name=docker-volumes " +
|
Net: "none",
|
||||||
"--net=none " +
|
ReadOnly: true,
|
||||||
"--read-only " +
|
Privileged: true,
|
||||||
"-v=/var/lib/rancher:/var/lib/rancher " +
|
Labels: []string{
|
||||||
"-v=/var/lib/docker:/var/lib/docker " +
|
CREATE_ONLY + "=true",
|
||||||
"-v=/var/lib/system-docker:/var/lib/system-docker " +
|
},
|
||||||
"state",
|
Volumes: []string{
|
||||||
CreateOnly: true,
|
"/var/lib/rancher:/var/lib/rancher",
|
||||||
|
"/var/lib/docker:/var/lib/docker",
|
||||||
|
"/var/lib/system-docker:/var/lib/system-docker",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
"all-volumes": {
|
||||||
Id: "all-volumes",
|
Image: "state",
|
||||||
Cmd: "--name=all-volumes " +
|
Net: "none",
|
||||||
"--rm " +
|
ReadOnly: true,
|
||||||
"--net=none " +
|
Privileged: true,
|
||||||
"--read-only " +
|
Labels: []string{
|
||||||
"--volumes-from=docker-volumes " +
|
CREATE_ONLY + "=true",
|
||||||
"--volumes-from=command-volumes " +
|
},
|
||||||
"--volumes-from=user-volumes " +
|
VolumesFrom: []string{
|
||||||
"--volumes-from=system-volumes " +
|
"docker-volumes",
|
||||||
"state",
|
"command-volumes",
|
||||||
CreateOnly: true,
|
"user-volumes",
|
||||||
|
"system-volumes",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
"cloud-init-pre": {
|
||||||
Id: "cloud-init-pre",
|
Image: "cloudinit",
|
||||||
Cmd: "--name=cloud-init-pre " +
|
Privileged: true,
|
||||||
"--rm " +
|
Net: "host",
|
||||||
"--privileged " +
|
Labels: []string{
|
||||||
"--net=host " +
|
RELOAD_CONFIG + "=true",
|
||||||
"-e CLOUD_INIT_NETWORK=false " +
|
DETACH + "=false",
|
||||||
"--volumes-from=command-volumes " +
|
},
|
||||||
"--volumes-from=system-volumes " +
|
Environment: []string{
|
||||||
"cloudinit",
|
"CLOUD_INIT_NETWORK=false",
|
||||||
ReloadConfig: true,
|
},
|
||||||
|
VolumesFrom: []string{
|
||||||
|
"command-volumes",
|
||||||
|
"system-volumes",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
"network": {
|
||||||
Id: "network",
|
Image: "network",
|
||||||
Cmd: "--name=network " +
|
CapAdd: []string{
|
||||||
"--rm " +
|
"NET_ADMIN",
|
||||||
"--cap-add=NET_ADMIN " +
|
},
|
||||||
"--net=host " +
|
Net: "host",
|
||||||
"--volumes-from=command-volumes " +
|
Labels: []string{
|
||||||
"--volumes-from=system-volumes " +
|
DETACH + "=false",
|
||||||
|
},
|
||||||
|
Links: []string{
|
||||||
|
"cloud-init-pre",
|
||||||
|
},
|
||||||
|
VolumesFrom: []string{
|
||||||
|
"command-volumes",
|
||||||
|
"system-volumes",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"cloud-init": {
|
||||||
|
Image: "cloudinit",
|
||||||
|
Privileged: true,
|
||||||
|
Labels: []string{
|
||||||
|
RELOAD_CONFIG + "=true",
|
||||||
|
DETACH + "=false",
|
||||||
|
},
|
||||||
|
Net: "host",
|
||||||
|
Links: []string{
|
||||||
|
"cloud-init-pre",
|
||||||
"network",
|
"network",
|
||||||
|
},
|
||||||
|
VolumesFrom: []string{
|
||||||
|
"command-volumes",
|
||||||
|
"system-volumes",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
"ntp": {
|
||||||
Id: "cloud-init",
|
Image: "ntp",
|
||||||
Cmd: "--name=cloud-init " +
|
Privileged: true,
|
||||||
"--rm " +
|
Net: "host",
|
||||||
"--privileged " +
|
Links: []string{
|
||||||
"--net=host " +
|
"cloud-init",
|
||||||
"--volumes-from=command-volumes " +
|
"network",
|
||||||
"--volumes-from=system-volumes " +
|
},
|
||||||
"cloudinit",
|
|
||||||
ReloadConfig: true,
|
|
||||||
},
|
},
|
||||||
{
|
"syslog": {
|
||||||
Id: "ntp",
|
Image: "syslog",
|
||||||
Cmd: "--name=ntp " +
|
Privileged: true,
|
||||||
"--rm " +
|
Net: "host",
|
||||||
"-d " +
|
Links: []string{
|
||||||
"--privileged " +
|
"cloud-init",
|
||||||
"--net=host " +
|
"network",
|
||||||
"ntp",
|
},
|
||||||
|
VolumesFrom: []string{
|
||||||
|
"system-volumes",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
"userdocker": {
|
||||||
Id: "syslog",
|
Image: "userdocker",
|
||||||
Cmd: "--name=syslog " +
|
Privileged: true,
|
||||||
"-d " +
|
Pid: "host",
|
||||||
"--rm " +
|
Ipc: "host",
|
||||||
"--privileged " +
|
Net: "host",
|
||||||
"--net=host " +
|
Links: []string{
|
||||||
"--ipc=host " +
|
"network",
|
||||||
"--pid=host " +
|
},
|
||||||
"--volumes-from=system-volumes " +
|
VolumesFrom: []string{
|
||||||
"syslog",
|
"all-volumes",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
"console": {
|
||||||
Id: "userdocker",
|
Image: "console",
|
||||||
Cmd: "--name=userdocker " +
|
Privileged: true,
|
||||||
"-d " +
|
Links: []string{
|
||||||
"--rm " +
|
"cloud-init",
|
||||||
"--restart=always " +
|
},
|
||||||
"--ipc=host " +
|
VolumesFrom: []string{
|
||||||
"--pid=host " +
|
"all-volumes",
|
||||||
"--net=host " +
|
},
|
||||||
"--privileged " +
|
Restart: "always",
|
||||||
"--volumes-from=all-volumes " +
|
Pid: "host",
|
||||||
"userdocker",
|
Ipc: "host",
|
||||||
},
|
Net: "host",
|
||||||
{
|
|
||||||
Id: "console",
|
|
||||||
Cmd: "--name=console " +
|
|
||||||
"-d " +
|
|
||||||
"--rm " +
|
|
||||||
"--privileged " +
|
|
||||||
"--volumes-from=all-volumes " +
|
|
||||||
"--restart=always " +
|
|
||||||
"--ipc=host " +
|
|
||||||
"--net=host " +
|
|
||||||
"--pid=host " +
|
|
||||||
"console",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
EnabledAddons: []string{},
|
EnabledAddons: []string{},
|
||||||
Addons: map[string]Config{
|
Addons: map[string]Config{
|
||||||
"ubuntu-console": {
|
"ubuntu-console": {
|
||||||
SystemContainers: []ContainerConfig{
|
SystemContainers: map[string]*project.ServiceConfig{
|
||||||
{
|
"console": {
|
||||||
Id: "console",
|
Image: "rancher/ubuntuconsole:" + VERSION,
|
||||||
Cmd: "--name=ubuntu-console " +
|
Privileged: true,
|
||||||
"-d " +
|
Labels: []string{
|
||||||
"--rm " +
|
DETACH + "=true",
|
||||||
"--privileged " +
|
},
|
||||||
"--volumes-from=all-volumes " +
|
Links: []string{
|
||||||
"--restart=always " +
|
"cloud-init",
|
||||||
"--ipc=host " +
|
},
|
||||||
"--net=host " +
|
VolumesFrom: []string{
|
||||||
"--pid=host " +
|
"all-volumes",
|
||||||
"rancher/ubuntuconsole:" + VERSION,
|
},
|
||||||
|
Restart: "always",
|
||||||
|
Pid: "host",
|
||||||
|
Ipc: "host",
|
||||||
|
Net: "host",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
|
import "github.com/rancherio/rancher-compose/project"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
CONSOLE_CONTAINER = "console"
|
CONSOLE_CONTAINER = "console"
|
||||||
DOCKER_BIN = "/usr/bin/docker"
|
DOCKER_BIN = "/usr/bin/docker"
|
||||||
@ -12,6 +14,14 @@ const (
|
|||||||
USER_INIT = "/sbin/init-user"
|
USER_INIT = "/sbin/init-user"
|
||||||
MODULES_ARCHIVE = "/modules.tar"
|
MODULES_ARCHIVE = "/modules.tar"
|
||||||
DEBUG = false
|
DEBUG = false
|
||||||
|
|
||||||
|
LABEL = "label"
|
||||||
|
HASH = "io.rancher.os.hash"
|
||||||
|
ID = "io.rancher.os.id"
|
||||||
|
DETACH = "io.rancher.os.detach"
|
||||||
|
REMOVE = "io.rancher.os.remove"
|
||||||
|
CREATE_ONLY = "io.rancher.os.createonly"
|
||||||
|
RELOAD_CONFIG = "io.rancher.os.reloadconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -22,30 +32,31 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ContainerConfig struct {
|
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"`
|
ReloadConfig bool `yaml:"reload_config,omitempty"`
|
||||||
CreateOnly bool `yaml:create_only,omitempty`
|
CreateOnly bool `yaml:create_only,omitempty`
|
||||||
|
Service *project.ServiceConfig `yaml:service,omitempty`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Addons map[string]Config `yaml:"addons,omitempty"`
|
Addons map[string]Config `yaml:"addons,omitempty"`
|
||||||
BootstrapContainers []ContainerConfig `yaml:"bootstrap_containers,omitempty"`
|
BootstrapContainers map[string]*project.ServiceConfig `yaml:"bootstrap_containers,omitempty"`
|
||||||
CloudInit CloudInit `yaml:"cloud_init,omitempty"`
|
CloudInit CloudInit `yaml:"cloud_init,omitempty"`
|
||||||
Console ConsoleConfig `yaml:"console,omitempty"`
|
Console ConsoleConfig `yaml:"console,omitempty"`
|
||||||
Debug bool `yaml:"debug,omitempty"`
|
Debug bool `yaml:"debug,omitempty"`
|
||||||
Disable []string `yaml:"disable,omitempty"`
|
//Disable []string `yaml:"disable,omitempty"`
|
||||||
EnabledAddons []string `yaml:"enabled_addons,omitempty"`
|
EnabledAddons []string `yaml:"enabled_addons,omitempty"`
|
||||||
Modules []string `yaml:"modules,omitempty"`
|
Modules []string `yaml:"modules,omitempty"`
|
||||||
Network NetworkConfig `yaml:"network,omitempty"`
|
Network NetworkConfig `yaml:"network,omitempty"`
|
||||||
Ssh SshConfig `yaml:"ssh,omitempty"`
|
Ssh SshConfig `yaml:"ssh,omitempty"`
|
||||||
State StateConfig `yaml:"state,omitempty"`
|
State StateConfig `yaml:"state,omitempty"`
|
||||||
SystemContainers []ContainerConfig `yaml:"system_containers,omitempty"`
|
SystemContainers map[string]*project.ServiceConfig `yaml:"system_containers,omitempty"`
|
||||||
SystemDocker DockerConfig `yaml:"system_docker,omitempty"`
|
SystemDocker DockerConfig `yaml:"system_docker,omitempty"`
|
||||||
Upgrade UpgradeConfig `yaml:"upgrade,omitempty"`
|
Upgrade UpgradeConfig `yaml:"upgrade,omitempty"`
|
||||||
UserContainers []ContainerConfig `yaml:"user_containers,omitempty"`
|
UserContainers []ContainerConfig `yaml:"user_containers,omitempty"`
|
||||||
UserDocker DockerConfig `yaml:"user_docker,omitempty"`
|
UserDocker DockerConfig `yaml:"user_docker,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConsoleConfig struct {
|
type ConsoleConfig struct {
|
||||||
|
@ -3,6 +3,8 @@ package docker
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
log "github.com/Sirupsen/logrus"
|
||||||
|
|
||||||
dockerClient "github.com/fsouza/go-dockerclient"
|
dockerClient "github.com/fsouza/go-dockerclient"
|
||||||
"github.com/rancherio/os/config"
|
"github.com/rancherio/os/config"
|
||||||
)
|
)
|
||||||
@ -26,12 +28,16 @@ func NewClient(endpoint string) (*dockerClient.Client, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retry := false
|
||||||
for i := 0; i < (MAX_WAIT / INTERVAL); i++ {
|
for i := 0; i < (MAX_WAIT / INTERVAL); i++ {
|
||||||
_, err = client.Info()
|
_, err = client.Info()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retry = true
|
||||||
|
|
||||||
|
log.Infof("Waiting for Docker at %s", endpoint)
|
||||||
time.Sleep(INTERVAL * time.Millisecond)
|
time.Sleep(INTERVAL * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,5 +45,8 @@ func NewClient(endpoint string) (*dockerClient.Client, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if retry {
|
||||||
|
log.Infof("Connected to Docker at %s", endpoint)
|
||||||
|
}
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
@ -16,12 +17,8 @@ import (
|
|||||||
dockerClient "github.com/fsouza/go-dockerclient"
|
dockerClient "github.com/fsouza/go-dockerclient"
|
||||||
"github.com/rancherio/os/config"
|
"github.com/rancherio/os/config"
|
||||||
"github.com/rancherio/os/util"
|
"github.com/rancherio/os/util"
|
||||||
)
|
"github.com/rancherio/rancher-compose/docker"
|
||||||
|
"github.com/rancherio/rancher-compose/project"
|
||||||
const (
|
|
||||||
LABEL = "label"
|
|
||||||
HASH = "io.rancher.os.hash"
|
|
||||||
ID = "io.rancher.os.id"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Container struct {
|
type Container struct {
|
||||||
@ -48,6 +45,10 @@ func getHash(containerCfg *config.ContainerConfig) (string, error) {
|
|||||||
|
|
||||||
w.Write([]byte(containerCfg.Id))
|
w.Write([]byte(containerCfg.Id))
|
||||||
w.Write([]byte(containerCfg.Cmd))
|
w.Write([]byte(containerCfg.Cmd))
|
||||||
|
if containerCfg.Service != nil {
|
||||||
|
//TODO: properly hash
|
||||||
|
w.Write([]byte(fmt.Sprintf("%v", containerCfg.Service)))
|
||||||
|
}
|
||||||
|
|
||||||
if w.Err != nil {
|
if w.Err != nil {
|
||||||
return "", w.Err
|
return "", w.Err
|
||||||
@ -61,6 +62,18 @@ func StartAndWait(dockerHost string, containerCfg *config.ContainerConfig) error
|
|||||||
return container.Err
|
return container.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewContainerFromService(dockerHost string, name string, service *project.ServiceConfig) *Container {
|
||||||
|
c := &Container{
|
||||||
|
Name: name,
|
||||||
|
dockerHost: dockerHost,
|
||||||
|
ContainerCfg: &config.ContainerConfig{
|
||||||
|
Id: name,
|
||||||
|
Service: service,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return c.Parse()
|
||||||
|
}
|
||||||
|
|
||||||
func NewContainer(dockerHost string, containerCfg *config.ContainerConfig) *Container {
|
func NewContainer(dockerHost string, containerCfg *config.ContainerConfig) *Container {
|
||||||
c := &Container{
|
c := &Container{
|
||||||
dockerHost: dockerHost,
|
dockerHost: dockerHost,
|
||||||
@ -78,7 +91,7 @@ func getByLabel(client *dockerClient.Client, key, value string) (*dockerClient.A
|
|||||||
containers, err := client.ListContainers(dockerClient.ListContainersOptions{
|
containers, err := client.ListContainers(dockerClient.ListContainersOptions{
|
||||||
All: true,
|
All: true,
|
||||||
Filters: map[string][]string{
|
Filters: map[string][]string{
|
||||||
LABEL: []string{fmt.Sprintf("%s=%s", key, value)},
|
config.LABEL: []string{fmt.Sprintf("%s=%s", key, value)},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -114,7 +127,7 @@ func (c *Container) Lookup() *Container {
|
|||||||
containers, err := client.ListContainers(dockerClient.ListContainersOptions{
|
containers, err := client.ListContainers(dockerClient.ListContainersOptions{
|
||||||
All: true,
|
All: true,
|
||||||
Filters: map[string][]string{
|
Filters: map[string][]string{
|
||||||
LABEL: []string{fmt.Sprintf("%s=%s", HASH, hash)},
|
config.LABEL: []string{fmt.Sprintf("%s=%s", config.HASH, hash)},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -157,11 +170,23 @@ func (c *Container) Reset() *Container {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) Parse() *Container {
|
func (c *Container) parseService() {
|
||||||
if c.Config != nil || c.Err != nil {
|
cfg, hostConfig, err := docker.Convert(c.ContainerCfg.Service)
|
||||||
return c
|
if err != nil {
|
||||||
|
c.Err = err
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.Config = cfg
|
||||||
|
c.HostConfig = hostConfig
|
||||||
|
|
||||||
|
c.detach = c.Config.Labels[config.DETACH] != "false"
|
||||||
|
c.remove = c.Config.Labels[config.REMOVE] != "false"
|
||||||
|
c.ContainerCfg.CreateOnly = c.Config.Labels[config.CREATE_ONLY] == "true"
|
||||||
|
c.ContainerCfg.ReloadConfig = c.Config.Labels[config.RELOAD_CONFIG] == "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Container) parseCmd() {
|
||||||
flags := flag.NewFlagSet("run", flag.ExitOnError)
|
flags := flag.NewFlagSet("run", flag.ExitOnError)
|
||||||
|
|
||||||
flRemove := flags.Bool([]string{"#rm", "-rm"}, false, "")
|
flRemove := flags.Bool([]string{"#rm", "-rm"}, false, "")
|
||||||
@ -170,7 +195,8 @@ func (c *Container) Parse() *Container {
|
|||||||
|
|
||||||
args, err := shlex.Split(c.ContainerCfg.Cmd)
|
args, err := shlex.Split(c.ContainerCfg.Cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.returnErr(err)
|
c.Err = err
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Parsing [%s]", strings.Join(args, ","))
|
log.Debugf("Parsing [%s]", strings.Join(args, ","))
|
||||||
@ -179,6 +205,21 @@ func (c *Container) Parse() *Container {
|
|||||||
c.Name = *flName
|
c.Name = *flName
|
||||||
c.detach = *flDetach
|
c.detach = *flDetach
|
||||||
c.remove = *flRemove
|
c.remove = *flRemove
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Container) Parse() *Container {
|
||||||
|
if c.Config != nil || c.Err != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(c.ContainerCfg.Cmd) > 0 {
|
||||||
|
c.parseCmd()
|
||||||
|
} else if c.ContainerCfg.Service != nil {
|
||||||
|
c.parseService()
|
||||||
|
} else {
|
||||||
|
c.Err = errors.New("Cmd or Service must be set")
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
if c.ContainerCfg.Id == "" {
|
if c.ContainerCfg.Id == "" {
|
||||||
c.ContainerCfg.Id = c.Name
|
c.ContainerCfg.Id = c.Name
|
||||||
@ -219,6 +260,7 @@ func (c *Container) Stage() *Container {
|
|||||||
OutputStream: os.Stdout,
|
OutputStream: os.Stdout,
|
||||||
}, dockerClient.AuthConfiguration{})
|
}, dockerClient.AuthConfiguration{})
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
|
log.Errorf("Failed to stage: %s: %v", c.Config.Image, err)
|
||||||
c.Err = err
|
c.Err = err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,7 +333,7 @@ func (c *Container) renameOld(client *dockerClient.Client, opts *dockerClient.Cr
|
|||||||
}
|
}
|
||||||
|
|
||||||
var newName string
|
var newName string
|
||||||
if label, ok := existing.Config.Labels[HASH]; ok {
|
if label, ok := existing.Config.Labels[config.HASH]; ok {
|
||||||
newName = fmt.Sprintf("%s-%s", existing.Name, label)
|
newName = fmt.Sprintf("%s-%s", existing.Name, label)
|
||||||
} else {
|
} else {
|
||||||
newName = fmt.Sprintf("%s-unknown-%s", existing.Name, util.RandSeq(12))
|
newName = fmt.Sprintf("%s-unknown-%s", existing.Name, util.RandSeq(12))
|
||||||
@ -316,6 +358,7 @@ func (c *Container) renameOld(client *dockerClient.Client, opts *dockerClient.Cr
|
|||||||
func (c *Container) getCreateOpts(client *dockerClient.Client) (*dockerClient.CreateContainerOptions, error) {
|
func (c *Container) getCreateOpts(client *dockerClient.Client) (*dockerClient.CreateContainerOptions, error) {
|
||||||
bytes, err := json.Marshal(c)
|
bytes, err := json.Marshal(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Errorf("Failed to marshall: %v", c)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,6 +366,7 @@ func (c *Container) getCreateOpts(client *dockerClient.Client) (*dockerClient.Cr
|
|||||||
|
|
||||||
err = json.Unmarshal(bytes, &opts)
|
err = json.Unmarshal(bytes, &opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Errorf("Failed to unmarshall: %s", string(bytes))
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,8 +379,8 @@ func (c *Container) getCreateOpts(client *dockerClient.Client) (*dockerClient.Cr
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
opts.Config.Labels[HASH] = hash
|
opts.Config.Labels[config.HASH] = hash
|
||||||
opts.Config.Labels[ID] = c.ContainerCfg.Id
|
opts.Config.Labels[config.ID] = c.ContainerCfg.Id
|
||||||
|
|
||||||
return &opts, nil
|
return &opts, nil
|
||||||
}
|
}
|
||||||
@ -346,7 +390,7 @@ func appendVolumesFrom(client *dockerClient.Client, containerCfg *config.Contain
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
container, err := getByLabel(client, ID, containerCfg.Id)
|
container, err := getByLabel(client, config.ID, containerCfg.Id)
|
||||||
if err != nil || container == nil {
|
if err != nil || container == nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -360,7 +404,7 @@ func appendVolumesFrom(client *dockerClient.Client, containerCfg *config.Contain
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) start(create_only, wait bool) *Container {
|
func (c *Container) start(createOnly, wait bool) *Container {
|
||||||
c.Lookup()
|
c.Lookup()
|
||||||
c.Stage()
|
c.Stage()
|
||||||
|
|
||||||
@ -378,6 +422,7 @@ func (c *Container) start(create_only, wait bool) *Container {
|
|||||||
|
|
||||||
opts, err := c.getCreateOpts(client)
|
opts, err := c.getCreateOpts(client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Errorf("Failed to create container create options: %v", err)
|
||||||
return c.returnErr(err)
|
return c.returnErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,7 +465,7 @@ func (c *Container) start(create_only, wait bool) *Container {
|
|||||||
hostConfig = opts.HostConfig
|
hostConfig = opts.HostConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
if create_only {
|
if createOnly {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,12 +484,17 @@ func (c *Container) start(create_only, wait bool) *Container {
|
|||||||
|
|
||||||
err = client.StartContainer(c.Container.ID, hostConfig)
|
err = client.StartContainer(c.Container.ID, hostConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Errorf("Error from Docker %s", err)
|
||||||
return c.returnErr(err)
|
return c.returnErr(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !c.detach && wait {
|
if !c.detach && wait {
|
||||||
_, c.Err = client.WaitContainer(c.Container.ID)
|
var exitCode int
|
||||||
|
exitCode, c.Err = client.WaitContainer(c.Container.ID)
|
||||||
|
if exitCode != 0 {
|
||||||
|
c.Err = errors.New(fmt.Sprintf("Container %s exited with code %d", c.Name, exitCode))
|
||||||
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
69
docker/factory.go
Normal file
69
docker/factory.go
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
package docker
|
||||||
|
|
||||||
|
import (
|
||||||
|
log "github.com/Sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/rancherio/os/config"
|
||||||
|
"github.com/rancherio/rancher-compose/project"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ContainerFactory struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type containerBasedService struct {
|
||||||
|
name string
|
||||||
|
project *project.Project
|
||||||
|
container *Container
|
||||||
|
serviceConfig *project.ServiceConfig
|
||||||
|
cfg *config.Config
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *containerBasedService) Up() error {
|
||||||
|
container := c.container
|
||||||
|
containerCfg := c.container.ContainerCfg
|
||||||
|
|
||||||
|
if containerCfg.CreateOnly {
|
||||||
|
container.Create()
|
||||||
|
c.project.Notify(project.CONTAINER_CREATED, c, map[string]string{
|
||||||
|
project.CONTAINER_ID: container.Container.ID,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
container.StartAndWait()
|
||||||
|
c.project.Notify(project.CONTAINER_STARTED, c, map[string]string{
|
||||||
|
project.CONTAINER_ID: container.Container.ID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if container.Err != nil {
|
||||||
|
log.Errorf("Failed to run %v: %v", containerCfg.Id, container.Err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if container.Err == nil && containerCfg.ReloadConfig {
|
||||||
|
return project.ErrRestart
|
||||||
|
}
|
||||||
|
|
||||||
|
return container.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *containerBasedService) Config() *project.ServiceConfig {
|
||||||
|
return c.serviceConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *containerBasedService) Name() string {
|
||||||
|
return c.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ContainerFactory) Create(project *project.Project, name string, serviceConfig *project.ServiceConfig) (project.Service, error) {
|
||||||
|
container := NewContainerFromService(config.DOCKER_SYSTEM_HOST, name, serviceConfig)
|
||||||
|
|
||||||
|
if container.Err != nil {
|
||||||
|
return nil, container.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &containerBasedService{
|
||||||
|
name: name,
|
||||||
|
project: project,
|
||||||
|
container: container,
|
||||||
|
serviceConfig: serviceConfig,
|
||||||
|
}, nil
|
||||||
|
}
|
@ -8,9 +8,10 @@ import (
|
|||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/rancherio/os/config"
|
"github.com/rancherio/os/config"
|
||||||
"github.com/rancherio/os/util"
|
"github.com/rancherio/os/util"
|
||||||
|
"github.com/rancherio/rancher-compose/project"
|
||||||
)
|
)
|
||||||
|
|
||||||
func runBootstrapContainers(cfg *config.Config) error {
|
func autoformat(cfg *config.Config) error {
|
||||||
if len(cfg.State.Autoformat) == 0 || util.ResolveDevice(cfg.State.Dev) != "" {
|
if len(cfg.State.Autoformat) == 0 || util.ResolveDevice(cfg.State.Dev) != "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -54,24 +55,22 @@ outer:
|
|||||||
|
|
||||||
if format != "" {
|
if format != "" {
|
||||||
log.Infof("Auto formatting : %s", format)
|
log.Infof("Auto formatting : %s", format)
|
||||||
return runContainersFrom("", cfg, append([]config.ContainerConfig{
|
return runServices("autoformat", cfg, map[string]*project.ServiceConfig{
|
||||||
{
|
"autoformat": {
|
||||||
Id: "auto-format",
|
Net: "none",
|
||||||
Cmd: "--name auto-format " +
|
Privileged: true,
|
||||||
"--rm " +
|
Image: "autoformat",
|
||||||
"--net=none " +
|
Command: format,
|
||||||
"--privileged " +
|
|
||||||
"autoformat " +
|
|
||||||
format,
|
|
||||||
},
|
},
|
||||||
}, cfg.BootstrapContainers...))
|
"udev": cfg.BootstrapContainers["udev"],
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func autoformat(cfg *config.Config) error {
|
func runBootstrapContainers(cfg *config.Config) error {
|
||||||
return runContainersFrom("", cfg, cfg.BootstrapContainers)
|
return runServices("bootstrap", cfg, cfg.BootstrapContainers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func startDocker(cfg *config.Config) (chan interface{}, error) {
|
func startDocker(cfg *config.Config) (chan interface{}, error) {
|
||||||
|
132
init/sysinit.go
132
init/sysinit.go
@ -10,6 +10,8 @@ import (
|
|||||||
"github.com/rancherio/os/config"
|
"github.com/rancherio/os/config"
|
||||||
"github.com/rancherio/os/docker"
|
"github.com/rancherio/os/docker"
|
||||||
"github.com/rancherio/os/util"
|
"github.com/rancherio/os/util"
|
||||||
|
|
||||||
|
"github.com/rancherio/rancher-compose/project"
|
||||||
)
|
)
|
||||||
|
|
||||||
func importImage(client *dockerClient.Client, name, fileName string) error {
|
func importImage(client *dockerClient.Client, name, fileName string) error {
|
||||||
@ -107,50 +109,63 @@ func loadImages(cfg *config.Config) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runContainersFrom(startFrom string, cfg *config.Config, containerConfigs []config.ContainerConfig) error {
|
func runServices(name string, cfg *config.Config, configs map[string]*project.ServiceConfig) error {
|
||||||
foundStart := false
|
project := project.NewProject(name, &docker.ContainerFactory{})
|
||||||
|
enabled := make(map[string]bool)
|
||||||
|
|
||||||
for i, containerConfig := range containerConfigs {
|
for name, serviceConfig := range configs {
|
||||||
container := docker.NewContainer(config.DOCKER_SYSTEM_HOST, &containerConfig)
|
if err := project.AddConfig(name, serviceConfig); err != nil {
|
||||||
|
log.Infof("Failed loading service %s", name)
|
||||||
if util.Contains(cfg.Disable, containerConfig.Id) {
|
|
||||||
log.Infof("%s is disabled : %v", containerConfig.Id, cfg.Disable)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if foundStart || startFrom == "" {
|
|
||||||
|
|
||||||
if containerConfig.CreateOnly {
|
|
||||||
log.Infof("Creating [%d/%d] %s", i+1, len(containerConfigs), containerConfig.Id)
|
|
||||||
container.Create()
|
|
||||||
} else {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
if containerConfig.ReloadConfig {
|
|
||||||
log.Info("Reloading configuration")
|
|
||||||
err := cfg.Reload()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return runContainersFrom(containerConfig.Id, cfg, cfg.SystemContainers)
|
|
||||||
}
|
|
||||||
} else if startFrom == containerConfig.Id {
|
|
||||||
foundStart = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
project.ReloadCallback = func() error {
|
||||||
|
err := cfg.Reload()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, addon := range cfg.EnabledAddons {
|
||||||
|
if _, ok := enabled[addon]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if config, ok := cfg.Addons[addon]; ok {
|
||||||
|
for name, s := range config.SystemContainers {
|
||||||
|
if err := project.AddConfig(name, s); err != nil {
|
||||||
|
log.Errorf("Failed to load %s : %v", name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bytes, err := util.LoadResource(addon)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed to load %s : %v", addon, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
err = project.Load(bytes)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed to load %s : %v", addon, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enabled[addon] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err := project.ReloadCallback()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed to reload %s : %v", name, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return project.Up()
|
||||||
}
|
}
|
||||||
|
|
||||||
func runContainers(cfg *config.Config) error {
|
func runContainers(cfg *config.Config) error {
|
||||||
return runContainersFrom("", cfg, cfg.SystemContainers)
|
return runServices("system-init", cfg, cfg.SystemContainers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func tailConsole(cfg *config.Config) error {
|
func tailConsole(cfg *config.Config) error {
|
||||||
@ -163,29 +178,26 @@ func tailConsole(cfg *config.Config) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, container := range cfg.SystemContainers {
|
console, ok := cfg.SystemContainers[config.CONSOLE_CONTAINER]
|
||||||
if container.Id != config.CONSOLE_CONTAINER {
|
if !ok {
|
||||||
continue
|
log.Error("Console not found")
|
||||||
}
|
return nil
|
||||||
|
|
||||||
c := docker.NewContainer(config.DOCKER_SYSTEM_HOST, &container).Lookup()
|
|
||||||
if c.Err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Infof("Tailing console : %s", c.Name)
|
|
||||||
return client.Logs(dockerClient.LogsOptions{
|
|
||||||
Container: c.Name,
|
|
||||||
Stdout: true,
|
|
||||||
Stderr: true,
|
|
||||||
Follow: true,
|
|
||||||
OutputStream: os.Stdout,
|
|
||||||
ErrorStream: os.Stderr,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Error("Console not found")
|
c := docker.NewContainerFromService(config.DOCKER_SYSTEM_HOST, config.CONSOLE_CONTAINER, console)
|
||||||
return nil
|
if c.Err != nil {
|
||||||
|
return c.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("Tailing console : %s", c.Name)
|
||||||
|
return client.Logs(dockerClient.LogsOptions{
|
||||||
|
Container: c.Name,
|
||||||
|
Stdout: true,
|
||||||
|
Stderr: true,
|
||||||
|
Follow: true,
|
||||||
|
OutputStream: os.Stdout,
|
||||||
|
ErrorStream: os.Stderr,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func SysInit() error {
|
func SysInit() error {
|
||||||
@ -201,6 +213,10 @@ func SysInit() error {
|
|||||||
syscall.Sync()
|
syscall.Sync()
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
func(cfg *config.Config) error {
|
||||||
|
log.Info("RancherOS booted")
|
||||||
|
return nil
|
||||||
|
},
|
||||||
tailConsole,
|
tailConsole,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
util/util.go
16
util/util.go
@ -4,9 +4,12 @@ import (
|
|||||||
"archive/tar"
|
"archive/tar"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/mount"
|
"github.com/docker/docker/pkg/mount"
|
||||||
@ -182,3 +185,16 @@ func MergeMaps(left, right map[interface{}]interface{}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func LoadResource(location string) ([]byte, error) {
|
||||||
|
if strings.HasPrefix(location, "http:/") || strings.HasPrefix(location, "https:/") {
|
||||||
|
resp, err := http.Get(location)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
return ioutil.ReadAll(resp.Body)
|
||||||
|
} else {
|
||||||
|
return ioutil.ReadFile(location)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user