macos.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. "path"
  18. "strings"
  19. "yunion.io/x/pkg/utils"
  20. "yunion.io/x/onecloud/pkg/apis"
  21. "yunion.io/x/onecloud/pkg/cloudcommon/types"
  22. deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis"
  23. "yunion.io/x/onecloud/pkg/util/macutils"
  24. "yunion.io/x/onecloud/pkg/util/seclib2"
  25. "yunion.io/x/onecloud/pkg/util/stringutils2"
  26. )
  27. type SMacOSRootFs struct {
  28. *sGuestRootFsDriver
  29. scripts []string
  30. }
  31. func NewMacOSRootFs(part IDiskPartition) IRootFsDriver {
  32. return &SMacOSRootFs{sGuestRootFsDriver: newGuestRootFsDriver(part)}
  33. }
  34. func (m *SMacOSRootFs) IsFsCaseInsensitive() bool {
  35. return false
  36. }
  37. func (m *SMacOSRootFs) GetName() string {
  38. return "macOS"
  39. }
  40. func (m *SMacOSRootFs) String() string {
  41. return "MacOSRootFs"
  42. }
  43. func (m *SMacOSRootFs) GetLoginAccount(rootFs IDiskPartition, user string, defaultRootUser bool, windowsDefaultAdminUser bool) (string, error) {
  44. selUsr := ""
  45. usrs := m.rootFs.ListDir("/Users", false)
  46. if len(usrs) > 0 {
  47. for _, usr := range usrs {
  48. if usr != "Shared" && usr[0] != '.' {
  49. if len(selUsr) < len(usr) {
  50. selUsr = usr
  51. }
  52. }
  53. }
  54. }
  55. return selUsr, nil
  56. }
  57. func (m *SMacOSRootFs) RootSignatures() []string {
  58. return []string{
  59. "/Applications", "/Library", "/Network",
  60. "/System", "/System/Library", "/Volumes", "/Users", "/usr",
  61. "/private/etc", "/private/var", "/bin", "/sbin", "/dev",
  62. }
  63. }
  64. func (m *SMacOSRootFs) DeployPublicKey(rootfs IDiskPartition, uname string, pubkeys *deployapi.SSHKeys) error {
  65. usrDir := fmt.Sprintf("/Users/%s", uname)
  66. return DeployAuthorizedKeys(m.rootFs, usrDir, pubkeys, false, false)
  67. }
  68. func (m *SMacOSRootFs) addScripts(lines []string) {
  69. if m.scripts == nil {
  70. m.scripts = []string{}
  71. }
  72. m.scripts = append(m.scripts, lines...)
  73. m.scripts = append(m.scripts, "")
  74. }
  75. func (m *SMacOSRootFs) ChangeUserPasswd(part IDiskPartition, account, gid, publicKey, password string, isRandomPassword bool) (string, error) {
  76. lines := []string{
  77. fmt.Sprintf("dscl . -passwd /Users/%s %s", account, password),
  78. fmt.Sprintf("rm -fr /Users/%s/Library/Keychains/*", account),
  79. }
  80. m.addScripts(lines)
  81. if len(publicKey) > 0 {
  82. return seclib2.EncryptBase64(publicKey, password)
  83. } else {
  84. return utils.EncryptAESBase64(gid, password)
  85. }
  86. }
  87. func (m *SMacOSRootFs) DeployHostname(part IDiskPartition, hostname, domain string) error {
  88. lines := []string{
  89. fmt.Sprintf("scutil --set HostName '%s'",
  90. stringutils2.EscapeString(hostname, nil)),
  91. fmt.Sprintf("scutil --set ComputerName '%s'",
  92. stringutils2.EscapeString(hostname, nil)),
  93. fmt.Sprintf("scutil --set LocalHostName '%s'",
  94. stringutils2.EscapeString(hostname, nil)),
  95. }
  96. m.addScripts(lines)
  97. return nil
  98. }
  99. func (m *SMacOSRootFs) DeployHosts(part IDiskPartition, hn, domain string, ips []string) error {
  100. return nil
  101. }
  102. func (m *SMacOSRootFs) GetReleaseInfo(IDiskPartition) *deployapi.ReleaseInfo {
  103. spath := "/System/Library/CoreServices/SystemVersion.plist"
  104. sInfo, _ := m.rootFs.FileGetContents(spath, false)
  105. info := macutils.ParsePlist(sInfo)
  106. distro, _ := info["ProductName"]
  107. version, _ := info["ProductUserVisibleVersion"]
  108. return &deployapi.ReleaseInfo{
  109. Distro: distro,
  110. Version: version,
  111. Arch: apis.OS_ARCH_X86_64,
  112. }
  113. }
  114. func (m *SMacOSRootFs) GetOs() string {
  115. return "macOs"
  116. }
  117. func (m *SMacOSRootFs) DeployNetworkingScripts(rootfs IDiskPartition, nics []*types.SServerNic) error {
  118. return nil
  119. }
  120. func (m *SMacOSRootFs) PrepareFsForTemplate(IDiskPartition) error {
  121. sshDir := "/private/etc/ssh"
  122. if m.rootFs.Exists(sshDir, false) {
  123. for _, f := range m.rootFs.ListDir(sshDir, false) {
  124. if strings.HasSuffix(f, "_key") || strings.HasSuffix(f, "_key.pub") {
  125. m.rootFs.Remove(path.Join(sshDir, f), false)
  126. }
  127. }
  128. }
  129. tmpDirs := []string{"/private/tmp", "/private/var/tmp",
  130. "/private/var/vm",
  131. "/System/Library/Caches",
  132. "/Library/Caches"}
  133. logDirs := []string{"/var/log", "/Library/Logs"}
  134. users := m.rootFs.ListDir("/Users", false)
  135. if len(users) > 0 {
  136. for _, usr := range users {
  137. if usr != "Shared" && usr[0] != '.' {
  138. tmpDirs = append(tmpDirs, fmt.Sprintf("/Users/%s/Library", usr))
  139. }
  140. }
  141. }
  142. for _, dir := range tmpDirs {
  143. if m.rootFs.Exists(dir, false) {
  144. if err := m.rootFs.Cleandir(dir, false, false); err != nil {
  145. return err
  146. }
  147. }
  148. }
  149. for _, dir := range logDirs {
  150. if m.rootFs.Exists(dir, false) {
  151. if err := m.rootFs.Zerofiles(dir, false); err != nil {
  152. return err
  153. }
  154. }
  155. }
  156. for _, dir := range []string{"/private/var/spool", "/private/var/run"} {
  157. if m.rootFs.Exists(dir, false) {
  158. if err := m.rootFs.Cleandir(dir, true, false); err != nil {
  159. return err
  160. }
  161. }
  162. }
  163. return nil
  164. }
  165. func (m *SMacOSRootFs) CommitChanges(part IDiskPartition) error {
  166. var (
  167. label = "com.meituan.cloud_init"
  168. spath = "/private/var/cloud_init.sh"
  169. )
  170. cont := macutils.LaunchdRun(label, spath)
  171. if err := m.rootFs.FilePutContents(fmt.Sprintf("/Library/LaunchDaemons/%s.plist", label), cont, false, false); err != nil {
  172. return err
  173. }
  174. lines := []string{"systemsetup -setcomputersleep Never",
  175. "systemsetup -setdisplaysleep Never",
  176. "systemsetup -setharddisksleep Never",
  177. "systemsetup -settimezone Asia/Shanghai",
  178. "networksetup -detectnewhardware",
  179. // # "diskutil disableJournal /",
  180. }
  181. m.addScripts(lines)
  182. m.addScripts([]string{fmt.Sprintf("echo > %s", spath)})
  183. cont = strings.Join(m.scripts, "\n") + "\n"
  184. return m.rootFs.FilePutContents(spath, cont, false, false)
  185. }
  186. func (d *SMacOSRootFs) ConfigSshd(loginAccount, loginPassword string, sshPort int) error {
  187. return nil
  188. }