b6f413b9e9
* initial completion of the sharing function * Adjusting multi-partition disk mounts * Add file sharing function * update usb auto mount shell * update samba config * add umount disk function * update change log * update usb auto mount \ * update usb auto mount * Update periodical.go * Update periodical.go * resolve alpha.1 issues * Update UI
1262 lines
42 KiB
Go
1262 lines
42 KiB
Go
package v1
|
||
|
||
import (
|
||
"bytes"
|
||
json2 "encoding/json"
|
||
"net/http"
|
||
"os/exec"
|
||
"path/filepath"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/IceWhaleTech/CasaOS/model"
|
||
"github.com/IceWhaleTech/CasaOS/model/notify"
|
||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||
"github.com/IceWhaleTech/CasaOS/pkg/docker"
|
||
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
||
port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port"
|
||
"github.com/IceWhaleTech/CasaOS/pkg/utils/random"
|
||
"github.com/IceWhaleTech/CasaOS/service"
|
||
"github.com/IceWhaleTech/CasaOS/service/docker_base"
|
||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||
"github.com/IceWhaleTech/CasaOS/types"
|
||
"github.com/gin-gonic/gin"
|
||
"github.com/gorilla/websocket"
|
||
"github.com/jinzhu/copier"
|
||
uuid "github.com/satori/go.uuid"
|
||
"go.uber.org/zap"
|
||
"golang.org/x/crypto/ssh"
|
||
)
|
||
|
||
var upgrader = websocket.Upgrader{
|
||
ReadBufferSize: 1024,
|
||
WriteBufferSize: 1024,
|
||
CheckOrigin: func(r *http.Request) bool { return true },
|
||
HandshakeTimeout: time.Duration(time.Second * 5),
|
||
}
|
||
|
||
//打开docker的terminal
|
||
func DockerTerminal(c *gin.Context) {
|
||
col := c.DefaultQuery("cols", "100")
|
||
row := c.DefaultQuery("rows", "30")
|
||
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
|
||
if err != nil {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||
return
|
||
}
|
||
defer conn.Close()
|
||
container := c.Param("id")
|
||
hr, err := service.Exec(container, row, col)
|
||
if err != nil {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||
return
|
||
}
|
||
// 关闭I/O流
|
||
defer hr.Close()
|
||
// 退出进程
|
||
defer func() {
|
||
hr.Conn.Write([]byte("exit\r"))
|
||
}()
|
||
go func() {
|
||
docker.WsWriterCopy(hr.Conn, conn)
|
||
}()
|
||
docker.WsReaderCopy(conn, hr.Conn)
|
||
}
|
||
|
||
func PostSshLogin(c *gin.Context) {
|
||
j := make(map[string]string)
|
||
c.ShouldBind(&j)
|
||
userName := j["username"]
|
||
password := j["password"]
|
||
port := j["port"]
|
||
if userName == "" || password == "" || port == "" {
|
||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "Username or password or port is empty"})
|
||
return
|
||
}
|
||
_, err := docker.NewSshClient(userName, password, port)
|
||
if err != nil {
|
||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Please check if the username and port are correct, and make sure that ssh server is installed."})
|
||
loger.Error("connect ssh error", zap.Any("error", err))
|
||
return
|
||
}
|
||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||
}
|
||
|
||
func WsSsh(c *gin.Context) {
|
||
_, e := exec.LookPath("ssh")
|
||
if e != nil {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: "ssh server not found"})
|
||
return
|
||
}
|
||
|
||
userName := c.Query("username")
|
||
password := c.Query("password")
|
||
port := c.Query("port")
|
||
wsConn, _ := upgrader.Upgrade(c.Writer, c.Request, nil)
|
||
var logBuff = new(bytes.Buffer)
|
||
|
||
quitChan := make(chan bool, 3)
|
||
// user := ""
|
||
// password := ""
|
||
var login int = 1
|
||
cols, _ := strconv.Atoi(c.DefaultQuery("cols", "200"))
|
||
rows, _ := strconv.Atoi(c.DefaultQuery("rows", "32"))
|
||
var client *ssh.Client
|
||
for login != 0 {
|
||
|
||
var err error
|
||
if userName == "" || password == "" || port == "" {
|
||
wsConn.WriteMessage(websocket.TextMessage, []byte("username or password or port is empty"))
|
||
}
|
||
// wsConn.WriteMessage(websocket.TextMessage, []byte("login:"))
|
||
// user = docker.ReceiveWsMsgUser(wsConn, logBuff)
|
||
// wsConn.WriteMessage(websocket.TextMessage, []byte("\r\n\x1b[0m"))
|
||
// wsConn.WriteMessage(websocket.TextMessage, []byte("password:"))
|
||
// password = docker.ReceiveWsMsgPassword(wsConn, logBuff)
|
||
// wsConn.WriteMessage(websocket.TextMessage, []byte("\r\n\x1b[0m"))
|
||
client, err = docker.NewSshClient(userName, password, port)
|
||
|
||
if err != nil && client == nil {
|
||
wsConn.WriteMessage(websocket.TextMessage, []byte(err.Error()))
|
||
wsConn.WriteMessage(websocket.TextMessage, []byte("\r\n\x1b[0m"))
|
||
} else {
|
||
login = 0
|
||
}
|
||
|
||
}
|
||
if client != nil {
|
||
defer client.Close()
|
||
}
|
||
|
||
ssConn, _ := docker.NewSshConn(cols, rows, client)
|
||
defer ssConn.Close()
|
||
|
||
go ssConn.ReceiveWsMsg(wsConn, logBuff, quitChan)
|
||
go ssConn.SendComboOutput(wsConn, quitChan)
|
||
go ssConn.SessionWait(quitChan)
|
||
|
||
<-quitChan
|
||
|
||
}
|
||
|
||
// @Summary 安装app(该接口需要post json数据)
|
||
// @Produce application/json
|
||
// @Accept application/json
|
||
// @Tags app
|
||
// @Param id path int true "id"
|
||
// @Param port formData int true "主端口"
|
||
// @Param tcp formData string false "tcp端口"
|
||
// @Param udp formData string false "udp端口"
|
||
// @Param env formData string false "环境变量"
|
||
// @Security ApiKeyAuth
|
||
// @Success 200 {string} string "ok"
|
||
// @Router /app/install [post]
|
||
func InstallApp(c *gin.Context) {
|
||
var appInfo model.ServerAppList
|
||
m := model.CustomizationPostData{}
|
||
c.ShouldBind(&m)
|
||
|
||
const CUSTOM = "custom"
|
||
var dockerImage string
|
||
var dockerImageVersion string
|
||
|
||
//check app name is exist
|
||
if len(m.Protocol) == 0 {
|
||
m.Protocol = "http"
|
||
}
|
||
m.ContainerName = strings.Replace(m.Label, " ", "_", -1)
|
||
if m.Origin != CUSTOM {
|
||
oldName := m.ContainerName
|
||
oldLabel := m.Label
|
||
for i := 0; true; i++ {
|
||
if i != 0 {
|
||
m.ContainerName = oldName + "-" + strconv.Itoa(i)
|
||
m.Label = oldLabel + "-" + strconv.Itoa(i)
|
||
}
|
||
if _, err := service.MyService.Docker().DockerListByName(m.ContainerName); err != nil {
|
||
break
|
||
}
|
||
}
|
||
} else {
|
||
if _, err := service.MyService.Docker().DockerListByName(m.ContainerName); err == nil {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.ERROR_APP_NAME_EXIST, Message: common_err.GetMsg(common_err.ERROR_APP_NAME_EXIST)})
|
||
return
|
||
}
|
||
|
||
}
|
||
|
||
//check port
|
||
if len(m.PortMap) > 0 && m.PortMap != "0" {
|
||
//c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||
portMap, _ := strconv.Atoi(m.PortMap)
|
||
if !port2.IsPortAvailable(portMap, "tcp") {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + m.PortMap})
|
||
return
|
||
}
|
||
}
|
||
//if len(m.Port) == 0 || m.Port == "0" {
|
||
// m.Port = m.PortMap
|
||
//}
|
||
|
||
imageArr := strings.Split(m.Image, ":")
|
||
if len(imageArr) == 2 {
|
||
dockerImage = imageArr[0]
|
||
dockerImageVersion = imageArr[1]
|
||
} else {
|
||
dockerImage = m.Image
|
||
dockerImageVersion = "latest"
|
||
}
|
||
m.Image = dockerImage + ":" + dockerImageVersion
|
||
for _, u := range m.Ports {
|
||
|
||
if u.Protocol == "udp" {
|
||
t, _ := strconv.Atoi(u.CommendPort)
|
||
if !port2.IsPortAvailable(t, "udp") {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort})
|
||
return
|
||
}
|
||
} else if u.Protocol == "tcp" {
|
||
|
||
te, _ := strconv.Atoi(u.CommendPort)
|
||
if !port2.IsPortAvailable(te, "tcp") {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort})
|
||
return
|
||
}
|
||
} else if u.Protocol == "both" {
|
||
t, _ := strconv.Atoi(u.CommendPort)
|
||
if !port2.IsPortAvailable(t, "udp") {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort})
|
||
return
|
||
}
|
||
te, _ := strconv.Atoi(u.CommendPort)
|
||
if !port2.IsPortAvailable(te, "tcp") {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort})
|
||
return
|
||
}
|
||
}
|
||
}
|
||
if m.Origin == CUSTOM {
|
||
for _, device := range m.Devices {
|
||
if file.CheckNotExist(device.Path) {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DEVICE_NOT_EXIST, Message: device.Path + "," + common_err.GetMsg(common_err.DEVICE_NOT_EXIST)})
|
||
return
|
||
}
|
||
|
||
}
|
||
} else {
|
||
dev := []model.PathMap{}
|
||
for _, device := range dev {
|
||
if !file.CheckNotExist(device.Path) {
|
||
dev = append(dev, device)
|
||
}
|
||
}
|
||
m.Devices = dev
|
||
}
|
||
|
||
//restart := c.PostForm("restart") //always 总是重启, unless-stopped 除非用户手动停止容器,否则总是重新启动, on-failure:仅当容器退出代码非零时重新启动
|
||
//if len(restart) > 0 {
|
||
//
|
||
//}
|
||
//
|
||
//privileged := c.PostForm("privileged") //是否处于特权模式
|
||
//if len(privileged) > 0 {
|
||
//
|
||
//}
|
||
id := uuid.NewV4().String()
|
||
m.CustomId = id
|
||
var relyMap = make(map[string]string)
|
||
go func() {
|
||
// installLog := model2.AppNotify{}
|
||
// installLog.State = 0
|
||
// installLog.CustomId = m.Label
|
||
// installLog.Message = "installing rely"
|
||
// installLog.Class = types.NOTIFY_APP
|
||
// installLog.Type = types.NOTIFY_TYPE_UNIMPORTANT
|
||
// installLog.CreatedAt = strconv.FormatInt(time.Now().Unix(), 10)
|
||
// installLog.UpdatedAt = strconv.FormatInt(time.Now().Unix(), 10)
|
||
// installLog.Id = uuid.NewV4().String()
|
||
// service.MyService.Notify().AddLog(installLog)
|
||
if m.Origin != CUSTOM {
|
||
for _, plugin := range appInfo.Plugins {
|
||
if plugin == "mysql" {
|
||
mid := uuid.NewV4().String()
|
||
mc := docker_base.MysqlConfig{}
|
||
mc.DataBasePassword = random.RandomString(6, false)
|
||
mc.DataBaseDB = appInfo.Title
|
||
mc.DataBaseUser = "root"
|
||
mc.DataBasePort = "3306"
|
||
mysqlContainerId, err := docker_base.MysqlCreate(mc, mid, m.CpuShares, m.Memory)
|
||
if len(mysqlContainerId) > 0 && err == nil {
|
||
|
||
mc.DataBaseHost = mid
|
||
|
||
m.Envs = docker_base.MysqlFilter(mc, m.Envs)
|
||
|
||
rely := model2.RelyDBModel{}
|
||
rely.Type = types.RELY_TYPE_MYSQL
|
||
rely.ContainerId = mysqlContainerId
|
||
rely.CustomId = mid
|
||
rely.ContainerCustomId = m.Label
|
||
var mysqlConfig model2.MysqlConfigs
|
||
|
||
//结构体转换
|
||
copier.Copy(&mysqlConfig, &mc)
|
||
rely.Config = mysqlConfig
|
||
service.MyService.Rely().Create(rely)
|
||
|
||
relyMap["mysql"] = mid
|
||
|
||
} else {
|
||
docker_base.MysqlDelete(mysqlContainerId)
|
||
// installLog.State = 0
|
||
// installLog.Message = err.Error()
|
||
// service.MyService.Notify().UpdateLog(installLog)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// step:下载镜像
|
||
err := service.MyService.Docker().DockerPullImage(dockerImage+":"+dockerImageVersion, m.Icon, m.Label)
|
||
if err != nil {
|
||
notify := notify.Application{}
|
||
notify.Icon = m.Icon
|
||
notify.Name = m.Label
|
||
notify.State = "PULLING"
|
||
notify.Type = "INSTALL"
|
||
notify.Success = false
|
||
notify.Finished = false
|
||
notify.Message = err.Error()
|
||
service.MyService.Notify().SendInstallAppBySocket(notify)
|
||
return
|
||
}
|
||
|
||
for !service.MyService.Docker().IsExistImage(m.Image) {
|
||
time.Sleep(time.Second)
|
||
}
|
||
|
||
_, err = service.MyService.Docker().DockerContainerCreate(m, "")
|
||
if err != nil {
|
||
//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":80}", 100)
|
||
notify := notify.Application{}
|
||
notify.Icon = m.Icon
|
||
notify.Name = m.Label
|
||
notify.State = "STARTING"
|
||
notify.Type = "INSTALL"
|
||
notify.Success = false
|
||
notify.Finished = false
|
||
notify.Message = err.Error()
|
||
service.MyService.Notify().SendInstallAppBySocket(notify)
|
||
return
|
||
} else {
|
||
notify := notify.Application{}
|
||
notify.Icon = m.Icon
|
||
notify.Name = m.Label
|
||
notify.State = "STARTING"
|
||
notify.Type = "INSTALL"
|
||
notify.Success = true
|
||
notify.Finished = false
|
||
service.MyService.Notify().SendInstallAppBySocket(notify)
|
||
}
|
||
|
||
// echo -e "hellow\nworld" >>
|
||
|
||
//step:启动容器
|
||
err = service.MyService.Docker().DockerContainerStart(m.ContainerName)
|
||
if err != nil {
|
||
//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":90}", 100)
|
||
notify := notify.Application{}
|
||
notify.Icon = m.Icon
|
||
notify.Name = m.Label
|
||
notify.State = "STARTING"
|
||
notify.Type = "INSTALL"
|
||
notify.Success = false
|
||
notify.Finished = false
|
||
notify.Message = err.Error()
|
||
service.MyService.Notify().SendInstallAppBySocket(notify)
|
||
return
|
||
} else {
|
||
// if m.Origin != CUSTOM {
|
||
// installLog.Message = "setting upnp"
|
||
// } else {
|
||
// installLog.Message = "nearing completion"
|
||
// }
|
||
// service.MyService.Notify().UpdateLog(installLog)
|
||
}
|
||
|
||
//step: 启动成功 检查容器状态确认启动成功
|
||
container, err := service.MyService.Docker().DockerContainerInfo(m.ContainerName)
|
||
if err != nil && container.ContainerJSONBase.State.Running {
|
||
notify := notify.Application{}
|
||
notify.Icon = m.Icon
|
||
notify.Name = m.Label
|
||
notify.State = "INSTALLED"
|
||
notify.Type = "INSTALL"
|
||
notify.Success = false
|
||
notify.Finished = true
|
||
notify.Message = err.Error()
|
||
service.MyService.Notify().SendInstallAppBySocket(notify)
|
||
return
|
||
} else {
|
||
notify := notify.Application{}
|
||
notify.Icon = m.Icon
|
||
notify.Name = m.Label
|
||
notify.State = "INSTALLED"
|
||
notify.Type = "INSTALL"
|
||
notify.Success = true
|
||
notify.Finished = true
|
||
service.MyService.Notify().SendInstallAppBySocket(notify)
|
||
}
|
||
|
||
// if m.Origin != "custom" {
|
||
// for i := 0; i < len(m.Volumes); i++ {
|
||
// m.Volumes[i].Path = docker.GetDir(id, m.Volumes[i].Path)
|
||
// }
|
||
// }
|
||
//service.MyService.App().SaveContainer(md)
|
||
config.CasaOSGlobalVariables.AppChange = true
|
||
|
||
}()
|
||
|
||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: m.Label})
|
||
|
||
}
|
||
|
||
//// @Summary 自定义安装app(该接口需要post json数据)
|
||
//// @Produce application/json
|
||
//// @Accept application/json
|
||
//// @Tags app
|
||
//// @Param id path int true "id"
|
||
//// @Param port formData int true "主端口"
|
||
//// @Param tcp formData string false "tcp端口"
|
||
//// @Param udp formData string false "udp端口"
|
||
//// @Param env formData string false "环境变量"
|
||
//// @Security ApiKeyAuth
|
||
//// @Success 200 {string} string "ok"
|
||
//// @Router /app/install/{id} [post]
|
||
//func CustomInstallApp(c *gin.Context) {
|
||
// //appId := c.Param("id")
|
||
// // appInfo := service.MyService.App().GetServerAppInfo(appId)
|
||
//
|
||
// m := model.CustomizationPostData{}
|
||
// c.ShouldBind(&m)
|
||
// //检查端口
|
||
// if len(m.PortMap) == 0 || m.PortMap == "0" {
|
||
// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||
// return
|
||
// }
|
||
// if len(m.Port) == 0 || m.Port == "0" {
|
||
// m.Port = m.PortMap
|
||
// }
|
||
//
|
||
// portMap, _ := strconv.Atoi(m.PortMap)
|
||
// if !port2.IsPortAvailable(portMap, "tcp") {
|
||
// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + m.PortMap})
|
||
// return
|
||
// }
|
||
//
|
||
// for _, u := range m.Udp {
|
||
// t, _ := strconv.Atoi(u.CommendPort)
|
||
// if !port2.IsPortAvailable(t, "udp") {
|
||
// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort})
|
||
// return
|
||
// }
|
||
// }
|
||
//
|
||
// for _, t := range m.Tcp {
|
||
// te, _ := strconv.Atoi(t.CommendPort)
|
||
// if !port2.IsPortAvailable(te, "tcp") {
|
||
// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + t.CommendPort})
|
||
// return
|
||
// }
|
||
// }
|
||
//
|
||
// //restart := c.PostForm("restart") //always 总是重启, unless-stopped 除非用户手动停止容器,否则总是重新启动, on-failure:仅当容器退出代码非零时重新启动
|
||
// //if len(restart) > 0 {
|
||
// //
|
||
// //}
|
||
// //
|
||
// //privileged := c.PostForm("privileged") //是否处于特权模式
|
||
// //if len(privileged) > 0 {
|
||
// //
|
||
// //}
|
||
//
|
||
// err := service.MyService.Docker().DockerPullImage(m.Image)
|
||
// if err != nil {
|
||
// c.JSON(http.StatusOK, model.Result{Success: common_err.PULL_IMAGE_ERROR, Message: common_err.GetMsg(common_err.PULL_IMAGE_ERROR)})
|
||
// }
|
||
//
|
||
// id := uuid.NewV4().String()
|
||
//
|
||
// var relyMap = make(map[string]string)
|
||
// go func() {
|
||
// installLog := model2.AppNotify{}
|
||
// installLog.CustomId = id
|
||
// installLog.State = 0
|
||
// installLog.Message = "installing rely"
|
||
// installLog.Speed = 30
|
||
// installLog.CreatedAt = time.Now()
|
||
// installLog.UpdatedAt = time.Now()
|
||
// service.MyService.Notify().AddLog(installLog)
|
||
//
|
||
// for !service.MyService.Docker().IsExistImage(m.Image) {
|
||
// time.Sleep(time.Second)
|
||
// }
|
||
//
|
||
// installLog.Speed = 50
|
||
// installLog.Message = "pulling"
|
||
// service.MyService.Notify().UpdateLog(installLog)
|
||
// // step:下载镜像
|
||
//
|
||
// var cpd model.PostData
|
||
// copier.Copy(&cpd, &m)
|
||
// //step:创建容器
|
||
// containerId, err := service.MyService.Docker().DockerContainerCreate(m.Image, id, cpd, m.NetworkModel, m.Image, "custom")
|
||
// installLog.ContainerId = containerId
|
||
// if err != nil {
|
||
// //service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":80}", 100)
|
||
// installLog.State = 0
|
||
// installLog.Speed = 80
|
||
// installLog.Message = err.Error()
|
||
// service.MyService.Notify().UpdateLog(installLog)
|
||
// return
|
||
// } else {
|
||
// //service.MyService.Redis().Set(id, "{\"id\":\""+id+"\",\"state\":true,\"message\":\"starting\",\"speed\":80}", 100)
|
||
// installLog.Speed = 80
|
||
// installLog.Message = "starting"
|
||
// service.MyService.Notify().UpdateLog(installLog)
|
||
// }
|
||
//
|
||
// //step:启动容器
|
||
// err = service.MyService.Docker().DockerContainerStart(id)
|
||
// if err != nil {
|
||
// //service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":90}", 100)
|
||
// installLog.State = 0
|
||
// installLog.Speed = 90
|
||
// installLog.Message = err.Error()
|
||
// service.MyService.Notify().UpdateLog(installLog)
|
||
// return
|
||
// } else {
|
||
// //service.MyService.Redis().Set(id, "{\"id\":\""+id+"\",\"state\":true,\"message\":\"setting upnp\",\"speed\":90}", 100)
|
||
// installLog.Speed = 90
|
||
// installLog.Message = "setting upnp"
|
||
// service.MyService.Notify().UpdateLog(installLog)
|
||
// }
|
||
//
|
||
// //step: 启动成功 检查容器状态确认启动成功
|
||
// containerStatus, err := service.MyService.Docker().DockerContainerInfo(id)
|
||
// if err != nil && containerStatus.ContainerJSONBase.State.Running {
|
||
// //service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":100}", 100)
|
||
// installLog.State = 0
|
||
// installLog.Speed = 100
|
||
// installLog.Message = err.Error()
|
||
// service.MyService.Notify().UpdateLog(installLog)
|
||
// return
|
||
// } else {
|
||
// //service.MyService.Redis().Set(id, "{\"id\":\""+id+"\",\"state\":true,\"message\":\"installed\",\"speed\":100}", 100)
|
||
// installLog.Speed = 100
|
||
// installLog.Message = "installed"
|
||
// service.MyService.Notify().UpdateLog(installLog)
|
||
// }
|
||
//
|
||
// rely := model.MapStrings{}
|
||
//
|
||
// copier.Copy(&rely, &relyMap)
|
||
//
|
||
// //step: 保存数据到数据库
|
||
// md := model2.AppListDBModel{
|
||
// CustomId: id,
|
||
// Title: m.Label,
|
||
// // ScreenshotLink: []string,
|
||
// Slogan: "",
|
||
// Description: m.Description,
|
||
// // Tags: ,
|
||
// Icon: m.Icon,
|
||
// Version: m.Image,
|
||
// ContainerId: containerId,
|
||
// Image: m.Image,
|
||
// Index: "",
|
||
// Port: m.Port,
|
||
// PortMap: m.PortMap,
|
||
// Label: m.Label,
|
||
// EnableUPNP: m.EnableUPNP,
|
||
// UdpPorts: m.Udp,
|
||
// TcpPorts: m.Tcp,
|
||
// Envs: m.Envs,
|
||
// Volumes: m.Volumes,
|
||
// Position: m.Position,
|
||
// NetModel: m.NetworkModel,
|
||
// Restart: m.Restart,
|
||
// CpuShares: m.CpuShares,
|
||
// Memory: m.Memory,
|
||
// Devices: m.Devices,
|
||
// Rely: rely,
|
||
// Origin: "custom",
|
||
// }
|
||
// if m.NetworkModel == "host" {
|
||
// m.PortMap = m.Port
|
||
// }
|
||
// service.MyService.App().SaveContainer(md)
|
||
//
|
||
// }()
|
||
//
|
||
// c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id})
|
||
//
|
||
//}
|
||
|
||
// @Summary 卸载app
|
||
// @Produce application/json
|
||
// @Accept multipart/form-data
|
||
// @Tags app
|
||
// @Param id path string true "容器id"
|
||
// @Security ApiKeyAuth
|
||
// @Success 200 {string} string "ok"
|
||
// @Router /app/uninstall/{id} [delete]
|
||
func UnInstallApp(c *gin.Context) {
|
||
appId := c.Param("id")
|
||
|
||
if len(appId) == 0 {
|
||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||
return
|
||
}
|
||
//info := service.MyService.App().GetUninstallInfo(appId)
|
||
|
||
info, err := service.MyService.Docker().DockerContainerInfo(appId)
|
||
if err != nil {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||
return
|
||
}
|
||
|
||
//step:停止容器
|
||
err = service.MyService.Docker().DockerContainerStop(appId)
|
||
if err != nil {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.UNINSTALL_APP_ERROR, Message: common_err.GetMsg(common_err.UNINSTALL_APP_ERROR), Data: err.Error()})
|
||
return
|
||
}
|
||
|
||
err = service.MyService.Docker().DockerContainerRemove(appId, false)
|
||
if err != nil {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.UNINSTALL_APP_ERROR, Message: common_err.GetMsg(common_err.UNINSTALL_APP_ERROR), Data: err.Error()})
|
||
return
|
||
}
|
||
|
||
// step:remove image
|
||
service.MyService.Docker().DockerImageRemove(info.Config.Image)
|
||
|
||
if info.Config.Labels["origin"] != "custom" {
|
||
//step: 删除文件夹
|
||
for _, v := range info.Mounts {
|
||
if strings.Contains(v.Source, info.Name) {
|
||
path := filepath.Join(strings.Split(v.Source, info.Name)[0], info.Name)
|
||
service.MyService.App().DelAppConfigDir(path)
|
||
}
|
||
}
|
||
|
||
//step: 删除install log
|
||
//service.MyService.Notify().DelLog(appId)
|
||
|
||
// for k, v := range info.Rely {
|
||
//
|
||
// if k == "mysql" {
|
||
// docker_base.MysqlDelete(v)
|
||
// service.MyService.Rely().Delete(v)
|
||
// }
|
||
// }
|
||
|
||
//if info.EnableUPNP {
|
||
// upnp, err := upnp2.Gateway()
|
||
// if err == nil {
|
||
// for _, p := range info.Ports {
|
||
// if p.Protocol == "udp" {
|
||
// upnp.CtrlUrl = upnp2.GetCtrlUrl(upnp.GatewayHost, upnp.DeviceDescUrl)
|
||
// upnp.LocalHost = ip_helper2.GetLoclIp()
|
||
// tComment, _ := strconv.Atoi(p.CommendPort)
|
||
// upnp.DelPortMapping(tComment, "UDP")
|
||
// time.Sleep(time.Millisecond * 200)
|
||
// } else if p.Protocol == "tcp" {
|
||
// upnp.CtrlUrl = upnp2.GetCtrlUrl(upnp.GatewayHost, upnp.DeviceDescUrl)
|
||
// upnp.LocalHost = ip_helper2.GetLoclIp()
|
||
// tComment, _ := strconv.Atoi(p.CommendPort)
|
||
// upnp.DelPortMapping(tComment, "TCP")
|
||
// time.Sleep(time.Millisecond * 200)
|
||
// } else if p.Protocol == "both" {
|
||
// upnp.CtrlUrl = upnp2.GetCtrlUrl(upnp.GatewayHost, upnp.DeviceDescUrl)
|
||
// upnp.LocalHost = ip_helper2.GetLoclIp()
|
||
// tComment, _ := strconv.Atoi(p.CommendPort)
|
||
// upnp.DelPortMapping(tComment, "UDP")
|
||
//
|
||
// upnp.DelPortMapping(tComment, "TCP")
|
||
// time.Sleep(time.Millisecond * 200)
|
||
// }
|
||
// }
|
||
// }
|
||
//}
|
||
}
|
||
config.CasaOSGlobalVariables.AppChange = true
|
||
notify := notify.Application{}
|
||
notify.Icon = info.Config.Labels["icon"]
|
||
notify.Name = strings.ReplaceAll(info.Name, "/", "")
|
||
notify.State = "FINISHED"
|
||
notify.Type = "UNINSTALL"
|
||
notify.Success = true
|
||
notify.Finished = true
|
||
service.MyService.Notify().SendUninstallAppBySocket(notify)
|
||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||
|
||
}
|
||
|
||
// @Summary 修改app状态
|
||
// @Produce application/json
|
||
// @Accept multipart/form-data
|
||
// @Tags app
|
||
// @Param id path string true "appid"
|
||
// @Param state query string false "是否停止 start stop restart"
|
||
// @Security ApiKeyAuth
|
||
// @Success 200 {string} string "ok"
|
||
// @Router /app/state/{id} [put]
|
||
func ChangAppState(c *gin.Context) {
|
||
appId := c.Param("id")
|
||
js := make(map[string]string)
|
||
c.ShouldBind(&js)
|
||
state := js["state"]
|
||
if len(appId) == 0 || len(state) == 0 {
|
||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||
return
|
||
}
|
||
var err error
|
||
if state == "start" {
|
||
err = service.MyService.Docker().DockerContainerStart(appId)
|
||
} else if state == "restart" {
|
||
service.MyService.Docker().DockerContainerStop(appId)
|
||
err = service.MyService.Docker().DockerContainerStart(appId)
|
||
} else {
|
||
err = service.MyService.Docker().DockerContainerStop(appId)
|
||
}
|
||
|
||
if err != nil {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||
return
|
||
}
|
||
info, err := service.MyService.App().GetContainerInfo(appId)
|
||
if err != nil {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||
return
|
||
}
|
||
|
||
// @tiger - 用 {'state': ...} 来体现出参上下文
|
||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: info.State})
|
||
}
|
||
|
||
// @Summary 查看容器日志
|
||
// @Produce application/json
|
||
// @Accept application/json
|
||
// @Tags app
|
||
// @Param id path string true "appid"
|
||
// @Security ApiKeyAuth
|
||
// @Success 200 {string} string "ok"
|
||
// @Router /app/logs/{id} [get]
|
||
func ContainerLog(c *gin.Context) {
|
||
appId := c.Param("id")
|
||
log, _ := service.MyService.Docker().DockerContainerLog(appId)
|
||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: log})
|
||
}
|
||
|
||
// @Summary 获取容器状态
|
||
// @Produce application/json
|
||
// @Accept application/json
|
||
// @Tags app
|
||
// @Param id path string true "容器id"
|
||
// @Param type query string false "type=1"
|
||
// @Security ApiKeyAuth
|
||
// @Success 200 {string} string "ok"
|
||
// @Router /app/state/{id} [get]
|
||
func GetContainerState(c *gin.Context) {
|
||
id := c.Param("id")
|
||
//t := c.DefaultQuery("type", "0")
|
||
containerInfo, e := service.MyService.App().GetSimpleContainerInfo(id)
|
||
if e != nil {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: e.Error()})
|
||
return
|
||
}
|
||
|
||
var data = make(map[string]interface{})
|
||
|
||
data["state"] = containerInfo.State
|
||
|
||
// if t == "1" {
|
||
// appInfo := service.MyService.App().GetAppDBInfo(id)
|
||
// data["app"] = appInfo
|
||
// }
|
||
|
||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||
}
|
||
|
||
// @Summary 更新设置
|
||
// @Produce application/json
|
||
// @Accept multipart/form-data
|
||
// @Tags app
|
||
// @Param id path string true "容器id"
|
||
// @Param shares formData string false "cpu权重"
|
||
// @Param mem formData string false "内存大小MB"
|
||
// @Param restart formData string false "重启策略"
|
||
// @Param label formData string false "应用名称"
|
||
// @Param position formData bool true "是否放到首页"
|
||
// @Security ApiKeyAuth
|
||
// @Success 200 {string} string "ok"
|
||
// @Router /app/update/{id}/setting [put]
|
||
func UpdateSetting(c *gin.Context) {
|
||
id := c.Param("id")
|
||
const CUSTOM = "custom"
|
||
m := model.CustomizationPostData{}
|
||
c.ShouldBind(&m)
|
||
|
||
if len(id) == 0 {
|
||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||
return
|
||
}
|
||
//var cpd model.CustomizationPostData
|
||
|
||
//copier.Copy(&cpd, &m)
|
||
|
||
//appInfo := service.MyService.App().GetAppDBInfo(id)
|
||
//info, err := service.MyService.Docker().DockerContainerInfo(id)
|
||
|
||
// //check app name is exist
|
||
// if _, err := service.MyService.Docker().DockerListByName(m.Label); err == nil {
|
||
// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR_APP_NAME_EXIST, Message: common_err.GetMsg(common_err.ERROR_APP_NAME_EXIST)})
|
||
// return
|
||
// }
|
||
service.MyService.Docker().DockerContainerStop(id)
|
||
portMap, _ := strconv.Atoi(m.PortMap)
|
||
if !port2.IsPortAvailable(portMap, "tcp") {
|
||
service.MyService.Docker().DockerContainerStart(id)
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + m.PortMap})
|
||
return
|
||
}
|
||
|
||
for _, u := range m.Ports {
|
||
|
||
if u.Protocol == "udp" {
|
||
t, _ := strconv.Atoi(u.CommendPort)
|
||
if !port2.IsPortAvailable(t, "udp") {
|
||
service.MyService.Docker().DockerContainerStart(id)
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort})
|
||
return
|
||
}
|
||
} else if u.Protocol == "tcp" {
|
||
te, _ := strconv.Atoi(u.CommendPort)
|
||
if !port2.IsPortAvailable(te, "tcp") {
|
||
service.MyService.Docker().DockerContainerStart(id)
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort})
|
||
return
|
||
}
|
||
} else if u.Protocol == "both" {
|
||
t, _ := strconv.Atoi(u.CommendPort)
|
||
if !port2.IsPortAvailable(t, "udp") {
|
||
service.MyService.Docker().DockerContainerStart(id)
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort})
|
||
return
|
||
}
|
||
|
||
te, _ := strconv.Atoi(u.CommendPort)
|
||
if !port2.IsPortAvailable(te, "tcp") {
|
||
service.MyService.Docker().DockerContainerStart(id)
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort})
|
||
return
|
||
}
|
||
}
|
||
|
||
}
|
||
service.MyService.Docker().DockerContainerUpdateName(id, id)
|
||
//service.MyService.Docker().DockerContainerRemove(id, true)
|
||
|
||
containerId, err := service.MyService.Docker().DockerContainerCreate(m, id)
|
||
if err != nil {
|
||
service.MyService.Docker().DockerContainerUpdateName(m.ContainerName, id)
|
||
service.MyService.Docker().DockerContainerStart(id)
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
|
||
return
|
||
}
|
||
// echo -e "hellow\nworld" >>
|
||
|
||
//step:启动容器
|
||
err = service.MyService.Docker().DockerContainerStart(containerId)
|
||
|
||
if err != nil {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
|
||
return
|
||
}
|
||
service.MyService.Docker().DockerContainerRemove(id, true)
|
||
//更新upnp
|
||
if m.Origin != CUSTOM {
|
||
//if appInfo.EnableUPNP != appInfo.EnableUPNP {
|
||
// if appInfo.EnableUPNP {
|
||
// upnp, err := upnp2.Gateway()
|
||
// if err == nil {
|
||
//
|
||
// for _, p := range appInfo.Ports {
|
||
// if p.Protocol == "udp" {
|
||
// upnp.CtrlUrl = upnp2.GetCtrlUrl(upnp.GatewayHost, upnp.DeviceDescUrl)
|
||
// upnp.LocalHost = ip_helper2.GetLoclIp()
|
||
// tComment, _ := strconv.Atoi(p.CommendPort)
|
||
// upnp.AddPortMapping(tComment, tComment, "UDP")
|
||
// time.Sleep(time.Millisecond * 200)
|
||
// } else if p.Protocol == "tcp" {
|
||
// upnp.CtrlUrl = upnp2.GetCtrlUrl(upnp.GatewayHost, upnp.DeviceDescUrl)
|
||
// upnp.LocalHost = ip_helper2.GetLoclIp()
|
||
// tComment, _ := strconv.Atoi(p.CommendPort)
|
||
// upnp.AddPortMapping(tComment, tComment, "TCP")
|
||
// time.Sleep(time.Millisecond * 200)
|
||
// } else if p.Protocol == "both" {
|
||
// upnp.CtrlUrl = upnp2.GetCtrlUrl(upnp.GatewayHost, upnp.DeviceDescUrl)
|
||
// upnp.LocalHost = ip_helper2.GetLoclIp()
|
||
// tComment, _ := strconv.Atoi(p.CommendPort)
|
||
// upnp.AddPortMapping(tComment, tComment, "UDP")
|
||
// time.Sleep(time.Millisecond * 200)
|
||
//
|
||
// upnp.AddPortMapping(tComment, tComment, "TCP")
|
||
// time.Sleep(time.Millisecond * 200)
|
||
// }
|
||
// }
|
||
// }
|
||
// } else {
|
||
// upnp, err := upnp2.Gateway()
|
||
// if err == nil {
|
||
// for _, p := range appInfo.Ports {
|
||
// if p.Protocol == "udp" {
|
||
//
|
||
// upnp.CtrlUrl = upnp2.GetCtrlUrl(upnp.GatewayHost, upnp.DeviceDescUrl)
|
||
// upnp.LocalHost = ip_helper2.GetLoclIp()
|
||
// tComment, _ := strconv.Atoi(p.CommendPort)
|
||
// upnp.DelPortMapping(tComment, "UDP")
|
||
// time.Sleep(time.Millisecond * 200)
|
||
// } else if p.Protocol == "tcp" {
|
||
// upnp.CtrlUrl = upnp2.GetCtrlUrl(upnp.GatewayHost, upnp.DeviceDescUrl)
|
||
// upnp.LocalHost = ip_helper2.GetLoclIp()
|
||
// tComment, _ := strconv.Atoi(p.CommendPort)
|
||
// upnp.DelPortMapping(tComment, "TCP")
|
||
// time.Sleep(time.Millisecond * 200)
|
||
// } else if p.Protocol == "both" {
|
||
// upnp.CtrlUrl = upnp2.GetCtrlUrl(upnp.GatewayHost, upnp.DeviceDescUrl)
|
||
// upnp.LocalHost = ip_helper2.GetLoclIp()
|
||
// tComment, _ := strconv.Atoi(p.CommendPort)
|
||
// upnp.DelPortMapping(tComment, "UDP")
|
||
// time.Sleep(time.Millisecond * 200)
|
||
//
|
||
// upnp.DelPortMapping(tComment, "TCP")
|
||
// time.Sleep(time.Millisecond * 200)
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
//}
|
||
}
|
||
|
||
//service.MyService.App().UpdateApp(appInfo)
|
||
|
||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||
}
|
||
|
||
// @Summary update app version
|
||
// @Produce application/json
|
||
// @Accept multipart/form-data
|
||
// @Tags app
|
||
// @Param id path string true "容器id"
|
||
// @Security ApiKeyAuth
|
||
// @Success 200 {string} string "ok"
|
||
// @Router /app/update/{id} [put]
|
||
func PutAppUpdate(c *gin.Context) {
|
||
id := c.Param("id")
|
||
|
||
if len(id) == 0 {
|
||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||
return
|
||
}
|
||
|
||
inspect, err := service.MyService.Docker().DockerContainerInfo(id)
|
||
if err != nil {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||
return
|
||
|
||
}
|
||
imageLatest := strings.Split(inspect.Config.Image, ":")[0] + ":latest"
|
||
err = service.MyService.Docker().DockerPullImage(imageLatest, "", "")
|
||
if err != nil {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||
return
|
||
|
||
}
|
||
service.MyService.Docker().DockerContainerStop(id)
|
||
service.MyService.Docker().DockerContainerUpdateName(id, id)
|
||
//service.MyService.Docker().DockerContainerRemove(id, true)
|
||
inspect.Image = imageLatest
|
||
inspect.Config.Image = imageLatest
|
||
containerId, err := service.MyService.Docker().DockerContainerCopyCreate(inspect)
|
||
if err != nil {
|
||
service.MyService.Docker().DockerContainerUpdateName(inspect.Name, id)
|
||
service.MyService.Docker().DockerContainerStart(id)
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
|
||
return
|
||
}
|
||
|
||
//step:启动容器
|
||
err = service.MyService.Docker().DockerContainerStart(containerId)
|
||
|
||
if err != nil {
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
|
||
return
|
||
}
|
||
service.MyService.Docker().DockerContainerRemove(id, true)
|
||
delete(service.NewVersionApp, id)
|
||
|
||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||
}
|
||
|
||
// @Summary 获取容器详情
|
||
// @Produce application/json
|
||
// @Accept application/json
|
||
// @Tags app
|
||
// @Param id path string true "appid"
|
||
// @Security ApiKeyAuth
|
||
// @Success 200 {string} string "ok"
|
||
// @Router /app/info/{id} [get]
|
||
func ContainerInfo(c *gin.Context) {
|
||
appId := c.Param("id")
|
||
|
||
// @tiger - 作为最佳实践,不应该直接把数据库的信息返回,来避免未来数据库结构上的迭代带来的新字段
|
||
appInfo := service.MyService.App().GetAppDBInfo(appId)
|
||
containerInfo, _ := service.MyService.Docker().DockerContainerStats(appId)
|
||
var cpuModel = "arm"
|
||
if cpu := service.MyService.System().GetCpuInfo(); len(cpu) > 0 {
|
||
if strings.Count(strings.ToLower(strings.TrimSpace(cpu[0].ModelName)), "intel") > 0 {
|
||
cpuModel = "intel"
|
||
} else if strings.Count(strings.ToLower(strings.TrimSpace(cpu[0].ModelName)), "amd") > 0 {
|
||
cpuModel = "amd"
|
||
}
|
||
}
|
||
|
||
info, err := service.MyService.Docker().DockerContainerInfo(appId)
|
||
if err != nil {
|
||
//todo 需要自定义错误
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||
return
|
||
}
|
||
con := struct {
|
||
Status string `json:"status"`
|
||
StartedAt string `json:"started_at"`
|
||
CPUShares int64 `json:"cpu_shares"`
|
||
Memory int64 `json:"total_memory"` // @tiger - 改成 total_memory,方便以后增加 free_memory 之类的字段
|
||
Restart string `json:"restart_policy"` // @tiger - 改成 restart_policy?
|
||
}{Status: info.State.Status, StartedAt: info.State.StartedAt, CPUShares: info.HostConfig.CPUShares, Memory: info.HostConfig.Memory >> 20, Restart: info.HostConfig.RestartPolicy.Name}
|
||
data := make(map[string]interface{}, 5)
|
||
data["app"] = appInfo // @tiget - 最佳实践是,返回 appid,然后具体的 app 信息由前端另行获取
|
||
data["cpu"] = cpuModel // @tiger - 改成 arch
|
||
data["memory"] = service.MyService.System().GetMemInfo()["total"] // @tiger - 改成 total_memory,方便以后增加 free_memory 之类的字段
|
||
data["container"] = json2.RawMessage(containerInfo)
|
||
data["info"] = con
|
||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||
}
|
||
|
||
func GetDockerNetworks(c *gin.Context) {
|
||
networks := service.MyService.Docker().DockerNetworkModelList()
|
||
list := []map[string]string{}
|
||
for _, network := range networks {
|
||
if network.Driver != "null" {
|
||
list = append(list, map[string]string{"name": network.Name, "driver": network.Driver, "id": network.ID})
|
||
}
|
||
}
|
||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
||
}
|
||
|
||
// @Summary 获取依赖数据
|
||
// @Produce application/json
|
||
// @Accept application/json
|
||
// @Tags app
|
||
// @Param id path string true "rely id"
|
||
// @Security ApiKeyAuth
|
||
// @Success 200 {string} string "ok"
|
||
// @Router /app/rely/{id}/info [get]
|
||
func ContainerRelyInfo(c *gin.Context) {
|
||
id := c.Param("id")
|
||
appInfo := service.MyService.Rely().GetInfo(id)
|
||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: appInfo})
|
||
}
|
||
|
||
// @Produce application/json
|
||
// @Accept application/json
|
||
// @Tags app
|
||
// @Param id path string true "appid"
|
||
// @Security ApiKeyAuth
|
||
// @Success 200 {string} string "ok"
|
||
// @Router /app/update/{id}/info [get]
|
||
func ContainerUpdateInfo(c *gin.Context) {
|
||
appId := c.Param("id")
|
||
//appInfo := service.MyService.App().GetAppDBInfo(appId)
|
||
info, err := service.MyService.Docker().DockerContainerInfo(appId)
|
||
if err != nil {
|
||
|
||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: err.Error()})
|
||
return
|
||
}
|
||
var port model.PortArray
|
||
// json2.Unmarshal([]byte(appInfo.Ports), &port)
|
||
|
||
for k, v := range info.HostConfig.PortBindings {
|
||
temp := model.PortMap{
|
||
CommendPort: v[0].HostPort,
|
||
ContainerPort: k.Port(),
|
||
|
||
Protocol: k.Proto(),
|
||
}
|
||
port = append(port, temp)
|
||
}
|
||
|
||
var envs model.EnvArray
|
||
// json2.Unmarshal([]byte(appInfo.Envs), &envs)
|
||
|
||
showENV := info.Config.Labels["show_env"]
|
||
showENVList := strings.Split(showENV, ",")
|
||
showENVMap := make(map[string]string)
|
||
if len(showENVList) > 0 && showENVList[0] != "" {
|
||
for _, name := range showENVList {
|
||
showENVMap[name] = "1"
|
||
}
|
||
}
|
||
for _, v := range info.Config.Env {
|
||
if len(showENVList) > 0 {
|
||
if _, ok := showENVMap[strings.Split(v, "=")[0]]; ok {
|
||
temp := model.Env{
|
||
Name: strings.Split(v, "=")[0],
|
||
Value: strings.Split(v, "=")[1],
|
||
}
|
||
envs = append(envs, temp)
|
||
}
|
||
} else {
|
||
temp := model.Env{
|
||
Name: strings.Split(v, "=")[0],
|
||
Value: strings.Split(v, "=")[1],
|
||
}
|
||
envs = append(envs, temp)
|
||
}
|
||
|
||
}
|
||
|
||
var vol model.PathArray
|
||
// json2.Unmarshal([]byte(appInfo.Volumes), &vol)
|
||
|
||
for i := 0; i < len(info.Mounts); i++ {
|
||
temp := model.PathMap{
|
||
Path: strings.ReplaceAll(info.Mounts[i].Source, "$AppID", info.Name),
|
||
ContainerPath: info.Mounts[i].Destination,
|
||
}
|
||
vol = append(vol, temp)
|
||
}
|
||
var driver model.PathArray
|
||
|
||
//volumesStr, _ := json2.Marshal(m.Volumes)
|
||
//devicesStr, _ := json2.Marshal(m.Devices)
|
||
for _, v := range info.HostConfig.Resources.Devices {
|
||
temp := model.PathMap{
|
||
Path: v.PathOnHost,
|
||
ContainerPath: v.PathInContainer,
|
||
}
|
||
driver = append(driver, temp)
|
||
}
|
||
|
||
m := model.CustomizationPostData{}
|
||
m.Icon = info.Config.Labels["icon"]
|
||
m.Ports = port
|
||
m.Image = info.Config.Image
|
||
m.Origin = info.Config.Labels["origin"]
|
||
if len(m.Origin) == 0 {
|
||
m.Origin = "local"
|
||
}
|
||
m.NetworkModel = string(info.HostConfig.NetworkMode)
|
||
m.Description = info.Config.Labels["desc"]
|
||
m.ContainerName = strings.ReplaceAll(info.Name, "/", "")
|
||
m.PortMap = info.Config.Labels["web"]
|
||
m.Devices = driver
|
||
m.Envs = envs
|
||
m.Memory = info.HostConfig.Memory >> 20
|
||
m.CpuShares = info.HostConfig.CPUShares
|
||
m.Volumes = vol //appInfo.Volumes
|
||
m.Restart = info.HostConfig.RestartPolicy.Name
|
||
m.EnableUPNP = false
|
||
m.Index = info.Config.Labels["index"]
|
||
m.Position = false
|
||
m.CustomId = info.Config.Labels["custom_id"]
|
||
m.Host = info.Config.Labels["host"]
|
||
if len(m.CustomId) == 0 {
|
||
m.CustomId = uuid.NewV4().String()
|
||
}
|
||
m.CapAdd = info.HostConfig.CapAdd
|
||
m.Cmd = info.Config.Cmd
|
||
m.HostName = info.Config.Hostname
|
||
m.Privileged = info.HostConfig.Privileged
|
||
name := info.Config.Labels["name"]
|
||
if len(name) == 0 {
|
||
name = strings.ReplaceAll(info.Name, "/", "")
|
||
}
|
||
m.Label = name
|
||
|
||
m.Protocol = info.Config.Labels["protocol"]
|
||
if m.Protocol == "" {
|
||
m.Protocol = "http"
|
||
}
|
||
|
||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: m})
|
||
}
|
||
|
||
////准备安装(暂时不需要)
|
||
//func ReadyInstall(c *gin.Context) {
|
||
// _, tcp, udp := service.MyService.GetManifestJsonByRepo()
|
||
// data := make(map[string]interface{}, 2)
|
||
// if t := gjson.Parse(tcp).Array(); len(t) > 0 {
|
||
// //tcpList := []model.TcpPorts{}
|
||
// //e := json2.Unmarshal([]byte(tcp), tcpList)
|
||
// //if e!=nil {
|
||
// // return
|
||
// //}
|
||
// //for _, port := range tcpList {
|
||
// // if port.ContainerPort>0&&port.ExtranetPort {
|
||
// //
|
||
// // }
|
||
// //}
|
||
// var inarr []interface{}
|
||
// for _, result := range t {
|
||
//
|
||
// var p int
|
||
// ok := true
|
||
// for ok {
|
||
// p, _ = port.GetAvailablePort()
|
||
// ok = !port.IsPortAvailable(p)
|
||
// }
|
||
// pm := model.PortMap{gjson.Get(result.Raw, "container_port").Int(), p}
|
||
// inarr = append(inarr, pm)
|
||
// }
|
||
// data["tcp"] = inarr
|
||
// }
|
||
// if u := gjson.Parse(udp).Array(); len(u) > 0 {
|
||
// //udpList := []model.UdpPorts{}
|
||
// //e := json2.Unmarshal([]byte(udp), udpList)
|
||
// //if e != nil {
|
||
// // return
|
||
// //}
|
||
// var inarr []model.PortMap
|
||
// for _, result := range u {
|
||
// var p int
|
||
// ok := true
|
||
// for ok {
|
||
// p, _ = port.GetAvailablePort()
|
||
// ok = !port.IsPortAvailable(p)
|
||
// }
|
||
// pm := model.PortMap{gjson.Get(result.Raw, "container_port").Int(), p}
|
||
// inarr = append(inarr, pm)
|
||
// }
|
||
// data["udp"] = inarr
|
||
// }
|
||
// c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||
//}
|