cloudinitexecute.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package cloudinitexecute
  2. import (
  3. "flag"
  4. "fmt"
  5. "io/ioutil"
  6. "os"
  7. "os/exec"
  8. "path"
  9. "strings"
  10. rancherConfig "github.com/rancher/os/config"
  11. "github.com/rancher/os/config/cloudinit/system"
  12. "github.com/rancher/os/docker"
  13. "github.com/rancher/os/log"
  14. "github.com/rancher/os/util"
  15. "golang.org/x/net/context"
  16. )
  17. const (
  18. resizeStamp = "/var/lib/rancher/resizefs.done"
  19. sshKeyName = "rancheros-cloud-config"
  20. )
  21. var (
  22. console bool
  23. preConsole bool
  24. flags *flag.FlagSet
  25. )
  26. func init() {
  27. flags = flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
  28. flags.BoolVar(&console, "console", false, "apply console configuration")
  29. flags.BoolVar(&preConsole, "pre-console", false, "apply pre-console configuration")
  30. }
  31. func Main() {
  32. flags.Parse(os.Args[1:])
  33. log.InitLogger()
  34. log.Infof("Running cloud-init-execute: pre-console=%v, console=%v", preConsole, console)
  35. cfg := rancherConfig.LoadConfig()
  36. if !console && !preConsole {
  37. console = true
  38. preConsole = true
  39. }
  40. if console {
  41. ApplyConsole(cfg)
  42. }
  43. if preConsole {
  44. applyPreConsole(cfg)
  45. }
  46. }
  47. func ApplyConsole(cfg *rancherConfig.CloudConfig) {
  48. if len(cfg.SSHAuthorizedKeys) > 0 {
  49. if err := authorizeSSHKeys("rancher", cfg.SSHAuthorizedKeys, sshKeyName); err != nil {
  50. log.Error(err)
  51. }
  52. if err := authorizeSSHKeys("docker", cfg.SSHAuthorizedKeys, sshKeyName); err != nil {
  53. log.Error(err)
  54. }
  55. }
  56. WriteFiles(cfg, "console")
  57. for _, mount := range cfg.Mounts {
  58. if len(mount) != 4 {
  59. log.Errorf("Unable to mount %s: must specify exactly four arguments", mount[1])
  60. }
  61. device := util.ResolveDevice(mount[0])
  62. if mount[2] == "swap" {
  63. cmd := exec.Command("swapon", device)
  64. cmd.Stdout = os.Stdout
  65. cmd.Stderr = os.Stderr
  66. err := cmd.Run()
  67. if err != nil {
  68. log.Errorf("Unable to swapon %s: %v", device, err)
  69. }
  70. continue
  71. }
  72. cmdArgs := []string{device, mount[1]}
  73. if mount[2] != "" {
  74. cmdArgs = append(cmdArgs, "-t", mount[2])
  75. }
  76. if mount[3] != "" {
  77. cmdArgs = append(cmdArgs, "-o", mount[3])
  78. }
  79. cmd := exec.Command("mount", cmdArgs...)
  80. cmd.Stdout = os.Stdout
  81. cmd.Stderr = os.Stderr
  82. if err := cmd.Run(); err != nil {
  83. log.Errorf("Failed to mount %s: %v", mount[1], err)
  84. }
  85. }
  86. util.RunCommandSequence(cfg.Runcmd)
  87. }
  88. func WriteFiles(cfg *rancherConfig.CloudConfig, container string) {
  89. for _, file := range cfg.WriteFiles {
  90. fileContainer := file.Container
  91. if fileContainer == "" {
  92. fileContainer = "console"
  93. }
  94. if fileContainer != container {
  95. continue
  96. }
  97. f := system.File{
  98. File: file.File,
  99. }
  100. fullPath, err := system.WriteFile(&f, "/")
  101. if err != nil {
  102. log.WithFields(log.Fields{"err": err, "path": fullPath}).Error("Error writing file")
  103. continue
  104. }
  105. log.Printf("Wrote file %s to filesystem", fullPath)
  106. }
  107. }
  108. func applyPreConsole(cfg *rancherConfig.CloudConfig) {
  109. if cfg.Rancher.ResizeDevice != "" {
  110. if _, err := os.Stat(resizeStamp); os.IsNotExist(err) {
  111. if err := resizeDevice(cfg); err == nil {
  112. os.Create(resizeStamp)
  113. } else {
  114. log.Errorf("Failed to resize %s: %s", cfg.Rancher.ResizeDevice, err)
  115. }
  116. } else {
  117. log.Infof("Skipped resizing %s because %s exists", cfg.Rancher.ResizeDevice, resizeStamp)
  118. }
  119. }
  120. for k, v := range cfg.Rancher.Sysctl {
  121. elems := []string{"/proc", "sys"}
  122. elems = append(elems, strings.Split(k, ".")...)
  123. path := path.Join(elems...)
  124. if err := ioutil.WriteFile(path, []byte(v), 0644); err != nil {
  125. log.Errorf("Failed to set sysctl key %s: %s", k, err)
  126. }
  127. }
  128. client, err := docker.NewSystemClient()
  129. if err != nil {
  130. log.Error(err)
  131. }
  132. for _, restart := range cfg.Rancher.RestartServices {
  133. if err = client.ContainerRestart(context.Background(), restart, 10); err != nil {
  134. log.Error(err)
  135. }
  136. }
  137. }
  138. func resizeDevice(cfg *rancherConfig.CloudConfig) error {
  139. cmd := exec.Command("growpart", cfg.Rancher.ResizeDevice, "1")
  140. cmd.Stdout = os.Stdout
  141. cmd.Stderr = os.Stderr
  142. cmd.Run()
  143. cmd = exec.Command("partprobe", cfg.Rancher.ResizeDevice)
  144. cmd.Stdout = os.Stdout
  145. cmd.Stderr = os.Stderr
  146. err := cmd.Run()
  147. if err != nil {
  148. return err
  149. }
  150. cmd = exec.Command("resize2fs", fmt.Sprintf("%s1", cfg.Rancher.ResizeDevice))
  151. cmd.Stdout = os.Stdout
  152. cmd.Stderr = os.Stderr
  153. err = cmd.Run()
  154. if err != nil {
  155. return err
  156. }
  157. return nil
  158. }