2015-03-18 13:21:32 +00:00
|
|
|
package init
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
2015-04-28 11:34:32 +00:00
|
|
|
"strings"
|
2015-03-18 13:21:32 +00:00
|
|
|
"syscall"
|
|
|
|
|
|
|
|
log "github.com/Sirupsen/logrus"
|
|
|
|
"github.com/rancherio/os/config"
|
2015-04-16 05:57:59 +00:00
|
|
|
"github.com/rancherio/os/docker"
|
2015-03-18 13:21:32 +00:00
|
|
|
"github.com/rancherio/os/util"
|
2015-03-29 09:57:15 +00:00
|
|
|
"github.com/rancherio/rancher-compose/project"
|
2015-03-18 13:21:32 +00:00
|
|
|
)
|
|
|
|
|
2015-04-28 11:34:32 +00:00
|
|
|
const boot2dockerMagic = "boot2docker, please format-me"
|
|
|
|
|
2015-03-29 09:57:15 +00:00
|
|
|
func autoformat(cfg *config.Config) error {
|
2015-03-18 13:21:32 +00:00
|
|
|
if len(cfg.State.Autoformat) == 0 || util.ResolveDevice(cfg.State.Dev) != "" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var format string
|
|
|
|
|
|
|
|
outer:
|
|
|
|
for _, dev := range cfg.State.Autoformat {
|
|
|
|
log.Infof("Checking %s to auto-format", dev)
|
|
|
|
if _, err := os.Stat(dev); os.IsNotExist(err) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
f, err := os.Open(dev)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
buffer := make([]byte, 1048576, 1048576)
|
|
|
|
c, err := f.Read(buffer)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if c != 1048576 {
|
|
|
|
log.Infof("%s not right size", dev)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2015-04-28 11:34:32 +00:00
|
|
|
boot2docker := false
|
|
|
|
|
|
|
|
if strings.HasPrefix(string(buffer[:len(boot2dockerMagic)]), boot2dockerMagic) {
|
|
|
|
boot2docker = true
|
|
|
|
}
|
|
|
|
|
|
|
|
if boot2docker == false {
|
|
|
|
for _, b := range buffer {
|
|
|
|
if b != 0 {
|
|
|
|
log.Infof("%s not empty", dev)
|
|
|
|
continue outer
|
|
|
|
}
|
2015-03-18 13:21:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
format = dev
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
if format != "" {
|
|
|
|
log.Infof("Auto formatting : %s", format)
|
2015-04-20 23:58:31 +00:00
|
|
|
|
|
|
|
// copy
|
|
|
|
udev := *cfg.BootstrapContainers["udev"]
|
|
|
|
udev.Links = append(udev.Links, "autoformat")
|
|
|
|
udev.LogDriver = "json-file"
|
|
|
|
|
|
|
|
err := docker.RunServices("autoformat", cfg, map[string]*project.ServiceConfig{
|
2015-03-29 09:57:15 +00:00
|
|
|
"autoformat": {
|
|
|
|
Net: "none",
|
|
|
|
Privileged: true,
|
|
|
|
Image: "autoformat",
|
|
|
|
Command: format,
|
2015-04-30 03:47:47 +00:00
|
|
|
Labels: project.NewSliceorMap(map[string]string{
|
|
|
|
config.DETACH: "false",
|
|
|
|
config.SCOPE: config.SYSTEM,
|
|
|
|
}),
|
2015-04-20 23:58:31 +00:00
|
|
|
LogDriver: "json-file",
|
2015-04-28 11:34:32 +00:00
|
|
|
Environment: []string{
|
|
|
|
"MAGIC=" + boot2dockerMagic,
|
|
|
|
},
|
2015-03-18 13:21:32 +00:00
|
|
|
},
|
2015-04-20 23:58:31 +00:00
|
|
|
"udev": &udev,
|
2015-03-29 09:57:15 +00:00
|
|
|
})
|
2015-04-20 23:58:31 +00:00
|
|
|
|
|
|
|
return err
|
2015-03-18 13:21:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-03-29 09:57:15 +00:00
|
|
|
func runBootstrapContainers(cfg *config.Config) error {
|
2015-04-16 05:57:59 +00:00
|
|
|
return docker.RunServices("bootstrap", cfg, cfg.BootstrapContainers)
|
2015-03-18 13:21:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func startDocker(cfg *config.Config) (chan interface{}, error) {
|
|
|
|
for _, d := range []string{config.DOCKER_SYSTEM_HOST, "/var/run"} {
|
|
|
|
err := os.MkdirAll(d, 0700)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-03 21:59:24 +00:00
|
|
|
cmd := exec.Command(cfg.BootstrapDocker.Args[0], cfg.BootstrapDocker.Args[1:]...)
|
2015-03-18 13:21:32 +00:00
|
|
|
if cfg.Debug {
|
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
}
|
|
|
|
err := cmd.Start()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
c := make(chan interface{})
|
|
|
|
go func() {
|
|
|
|
<-c
|
|
|
|
cmd.Process.Signal(syscall.SIGTERM)
|
|
|
|
cmd.Wait()
|
|
|
|
c <- struct{}{}
|
|
|
|
}()
|
|
|
|
|
|
|
|
return c, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func stopDocker(c chan interface{}) error {
|
|
|
|
c <- struct{}{}
|
|
|
|
<-c
|
|
|
|
|
|
|
|
return os.RemoveAll(config.DOCKER_SYSTEM_HOME)
|
|
|
|
}
|
|
|
|
|
|
|
|
func bootstrap(cfg *config.Config) error {
|
|
|
|
log.Info("Starting bootstrap")
|
|
|
|
c, err := startDocker(cfg)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
initFuncs := []config.InitFunc{
|
|
|
|
loadImages,
|
|
|
|
runBootstrapContainers,
|
|
|
|
autoformat,
|
|
|
|
}
|
|
|
|
|
|
|
|
defer stopDocker(c)
|
|
|
|
|
|
|
|
return config.RunInitFuncs(cfg, initFuncs)
|
|
|
|
}
|