helper.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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 megactl
  15. import (
  16. "fmt"
  17. "strings"
  18. "yunion.io/x/log"
  19. "yunion.io/x/pkg/errors"
  20. api "yunion.io/x/onecloud/pkg/apis/compute"
  21. "yunion.io/x/onecloud/pkg/baremetal/utils/raid"
  22. "yunion.io/x/onecloud/pkg/compute/baremetal"
  23. )
  24. func storcliIsJBODEnabled(
  25. getCmd func(args ...string) (string, error),
  26. term raid.IExecTerm,
  27. ) bool {
  28. cmd, err := getCmd("show", "jbod")
  29. if err != nil {
  30. log.Errorf("get storcli controller cmd: %v", err)
  31. return false
  32. }
  33. lines, err := term.Run(cmd)
  34. if err != nil {
  35. log.Errorf("storcliIsJBODEnabled error: %s", err)
  36. return false
  37. }
  38. for _, line := range lines {
  39. line = strings.ToLower(line)
  40. if strings.HasPrefix(line, "jbod") {
  41. data := strings.Split(line, " ")
  42. if strings.TrimSpace(data[len(data)-1]) == "on" {
  43. return true
  44. }
  45. return false
  46. }
  47. }
  48. return false
  49. }
  50. func storcliEnableJBOD(
  51. getCmd func(args ...string) (string, error),
  52. term raid.IExecTerm,
  53. enable bool) bool {
  54. val := "off"
  55. if enable {
  56. val = "on"
  57. }
  58. cmd, err := getCmd("set", fmt.Sprintf("jbod=%s", val), "force")
  59. if err != nil {
  60. log.Errorf("get storcli controller cmd: %v", err)
  61. return false
  62. }
  63. _, err = term.Run(cmd)
  64. if err != nil {
  65. log.Errorf("EnableJBOD %v fail: %v", enable, err)
  66. return false
  67. }
  68. return true
  69. }
  70. func storcliBuildJBOD(
  71. getCmd func(args ...string) (string, error),
  72. term raid.IExecTerm,
  73. devs []*baremetal.BaremetalStorage) error {
  74. if !storcliIsJBODEnabled(getCmd, term) {
  75. storcliEnableJBOD(getCmd, term, true)
  76. storcliEnableJBOD(getCmd, term, false)
  77. storcliEnableJBOD(getCmd, term, true)
  78. }
  79. if !storcliIsJBODEnabled(getCmd, term) {
  80. return fmt.Errorf("JBOD not supported")
  81. }
  82. cmds := []string{}
  83. for _, d := range devs {
  84. // cmd := GetCommand2(fmt.Sprintf("/c%d/e%d/s%d", adapter.storcliIndex, d.Enclosure, d.Slot))
  85. cmd, err := getCmd()
  86. if err != nil {
  87. return errors.Wrapf(err, "getCmd for dev %#v", d)
  88. }
  89. cmd = fmt.Sprintf("%s/e%d/s%d", cmd, d.Enclosure, d.Slot)
  90. cmds = append(cmds, cmd)
  91. }
  92. log.Infof("storcliBuildJBOD cmds: %v", cmds)
  93. _, err := term.Run(cmds...)
  94. if err != nil {
  95. return err
  96. }
  97. return nil
  98. }
  99. func storcliBuildNoRaid(
  100. getCmd func(args ...string) (string, error),
  101. term raid.IExecTerm,
  102. devs []*baremetal.BaremetalStorage) error {
  103. err := storcliBuildJBOD(getCmd, term, devs)
  104. if err == nil {
  105. return nil
  106. }
  107. log.Errorf("Try storcli build JBOD fail: %v", err)
  108. labels := []string{}
  109. for _, dev := range devs {
  110. labels = append(labels, GetSpecString(dev))
  111. }
  112. args := []string{
  113. "add", "vd", "each", "type=raid0",
  114. fmt.Sprintf("drives=%s", strings.Join(labels, ",")),
  115. "wt", "nora", "direct",
  116. }
  117. cmd, err := getCmd(args...)
  118. if err != nil {
  119. return errors.Wrapf(err, "build none raid")
  120. }
  121. _, err = term.Run(cmd)
  122. return err
  123. }
  124. func storcliClearJBODDisks(
  125. getCmd func(args ...string) (string, error),
  126. term raid.IExecTerm,
  127. devs []*MegaRaidPhyDev,
  128. ) error {
  129. errs := make([]error, 0)
  130. for _, dev := range devs {
  131. cmd, err := getCmd()
  132. if err != nil {
  133. return errors.Wrap(err, "get cmd error")
  134. }
  135. cmd = fmt.Sprintf("%s/e%d/s%d set good force", cmd, dev.enclosure, dev.slot)
  136. if _, err := term.Run(cmd); err != nil {
  137. err = errors.Wrapf(err, "Set PD good storcli cmd %v", cmd)
  138. errs = append(errs, err)
  139. }
  140. }
  141. return errors.NewAggregate(errs)
  142. }
  143. func storcliBuildRaid(
  144. getCmd func(args ...string) (string, error),
  145. term raid.IExecTerm,
  146. devs []*baremetal.BaremetalStorage,
  147. conf *api.BaremetalDiskConfig,
  148. level uint,
  149. ) error {
  150. args := []string{}
  151. args = append(args, "add", "vd", fmt.Sprintf("type=r%d", level))
  152. args = append(args, conf2ParamsStorcliSize(conf)...)
  153. labels := []string{}
  154. for _, dev := range devs {
  155. labels = append(labels, GetSpecString(dev))
  156. }
  157. args = append(args, fmt.Sprintf("drives=%s", strings.Join(labels, ",")))
  158. if level == 10 {
  159. args = append(args, "PDperArray=2")
  160. }
  161. args = append(args, conf2ParamsStorcli(conf)...)
  162. cmd, err := getCmd(args...)
  163. if err != nil {
  164. return errors.Wrapf(err, "build raid %d", level)
  165. }
  166. if _, err := term.Run(cmd); err != nil {
  167. return err
  168. }
  169. return nil
  170. }
  171. func conf2ParamsStorcliSize(conf *api.BaremetalDiskConfig) []string {
  172. params := []string{}
  173. szStr := []string{}
  174. if len(conf.Size) > 0 {
  175. for _, sz := range conf.Size {
  176. szStr = append(szStr, fmt.Sprintf("%dMB", sz))
  177. }
  178. params = append(params, fmt.Sprintf("Size=%s", strings.Join(szStr, ",")))
  179. }
  180. return params
  181. }
  182. func conf2ParamsStorcli(conf *api.BaremetalDiskConfig) []string {
  183. params := []string{}
  184. if conf.WT != nil {
  185. if *conf.WT {
  186. params = append(params, "wt")
  187. } else {
  188. params = append(params, "wb")
  189. }
  190. }
  191. if conf.RA != nil {
  192. if *conf.RA {
  193. params = append(params, "ra")
  194. } else {
  195. params = append(params, "nora")
  196. }
  197. }
  198. if conf.Direct != nil {
  199. if *conf.Direct {
  200. params = append(params, "direct")
  201. } else {
  202. params = append(params, "cached")
  203. }
  204. }
  205. if conf.Cachedbadbbu != nil {
  206. if *conf.Cachedbadbbu {
  207. params = append(params, "CachedBadBBU")
  208. } else {
  209. params = append(params, "NoCachedBadBBU")
  210. }
  211. }
  212. if conf.Strip != nil {
  213. params = append(params, fmt.Sprintf("Strip=%d", *conf.Strip))
  214. }
  215. return params
  216. }