mirror of
https://github.com/XShengTech/MEGREZ.git
synced 2026-01-14 00:57:17 +08:00
136 lines
4.3 KiB
Go
136 lines
4.3 KiB
Go
package instances
|
|
|
|
import (
|
|
"megrez/models"
|
|
"megrez/routers/api/v1/middleware"
|
|
"megrez/services/database"
|
|
"megrez/services/dispatcher"
|
|
"megrez/services/instanceController"
|
|
"megrez/services/redis"
|
|
"strconv"
|
|
|
|
"github.com/kataras/iris/v12"
|
|
)
|
|
|
|
type controlStruct struct {
|
|
Action instanceController.Action `json:"action"` // 1: start, 2: pause , 3: stop, 4: restart
|
|
}
|
|
|
|
func controlHandler(ctx iris.Context) {
|
|
id, err := ctx.Params().GetUint("id")
|
|
if err != nil {
|
|
middleware.Error(ctx, middleware.CodeBadRequest, iris.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
var req controlStruct
|
|
err = ctx.ReadJSON(&req)
|
|
if err != nil {
|
|
middleware.Error(ctx, middleware.CodeBadRequest, iris.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
instance := models.Instances{
|
|
ID: id,
|
|
}
|
|
result := database.DB.First(&instance)
|
|
if result.Error != nil {
|
|
l.Error("detail instance error: %v", result.Error)
|
|
middleware.Error(ctx, middleware.CodeInstanceDetailError, iris.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if models.InstanceIngStatusCheck(instance.Status) {
|
|
middleware.Error(ctx, middleware.CodeInstanceStatusError, iris.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if req.Action == instanceController.ActionStop && instance.Status != models.InstanceRunning && instance.Status != models.InstancePaused {
|
|
middleware.Error(ctx, middleware.CodeInstanceStatusError, iris.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if req.Action == instanceController.ActionPause && instance.Status != models.InstanceRunning {
|
|
middleware.Error(ctx, middleware.CodeInstanceStatusError, iris.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if req.Action == instanceController.ActionStart && instance.Status != models.InstanceStopped && instance.Status != models.InstancePaused {
|
|
middleware.Error(ctx, middleware.CodeInstanceStatusError, 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
|
|
}
|
|
|
|
status := instance.Status
|
|
if status == models.InstanceStopped && (req.Action == instanceController.ActionStart || req.Action == instanceController.ActionRestart) {
|
|
remainGpu, err := redis.RawDB.IncrBy(ctx, "remain_gpu:server:"+strconv.Itoa(int(server.ID)), int64(-instance.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(instance.GpuCount))
|
|
middleware.Error(ctx, middleware.CodeResourceInsufficient, iris.StatusBadRequest)
|
|
return
|
|
}
|
|
}
|
|
|
|
switch req.Action {
|
|
case instanceController.ActionStart:
|
|
result = database.DB.Model(&instance).Update("status", models.InstanceStarting)
|
|
if result.Error != nil {
|
|
l.Error("update instance status error: %v", result.Error)
|
|
middleware.Error(ctx, middleware.CodeInstanceStartError, iris.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
case instanceController.ActionPause:
|
|
result = database.DB.Model(&instance).Update("status", models.InstancePausing)
|
|
if result.Error != nil {
|
|
l.Error("update instance status error: %v", result.Error)
|
|
middleware.Error(ctx, middleware.CodeInstancePauseError, iris.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
case instanceController.ActionStop:
|
|
result = database.DB.Model(&instance).Update("status", models.InstanceStopping)
|
|
if result.Error != nil {
|
|
l.Error("update instance status error: %v", result.Error)
|
|
middleware.Error(ctx, middleware.CodeInstanceStopError, iris.StatusInternalServerError)
|
|
return
|
|
}
|
|
redis.RawDB.IncrBy(ctx, "remain_gpu:server:"+strconv.Itoa(int(server.ID)), int64(instance.GpuCount))
|
|
|
|
case instanceController.ActionRestart:
|
|
result = database.DB.Model(&instance).Update("status", models.InstanceRestarting)
|
|
if result.Error != nil {
|
|
l.Error("update instance status error: %v", result.Error)
|
|
middleware.Error(ctx, middleware.CodeInstanceRestartError, iris.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
default:
|
|
}
|
|
|
|
dispatcherData := dispatcher.Data{
|
|
Type: dispatcher.Control,
|
|
InstanceID: instance.ID,
|
|
Status: status,
|
|
Action: req.Action,
|
|
}
|
|
dispatcher.Push(instance.ServerID, dispatcherData)
|
|
|
|
middleware.Success(ctx)
|
|
}
|