userdata.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package fsdriver
  15. import (
  16. "fmt"
  17. "strings"
  18. "yunion.io/x/log"
  19. "yunion.io/x/pkg/errors"
  20. "yunion.io/x/pkg/util/cloudinit"
  21. )
  22. func (d *sGuestRootFsDriver) DeployUserData(userData string) error {
  23. log.Errorf("DeployUserData not implemented for %s", d.GetIRootFsDriver().String())
  24. return nil
  25. }
  26. func (d *sLinuxRootFs) DeployUserData(userData string) error {
  27. return d.deployUserDataBySystemd(userData)
  28. }
  29. func (d *sLinuxRootFs) deployUserDataByCron(userData string) error {
  30. const userDataPath = "/etc/userdata.sh"
  31. const userDataCronPath = "/etc/cron.d/userdata"
  32. config, err := cloudinit.ParseUserData(userData)
  33. var scripts string
  34. if err != nil {
  35. scripts = userData
  36. } else {
  37. scripts = config.UserDataScript()
  38. }
  39. // scripts += "\n"
  40. // scripts += fmt.Sprintf("rm -f %s\n", userDataCronPath)
  41. err = d.rootFs.FilePutContents(userDataPath, scripts, false, false)
  42. if err != nil {
  43. return errors.Wrap(err, "save user_data fail")
  44. }
  45. err = d.rootFs.Chmod(userDataPath, 0755, false)
  46. if err != nil {
  47. return errors.Wrap(err, "chmod user_data fail")
  48. }
  49. cron := fmt.Sprintf("@reboot /bin/sh %s\n", userDataPath)
  50. err = d.rootFs.FilePutContents(userDataCronPath, cron, false, false)
  51. if err != nil {
  52. return errors.Wrap(err, "save user_data cron fail")
  53. }
  54. return nil
  55. }
  56. func (d *sLinuxRootFs) deployUserDataBySystemd(userData string) error {
  57. const scriptPath = "/etc/userdata.sh"
  58. const serviceName = "cloud-userdata"
  59. {
  60. config, err := cloudinit.ParseUserData(userData)
  61. var scripts string
  62. if err != nil {
  63. scripts = userData
  64. } else {
  65. scripts = config.UserDataScript()
  66. }
  67. scripts += "\n"
  68. if d.isSupportSystemd() {
  69. // diable systemd service
  70. scripts += fmt.Sprintf("systemctl disable --now %s\n", serviceName)
  71. } else {
  72. // cleanup crontab
  73. scripts += fmt.Sprintf("crontab -l 2>/dev/null | grep -v '%s') |crontab -\n", scriptPath)
  74. }
  75. err = d.rootFs.FilePutContents(scriptPath, scripts, false, false)
  76. if err != nil {
  77. return errors.Wrap(err, "save user_data fail")
  78. }
  79. err = d.rootFs.Chmod(scriptPath, 0755, false)
  80. if err != nil {
  81. return errors.Wrap(err, "chmod user_data fail")
  82. }
  83. }
  84. {
  85. err := d.installInitScript(serviceName, "/bin/sh "+scriptPath, true)
  86. if err != nil {
  87. return errors.Wrap(err, "installInitScript")
  88. }
  89. }
  90. return nil
  91. }
  92. func (w *SWindowsRootFs) DeployUserData(userData string) error {
  93. config, err := cloudinit.ParseUserData(userData)
  94. var scripts string
  95. if err != nil {
  96. scripts = userData
  97. } else {
  98. scripts = config.UserDataScript()
  99. }
  100. const scriptPath = "/windows/userdata.bat"
  101. err = w.rootFs.FilePutContents(scriptPath, scripts, false, true)
  102. if err != nil {
  103. return errors.Wrap(err, "save user_data fail")
  104. }
  105. userDataScript := strings.Join([]string{
  106. `set USER_DATA_SCRIPT=%SystemRoot%\userdata.bat`,
  107. `if exist %%USER_DATA_SCRIPT% (`,
  108. ` call %%USER_DATA_SCRIPT%`,
  109. ` del %%USER_DATA_SCRIPT%`,
  110. `)`,
  111. }, "\r\n")
  112. w.appendGuestBootScript("userdata", userDataScript)
  113. return nil
  114. }