2018-09-16 04:55:26 +00:00
|
|
|
package sysinit
|
2015-03-18 13:21:32 +00:00
|
|
|
|
|
|
|
import (
|
2018-11-20 03:08:26 +00:00
|
|
|
"fmt"
|
2015-03-18 13:21:32 +00:00
|
|
|
"os"
|
2018-02-27 09:55:59 +00:00
|
|
|
"os/exec"
|
2015-03-18 13:21:32 +00:00
|
|
|
"path"
|
2018-09-09 08:07:50 +00:00
|
|
|
"path/filepath"
|
2018-11-20 03:08:26 +00:00
|
|
|
"strings"
|
2015-03-18 13:21:32 +00:00
|
|
|
"syscall"
|
|
|
|
|
2016-10-17 21:47:44 +00:00
|
|
|
"github.com/rancher/os/cmd/control"
|
2015-10-12 11:50:17 +00:00
|
|
|
"github.com/rancher/os/config"
|
2018-09-16 04:55:26 +00:00
|
|
|
"github.com/rancher/os/pkg/compose"
|
|
|
|
"github.com/rancher/os/pkg/docker"
|
|
|
|
"github.com/rancher/os/pkg/log"
|
2018-10-23 04:13:32 +00:00
|
|
|
|
|
|
|
"github.com/docker/engine-api/types"
|
|
|
|
"github.com/docker/libcompose/project/options"
|
2018-09-16 04:55:26 +00:00
|
|
|
"golang.org/x/net/context"
|
2015-03-18 13:21:32 +00:00
|
|
|
)
|
|
|
|
|
2016-10-17 21:47:44 +00:00
|
|
|
const (
|
|
|
|
systemImagesPreloadDirectory = "/var/lib/rancher/preload/system-docker"
|
2018-11-20 03:08:26 +00:00
|
|
|
systemImagesLoadStamp = "/var/lib/rancher/.sysimages_%s_loaded.done"
|
2016-10-17 21:47:44 +00:00
|
|
|
)
|
|
|
|
|
2015-03-18 13:21:32 +00:00
|
|
|
func hasImage(name string) bool {
|
2018-09-30 06:30:25 +00:00
|
|
|
stamp := path.Join(config.StateDir, name)
|
2015-03-18 13:21:32 +00:00
|
|
|
if _, err := os.Stat(stamp); os.IsNotExist(err) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2018-09-09 08:07:50 +00:00
|
|
|
func getImagesArchive(bootstrap bool) string {
|
|
|
|
var archive string
|
|
|
|
if bootstrap {
|
|
|
|
archive = path.Join(config.ImagesPath, config.InitImages)
|
|
|
|
} else {
|
|
|
|
archive = path.Join(config.ImagesPath, config.SystemImages)
|
2015-03-18 13:21:32 +00:00
|
|
|
}
|
|
|
|
|
2018-09-09 08:07:50 +00:00
|
|
|
return archive
|
|
|
|
}
|
2015-03-18 13:21:32 +00:00
|
|
|
|
2018-09-16 04:55:26 +00:00
|
|
|
func LoadBootstrapImages(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
2018-09-09 08:07:50 +00:00
|
|
|
return loadImages(cfg, true)
|
|
|
|
}
|
2015-03-18 13:21:32 +00:00
|
|
|
|
2018-09-16 04:55:26 +00:00
|
|
|
func LoadSystemImages(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
2018-11-20 03:08:26 +00:00
|
|
|
stamp := fmt.Sprintf(systemImagesLoadStamp, strings.Replace(config.Version, ".", "_", -1))
|
|
|
|
if _, err := os.Stat(stamp); os.IsNotExist(err) {
|
|
|
|
os.Create(stamp)
|
|
|
|
return loadImages(cfg, false)
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Infof("Skipped loading system images because %s exists", systemImagesLoadStamp)
|
|
|
|
return cfg, nil
|
2015-03-18 13:21:32 +00:00
|
|
|
}
|
|
|
|
|
2018-09-09 08:07:50 +00:00
|
|
|
func loadImages(cfg *config.CloudConfig, bootstrap bool) (*config.CloudConfig, error) {
|
|
|
|
archive := getImagesArchive(bootstrap)
|
2015-03-18 13:21:32 +00:00
|
|
|
|
|
|
|
client, err := docker.NewSystemClient()
|
|
|
|
if err != nil {
|
2015-09-23 11:36:28 +00:00
|
|
|
return cfg, err
|
2015-03-18 13:21:32 +00:00
|
|
|
}
|
|
|
|
|
2018-09-09 08:07:50 +00:00
|
|
|
if !hasImage(filepath.Base(archive)) {
|
|
|
|
if _, err := os.Stat(archive); os.IsNotExist(err) {
|
|
|
|
log.Fatalf("FATAL: Could not load images from %s (file not found)", archive)
|
2015-03-18 13:21:32 +00:00
|
|
|
}
|
|
|
|
|
2018-02-27 09:55:59 +00:00
|
|
|
// client.ImageLoad is an asynchronous operation
|
|
|
|
// To ensure the order of execution, use cmd instead of it
|
2018-09-09 08:07:50 +00:00
|
|
|
log.Infof("Loading images from %s", archive)
|
|
|
|
cmd := exec.Command("/usr/bin/system-docker", "load", "-q", "-i", archive)
|
|
|
|
if out, err := cmd.CombinedOutput(); err != nil {
|
|
|
|
log.Fatalf("FATAL: Error loading images from %s (%v)\n%s ", archive, err, out)
|
2015-03-18 13:21:32 +00:00
|
|
|
}
|
2016-02-03 12:24:12 +00:00
|
|
|
|
2018-09-09 08:07:50 +00:00
|
|
|
log.Infof("Done loading images from %s", archive)
|
2015-03-18 13:21:32 +00:00
|
|
|
}
|
|
|
|
|
2018-02-27 09:55:59 +00:00
|
|
|
dockerImages, _ := client.ImageList(context.Background(), types.ImageListOptions{})
|
|
|
|
for _, dimg := range dockerImages {
|
2018-11-20 03:08:26 +00:00
|
|
|
log.Debugf("Loaded a docker image: %s", dimg.RepoTags)
|
2018-02-27 09:55:59 +00:00
|
|
|
}
|
|
|
|
|
2015-09-23 11:36:28 +00:00
|
|
|
return cfg, nil
|
2015-03-18 13:21:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func SysInit() error {
|
2016-06-02 01:41:55 +00:00
|
|
|
cfg := config.LoadConfig()
|
2015-03-18 13:21:32 +00:00
|
|
|
|
2016-10-17 21:47:44 +00:00
|
|
|
if err := control.PreloadImages(docker.NewSystemClient, systemImagesPreloadDirectory); err != nil {
|
|
|
|
log.Errorf("Failed to preload System Docker images: %v", err)
|
|
|
|
}
|
|
|
|
|
2016-06-02 01:41:55 +00:00
|
|
|
_, err := config.ChainCfgFuncs(cfg,
|
2018-09-16 04:55:26 +00:00
|
|
|
config.CfgFuncs{
|
|
|
|
{"loadSystemImages", LoadSystemImages},
|
|
|
|
{"start project", func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
2017-05-02 23:45:58 +00:00
|
|
|
p, err := compose.GetProject(cfg, false, true)
|
|
|
|
if err != nil {
|
|
|
|
return cfg, err
|
|
|
|
}
|
|
|
|
return cfg, p.Up(context.Background(), options.Up{
|
|
|
|
Create: options.Create{
|
|
|
|
NoRecreate: true,
|
|
|
|
},
|
|
|
|
Log: cfg.Rancher.Log,
|
|
|
|
})
|
|
|
|
}},
|
2018-09-16 04:55:26 +00:00
|
|
|
{"sync", func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
2017-05-02 23:45:58 +00:00
|
|
|
syscall.Sync()
|
|
|
|
return cfg, nil
|
|
|
|
}},
|
2018-09-16 04:55:26 +00:00
|
|
|
{"banner", func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
2017-05-02 23:45:58 +00:00
|
|
|
log.Infof("RancherOS %s started", config.Version)
|
|
|
|
return cfg, nil
|
|
|
|
}}})
|
2015-09-23 11:36:28 +00:00
|
|
|
return err
|
2015-03-18 13:21:32 +00:00
|
|
|
}
|
2018-09-16 04:55:26 +00:00
|
|
|
|
|
|
|
func RunSysInit(c *config.CloudConfig) (*config.CloudConfig, error) {
|
|
|
|
args := append([]string{config.SysInitBin}, os.Args[1:]...)
|
|
|
|
|
|
|
|
cmd := &exec.Cmd{
|
|
|
|
Path: config.RosBin,
|
|
|
|
Args: args,
|
|
|
|
}
|
|
|
|
|
|
|
|
cmd.Stdin = os.Stdin
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
|
|
|
|
if err := cmd.Start(); err != nil {
|
|
|
|
return c, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return c, os.Stdin.Close()
|
|
|
|
}
|