sysinit.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package init
  2. import (
  3. "os"
  4. "os/exec"
  5. "path"
  6. "syscall"
  7. "golang.org/x/net/context"
  8. "github.com/docker/engine-api/types"
  9. "github.com/docker/libcompose/project/options"
  10. "github.com/rancher/os/cmd/control"
  11. "github.com/rancher/os/compose"
  12. "github.com/rancher/os/config"
  13. "github.com/rancher/os/docker"
  14. "github.com/rancher/os/log"
  15. )
  16. const (
  17. systemImagesPreloadDirectory = "/var/lib/rancher/preload/system-docker"
  18. )
  19. func hasImage(name string) bool {
  20. stamp := path.Join(state, name)
  21. if _, err := os.Stat(stamp); os.IsNotExist(err) {
  22. return false
  23. }
  24. return true
  25. }
  26. func findImages(cfg *config.CloudConfig) ([]string, error) {
  27. log.Debugf("Looking for images at %s", config.ImagesPath)
  28. result := []string{}
  29. dir, err := os.Open(config.ImagesPath)
  30. if os.IsNotExist(err) {
  31. log.Debugf("Not loading images, %s does not exist", config.ImagesPath)
  32. return result, nil
  33. }
  34. if err != nil {
  35. return nil, err
  36. }
  37. defer dir.Close()
  38. files, err := dir.Readdirnames(0)
  39. if err != nil {
  40. return nil, err
  41. }
  42. for _, fileName := range files {
  43. if ok, _ := path.Match(config.ImagesPattern, fileName); ok {
  44. log.Debugf("Found %s", fileName)
  45. result = append(result, fileName)
  46. }
  47. }
  48. return result, nil
  49. }
  50. func loadImages(cfg *config.CloudConfig) (*config.CloudConfig, error) {
  51. images, err := findImages(cfg)
  52. if err != nil || len(images) == 0 {
  53. return cfg, err
  54. }
  55. client, err := docker.NewSystemClient()
  56. if err != nil {
  57. return cfg, err
  58. }
  59. for _, image := range images {
  60. if hasImage(image) {
  61. continue
  62. }
  63. // client.ImageLoad is an asynchronous operation
  64. // To ensure the order of execution, use cmd instead of it
  65. inputFileName := path.Join(config.ImagesPath, image)
  66. log.Infof("Loading images from %s", inputFileName)
  67. if err = exec.Command("/usr/bin/system-docker", "load", "-q", "-i", inputFileName).Run(); err != nil {
  68. log.Fatalf("FATAL: failed loading images from %s: %s", inputFileName, err)
  69. }
  70. log.Infof("Done loading images from %s", inputFileName)
  71. }
  72. dockerImages, _ := client.ImageList(context.Background(), types.ImageListOptions{})
  73. for _, dimg := range dockerImages {
  74. log.Infof("Got image repo tags: %s", dimg.RepoTags)
  75. }
  76. return cfg, nil
  77. }
  78. func SysInit() error {
  79. cfg := config.LoadConfig()
  80. if err := control.PreloadImages(docker.NewSystemClient, systemImagesPreloadDirectory); err != nil {
  81. log.Errorf("Failed to preload System Docker images: %v", err)
  82. }
  83. _, err := config.ChainCfgFuncs(cfg,
  84. []config.CfgFuncData{
  85. config.CfgFuncData{"loadImages", loadImages},
  86. config.CfgFuncData{"start project", func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
  87. p, err := compose.GetProject(cfg, false, true)
  88. if err != nil {
  89. return cfg, err
  90. }
  91. return cfg, p.Up(context.Background(), options.Up{
  92. Create: options.Create{
  93. NoRecreate: true,
  94. },
  95. Log: cfg.Rancher.Log,
  96. })
  97. }},
  98. config.CfgFuncData{"sync", func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
  99. syscall.Sync()
  100. return cfg, nil
  101. }},
  102. config.CfgFuncData{"banner", func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
  103. log.Infof("RancherOS %s started", config.Version)
  104. return cfg, nil
  105. }}})
  106. return err
  107. }