Added more data to message info
This commit is contained in:
parent
4bffae63b7
commit
3c08208a60
@ -12,12 +12,13 @@ type ImageInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ServerInfo struct {
|
type ServerInfo struct {
|
||||||
Id string
|
Id string
|
||||||
OwnerId string
|
OwnerId string
|
||||||
Image ImageInfo
|
DefaultCommand string
|
||||||
On bool
|
Image ImageInfo
|
||||||
Nickname string
|
On bool
|
||||||
Ports []Port
|
Nickname string
|
||||||
|
Ports []Port
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileBrowserInfo struct {
|
type FileBrowserInfo struct {
|
||||||
@ -33,4 +34,6 @@ type ServerData struct {
|
|||||||
VolumeId string
|
VolumeId string
|
||||||
Nickname string
|
Nickname string
|
||||||
UserPermissions map[string]Permission
|
UserPermissions map[string]Permission
|
||||||
|
DefaultCommand string
|
||||||
|
DefaultPorts []Port
|
||||||
}
|
}
|
||||||
|
@ -61,33 +61,51 @@ var upgrader = websocket.Upgrader{
|
|||||||
|
|
||||||
func (con Connection) getServerInfo(volume volume.Volume) (*models.ServerInfo, error) {
|
func (con Connection) getServerInfo(volume volume.Volume) (*models.ServerInfo, error) {
|
||||||
var volumeLabels VolumeLabels
|
var volumeLabels VolumeLabels
|
||||||
jsonData, err := json.Marshal(volume.Labels)
|
var serverData models.ServerData
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
json.Unmarshal(jsonData, &volumeLabels)
|
|
||||||
imageList, err := con.apiClient.ImageList(context.Background(), image.ListOptions{Filters: filters.NewArgs(filters.Arg("reference", volumeLabels.ImageId))})
|
|
||||||
if len(imageList) == 0 {
|
|
||||||
return nil, fmt.Errorf("ImageId %s does not exist", volumeLabels.ImageId)
|
|
||||||
}
|
|
||||||
imageSummery := imageList[0]
|
|
||||||
imageInspect, _, err := con.apiClient.ImageInspectWithRaw(context.Background(), imageSummery.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var imagePorts []models.Port = make([]models.Port, len(imageInspect.Config.ExposedPorts))
|
con.connection.Database("Backend").Collection("Servers").FindOne(context.TODO(), bson.D{{Key: "id", Value: volume.Name}}).Decode(&serverData)
|
||||||
i := 0
|
jsonData, err := json.Marshal(volume.Labels)
|
||||||
for imagePort := range imageInspect.Config.ExposedPorts {
|
|
||||||
imagePorts[i] = models.Port{Protocol: imagePort.Proto(), Number: imagePort.Int()}
|
if err != nil {
|
||||||
i += 1
|
return nil, err
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(jsonData, &volumeLabels)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
|
||||||
|
}
|
||||||
|
var imagePorts []models.Port
|
||||||
|
|
||||||
|
if len(serverData.DefaultPorts) == 0 {
|
||||||
|
|
||||||
|
imageList, err := con.apiClient.ImageList(context.TODO(), image.ListOptions{Filters: filters.NewArgs(filters.Arg("reference", volumeLabels.ImageId))})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(imageList) == 0 {
|
||||||
|
return nil, fmt.Errorf("ImageId %s does not exist", volumeLabels.ImageId)
|
||||||
|
}
|
||||||
|
imageSummery := imageList[0]
|
||||||
|
imageInspect, _, err := con.apiClient.ImageInspectWithRaw(context.TODO(), imageSummery.ID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
imagePorts = make([]models.Port, len(imageInspect.Config.ExposedPorts))
|
||||||
|
i := 0
|
||||||
|
for imagePort := range imageInspect.Config.ExposedPorts {
|
||||||
|
imagePorts[i] = models.Port{Protocol: imagePort.Proto(), Number: imagePort.Int()}
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
imagePorts = serverData.DefaultPorts
|
||||||
}
|
}
|
||||||
|
|
||||||
imageNameAndVersion := strings.Split(volumeLabels.ImageId, ":")
|
imageNameAndVersion := strings.Split(volumeLabels.ImageId, ":")
|
||||||
|
|
||||||
imageName := imageNameAndVersion[0]
|
imageName := imageNameAndVersion[0]
|
||||||
imageVersion := imageNameAndVersion[1]
|
imageVersion := imageNameAndVersion[1]
|
||||||
containers, err := con.apiClient.ContainerList(context.Background(), container.ListOptions{
|
containers, err := con.apiClient.ContainerList(context.TODO(), container.ListOptions{
|
||||||
All: true,
|
All: true,
|
||||||
Filters: filters.NewArgs(filters.Arg("label", "type=GAME"), filters.Arg("label", fmt.Sprintf("volume_id=%s", volume.Name))),
|
Filters: filters.NewArgs(filters.Arg("label", "type=GAME"), filters.Arg("label", fmt.Sprintf("volume_id=%s", volume.Name))),
|
||||||
})
|
})
|
||||||
@ -101,8 +119,6 @@ func (con Connection) getServerInfo(volume volume.Volume) (*models.ServerInfo, e
|
|||||||
state = container.State == "running"
|
state = container.State == "running"
|
||||||
ports = transformContainerPortsToModel(container.Ports)
|
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{
|
serverInfo := models.ServerInfo{
|
||||||
Id: volume.Name,
|
Id: volume.Name,
|
||||||
@ -111,17 +127,18 @@ func (con Connection) getServerInfo(volume volume.Volume) (*models.ServerInfo, e
|
|||||||
Version: imageVersion,
|
Version: imageVersion,
|
||||||
Ports: imagePorts,
|
Ports: imagePorts,
|
||||||
},
|
},
|
||||||
OwnerId: volumeLabels.OwnerId,
|
OwnerId: volumeLabels.OwnerId,
|
||||||
On: state,
|
On: state,
|
||||||
Ports: ports,
|
Ports: ports,
|
||||||
Nickname: serverData.Nickname,
|
Nickname: serverData.Nickname,
|
||||||
|
DefaultCommand: serverData.DefaultCommand,
|
||||||
}
|
}
|
||||||
return &serverInfo, nil
|
return &serverInfo, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (con Connection) getServerInfoFromId(ServerId string) (*models.ServerInfo, error) {
|
func (con Connection) getServerInfoFromId(ServerId string) (*models.ServerInfo, error) {
|
||||||
volume, err := con.apiClient.VolumeInspect(context.Background(), ServerId)
|
volume, err := con.apiClient.VolumeInspect(context.TODO(), ServerId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -151,7 +168,9 @@ func convertLabelsToMap(v any) (map[string]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CreateServerRequest struct {
|
type CreateServerRequest struct {
|
||||||
ImageId string `json:"image_id"`
|
ImageId string `json:"image_id"`
|
||||||
|
DefaultPorts []models.Port `json:"default_ports"`
|
||||||
|
DefaultCommand string `json:"default_command"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (con Connection) CreateServer(ctx *gin.Context) {
|
func (con Connection) CreateServer(ctx *gin.Context) {
|
||||||
@ -167,7 +186,7 @@ func (con Connection) CreateServer(ctx *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
imageList, err := con.apiClient.ImageList(context.Background(), image.ListOptions{All: true, Filters: filters.NewArgs(filters.Arg("reference", request.ImageId))})
|
imageList, err := con.apiClient.ImageList(context.TODO(), image.ListOptions{All: true, Filters: filters.NewArgs(filters.Arg("reference", request.ImageId))})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.AbortWithError(400, err)
|
ctx.AbortWithError(400, err)
|
||||||
return
|
return
|
||||||
@ -182,13 +201,21 @@ func (con Connection) CreateServer(ctx *gin.Context) {
|
|||||||
ctx.AbortWithError(400, err)
|
ctx.AbortWithError(400, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
volumeResponse, err := con.apiClient.VolumeCreate(context.Background(), volume.CreateOptions{
|
volumeResponse, err := con.apiClient.VolumeCreate(context.TODO(), volume.CreateOptions{
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.AbortWithError(500, err)
|
ctx.AbortWithError(500, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
con.connection.Database("Backend").Collection("Servers").InsertOne(context.TODO(), models.ServerData{
|
||||||
|
Id: volumeResponse.Name,
|
||||||
|
OwnerId: claims.(*auth.AuthClaims).Username,
|
||||||
|
Image: imageSummary.RepoTags[0],
|
||||||
|
VolumeId: volumeResponse.Name,
|
||||||
|
DefaultPorts: request.DefaultPorts,
|
||||||
|
DefaultCommand: request.DefaultCommand,
|
||||||
|
})
|
||||||
|
|
||||||
ctx.JSON(200, volumeResponse.Name)
|
ctx.JSON(200, volumeResponse.Name)
|
||||||
}
|
}
|
||||||
@ -225,6 +252,7 @@ func (con Connection) StartServer(ctx *gin.Context) {
|
|||||||
ctx.Status(200)
|
ctx.Status(200)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
imageId := serverInfo.Image.Name + ":" + serverInfo.Image.Version
|
imageId := serverInfo.Image.Name + ":" + serverInfo.Image.Version
|
||||||
labels := ContainerLabels{
|
labels := ContainerLabels{
|
||||||
OwnerId: claims.(*auth.AuthClaims).Username,
|
OwnerId: claims.(*auth.AuthClaims).Username,
|
||||||
@ -243,7 +271,7 @@ func (con Connection) StartServer(ctx *gin.Context) {
|
|||||||
|
|
||||||
volumes := make(map[string]struct{})
|
volumes := make(map[string]struct{})
|
||||||
|
|
||||||
image, _, err := con.apiClient.ImageInspectWithRaw(context.Background(), imageId)
|
image, _, err := con.apiClient.ImageInspectWithRaw(context.TODO(), imageId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.AbortWithError(500, err)
|
ctx.AbortWithError(500, err)
|
||||||
return
|
return
|
||||||
@ -261,7 +289,7 @@ func (con Connection) StartServer(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, portCouple := range request.Ports {
|
for _, portCouple := range request.Ports {
|
||||||
portMapping[nat.Port(fmt.Sprintf("%d/%s", portCouple.Source.Number, portCouple.Source.Protocol))] = []nat.PortBinding{{HostPort: fmt.Sprint(portCouple.Destination.Number)}}
|
portMapping[nat.Port(fmt.Sprintf("%d/%s", portCouple.Source.Number, portCouple.Source.Protocol))] = []nat.PortBinding{{HostIP: "0.0.0.0", HostPort: fmt.Sprint(portCouple.Destination.Number)}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,9 +302,12 @@ func (con Connection) StartServer(ctx *gin.Context) {
|
|||||||
if len(words) == 0 {
|
if len(words) == 0 {
|
||||||
words = nil
|
words = nil
|
||||||
}
|
}
|
||||||
|
portSet := make(nat.PortSet)
|
||||||
|
for port, _ := range portMapping {
|
||||||
|
portSet[port] = struct{}{}
|
||||||
|
}
|
||||||
response, err := con.apiClient.ContainerCreate(
|
response, err := con.apiClient.ContainerCreate(
|
||||||
context.Background(),
|
context.TODO(),
|
||||||
&container.Config{
|
&container.Config{
|
||||||
AttachStdin: true,
|
AttachStdin: true,
|
||||||
AttachStdout: true,
|
AttachStdout: true,
|
||||||
@ -288,6 +319,7 @@ func (con Connection) StartServer(ctx *gin.Context) {
|
|||||||
Volumes: volumes,
|
Volumes: volumes,
|
||||||
Labels: jsonLabels,
|
Labels: jsonLabels,
|
||||||
Cmd: words,
|
Cmd: words,
|
||||||
|
ExposedPorts: portSet,
|
||||||
},
|
},
|
||||||
&container.HostConfig{
|
&container.HostConfig{
|
||||||
AutoRemove: true,
|
AutoRemove: true,
|
||||||
@ -310,7 +342,7 @@ func (con Connection) StartServer(ctx *gin.Context) {
|
|||||||
HostIP, hostIPexists := os.LookupEnv("HOST_IP")
|
HostIP, hostIPexists := os.LookupEnv("HOST_IP")
|
||||||
if exists && hostIPexists {
|
if exists && hostIPexists {
|
||||||
time.Sleep(time.Millisecond * 100)
|
time.Sleep(time.Millisecond * 100)
|
||||||
containerData, err := con.apiClient.ContainerInspect(context.Background(), response.ID)
|
containerData, err := con.apiClient.ContainerInspect(context.TODO(), response.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.AbortWithError(500, err)
|
ctx.AbortWithError(500, err)
|
||||||
return
|
return
|
||||||
@ -366,7 +398,7 @@ func (con Connection) GetServers(ctx *gin.Context) {
|
|||||||
|
|
||||||
func (con Connection) StopServer(ctx *gin.Context) {
|
func (con Connection) StopServer(ctx *gin.Context) {
|
||||||
serverId := ctx.Param("server_id")
|
serverId := ctx.Param("server_id")
|
||||||
containersList, err := con.apiClient.ContainerList(context.Background(), container.ListOptions{
|
containersList, err := con.apiClient.ContainerList(context.TODO(), container.ListOptions{
|
||||||
Filters: filters.NewArgs(filters.Arg("label", "volume_id="+serverId), filters.Arg("label", "type=GAME")),
|
Filters: filters.NewArgs(filters.Arg("label", "volume_id="+serverId), filters.Arg("label", "type=GAME")),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -379,29 +411,31 @@ func (con Connection) StopServer(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, containerData := range containersList {
|
for _, containerData := range containersList {
|
||||||
con.apiClient.ContainerStop(context.Background(), containerData.ID, container.StopOptions{})
|
con.apiClient.ContainerStop(context.TODO(), containerData.ID, container.StopOptions{})
|
||||||
}
|
}
|
||||||
ctx.Status(200)
|
ctx.Status(200)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (con Connection) DeleteServer(ctx *gin.Context) {
|
func (con Connection) DeleteServer(ctx *gin.Context) {
|
||||||
serverId := ctx.Param("server_id")
|
serverId := ctx.Param("server_id")
|
||||||
containers, err := con.apiClient.ContainerList(context.Background(), container.ListOptions{All: true, Filters: filters.NewArgs(filters.Arg("label", "volume_id="+serverId))})
|
containers, err := con.apiClient.ContainerList(context.TODO(), container.ListOptions{All: true, Filters: filters.NewArgs(filters.Arg("label", "volume_id="+serverId))})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.AbortWithError(500, err)
|
ctx.AbortWithError(500, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, containerInstance := range containers {
|
for _, containerInstance := range containers {
|
||||||
con.apiClient.ContainerStop(context.Background(), containerInstance.ID, container.StopOptions{})
|
con.apiClient.ContainerStop(context.TODO(), containerInstance.ID, container.StopOptions{})
|
||||||
err := con.apiClient.ContainerRemove(context.Background(), containerInstance.ID, container.RemoveOptions{Force: true, RemoveLinks: true})
|
err := con.apiClient.ContainerRemove(context.TODO(), containerInstance.ID, container.RemoveOptions{Force: true, RemoveLinks: true})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.AbortWithError(500, err)
|
ctx.AbortWithError(500, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
con.apiClient.VolumeRemove(context.Background(), serverId, false)
|
con.apiClient.VolumeRemove(context.TODO(), serverId, false)
|
||||||
|
con.connection.Database("Backend").Collection("Servers").FindOneAndDelete(context.TODO(), bson.D{{Key: "id", Value: serverId}})
|
||||||
|
|
||||||
ctx.JSON(200, "ok")
|
ctx.JSON(200, "ok")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,16 +446,20 @@ type RunCommandRequest struct {
|
|||||||
func (con Connection) RunCommand(ctx *gin.Context) {
|
func (con Connection) RunCommand(ctx *gin.Context) {
|
||||||
var request RunCommandRequest
|
var request RunCommandRequest
|
||||||
err := json.NewDecoder(ctx.Request.Body).Decode(&request)
|
err := json.NewDecoder(ctx.Request.Body).Decode(&request)
|
||||||
|
if err != nil {
|
||||||
|
ctx.AbortWithError(500, err)
|
||||||
|
}
|
||||||
|
|
||||||
serverId := ctx.Param("server_id")
|
serverId := ctx.Param("server_id")
|
||||||
log.Print("Writing command \"", request.Command, "\"")
|
log.Print("Writing command \"", request.Command, "\"")
|
||||||
containers, err := con.apiClient.ContainerList(context.Background(), container.ListOptions{Filters: filters.NewArgs(filters.Arg("label", "volume_id="+serverId))})
|
containers, err := con.apiClient.ContainerList(context.TODO(), container.ListOptions{Filters: filters.NewArgs(filters.Arg("label", "volume_id="+serverId))})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.AbortWithError(500, err)
|
ctx.AbortWithError(500, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, containerData := range containers {
|
for _, containerData := range containers {
|
||||||
hijacked, err := con.apiClient.ContainerAttach(context.Background(), containerData.ID, container.AttachOptions{Stream: true, Stdin: true})
|
hijacked, err := con.apiClient.ContainerAttach(context.TODO(), containerData.ID, container.AttachOptions{Stream: true, Stdin: true})
|
||||||
defer func() { hijacked.Close(); hijacked.CloseWrite() }()
|
defer func() { hijacked.Close(); hijacked.CloseWrite() }()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.AbortWithError(500, err)
|
ctx.AbortWithError(500, err)
|
||||||
@ -464,7 +502,7 @@ func (con Connection) AttachServer(ctx *gin.Context) {
|
|||||||
ctx.AbortWithStatus(404)
|
ctx.AbortWithStatus(404)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
hijacked, err := con.apiClient.ContainerAttach(context.Background(), containers[0].ID, container.AttachOptions{Stream: true, Stdin: true, Stdout: true, Stderr: true, Logs: true})
|
hijacked, err := con.apiClient.ContainerAttach(context.TODO(), containers[0].ID, container.AttachOptions{Stream: true, Stdin: true, Stdout: true, Stderr: true, Logs: true})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.AbortWithError(500, err)
|
ctx.AbortWithError(500, err)
|
||||||
return
|
return
|
||||||
@ -478,7 +516,7 @@ func (con Connection) AttachServer(ctx *gin.Context) {
|
|||||||
defer ws.Close()
|
defer ws.Close()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
data := make([]byte, 0, 1024)
|
data := make([]byte, 1024)
|
||||||
for {
|
for {
|
||||||
if stop {
|
if stop {
|
||||||
break
|
break
|
||||||
@ -490,10 +528,10 @@ func (con Connection) AttachServer(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
|
|
||||||
log.Println("Got ", count, " bytes: ", data)
|
log.Println("Got ", count, " bytes: ", string(data[:count]))
|
||||||
|
containerRead <- string(data[:count])
|
||||||
}
|
}
|
||||||
|
|
||||||
containerRead <- string(data)
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -520,6 +558,10 @@ func (con Connection) AttachServer(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
if stop {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case Command := <-websocketRead:
|
case Command := <-websocketRead:
|
||||||
switch Command.CommandType {
|
switch Command.CommandType {
|
||||||
@ -532,13 +574,12 @@ func (con Connection) AttachServer(ctx *gin.Context) {
|
|||||||
|
|
||||||
case "close":
|
case "close":
|
||||||
stop = true
|
stop = true
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case data := <-containerRead:
|
case data := <-containerRead:
|
||||||
err := ws.WriteJSON(data)
|
err := ws.WriteJSON(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
stop = true
|
stop = true
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -559,7 +600,7 @@ func (con Connection) serverAuthorized(permissions models.Permission) func(*gin.
|
|||||||
|
|
||||||
var serverData models.ServerData
|
var serverData models.ServerData
|
||||||
|
|
||||||
con.connection.Database("Backend").Collection("Servers").FindOne(context.Background(), bson.D{{Key: "ServerId", Value: server_id}}).Decode(&serverData)
|
con.connection.Database("Backend").Collection("Servers").FindOne(context.TODO(), bson.D{{Key: "id", Value: server_id}}).Decode(&serverData)
|
||||||
|
|
||||||
if serverData.OwnerId == claims.(*auth.AuthClaims).Username {
|
if serverData.OwnerId == claims.(*auth.AuthClaims).Username {
|
||||||
return true
|
return true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user