Unverified Commit 283baf36 authored by barnettZQG's avatar barnettZQG Committed by GitHub
Browse files

Merge pull request #1012 from GLYASAI/batch-operation

Feature: reason for event
parents 0768cd86 71f2c6fb
Showing with 56 additions and 38 deletions
+56 -38
......@@ -67,12 +67,12 @@ func (t *TenantStruct) StartService(w http.ResponseWriter, r *http.Request) {
tenant := r.Context().Value(middleware.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(middleware.ContextKey("service")).(*dbmodel.TenantServices)
sEvent := r.Context().Value(middleware.ContextKey("event")).(*dbmodel.ServiceEvent)
if err := handler.CheckTenantResource(r.Context(), tenant, service.Replicas*service.ContainerMemory); err != nil {
httputil.ReturnResNotEnough(r, w, err.Error())
httputil.ReturnResNotEnough(r, w, sEvent.EventID, err.Error())
return
}
sEvent := r.Context().Value(middleware.ContextKey("event")).(*dbmodel.ServiceEvent)
startStopStruct := &api_model.StartStopStruct{
TenantID: tenantID,
ServiceID: serviceID,
......@@ -168,7 +168,7 @@ func (t *TenantStruct) RestartService(w http.ResponseWriter, r *http.Request) {
tenant := r.Context().Value(middleware.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(middleware.ContextKey("service")).(*dbmodel.TenantServices)
if err := handler.CheckTenantResource(r.Context(), tenant, service.Replicas*service.ContainerMemory); err != nil {
httputil.ReturnResNotEnough(r, w, err.Error())
httputil.ReturnResNotEnough(r, w, sEvent.EventID, err.Error())
return
}
......@@ -219,7 +219,7 @@ func (t *TenantStruct) VerticalService(w http.ResponseWriter, r *http.Request) {
tenant := r.Context().Value(middleware.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(middleware.ContextKey("service")).(*dbmodel.TenantServices)
if err := handler.CheckTenantResource(r.Context(), tenant, service.Replicas*mem); err != nil {
httputil.ReturnResNotEnough(r, w, err.Error())
httputil.ReturnResNotEnough(r, w, sEvent.EventID, err.Error())
return
}
......@@ -274,7 +274,7 @@ func (t *TenantStruct) HorizontalService(w http.ResponseWriter, r *http.Request)
tenant := r.Context().Value(middleware.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(middleware.ContextKey("service")).(*dbmodel.TenantServices)
if err := handler.CheckTenantResource(r.Context(), tenant, service.ContainerMemory*int(replicas)); err != nil {
httputil.ReturnResNotEnough(r, w, err.Error())
httputil.ReturnResNotEnough(r, w, sEvent.EventID, err.Error())
return
}
......@@ -332,7 +332,7 @@ func (t *TenantStruct) BuildService(w http.ResponseWriter, r *http.Request) {
tenant := r.Context().Value(middleware.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(middleware.ContextKey("service")).(*dbmodel.TenantServices)
if err := handler.CheckTenantResource(r.Context(), tenant, service.Replicas*service.ContainerMemory); err != nil {
httputil.ReturnResNotEnough(r, w, err.Error())
httputil.ReturnResNotEnough(r, w, build.EventID, err.Error())
return
}
......@@ -548,7 +548,7 @@ func (t *TenantStruct) UpgradeService(w http.ResponseWriter, r *http.Request) {
tenant := r.Context().Value(middleware.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(middleware.ContextKey("service")).(*dbmodel.TenantServices)
if err := handler.CheckTenantResource(r.Context(), tenant, service.Replicas*service.ContainerMemory); err != nil {
httputil.ReturnResNotEnough(r, w, err.Error())
httputil.ReturnResNotEnough(r, w, upgradeRequest.EventID, err.Error())
return
}
......@@ -638,7 +638,7 @@ func (t *TenantStruct) RollBack(w http.ResponseWriter, r *http.Request) {
tenant := r.Context().Value(middleware.ContextKey("tenant")).(*dbmodel.Tenants)
service := r.Context().Value(middleware.ContextKey("service")).(*dbmodel.TenantServices)
if err := handler.CheckTenantResource(r.Context(), tenant, service.Replicas*service.ContainerMemory); err != nil {
httputil.ReturnResNotEnough(r, w, err.Error())
httputil.ReturnResNotEnough(r, w, rollbackRequest.EventID, err.Error())
return
}
......
......@@ -59,27 +59,6 @@ func CreateBatchOperationHandler(mqCli gclient.MQClient, statusCli *client.AppRu
}
}
func setStartupSequenceConfig(configs map[string]string, depsids []string) map[string]string {
configs["boot_seq_dep_service_ids"] = strings.Join(depsids, ",")
return configs
}
func checkResourceEnough(serviceID string) error {
service, err := db.GetManager().TenantServiceDao().GetServiceByID(serviceID)
if err != nil {
logrus.Errorf("get service by id error, %v", err)
return err
}
tenant, err := db.GetManager().TenantDao().GetTenantByUUID(service.TenantID)
if err != nil {
logrus.Errorf("get tenant by id error: %v", err)
return err
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
return CheckTenantResource(ctx, tenant, service.ContainerMemory*service.Replicas)
}
func (b *BatchOperationHandler) serviceStartupSequence(serviceIDs []string) map[string][]string {
sd, err := NewServiceDependency(serviceIDs)
if err != nil {
......@@ -112,7 +91,7 @@ func (b *BatchOperationHandler) Build(ctx context.Context, tenant *dbmodel.Tenan
batchOpResult = append(batchOpResult, batchOpResult2...)
// create events
if err := b.createEvents(tenant.UUID, operator, batchOpReqs); err != nil {
if err := b.createEvents(tenant.UUID, operator, batchOpReqs, allocm.badOpRequest, allocm.memoryType); err != nil {
return nil, err
}
......@@ -158,7 +137,7 @@ func (b *BatchOperationHandler) Start(ctx context.Context, tenant *dbmodel.Tenan
batchOpResult = append(batchOpResult, batchOpResult2...)
// create events
if err := b.createEvents(tenant.UUID, operator, batchOpReqs); err != nil {
if err := b.createEvents(tenant.UUID, operator, batchOpReqs, allocm.BadOpRequests(), allocm.memoryType); err != nil {
return nil, err
}
......@@ -192,7 +171,7 @@ func (b *BatchOperationHandler) Stop(ctx context.Context, tenant *dbmodel.Tenant
batchOpReqs, batchOpResult := b.checkEvents(batchOpReqs)
// create events
if err := b.createEvents(tenant.UUID, operator, batchOpReqs); err != nil {
if err := b.createEvents(tenant.UUID, operator, batchOpReqs, nil, ""); err != nil {
return nil, err
}
......@@ -237,7 +216,7 @@ func (b *BatchOperationHandler) Upgrade(ctx context.Context, tenant *dbmodel.Ten
batchOpResult = append(batchOpResult, batchOpResult2...)
// create events
if err := b.createEvents(tenant.UUID, operator, batchOpReqs); err != nil {
if err := b.createEvents(tenant.UUID, operator, batchOpReqs, allocm.BadOpRequests(), allocm.memoryType); err != nil {
return nil, err
}
......@@ -279,11 +258,17 @@ func (b *BatchOperationHandler) checkEvents(batchOpReqs model.BatchOpRequesters)
}
return validReqs, batchOpResult
}
func (b *BatchOperationHandler) createEvents(tenantID, operator string, batchOpReqs model.BatchOpRequesters) error {
func (b *BatchOperationHandler) createEvents(tenantID, operator string, batchOpReqs, badOpReqs model.BatchOpRequesters, memoryType string) error {
if logrus.IsLevelEnabled(logrus.DebugLevel) {
defer util.Elapsed("[BatchOperationHandler] create events")()
}
bads := make(map[string]struct{})
for _, req := range badOpReqs {
bads[req.GetEventID()] = struct{}{}
}
var events []*dbmodel.ServiceEvent
for _, req := range batchOpReqs {
event := &dbmodel.ServiceEvent{
......@@ -296,6 +281,14 @@ func (b *BatchOperationHandler) createEvents(tenantID, operator string, batchOpR
SynType: dbmodel.ASYNEVENTTYPE,
OptType: req.OpType(),
}
_, ok := bads[req.GetEventID()]
if ok {
event.Reason = memoryType
event.EndTime = event.StartTime
event.FinalStatus = "complete"
event.Status = "failure"
}
events = append(events, event)
}
......@@ -432,9 +425,7 @@ func (s *ServiceDependency) buildLinkListByHead(l *list.List) []*list.List {
if len(sublists) == 0 {
result = append(result, newl)
} else {
for _, sublist := range sublists {
result = append(result, sublist)
}
result = append(result, sublists...)
}
}
......@@ -473,9 +464,11 @@ func alreadyInLinkedList(l *list.List, depsid string) bool {
type AllocMemory struct {
tenant *dbmodel.Tenants
allcm *int64
memoryType string
components map[string]*dbmodel.TenantServices
batchOpResult model.BatchOpResult
batchOpRequests model.BatchOpRequesters
badOpRequest model.BatchOpRequesters
}
// NewAllocMemory creates a new AllocMemory.
......@@ -495,12 +488,14 @@ func NewAllocMemory(ctx context.Context, statusCli *client.AppRuntimeSyncClient,
}
allocm := tenant.LimitMemory - int(tenantUsedResource.MemoryLimit)
am.allcm = util.Int64(int64(allocm))
am.memoryType = "tenant_lack_of_memory"
} else {
allcm, err := ClusterAllocMemory(ctx)
if err != nil {
return nil, err
}
am.allcm = util.Int64(allcm)
am.memoryType = "cluster_lack_of_memory"
}
components, err := am.listComponents(batchOpReqs.ComponentIDs())
......@@ -512,18 +507,21 @@ func NewAllocMemory(ctx context.Context, statusCli *client.AppRuntimeSyncClient,
// check alloc memory for every components.
var reqs model.BatchOpRequesters
var batchOpResult model.BatchOpResult
var badOpRequest model.BatchOpRequesters
for _, req := range batchOpReqs {
req := req
if err := am.check(req.GetComponentID()); err != nil {
item := req.BatchOpFailureItem()
item.ErrMsg = err.Error()
batchOpResult = append(batchOpResult, item)
badOpRequest = append(badOpRequest, req)
continue
}
reqs = append(reqs, req)
}
am.batchOpResult = batchOpResult
am.batchOpRequests = reqs
am.badOpRequest = badOpRequest
return am, nil
}
......@@ -538,6 +536,11 @@ func (a *AllocMemory) BatchOpRequests() model.BatchOpRequesters {
return a.batchOpRequests
}
// BadOpRequests returns the badOpRequests.
func (a *AllocMemory) BadOpRequests() model.BatchOpRequesters {
return a.badOpRequest
}
func (a *AllocMemory) listComponents(componentIDs []string) (map[string]*dbmodel.TenantServices, error) {
components, err := db.GetManager().TenantServiceDao().GetServiceByIDs(componentIDs)
if err != nil {
......
......@@ -390,6 +390,7 @@ type EventDao interface {
GetLastASyncEvent(target, targetID string) (*model.ServiceEvent, error)
UnfinishedEvents(target, targetID string, optTypes ...string) ([]*model.ServiceEvent, error)
LatestFailurePodEvent(podName string) (*model.ServiceEvent, error)
UpdateReason(eventID string, reason string) error
}
//VersionInfoDao VersionInfoDao
......
......@@ -92,6 +92,7 @@ type ServiceEvent struct {
Status string `gorm:"column:status;size:40"`
FinalStatus string `gorm:"column:final_status;size:40"`
Message string `gorm:"column:message"`
Reason string `gorm:"column:reason"`
}
//TableName 表名
......
......@@ -75,6 +75,11 @@ func (c *EventDaoImpl) CreateEventsInBatch(events []*model.ServiceEvent) error {
return nil
}
// UpdateReason update reasion.
func (c *EventDaoImpl) UpdateReason(eventID string, reason string) error {
return c.DB.Model(&model.ServiceEvent{}).Where("event_id=?", eventID).UpdateColumn("reason", reason).Error
}
//GetEventByEventID get event log message
func (c *EventDaoImpl) GetEventByEventID(eventID string) (*model.ServiceEvent, error) {
var result model.ServiceEvent
......
......@@ -30,7 +30,9 @@ import (
"github.com/go-chi/render"
"github.com/go-playground/validator/v10"
"github.com/goodrain/rainbond/api/util/bcode"
"github.com/goodrain/rainbond/db"
govalidator "github.com/goodrain/rainbond/util/govalidator"
"github.com/jinzhu/gorm"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)
......@@ -195,8 +197,14 @@ func ReturnNoFomart(r *http.Request, w http.ResponseWriter, code int, reb interf
}
//ReturnResNotEnough http return node resource not enough, http code = 412
func ReturnResNotEnough(r *http.Request, w http.ResponseWriter, msg string) {
func ReturnResNotEnough(r *http.Request, w http.ResponseWriter, eventID, msg string) {
logrus.Debugf("resource not enough, msg: %s", msg)
if err := db.GetManager().ServiceEventDao().UpdateReason(eventID, msg); err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
logrus.Warningf("update event reason: %v", err)
}
}
r = r.WithContext(context.WithValue(r.Context(), render.StatusCtxKey, 412))
render.DefaultResponder(w, r, ResponseBody{Msg: msg})
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment