added more stuff
This commit is contained in:
@@ -1,122 +1,215 @@
|
||||
package servers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"acooldomain.co/backend/models"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/volume"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
type Connection struct {
|
||||
connection *mongo.Client
|
||||
apiClient *client.Client
|
||||
}
|
||||
|
||||
type ContainerLabels struct {
|
||||
OwnerId string `json:"user_id"`
|
||||
ImageId string `json:"image_id"`
|
||||
VolumeId string `json:"volume_id"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type VolumeLabels struct {
|
||||
OwnerId string `json:"user_id"`
|
||||
ImageId string `json:"image_id"`
|
||||
}
|
||||
|
||||
type ImageLabels struct {
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
func transformContainerPortsToModel(ports []types.Port) []models.Port {
|
||||
modelPorts := make([]models.Port, len(ports))
|
||||
for index, port := range ports {
|
||||
modelPorts[index] = models.Port{
|
||||
Number: int(port.PublicPort),
|
||||
Protocol: port.Type,
|
||||
}
|
||||
}
|
||||
return modelPorts
|
||||
}
|
||||
|
||||
func (con Connection) GetServers(ctx *gin.Context) {
|
||||
volumes, err := con.apiClient.VolumeList(
|
||||
context.TODO(),
|
||||
volume.ListOptions{
|
||||
Filters: filters.NewArgs(filters.Arg("label", "type=GAME")),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
}
|
||||
var volumeLabels VolumeLabels
|
||||
var servers []models.ServerInfo
|
||||
println("Found %d Containers", len(volumes.Volumes))
|
||||
for _, volume := range volumes.Volumes {
|
||||
jsonData, err := json.Marshal(volume.Labels)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
json.Unmarshal(jsonData, &volumeLabels)
|
||||
|
||||
imageNameAndVersion := strings.Split(volumeLabels.ImageId, ":")
|
||||
|
||||
imageName := imageNameAndVersion[0]
|
||||
imageVersion := imageNameAndVersion[1]
|
||||
containers, err := con.apiClient.ContainerList(context.Background(), container.ListOptions{
|
||||
All: true,
|
||||
Filters: filters.NewArgs(filters.Arg("label", "type=GAME"), filters.Arg("label", fmt.Sprintf("volume_id=%s", volume.Name))),
|
||||
})
|
||||
var state bool
|
||||
var ports []models.Port
|
||||
if err != nil || len(containers) == 0 {
|
||||
state = false
|
||||
ports = nil
|
||||
} else {
|
||||
container := containers[0]
|
||||
state = container.State == "running"
|
||||
ports = container.Ports
|
||||
}
|
||||
var serverData models.ServerData
|
||||
con.connection.Database("backend").Collection("servers").FindOne(context.TODO(), bson.D{{Key: "volume_id", Value: volume.Name}}).Decode(&serverData)
|
||||
|
||||
servers = append(servers, models.ServerInfo{
|
||||
Id: volume.Name,
|
||||
Image: models.ImageInfo{
|
||||
Name: imageName,
|
||||
Version: imageVersion,
|
||||
},
|
||||
OwnerId: volumeLabels.OwnerId,
|
||||
On: state,
|
||||
Ports: ports,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
}
|
||||
ctx.JSON(200, servers)
|
||||
|
||||
}
|
||||
|
||||
func LoadGroup(group *gin.RouterGroup, mongo_client *mongo.Client) {
|
||||
apiClient, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer apiClient.Close()
|
||||
|
||||
connection := Connection{connection: mongo_client, apiClient: apiClient}
|
||||
group.GET("/", connection.GetServers)
|
||||
}
|
||||
package servers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"acooldomain.co/backend/auth"
|
||||
"acooldomain.co/backend/models"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/volume"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/gin-gonic/gin"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
type Connection struct {
|
||||
connection *mongo.Client
|
||||
apiClient *client.Client
|
||||
}
|
||||
|
||||
type ContainerLabels struct {
|
||||
OwnerId string `json:"user_id"`
|
||||
ImageId string `json:"image_id"`
|
||||
VolumeId string `json:"volume_id"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type VolumeLabels struct {
|
||||
OwnerId string `json:"user_id"`
|
||||
ImageId string `json:"image_id"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type ImageLabels struct {
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
func (con Connection) getServerInfo(volume volume.Volume) (*models.ServerInfo, error) {
|
||||
var volumeLabels VolumeLabels
|
||||
jsonData, err := json.Marshal(volume.Labels)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
json.Unmarshal(jsonData, &volumeLabels)
|
||||
|
||||
imageNameAndVersion := strings.Split(volumeLabels.ImageId, ":")
|
||||
|
||||
imageName := imageNameAndVersion[0]
|
||||
imageVersion := imageNameAndVersion[1]
|
||||
containers, err := con.apiClient.ContainerList(context.Background(), container.ListOptions{
|
||||
All: true,
|
||||
Filters: filters.NewArgs(filters.Arg("label", "type=GAME"), filters.Arg("label", fmt.Sprintf("volume_id=%s", volume.Name))),
|
||||
})
|
||||
var state bool
|
||||
var ports []models.Port
|
||||
if err != nil || len(containers) == 0 {
|
||||
state = false
|
||||
ports = nil
|
||||
} else {
|
||||
container := containers[0]
|
||||
state = container.State == "running"
|
||||
ports = transformContainerPortsToModel(container.Ports)
|
||||
}
|
||||
var serverData models.ServerData
|
||||
con.connection.Database("backend").Collection("servers").FindOne(context.TODO(), bson.D{{Key: "volume_id", Value: volume.Name}}).Decode(&serverData)
|
||||
|
||||
serverInfo := models.ServerInfo{
|
||||
Id: volume.Name,
|
||||
Image: models.ImageInfo{
|
||||
Name: imageName,
|
||||
Version: imageVersion,
|
||||
},
|
||||
OwnerId: volumeLabels.OwnerId,
|
||||
On: state,
|
||||
Ports: ports,
|
||||
Nickname: serverData.Nickname,
|
||||
}
|
||||
return &serverInfo, nil
|
||||
|
||||
}
|
||||
|
||||
func (con Connection) getServerInfoFromId(ServerId string) (*models.ServerInfo, error) {
|
||||
volume, err := con.apiClient.VolumeInspect(context.Background(), ServerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return con.getServerInfo(volume)
|
||||
}
|
||||
|
||||
func transformContainerPortsToModel(ports []types.Port) []models.Port {
|
||||
modelPorts := make([]models.Port, len(ports))
|
||||
for index, port := range ports {
|
||||
modelPorts[index] = models.Port{
|
||||
Number: int(port.PublicPort),
|
||||
Protocol: port.Type,
|
||||
}
|
||||
}
|
||||
return modelPorts
|
||||
}
|
||||
|
||||
func (con Connection) StartServer(ctx *gin.Context) {
|
||||
serverId := ctx.Param("server_id")
|
||||
claims, exists := ctx.Get("claims")
|
||||
if !exists {
|
||||
ctx.AbortWithStatus(403)
|
||||
}
|
||||
|
||||
// command := ctx.Param("command")
|
||||
|
||||
serverInfo, err := con.getServerInfoFromId(serverId)
|
||||
|
||||
if err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
}
|
||||
|
||||
if serverInfo.On {
|
||||
ctx.Status(200)
|
||||
return
|
||||
}
|
||||
imageId := serverInfo.Image.Name + ":" + serverInfo.Image.Version
|
||||
labels := ContainerLabels{
|
||||
OwnerId: claims.(*auth.AuthClaims).Username,
|
||||
ImageId: imageId,
|
||||
VolumeId: serverInfo.Id,
|
||||
Type: "GAME",
|
||||
}
|
||||
|
||||
jsonString, err := json.Marshal(labels)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
}
|
||||
jsonLabels := make(map[string]string)
|
||||
json.Unmarshal(jsonString, &jsonLabels)
|
||||
|
||||
volumes := make(map[string]struct{})
|
||||
|
||||
image, _, err := con.apiClient.ImageInspectWithRaw(context.Background(), imageId)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
}
|
||||
|
||||
response, err := con.apiClient.ContainerCreate(
|
||||
context.Background(),
|
||||
&container.Config{
|
||||
AttachStdin: true,
|
||||
AttachStdout: true,
|
||||
AttachStderr: true,
|
||||
Tty: true,
|
||||
OpenStdin: false,
|
||||
StdinOnce: false,
|
||||
Image: imageId,
|
||||
Volumes: volumes,
|
||||
Labels: jsonLabels,
|
||||
},
|
||||
&container.HostConfig{
|
||||
AutoRemove: false,
|
||||
Mounts: []mount.Mount{{Source: serverInfo.Id, Target: image.Config.WorkingDir, Type: "volume"}},
|
||||
},
|
||||
&network.NetworkingConfig{},
|
||||
&v1.Platform{},
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
}
|
||||
ctx.JSON(200, response.ID)
|
||||
}
|
||||
|
||||
func (con Connection) GetServers(ctx *gin.Context) {
|
||||
volumes, err := con.apiClient.VolumeList(
|
||||
context.TODO(),
|
||||
volume.ListOptions{
|
||||
Filters: filters.NewArgs(filters.Arg("label", "type=GAME")),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
}
|
||||
var servers []models.ServerInfo
|
||||
println("Found %d Containers", len(volumes.Volumes))
|
||||
for _, volume := range volumes.Volumes {
|
||||
serverInfo, err := con.getServerInfo(*volume)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
servers = append(servers, *serverInfo)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
}
|
||||
ctx.JSON(200, servers)
|
||||
|
||||
}
|
||||
|
||||
func LoadGroup(group *gin.RouterGroup, mongo_client *mongo.Client) {
|
||||
apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer apiClient.Close()
|
||||
|
||||
connection := Connection{connection: mongo_client, apiClient: apiClient}
|
||||
group.Use(auth.AuthorizedTo(models.Create)).POST("/:server_id/start", connection.StartServer)
|
||||
group.GET("/", connection.GetServers)
|
||||
}
|
||||
|
Reference in New Issue
Block a user