mirror of
https://github.com/XShengTech/MEGREZ.git
synced 2026-01-13 16:47:16 +08:00
143 lines
3.8 KiB
Go
143 lines
3.8 KiB
Go
package instances
|
|
|
|
import (
|
|
"megrez/models"
|
|
"megrez/routers/api/v1/middleware"
|
|
"megrez/services/database"
|
|
"megrez/services/dispatcher"
|
|
"megrez/services/redis"
|
|
"strconv"
|
|
|
|
"github.com/kataras/iris/v12"
|
|
)
|
|
|
|
type modifyReqStruct struct {
|
|
CpuOnly bool `json:"cpu_only"`
|
|
GpuCount *int `json:"gpu_count"`
|
|
VolumeSize *int `json:"volume_size"`
|
|
}
|
|
|
|
func modifyHandler(ctx iris.Context) {
|
|
l.SetFunction("modifyHandler")
|
|
|
|
id, err := ctx.Params().GetUint("id")
|
|
if err != nil {
|
|
middleware.Error(ctx, middleware.CodeBadRequest, iris.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
var req modifyReqStruct
|
|
err = ctx.ReadJSON(&req)
|
|
if err != nil {
|
|
middleware.Error(ctx, middleware.CodeBadRequest, iris.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if req.CpuOnly {
|
|
req.GpuCount = nil
|
|
}
|
|
|
|
if req.GpuCount != nil {
|
|
if *req.GpuCount < 0 {
|
|
middleware.Error(ctx, middleware.CodeBadRequest, iris.StatusBadRequest)
|
|
return
|
|
}
|
|
}
|
|
|
|
if req.VolumeSize != nil {
|
|
if *req.VolumeSize < 50 {
|
|
middleware.Error(ctx, middleware.CodeBadRequest, iris.StatusBadRequest)
|
|
return
|
|
}
|
|
}
|
|
|
|
instance := models.Instances{
|
|
ID: id,
|
|
}
|
|
result := database.DB.First(&instance)
|
|
if result.Error != nil {
|
|
l.Error("query instance error: %v", result.Error)
|
|
middleware.Error(ctx, middleware.CodeInstanceQueryError, iris.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if instance.Status != models.InstanceStatusStopped {
|
|
middleware.Error(ctx, middleware.CodeInstanceStatusError, iris.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
hasChanges := false
|
|
if req.CpuOnly != instance.CpuOnly {
|
|
hasChanges = true
|
|
}
|
|
if req.GpuCount != nil && *req.GpuCount != instance.GpuCount {
|
|
hasChanges = true
|
|
}
|
|
if req.VolumeSize != nil && *req.VolumeSize != instance.VolumeSize {
|
|
hasChanges = true
|
|
}
|
|
if !hasChanges {
|
|
middleware.Error(ctx, middleware.CodeBadRequest, iris.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
server := models.Servers{
|
|
ID: instance.ServerID,
|
|
}
|
|
result = database.DB.First(&server)
|
|
if result.Error != nil {
|
|
l.Error("query server error: %v", result.Error)
|
|
middleware.Error(ctx, middleware.CodeServerQueryError, iris.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if req.GpuCount != nil {
|
|
remainGpu, err := redis.RawDB.IncrBy(ctx, "remain_gpu:server:"+strconv.Itoa(int(server.ID)), int64(-*req.GpuCount)).Result()
|
|
if err != nil {
|
|
l.Error("incrby gpu num error: %v", err)
|
|
middleware.Error(ctx, middleware.CodeServerQueryError, iris.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if remainGpu < 0 {
|
|
redis.RawDB.IncrBy(ctx, "remain_gpu:server:"+strconv.Itoa(int(server.ID)), int64(*req.GpuCount))
|
|
middleware.Error(ctx, middleware.CodeResourceInsufficient, iris.StatusBadRequest)
|
|
return
|
|
}
|
|
}
|
|
if req.VolumeSize != nil {
|
|
remainVolume, err := redis.RawDB.IncrBy(ctx, "remain_volume:server:"+strconv.Itoa(int(server.ID)), int64(instance.VolumeSize-*req.VolumeSize)).Result()
|
|
if err != nil {
|
|
l.Error("incrby volume size error: %v", err)
|
|
middleware.Error(ctx, middleware.CodeServerQueryError, iris.StatusInternalServerError)
|
|
return
|
|
}
|
|
if remainVolume < 0 {
|
|
redis.RawDB.IncrBy(ctx, "remain_volume:server:"+strconv.Itoa(int(server.ID)), int64(*req.VolumeSize-instance.VolumeSize))
|
|
middleware.Error(ctx, middleware.CodeResourceInsufficient, iris.StatusBadRequest)
|
|
return
|
|
}
|
|
}
|
|
|
|
status := instance.Status
|
|
result = database.DB.Model(&instance).Update("status", models.InstanceStatusModifying)
|
|
if result.Error != nil {
|
|
l.Error("update instance status error: %v", result.Error)
|
|
middleware.Error(ctx, middleware.CodeServerSaveError, iris.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
dispatcherData := dispatcher.Data{
|
|
Type: dispatcher.Modify,
|
|
InstanceID: instance.ID,
|
|
Status: status,
|
|
|
|
CpuOnly: req.CpuOnly,
|
|
GpuCount: req.GpuCount,
|
|
VolumeSize: req.VolumeSize,
|
|
}
|
|
dispatcher.Push(instance.ServerID, dispatcherData)
|
|
|
|
middleware.Success(ctx)
|
|
}
|