Files
ai/models/server.go
2023-06-05 16:48:22 +08:00

223 lines
7.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package models
import (
"encoding/json"
"fmt"
"main/configs"
"net/http"
"time"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
)
type Server struct {
ID string `json:"id" gorm:"primary_key"`
Name string `json:"name"`
Type string `json:"type"` // (訓練|推理)
IP string `json:"ip"`
Port int `json:"port"`
Status string `json:"status"` // (異常|初始化|閒置|就緒|工作中|關閉中)
UserName string `json:"username"`
Password string `json:"password"`
Models []map[string]interface{} `json:"models" gorm:"-"` // 數據庫不必保存
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`
}
type ServerList struct {
Total int `json:"total"`
List []Server `json:"list"`
Config struct {
TencentCloud struct {
SecretId string `yaml:"SecretId"`
SecretKey string `yaml:"SecretKey"`
Region string `yaml:"Region"`
} `yaml:"TencentCloud"`
} `json:"-"`
}
// 獲取服務器列表
func (servers *ServerList) Read() error {
// 從數據庫中獲取全部服務器列表
configs.ORMDB().Find(&servers.List)
// 打印現有的服務器列表
for _, server := range servers.List {
fmt.Println(server)
}
// 如果一個服務器都沒有, 提示
if len(servers.List) == 0 {
fmt.Println("記錄的服務器列表為空")
}
// 從騰訊雲API獲取服務器列表
client, err := cvm.NewClient(common.NewCredential(servers.Config.TencentCloud.SecretId, servers.Config.TencentCloud.SecretKey), servers.Config.TencentCloud.Region, profile.NewClientProfile())
if err != nil {
return fmt.Errorf("初始化騰訊雲SDK客戶端失敗: %v", err)
}
// 实例化一个请求对象,每个接口都会对应一个request对象
request := cvm.NewDescribeInstancesRequest()
response, err := client.DescribeInstances(request)
if _, ok := err.(*errors.TencentCloudSDKError); ok {
return fmt.Errorf("已返回 API 错误: %v", err)
}
if err != nil {
return fmt.Errorf("运行实例失败: %v", err)
}
for _, instance := range response.Response.InstanceSet {
var server Server
server.ID = *instance.InstanceId
server.Name = *instance.InstanceName
server.IP = *instance.PublicIpAddresses[0]
server.Port = 7890
server.Status = "初始化"
servers.List = append(servers.List, server)
}
if len(response.Response.InstanceSet) == 0 {
fmt.Println("服務器列表為空")
return nil
}
return nil
}
// 通過腾讯云API創建服務器
func (servers *ServerList) Create() (server Server, err error) {
client, err := cvm.NewClient(common.NewCredential(servers.Config.TencentCloud.SecretId, servers.Config.TencentCloud.SecretKey), servers.Config.TencentCloud.Region, profile.NewClientProfile())
if err != nil {
return server, fmt.Errorf("初始化騰訊雲SDK客戶端失敗: %v", err)
}
// 实例化一个请求对象, 指定啓動模板, 以創建指定規格的服務器
request := cvm.NewRunInstancesRequest()
request.LaunchTemplate = &cvm.LaunchTemplate{LaunchTemplateId: common.StringPtr("lt-ks6y5evh")}
response, err := client.RunInstances(request)
if _, ok := err.(*errors.TencentCloudSDKError); ok {
return server, fmt.Errorf("已返回 API 错误: %v", err)
}
if err != nil {
return server, fmt.Errorf("运行实例失败: %v", err)
}
fmt.Println("創建服務器成功:", response.Response.InstanceIdSet[0])
request2 := cvm.NewDescribeInstancesRequest()
//request2.InstanceIds = []*string{response.Response.InstanceIdSet[0]}
response2, err := client.DescribeInstances(request2)
if _, ok := err.(*errors.TencentCloudSDKError); ok {
return server, fmt.Errorf("已返回 API 错误: %v", err)
}
if err != nil {
return server, fmt.Errorf("獲取實例詳情失敗: %v", err)
}
// 縮進格式化打印
b, _ := json.MarshalIndent(response2.Response.InstanceSet, "", " ")
fmt.Println(string(b))
for _, instance := range response2.Response.InstanceSet {
if *instance.InstanceId != *response.Response.InstanceIdSet[0] {
var server Server
server.ID = *instance.InstanceId
server.Name = *instance.InstanceName
server.IP = *instance.PublicIpAddresses[0]
server.Port = 7890
server.Status = *instance.InstanceState
servers.List = append(servers.List, server)
configs.ORMDB().Create(&server)
break
}
}
return server, nil
}
// 通過腾讯云API註銷指定的服務器
func (servers *ServerList) Delete(InstanceId string) error {
client, err := cvm.NewClient(common.NewCredential(servers.Config.TencentCloud.SecretId, servers.Config.TencentCloud.SecretKey), servers.Config.TencentCloud.Region, profile.NewClientProfile())
if err != nil {
return fmt.Errorf("初始化騰訊雲SDK客戶端失敗: %v", err)
}
// 实例化一个请求对象,每个接口都会对应一个request对象
request := cvm.NewTerminateInstancesRequest()
// 指定要註銷的服務器ID
request.InstanceIds = []*string{common.StringPtr(InstanceId)}
// 返回的resp是一个TerminateInstancesResponse的实例与请求对象对应
response, err := client.TerminateInstances(request)
if _, ok := err.(*errors.TencentCloudSDKError); ok {
return fmt.Errorf("已返回 API 错误: %v", err)
}
if err != nil {
return fmt.Errorf("註銷實例失敗: %v", err)
}
fmt.Println("註銷服務器成功:", InstanceId, response.Response)
// 從列表中刪除服務器
for i, server := range servers.List {
if server.ID == InstanceId {
servers.List = append(servers.List[:i], servers.List[i+1:]...)
break
}
}
return nil
}
func (server *Server) CheckStatus() error {
switch server.Type {
case "訓練":
resp, err := http.Get(fmt.Sprintf("http://%s:%d/dreambooth/status", server.IP, server.Port))
if err != nil {
server.Status = "異常"
return err
}
defer resp.Body.Close()
// 解碼JSON
var data map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
return err
}
// 解碼JSON
var current_state map[string]interface{}
if err := json.Unmarshal([]byte(data["current_state"].(string)), &current_state); err != nil {
return err
}
//log.Println("current_state:", current_state)
// 檢查服務器是否正常
if !current_state["active"].(bool) {
server.Status = "異常"
return fmt.Errorf("服務器狀態異常: active=false")
}
server.Status = "正常"
case "推理":
server.Status = "異常"
default:
server.Status = "異常"
}
// 檢查服務器是否正常
return nil
}
func init() {
configs.ORMDB().AutoMigrate(&Server{})
// 檢查所有服務器的狀態, 無效的服務器設置為異常
var servers []Server
configs.ORMDB().Find(&servers)
for _, server := range servers {
server.CheckStatus()
}
}