Fix the storage loss caused by modifying the English name of the component

This commit is contained in:
yangk 2021-12-05 18:25:44 +08:00
parent 52c8bb538f
commit 5011b94a4c
6 changed files with 94 additions and 1 deletions

View File

@ -179,6 +179,7 @@ type ApplicationInterface interface {
SyncAppConfigGroups(w http.ResponseWriter, r *http.Request) SyncAppConfigGroups(w http.ResponseWriter, r *http.Request)
ListAppStatuses(w http.ResponseWriter, r *http.Request) ListAppStatuses(w http.ResponseWriter, r *http.Request)
CheckGovernanceMode(w http.ResponseWriter, r *http.Request) CheckGovernanceMode(w http.ResponseWriter, r *http.Request)
ChangeVolumes(w http.ResponseWriter, r *http.Request)
} }
//Gatewayer gateway api interface //Gatewayer gateway api interface

View File

@ -319,6 +319,7 @@ func (v2 *V2) applicationRouter() chi.Router {
// Operation application // Operation application
r.Put("/", controller.GetManager().UpdateApp) r.Put("/", controller.GetManager().UpdateApp)
r.Delete("/", controller.GetManager().DeleteApp) r.Delete("/", controller.GetManager().DeleteApp)
r.Put("/volumes", controller.GetManager().ChangeVolumes)
// Get services under application // Get services under application
r.Get("/services", controller.GetManager().ListServices) r.Get("/services", controller.GetManager().ListServices)
// bind components // bind components

View File

@ -300,3 +300,15 @@ func (a *ApplicationController) CheckGovernanceMode(w http.ResponseWriter, r *ht
} }
httputil.ReturnSuccess(r, w, nil) 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)
}

View File

@ -4,8 +4,11 @@ import (
"context" "context"
"fmt" "fmt"
governance_mode "github.com/goodrain/rainbond/api/handler/app_governance_mode" governance_mode "github.com/goodrain/rainbond/api/handler/app_governance_mode"
"io/ioutil"
"os"
"sort" "sort"
"strconv" "strconv"
"strings"
"time" "time"
"github.com/goodrain/rainbond/api/client/prometheus" "github.com/goodrain/rainbond/api/client/prometheus"
@ -63,6 +66,7 @@ type ApplicationHandler interface {
SyncAppConfigGroups(app *dbmodel.Application, appConfigGroups []model.AppConfigGroup) error SyncAppConfigGroups(app *dbmodel.Application, appConfigGroups []model.AppConfigGroup) error
ListAppStatuses(ctx context.Context, appIDs []string) ([]*model.AppStatus, error) ListAppStatuses(ctx context.Context, appIDs []string) ([]*model.AppStatus, error)
CheckGovernanceMode(ctx context.Context, governanceMode string) error CheckGovernanceMode(ctx context.Context, governanceMode string) error
ChangeVolumes(app *dbmodel.Application) error
} }
// NewApplicationHandler creates a new Tenant Application Handler. // NewApplicationHandler creates a new Tenant Application Handler.
@ -770,3 +774,68 @@ func (a *ApplicationAction) CheckGovernanceMode(ctx context.Context, governanceM
} }
return nil 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
}

View File

@ -104,7 +104,7 @@ func (e Extractor) Extract(meta *metav1.ObjectMeta) *Ingress {
pia := &Ingress{ pia := &Ingress{
ObjectMeta: *meta, ObjectMeta: *meta,
} }
err := mergo.MapWithOverwrite(pia, data) err := mergo.Map(pia, data)
if err != nil { if err != nil {
logrus.Errorf("unexpected error merging extracted annotations: %v", err) logrus.Errorf("unexpected error merging extracted annotations: %v", err)
} }

View File

@ -818,3 +818,13 @@ func Elapsed(what string) func() {
logrus.Debugf("%s took %v", what, time.Since(start)) 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
}