diff --git a/api/api/api_interface.go b/api/api/api_interface.go index 219a12245..2258c1b5a 100644 --- a/api/api/api_interface.go +++ b/api/api/api_interface.go @@ -179,6 +179,7 @@ type ApplicationInterface interface { SyncAppConfigGroups(w http.ResponseWriter, r *http.Request) ListAppStatuses(w http.ResponseWriter, r *http.Request) CheckGovernanceMode(w http.ResponseWriter, r *http.Request) + ChangeVolumes(w http.ResponseWriter, r *http.Request) } //Gatewayer gateway api interface diff --git a/api/api_routers/version2/v2Routers.go b/api/api_routers/version2/v2Routers.go index d5d716c36..0e617f7ff 100644 --- a/api/api_routers/version2/v2Routers.go +++ b/api/api_routers/version2/v2Routers.go @@ -319,6 +319,7 @@ func (v2 *V2) applicationRouter() chi.Router { // Operation application r.Put("/", controller.GetManager().UpdateApp) r.Delete("/", controller.GetManager().DeleteApp) + r.Put("/volumes", controller.GetManager().ChangeVolumes) // Get services under application r.Get("/services", controller.GetManager().ListServices) // bind components diff --git a/api/controller/application.go b/api/controller/application.go index 20027980a..99f485a26 100644 --- a/api/controller/application.go +++ b/api/controller/application.go @@ -300,3 +300,15 @@ func (a *ApplicationController) CheckGovernanceMode(w http.ResponseWriter, r *ht } httputil.ReturnSuccess(r, w, nil) } + +// ChangeVolumes Since the component name supports modification, the storage directory of stateful components will change. +// This interface is used to modify the original directory name to the storage directory that will actually be used. +func (a *ApplicationController) ChangeVolumes(w http.ResponseWriter, r *http.Request) { + app := r.Context().Value(ctxutil.ContextKey("application")).(*dbmodel.Application) + err := handler.GetApplicationHandler().ChangeVolumes(app) + if err != nil { + httputil.ReturnBcodeError(r, w, err) + return + } + httputil.ReturnSuccess(r, w, nil) +} diff --git a/api/handler/application_handler.go b/api/handler/application_handler.go index 17286c35d..bc53cc7b0 100644 --- a/api/handler/application_handler.go +++ b/api/handler/application_handler.go @@ -4,8 +4,11 @@ import ( "context" "fmt" governance_mode "github.com/goodrain/rainbond/api/handler/app_governance_mode" + "io/ioutil" + "os" "sort" "strconv" + "strings" "time" "github.com/goodrain/rainbond/api/client/prometheus" @@ -63,6 +66,7 @@ type ApplicationHandler interface { SyncAppConfigGroups(app *dbmodel.Application, appConfigGroups []model.AppConfigGroup) error ListAppStatuses(ctx context.Context, appIDs []string) ([]*model.AppStatus, error) CheckGovernanceMode(ctx context.Context, governanceMode string) error + ChangeVolumes(app *dbmodel.Application) error } // NewApplicationHandler creates a new Tenant Application Handler. @@ -770,3 +774,68 @@ func (a *ApplicationAction) CheckGovernanceMode(ctx context.Context, governanceM } return nil } + +// ChangeVolumes Since the component name supports modification, the storage directory of stateful components will change. +// This interface is used to modify the original directory name to the storage directory that will actually be used. +func (a *ApplicationAction) ChangeVolumes(app *dbmodel.Application) error { + components, err := db.GetManager().TenantServiceDao().ListByAppID(app.AppID) + if err != nil { + return err + } + sharePath := os.Getenv("SHARE_DATA_PATH") + if sharePath == "" { + sharePath = "/grdata" + } + + var componentIDs []string + k8sComponentNames := make(map[string]string) + for _, component := range components { + if !component.IsState() { + continue + } + componentIDs = append(componentIDs, component.ServiceID) + k8sComponentNames[component.ServiceID] = component.K8sComponentName + } + volumes, err := db.GetManager().TenantServiceVolumeDao().ListVolumesByComponentIDs(componentIDs) + if err != nil { + return err + } + componentVolumes := make(map[string][]*dbmodel.TenantServiceVolume) + for _, volume := range volumes { + componentVolumes[volume.ServiceID] = append(componentVolumes[volume.ServiceID], volume) + } + + for componentID, singleComponentVols := range componentVolumes { + for _, componentVolume := range singleComponentVols { + parentDir := fmt.Sprintf("%s/tenant/%s/service/%s%s", sharePath, app.TenantID, componentID, componentVolume.VolumePath) + newPath := fmt.Sprintf("%s/%s-%s", parentDir, app.K8sApp, k8sComponentNames[componentID]) + if err := changeVolumeDirectoryNames(parentDir, newPath); err != nil { + return err + } + } + } + return nil +} + +func changeVolumeDirectoryNames(parentDir, newPath string) error { + files, _ := ioutil.ReadDir(parentDir) + for _, f := range files { + if !f.IsDir() { + continue + } + isEndWithNumber, suffix := util.IsEndWithNumber(f.Name()) + if isEndWithNumber { + oldPath := fmt.Sprintf("%s/%s", parentDir, f.Name()) + newVolPath := newPath + suffix + if err := os.Rename(oldPath, newVolPath); err != nil { + if err == os.ErrExist || strings.Contains(err.Error(), "file exists"){ + logrus.Infof("Ingore change volume path err: [%v]", err) + continue + } + return err + } + logrus.Infof("Success change volume path [%s] to [%s]", oldPath, newVolPath) + } + } + return nil +} diff --git a/gateway/annotations/annotations.go b/gateway/annotations/annotations.go index aada4902c..b974b324b 100644 --- a/gateway/annotations/annotations.go +++ b/gateway/annotations/annotations.go @@ -104,7 +104,7 @@ func (e Extractor) Extract(meta *metav1.ObjectMeta) *Ingress { pia := &Ingress{ ObjectMeta: *meta, } - err := mergo.MapWithOverwrite(pia, data) + err := mergo.Map(pia, data) if err != nil { logrus.Errorf("unexpected error merging extracted annotations: %v", err) } diff --git a/util/comman.go b/util/comman.go index a2798b357..dc560413d 100644 --- a/util/comman.go +++ b/util/comman.go @@ -818,3 +818,13 @@ func Elapsed(what string) func() { logrus.Debugf("%s took %v", what, time.Since(start)) } } + +// IsEndWithNumber Determine whether the stateful component directory name is satisfied, that is, it ends with a number +func IsEndWithNumber(dir string) (isEndWithNumber bool, suffix string) { + reg := regexp.MustCompile(`^*-[0-9]*?$`) + if reg == nil { + return false, "" + } + suffix = reg.FindString(dir) + return suffix != "", suffix +}