mgr.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. Copyright 2019 The Rook Authors. All rights reserved.
  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. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package client
  14. import (
  15. "encoding/json"
  16. "time"
  17. "github.com/pkg/errors"
  18. "github.com/rook/rook/pkg/clusterd"
  19. )
  20. var (
  21. moduleEnableWaitTime = 5 * time.Second
  22. )
  23. func CephMgrMap(context *clusterd.Context, clusterInfo *ClusterInfo) (*MgrMap, error) {
  24. args := []string{"mgr", "dump"}
  25. buf, err := NewCephCommand(context, clusterInfo, args).Run()
  26. if err != nil {
  27. if len(buf) > 0 {
  28. return nil, errors.Wrapf(err, "failed to get mgr dump. %s", string(buf))
  29. }
  30. return nil, errors.Wrap(err, "failed to get mgr dump")
  31. }
  32. var mgrMap MgrMap
  33. if err := json.Unmarshal([]byte(buf), &mgrMap); err != nil {
  34. return nil, errors.Wrap(err, "failed to unmarshal mgr dump")
  35. }
  36. return &mgrMap, nil
  37. }
  38. func CephMgrStat(context *clusterd.Context, clusterInfo *ClusterInfo) (*MgrStat, error) {
  39. args := []string{"mgr", "stat"}
  40. buf, err := NewCephCommand(context, clusterInfo, args).Run()
  41. if err != nil {
  42. if len(buf) > 0 {
  43. return nil, errors.Wrapf(err, "failed to get mgr stat. %s", string(buf))
  44. }
  45. return nil, errors.Wrap(err, "failed to get mgr stat")
  46. }
  47. var mgrStat MgrStat
  48. if err := json.Unmarshal([]byte(buf), &mgrStat); err != nil {
  49. return nil, errors.Wrap(err, "failed to unmarshal mgr stat")
  50. }
  51. return &mgrStat, nil
  52. }
  53. // MgrEnableModule enables a mgr module
  54. func MgrEnableModule(context *clusterd.Context, clusterInfo *ClusterInfo, name string, force bool) error {
  55. retryCount := 5
  56. var err error
  57. for i := 0; i < retryCount; i++ {
  58. if name == "balancer" {
  59. logger.Debug("balancer module is always 'on', doing nothing", name)
  60. return nil
  61. } else {
  62. err = enableModule(context, clusterInfo, name, force, "enable")
  63. }
  64. if err != nil {
  65. if i < retryCount-1 {
  66. logger.Warningf("failed to enable mgr module %q. trying again...", name)
  67. time.Sleep(moduleEnableWaitTime)
  68. continue
  69. } else {
  70. return errors.Wrapf(err, "failed to enable mgr module %q even after %d retries", name, retryCount)
  71. }
  72. }
  73. break
  74. }
  75. return nil
  76. }
  77. // MgrDisableModule disables a mgr module
  78. func MgrDisableModule(context *clusterd.Context, clusterInfo *ClusterInfo, name string) error {
  79. if name == "balancer" {
  80. return enableDisableBalancerModule(context, clusterInfo, "off")
  81. }
  82. return enableModule(context, clusterInfo, name, false, "disable")
  83. }
  84. func enableModule(context *clusterd.Context, clusterInfo *ClusterInfo, name string, force bool, action string) error {
  85. args := []string{"mgr", "module", action, name}
  86. if force {
  87. args = append(args, "--force")
  88. }
  89. _, err := NewCephCommand(context, clusterInfo, args).Run()
  90. if err != nil {
  91. return errors.Wrapf(err, "failed to enable mgr module %q", name)
  92. }
  93. return nil
  94. }
  95. // enableDisableBalancerModule enables the ceph balancer module
  96. func enableDisableBalancerModule(context *clusterd.Context, clusterInfo *ClusterInfo, action string) error {
  97. args := []string{"balancer", action}
  98. _, err := NewCephCommand(context, clusterInfo, args).Run()
  99. if err != nil {
  100. return errors.Wrapf(err, "failed to turn %q the balancer module", action)
  101. }
  102. return nil
  103. }
  104. func setBalancerMode(context *clusterd.Context, clusterInfo *ClusterInfo, mode string) error {
  105. args := []string{"balancer", "mode", mode}
  106. _, err := NewCephCommand(context, clusterInfo, args).Run()
  107. if err != nil {
  108. return errors.Wrapf(err, "failed to set balancer mode %q", mode)
  109. }
  110. return nil
  111. }
  112. // setMinCompatClientLuminous set the minimum compatibility for clients to Luminous
  113. func setMinCompatClientLuminous(context *clusterd.Context, clusterInfo *ClusterInfo) error {
  114. args := []string{"osd", "set-require-min-compat-client", "luminous", "--yes-i-really-mean-it"}
  115. _, err := NewCephCommand(context, clusterInfo, args).Run()
  116. if err != nil {
  117. return errors.Wrap(err, "failed to set set-require-min-compat-client to luminous")
  118. }
  119. return nil
  120. }
  121. // mgrSetBalancerMode sets the given mode to the balancer module
  122. func mgrSetBalancerMode(context *clusterd.Context, clusterInfo *ClusterInfo, balancerModuleMode string) error {
  123. retryCount := 5
  124. for i := 0; i < retryCount; i++ {
  125. err := setBalancerMode(context, clusterInfo, balancerModuleMode)
  126. if err != nil {
  127. if i < retryCount-1 {
  128. logger.Warningf("failed to set mgr module mode %q. trying again...", balancerModuleMode)
  129. time.Sleep(moduleEnableWaitTime)
  130. continue
  131. } else {
  132. return errors.Wrapf(err, "failed to set mgr module mode %q even after %d retries", balancerModuleMode, retryCount)
  133. }
  134. }
  135. break
  136. }
  137. return nil
  138. }
  139. // ConfigureBalancerModule configures the balancer module
  140. func ConfigureBalancerModule(context *clusterd.Context, clusterInfo *ClusterInfo, balancerModuleMode string) error {
  141. // Set min compat client to luminous before enabling the balancer mode "upmap"
  142. err := setMinCompatClientLuminous(context, clusterInfo)
  143. if err != nil {
  144. return errors.Wrap(err, "failed to set minimum compatibility client")
  145. }
  146. // Set balancer module mode
  147. err = mgrSetBalancerMode(context, clusterInfo, balancerModuleMode)
  148. if err != nil {
  149. return errors.Wrapf(err, "failed to set balancer module mode to %q", balancerModuleMode)
  150. }
  151. return nil
  152. }