2021-09-26 02:35:02 +00:00
package v1
import (
"bytes"
json2 "encoding/json"
2021-10-22 08:49:09 +00:00
"net/http"
2022-07-22 03:02:11 +00:00
"os/exec"
2022-06-08 10:19:45 +00:00
"path/filepath"
2021-10-22 08:49:09 +00:00
"strconv"
"strings"
"time"
2021-09-27 06:17:36 +00:00
"github.com/IceWhaleTech/CasaOS/model"
2022-06-08 10:19:45 +00:00
"github.com/IceWhaleTech/CasaOS/model/notify"
2021-12-09 11:02:41 +00:00
"github.com/IceWhaleTech/CasaOS/pkg/config"
2021-09-27 06:17:36 +00:00
"github.com/IceWhaleTech/CasaOS/pkg/docker"
2022-06-29 03:09:58 +00:00
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
2021-09-27 06:17:36 +00:00
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
2022-07-22 03:02:11 +00:00
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
2021-09-27 06:17:36 +00:00
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"
2021-09-26 02:35:02 +00:00
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"github.com/jinzhu/copier"
uuid "github.com/satori/go.uuid"
2022-07-22 03:02:11 +00:00
"go.uber.org/zap"
2021-10-27 09:27:46 +00:00
"golang.org/x/crypto/ssh"
2021-09-26 02:35:02 +00:00
)
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 {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : common_err . GetMsg ( common_err . SERVICE_ERROR ) , Data : err . Error ( ) } )
2021-09-26 02:35:02 +00:00
return
}
defer conn . Close ( )
container := c . Param ( "id" )
hr , err := service . Exec ( container , row , col )
if err != nil {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : common_err . GetMsg ( common_err . SERVICE_ERROR ) , Data : err . Error ( ) } )
2021-09-26 02:35:02 +00:00
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 )
}
2022-07-22 03:02:11 +00:00
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 ) } )
}
2021-09-26 02:35:02 +00:00
func WsSsh ( c * gin . Context ) {
2022-07-22 03:02:11 +00:00
_ , 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
}
2021-10-27 09:27:46 +00:00
2022-07-22 03:02:11 +00:00
userName := c . Query ( "username" )
password := c . Query ( "password" )
port := c . Query ( "port" )
wsConn , _ := upgrader . Upgrade ( c . Writer , c . Request , nil )
2021-10-27 09:27:46 +00:00
var logBuff = new ( bytes . Buffer )
2022-07-22 03:02:11 +00:00
2021-10-27 09:27:46 +00:00
quitChan := make ( chan bool , 3 )
2022-07-22 03:02:11 +00:00
// user := ""
// password := ""
2021-10-27 09:27:46 +00:00
var login int = 1
2021-09-26 02:35:02 +00:00
cols , _ := strconv . Atoi ( c . DefaultQuery ( "cols" , "200" ) )
rows , _ := strconv . Atoi ( c . DefaultQuery ( "rows" , "32" ) )
2021-10-27 09:27:46 +00:00
var client * ssh . Client
for login != 0 {
var err error
2022-07-22 03:02:11 +00:00
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 )
2021-10-27 09:27:46 +00:00
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 ( )
}
2021-09-26 02:35:02 +00:00
ssConn , _ := docker . NewSshConn ( cols , rows , client )
defer ssConn . Close ( )
go ssConn . ReceiveWsMsg ( wsConn , logBuff , quitChan )
go ssConn . SendComboOutput ( wsConn , quitChan )
go ssConn . SessionWait ( quitChan )
2021-10-27 09:27:46 +00:00
2021-09-26 02:35:02 +00:00
<- 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"
2022-06-08 10:19:45 +00:00
// @Router /app/install [post]
2021-09-26 02:35:02 +00:00
func InstallApp ( c * gin . Context ) {
var appInfo model . ServerAppList
m := model . CustomizationPostData { }
2022-07-22 03:02:11 +00:00
c . ShouldBind ( & m )
2021-09-26 02:35:02 +00:00
const CUSTOM = "custom"
var dockerImage string
var dockerImageVersion string
2022-05-05 05:46:55 +00:00
//check app name is exist
2022-06-08 10:19:45 +00:00
if len ( m . Protocol ) == 0 {
m . Protocol = "http"
}
2022-07-22 03:02:11 +00:00
m . ContainerName = strings . Replace ( m . Label , " " , "_" , - 1 )
if m . Origin != CUSTOM {
oldName := m . ContainerName
oldLabel := m . Label
2022-05-13 10:12:26 +00:00
for i := 0 ; true ; i ++ {
if i != 0 {
2022-07-22 03:02:11 +00:00
m . ContainerName = oldName + "-" + strconv . Itoa ( i )
m . Label = oldLabel + "-" + strconv . Itoa ( i )
2022-05-13 10:12:26 +00:00
}
2022-07-22 03:02:11 +00:00
if _ , err := service . MyService . Docker ( ) . DockerListByName ( m . ContainerName ) ; err != nil {
2022-05-13 10:12:26 +00:00
break
}
}
} else {
2022-07-22 03:02:11 +00:00
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 ) } )
2022-05-05 05:46:55 +00:00
return
}
}
2022-05-13 10:12:26 +00:00
2022-06-08 10:19:45 +00:00
//check port
2021-09-26 02:35:02 +00:00
if len ( m . PortMap ) > 0 && m . PortMap != "0" {
2022-06-29 03:09:58 +00:00
//c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
2021-09-26 02:35:02 +00:00
portMap , _ := strconv . Atoi ( m . PortMap )
if ! port2 . IsPortAvailable ( portMap , "tcp" ) {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : "Duplicate port:" + m . PortMap } )
2021-09-26 02:35:02 +00:00
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"
}
2022-08-15 03:37:21 +00:00
m . Image = dockerImage + ":" + dockerImageVersion
2021-09-26 02:35:02 +00:00
for _ , u := range m . Ports {
if u . Protocol == "udp" {
t , _ := strconv . Atoi ( u . CommendPort )
if ! port2 . IsPortAvailable ( t , "udp" ) {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : "Duplicate port:" + u . CommendPort } )
2021-09-26 02:35:02 +00:00
return
}
} else if u . Protocol == "tcp" {
te , _ := strconv . Atoi ( u . CommendPort )
if ! port2 . IsPortAvailable ( te , "tcp" ) {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : "Duplicate port:" + u . CommendPort } )
2021-09-26 02:35:02 +00:00
return
}
} else if u . Protocol == "both" {
t , _ := strconv . Atoi ( u . CommendPort )
if ! port2 . IsPortAvailable ( t , "udp" ) {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : "Duplicate port:" + u . CommendPort } )
2021-09-26 02:35:02 +00:00
return
}
te , _ := strconv . Atoi ( u . CommendPort )
if ! port2 . IsPortAvailable ( te , "tcp" ) {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : "Duplicate port:" + u . CommendPort } )
2021-09-26 02:35:02 +00:00
return
}
}
}
2022-07-22 03:02:11 +00:00
if m . Origin == CUSTOM {
2021-12-29 08:42:20 +00:00
for _ , device := range m . Devices {
if file . CheckNotExist ( device . Path ) {
2022-07-22 03:02:11 +00:00
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 ) } )
2021-12-29 08:42:20 +00:00
return
}
2021-09-26 02:35:02 +00:00
}
2021-12-29 08:42:20 +00:00
} else {
dev := [ ] model . PathMap { }
for _ , device := range dev {
if ! file . CheckNotExist ( device . Path ) {
dev = append ( dev , device )
}
}
m . Devices = dev
2021-09-26 02:35:02 +00:00
}
2021-12-29 08:42:20 +00:00
2021-09-26 02:35:02 +00:00
//restart := c.PostForm("restart") //always 总是重启, unless-stopped 除非用户手动停止容器,否则总是重新启动, on-failure:仅当容器退出代码非零时重新启动
//if len(restart) > 0 {
//
//}
//
//privileged := c.PostForm("privileged") //是否处于特权模式
//if len(privileged) > 0 {
//
//}
2022-05-13 10:12:26 +00:00
id := uuid . NewV4 ( ) . String ( )
m . CustomId = id
2021-09-26 02:35:02 +00:00
var relyMap = make ( map [ string ] string )
go func ( ) {
2022-06-08 10:19:45 +00:00
// 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)
2022-07-22 03:02:11 +00:00
if m . Origin != CUSTOM {
2021-09-26 02:35:02 +00:00
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
2022-05-05 05:46:55 +00:00
rely . ContainerCustomId = m . Label
2021-12-03 08:48:07 +00:00
var mysqlConfig model2 . MysqlConfigs
2021-09-26 02:35:02 +00:00
//结构体转换
2021-12-03 08:48:07 +00:00
copier . Copy ( & mysqlConfig , & mc )
rely . Config = mysqlConfig
2021-09-26 02:35:02 +00:00
service . MyService . Rely ( ) . Create ( rely )
relyMap [ "mysql" ] = mid
} else {
docker_base . MysqlDelete ( mysqlContainerId )
2022-06-08 10:19:45 +00:00
// installLog.State = 0
// installLog.Message = err.Error()
// service.MyService.Notify().UpdateLog(installLog)
2021-09-26 02:35:02 +00:00
}
}
}
}
// step: 下载镜像
2022-06-08 10:19:45 +00:00
err := service . MyService . Docker ( ) . DockerPullImage ( dockerImage + ":" + dockerImageVersion , m . Icon , m . Label )
2021-09-26 02:35:02 +00:00
if err != nil {
2022-06-08 10:19:45 +00:00
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 )
2021-09-26 02:35:02 +00:00
return
}
2022-08-15 03:37:21 +00:00
for ! service . MyService . Docker ( ) . IsExistImage ( m . Image ) {
2021-09-26 02:35:02 +00:00
time . Sleep ( time . Second )
}
2022-08-15 03:37:21 +00:00
_ , err = service . MyService . Docker ( ) . DockerContainerCreate ( m , "" )
2021-09-26 02:35:02 +00:00
if err != nil {
//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":80}", 100)
2022-06-08 10:19:45 +00:00
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 )
2021-09-26 02:35:02 +00:00
return
} else {
2022-06-08 10:19:45 +00:00
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 )
2021-09-26 02:35:02 +00:00
}
2021-11-03 09:07:46 +00:00
// echo -e "hellow\nworld" >>
2021-09-26 02:35:02 +00:00
//step: 启动容器
2022-07-22 03:02:11 +00:00
err = service . MyService . Docker ( ) . DockerContainerStart ( m . ContainerName )
2021-09-26 02:35:02 +00:00
if err != nil {
//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":90}", 100)
2022-06-08 10:19:45 +00:00
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 )
2021-09-26 02:35:02 +00:00
return
} else {
2022-06-08 10:19:45 +00:00
// if m.Origin != CUSTOM {
// installLog.Message = "setting upnp"
// } else {
// installLog.Message = "nearing completion"
// }
// service.MyService.Notify().UpdateLog(installLog)
2021-09-26 02:35:02 +00:00
}
//step: 启动成功 检查容器状态确认启动成功
2022-07-22 03:02:11 +00:00
container , err := service . MyService . Docker ( ) . DockerContainerInfo ( m . ContainerName )
2021-09-26 02:35:02 +00:00
if err != nil && container . ContainerJSONBase . State . Running {
2022-06-08 10:19:45 +00:00
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 )
2021-09-26 02:35:02 +00:00
return
} else {
2022-06-08 10:19:45 +00:00
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 )
2021-09-26 02:35:02 +00:00
}
2021-12-29 08:42:20 +00:00
// if m.Origin != "custom" {
// for i := 0; i < len(m.Volumes); i++ {
// m.Volumes[i].Path = docker.GetDir(id, m.Volumes[i].Path)
// }
// }
2022-05-05 05:46:55 +00:00
//service.MyService.App().SaveContainer(md)
2021-12-10 06:17:36 +00:00
config . CasaOSGlobalVariables . AppChange = true
2021-09-26 02:35:02 +00:00
} ( )
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SUCCESS , model . Result { Success : common_err . SUCCESS , Message : common_err . GetMsg ( common_err . SUCCESS ) , Data : m . Label } )
2021-09-26 02:35:02 +00:00
}
//// @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{}
2022-07-22 03:02:11 +00:00
// c.ShouldBind(&m)
2021-09-26 02:35:02 +00:00
// //检查端口
// if len(m.PortMap) == 0 || m.PortMap == "0" {
2022-06-29 03:09:58 +00:00
// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
2021-09-26 02:35:02 +00:00
// return
// }
// if len(m.Port) == 0 || m.Port == "0" {
// m.Port = m.PortMap
// }
//
// portMap, _ := strconv.Atoi(m.PortMap)
// if !port2.IsPortAvailable(portMap, "tcp") {
2022-06-29 03:09:58 +00:00
// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + m.PortMap})
2021-09-26 02:35:02 +00:00
// return
// }
//
// for _, u := range m.Udp {
// t, _ := strconv.Atoi(u.CommendPort)
// if !port2.IsPortAvailable(t, "udp") {
2022-06-29 03:09:58 +00:00
// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort})
2021-09-26 02:35:02 +00:00
// return
// }
// }
//
// for _, t := range m.Tcp {
// te, _ := strconv.Atoi(t.CommendPort)
// if !port2.IsPortAvailable(te, "tcp") {
2022-06-29 03:09:58 +00:00
// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + t.CommendPort})
2021-09-26 02:35:02 +00:00
// 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 {
2022-06-29 03:09:58 +00:00
// c.JSON(http.StatusOK, model.Result{Success: common_err.PULL_IMAGE_ERROR, Message: common_err.GetMsg(common_err.PULL_IMAGE_ERROR)})
2021-09-26 02:35:02 +00:00
// }
//
// 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)
//
// }()
//
2022-06-29 03:09:58 +00:00
// c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id})
2021-09-26 02:35:02 +00:00
//
//}
// @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 {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . CLIENT_ERROR , model . Result { Success : common_err . INVALID_PARAMS , Message : common_err . GetMsg ( common_err . INVALID_PARAMS ) } )
2021-09-26 02:35:02 +00:00
return
}
2022-05-05 05:46:55 +00:00
//info := service.MyService.App().GetUninstallInfo(appId)
info , err := service . MyService . Docker ( ) . DockerContainerInfo ( appId )
if err != nil {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : common_err . GetMsg ( common_err . SERVICE_ERROR ) , Data : err . Error ( ) } )
2022-05-05 05:46:55 +00:00
return
}
2021-09-26 02:35:02 +00:00
//step: 停止容器
2022-05-05 05:46:55 +00:00
err = service . MyService . Docker ( ) . DockerContainerStop ( appId )
2021-09-26 02:35:02 +00:00
if err != nil {
2022-07-22 03:02:11 +00:00
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 ( ) } )
2021-09-26 02:35:02 +00:00
return
}
2021-12-06 09:08:36 +00:00
err = service . MyService . Docker ( ) . DockerContainerRemove ( appId , false )
2021-09-26 02:35:02 +00:00
if err != nil {
2022-07-22 03:02:11 +00:00
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 ( ) } )
2021-09-26 02:35:02 +00:00
return
}
2022-06-08 10:19:45 +00:00
// step: remove image
service . MyService . Docker ( ) . DockerImageRemove ( info . Config . Image )
2021-09-26 02:35:02 +00:00
2022-05-05 05:46:55 +00:00
if info . Config . Labels [ "origin" ] != "custom" {
2021-09-26 02:35:02 +00:00
//step: 删除文件夹
2022-06-08 10:19:45 +00:00
for _ , v := range info . Mounts {
2022-05-05 05:46:55 +00:00
if strings . Contains ( v . Source , info . Name ) {
2022-06-08 10:19:45 +00:00
path := filepath . Join ( strings . Split ( v . Source , info . Name ) [ 0 ] , info . Name )
service . MyService . App ( ) . DelAppConfigDir ( path )
2021-11-25 11:41:25 +00:00
}
2021-11-03 09:07:46 +00:00
}
2021-09-26 02:35:02 +00:00
//step: 删除install log
2022-02-17 10:43:25 +00:00
//service.MyService.Notify().DelLog(appId)
2021-09-26 02:35:02 +00:00
// 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)
// }
// }
// }
//}
}
2021-12-10 06:17:36 +00:00
config . CasaOSGlobalVariables . AppChange = true
2022-06-08 10:19:45 +00:00
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 )
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SUCCESS , model . Result { Success : common_err . SUCCESS , Message : common_err . GetMsg ( common_err . SUCCESS ) } )
2021-09-26 02:35:02 +00:00
}
// @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" )
2022-07-22 03:02:11 +00:00
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
}
2021-09-26 02:35:02 +00:00
var err error
2022-07-22 03:02:11 +00:00
if state == "start" {
2021-09-26 02:35:02 +00:00
err = service . MyService . Docker ( ) . DockerContainerStart ( appId )
} else if state == "restart" {
2022-05-05 05:46:55 +00:00
service . MyService . Docker ( ) . DockerContainerStop ( appId )
2021-09-26 02:35:02 +00:00
err = service . MyService . Docker ( ) . DockerContainerStart ( appId )
2022-07-22 03:02:11 +00:00
} else {
err = service . MyService . Docker ( ) . DockerContainerStop ( appId )
2021-09-26 02:35:02 +00:00
}
2022-07-22 03:02:11 +00:00
2021-09-26 02:35:02 +00:00
if err != nil {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : common_err . GetMsg ( common_err . SERVICE_ERROR ) , Data : err . Error ( ) } )
2021-09-26 02:35:02 +00:00
return
}
info , err := service . MyService . App ( ) . GetContainerInfo ( appId )
if err != nil {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : common_err . GetMsg ( common_err . SERVICE_ERROR ) , Data : err . Error ( ) } )
2021-09-26 02:35:02 +00:00
return
}
2022-07-22 03:02:11 +00:00
// @tiger - 用 {'state': ...} 来体现出参上下文
c . JSON ( common_err . SUCCESS , model . Result { Success : common_err . SUCCESS , Message : common_err . GetMsg ( common_err . SUCCESS ) , Data : info . State } )
2021-09-26 02:35:02 +00:00
}
// @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 )
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SUCCESS , model . Result { Success : common_err . SUCCESS , Message : common_err . GetMsg ( common_err . SUCCESS ) , Data : log } )
2021-09-26 02:35:02 +00:00
}
// @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" )
2022-07-22 03:02:11 +00:00
//t := c.DefaultQuery("type", "0")
2021-09-26 02:35:02 +00:00
containerInfo , e := service . MyService . App ( ) . GetSimpleContainerInfo ( id )
if e != nil {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : e . Error ( ) } )
2021-09-26 02:35:02 +00:00
return
}
var data = make ( map [ string ] interface { } )
data [ "state" ] = containerInfo . State
2022-07-22 03:02:11 +00:00
// if t == "1" {
// appInfo := service.MyService.App().GetAppDBInfo(id)
// data["app"] = appInfo
// }
2021-09-26 02:35:02 +00:00
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SUCCESS , model . Result { Success : common_err . SUCCESS , Message : common_err . GetMsg ( common_err . SUCCESS ) , Data : data } )
2021-09-26 02:35:02 +00:00
}
// @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 { }
2022-07-22 03:02:11 +00:00
c . ShouldBind ( & m )
2021-09-26 02:35:02 +00:00
if len ( id ) == 0 {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . CLIENT_ERROR , model . Result { Success : common_err . INVALID_PARAMS , Message : common_err . GetMsg ( common_err . INVALID_PARAMS ) } )
2021-09-26 02:35:02 +00:00
return
}
2022-05-05 05:46:55 +00:00
//var cpd model.CustomizationPostData
2021-09-26 02:35:02 +00:00
2022-05-05 05:46:55 +00:00
//copier.Copy(&cpd, &m)
2021-09-26 02:35:02 +00:00
2022-05-05 05:46:55 +00:00
//appInfo := service.MyService.App().GetAppDBInfo(id)
//info, err := service.MyService.Docker().DockerContainerInfo(id)
2021-09-26 02:35:02 +00:00
2022-05-05 05:46:55 +00:00
// //check app name is exist
// if _, err := service.MyService.Docker().DockerListByName(m.Label); err == nil {
2022-06-29 03:09:58 +00:00
// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR_APP_NAME_EXIST, Message: common_err.GetMsg(common_err.ERROR_APP_NAME_EXIST)})
2022-05-05 05:46:55 +00:00
// return
// }
2022-05-13 10:12:26 +00:00
service . MyService . Docker ( ) . DockerContainerStop ( id )
2021-09-26 02:35:02 +00:00
portMap , _ := strconv . Atoi ( m . PortMap )
if ! port2 . IsPortAvailable ( portMap , "tcp" ) {
2022-05-13 10:12:26 +00:00
service . MyService . Docker ( ) . DockerContainerStart ( id )
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : "Duplicate port:" + m . PortMap } )
2021-09-26 02:35:02 +00:00
return
}
for _ , u := range m . Ports {
if u . Protocol == "udp" {
t , _ := strconv . Atoi ( u . CommendPort )
if ! port2 . IsPortAvailable ( t , "udp" ) {
2022-05-13 10:12:26 +00:00
service . MyService . Docker ( ) . DockerContainerStart ( id )
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : "Duplicate port:" + u . CommendPort } )
2021-09-26 02:35:02 +00:00
return
}
} else if u . Protocol == "tcp" {
te , _ := strconv . Atoi ( u . CommendPort )
if ! port2 . IsPortAvailable ( te , "tcp" ) {
2022-05-13 10:12:26 +00:00
service . MyService . Docker ( ) . DockerContainerStart ( id )
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : "Duplicate port:" + u . CommendPort } )
2021-09-26 02:35:02 +00:00
return
}
} else if u . Protocol == "both" {
t , _ := strconv . Atoi ( u . CommendPort )
if ! port2 . IsPortAvailable ( t , "udp" ) {
2022-05-13 10:12:26 +00:00
service . MyService . Docker ( ) . DockerContainerStart ( id )
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : "Duplicate port:" + u . CommendPort } )
2021-09-26 02:35:02 +00:00
return
}
te , _ := strconv . Atoi ( u . CommendPort )
if ! port2 . IsPortAvailable ( te , "tcp" ) {
2022-05-13 10:12:26 +00:00
service . MyService . Docker ( ) . DockerContainerStart ( id )
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : "Duplicate port:" + u . CommendPort } )
2021-09-26 02:35:02 +00:00
return
}
}
}
2022-05-05 05:46:55 +00:00
service . MyService . Docker ( ) . DockerContainerUpdateName ( id , id )
//service.MyService.Docker().DockerContainerRemove(id, true)
2021-09-26 02:35:02 +00:00
2022-08-15 03:37:21 +00:00
containerId , err := service . MyService . Docker ( ) . DockerContainerCreate ( m , id )
2022-05-05 05:46:55 +00:00
if err != nil {
2022-07-22 03:02:11 +00:00
service . MyService . Docker ( ) . DockerContainerUpdateName ( m . ContainerName , id )
2022-05-05 05:46:55 +00:00
service . MyService . Docker ( ) . DockerContainerStart ( id )
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : common_err . GetMsg ( common_err . SERVICE_ERROR ) } )
2022-05-05 05:46:55 +00:00
return
2021-09-26 02:35:02 +00:00
}
2022-05-05 05:46:55 +00:00
// echo -e "hellow\nworld" >>
//step: 启动容器
err = service . MyService . Docker ( ) . DockerContainerStart ( containerId )
2021-09-26 02:35:02 +00:00
if err != nil {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : common_err . GetMsg ( common_err . SERVICE_ERROR ) } )
2021-09-26 02:35:02 +00:00
return
}
2022-05-05 05:46:55 +00:00
service . MyService . Docker ( ) . DockerContainerRemove ( id , true )
2021-09-26 02:35:02 +00:00
//更新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)
// }
// }
// }
// }
//}
}
2022-05-05 05:46:55 +00:00
//service.MyService.App().UpdateApp(appInfo)
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SUCCESS , model . Result { Success : common_err . SUCCESS , Message : common_err . GetMsg ( common_err . SUCCESS ) } )
2022-05-05 05:46:55 +00:00
}
// @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 {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . CLIENT_ERROR , model . Result { Success : common_err . INVALID_PARAMS , Message : common_err . GetMsg ( common_err . INVALID_PARAMS ) } )
2022-05-05 05:46:55 +00:00
return
}
inspect , err := service . MyService . Docker ( ) . DockerContainerInfo ( id )
if err != nil {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : common_err . GetMsg ( common_err . SERVICE_ERROR ) , Data : err . Error ( ) } )
2022-05-05 05:46:55 +00:00
return
}
imageLatest := strings . Split ( inspect . Config . Image , ":" ) [ 0 ] + ":latest"
2022-06-08 10:19:45 +00:00
err = service . MyService . Docker ( ) . DockerPullImage ( imageLatest , "" , "" )
2022-05-05 05:46:55 +00:00
if err != nil {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : common_err . GetMsg ( common_err . SERVICE_ERROR ) , Data : err . Error ( ) } )
2022-05-05 05:46:55 +00:00
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 )
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : common_err . GetMsg ( common_err . SERVICE_ERROR ) } )
2022-05-05 05:46:55 +00:00
return
}
//step: 启动容器
err = service . MyService . Docker ( ) . DockerContainerStart ( containerId )
if err != nil {
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : common_err . GetMsg ( common_err . SERVICE_ERROR ) } )
2022-05-05 05:46:55 +00:00
return
}
service . MyService . Docker ( ) . DockerContainerRemove ( id , true )
delete ( service . NewVersionApp , id )
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SUCCESS , model . Result { Success : common_err . SUCCESS , Message : common_err . GetMsg ( common_err . SUCCESS ) } )
2021-09-26 02:35:02 +00:00
}
// @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" )
2022-07-22 03:02:11 +00:00
// @tiger - 作为最佳实践,不应该直接把数据库的信息返回,来避免未来数据库结构上的迭代带来的新字段
2021-09-26 02:35:02 +00:00
appInfo := service . MyService . App ( ) . GetAppDBInfo ( appId )
containerInfo , _ := service . MyService . Docker ( ) . DockerContainerStats ( appId )
var cpuModel = "arm"
2022-06-29 03:09:58 +00:00
if cpu := service . MyService . System ( ) . GetCpuInfo ( ) ; len ( cpu ) > 0 {
2021-09-26 02:35:02 +00:00
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 需要自定义错误
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SERVICE_ERROR , Message : common_err . GetMsg ( common_err . SERVICE_ERROR ) , Data : err . Error ( ) } )
2021-09-26 02:35:02 +00:00
return
}
con := struct {
Status string ` json:"status" `
StartedAt string ` json:"started_at" `
CPUShares int64 ` json:"cpu_shares" `
2022-07-22 03:02:11 +00:00
Memory int64 ` json:"total_memory" ` // @tiger - 改成 total_memory, 方便以后增加 free_memory 之类的字段
Restart string ` json:"restart_policy" ` // @tiger - 改成 restart_policy?
2021-09-26 02:35:02 +00:00
} { 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 )
2022-07-22 03:02:11 +00:00
data [ "app" ] = appInfo // @tiget - 最佳实践是,返回 appid, 然后具体的 app 信息由前端另行获取
data [ "cpu" ] = cpuModel // @tiger - 改成 arch
data [ "memory" ] = service . MyService . System ( ) . GetMemInfo ( ) [ "total" ] // @tiger - 改成 total_memory, 方便以后增加 free_memory 之类的字段
2021-09-26 02:35:02 +00:00
data [ "container" ] = json2 . RawMessage ( containerInfo )
data [ "info" ] = con
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SUCCESS , model . Result { Success : common_err . SUCCESS , Message : common_err . GetMsg ( common_err . SUCCESS ) , Data : data } )
2021-09-26 02:35:02 +00:00
}
2022-07-22 03:02:11 +00:00
func GetDockerNetworks ( c * gin . Context ) {
2021-09-26 02:35:02 +00:00
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 } )
}
}
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SUCCESS , model . Result { Success : common_err . SUCCESS , Message : common_err . GetMsg ( common_err . SUCCESS ) , Data : list } )
2021-09-26 02:35:02 +00:00
}
// @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 )
2022-06-29 03:09:58 +00:00
c . JSON ( http . StatusOK , model . Result { Success : common_err . SUCCESS , Message : common_err . GetMsg ( common_err . SUCCESS ) , Data : appInfo } )
2021-09-26 02:35:02 +00:00
}
// @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" )
2022-05-05 05:46:55 +00:00
//appInfo := service.MyService.App().GetAppDBInfo(appId)
2021-09-26 02:35:02 +00:00
info , err := service . MyService . Docker ( ) . DockerContainerInfo ( appId )
if err != nil {
2022-06-08 10:19:45 +00:00
2022-07-22 03:02:11 +00:00
c . JSON ( common_err . SERVICE_ERROR , model . Result { Success : common_err . SUCCESS , Message : common_err . GetMsg ( common_err . SUCCESS ) , Data : err . Error ( ) } )
2021-09-26 02:35:02 +00:00
return
}
2021-11-03 09:07:46 +00:00
var port model . PortArray
2022-05-05 05:46:55 +00:00
// 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 )
}
2021-09-26 02:35:02 +00:00
2021-11-03 09:07:46 +00:00
var envs model . EnvArray
2022-05-05 05:46:55 +00:00
// json2.Unmarshal([]byte(appInfo.Envs), &envs)
2021-09-26 02:35:02 +00:00
2022-06-13 12:43:19 +00:00
showENV := info . Config . Labels [ "show_env" ]
showENVList := strings . Split ( showENV , "," )
showENVMap := make ( map [ string ] string )
2022-08-18 03:18:27 +00:00
if len ( showENVList ) > 0 && showENVList [ 0 ] != "" {
2022-06-08 10:19:45 +00:00
for _ , name := range showENVList {
showENVMap [ name ] = "1"
2022-05-05 05:46:55 +00:00
}
2022-06-13 12:43:19 +00:00
}
for _ , v := range info . Config . Env {
2022-07-26 03:03:45 +00:00
if len ( showENVList ) > 0 {
2022-06-13 12:43:19 +00:00
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 {
2022-06-08 10:19:45 +00:00
temp := model . Env {
Name : strings . Split ( v , "=" ) [ 0 ] ,
Value : strings . Split ( v , "=" ) [ 1 ] ,
}
envs = append ( envs , temp )
}
2021-11-09 10:57:50 +00:00
}
2022-05-05 05:46:55 +00:00
var vol model . PathArray
// json2.Unmarshal([]byte(appInfo.Volumes), &vol)
2022-05-17 04:57:34 +00:00
for i := 0 ; i < len ( info . Mounts ) ; i ++ {
2022-05-05 05:46:55 +00:00
temp := model . PathMap {
2022-05-17 04:57:34 +00:00
Path : strings . ReplaceAll ( info . Mounts [ i ] . Source , "$AppID" , info . Name ) ,
ContainerPath : info . Mounts [ i ] . Destination ,
2022-05-05 05:46:55 +00:00
}
vol = append ( vol , temp )
}
var driver model . PathArray
2021-09-26 02:35:02 +00:00
//volumesStr, _ := json2.Marshal(m.Volumes)
//devicesStr, _ := json2.Marshal(m.Devices)
2022-05-05 05:46:55 +00:00
for _ , v := range info . HostConfig . Resources . Devices {
temp := model . PathMap {
Path : v . PathOnHost ,
ContainerPath : v . PathInContainer ,
}
driver = append ( driver , temp )
}
2021-09-26 02:35:02 +00:00
m := model . CustomizationPostData { }
2022-05-05 05:46:55 +00:00
m . Icon = info . Config . Labels [ "icon" ]
2021-09-26 02:35:02 +00:00
m . Ports = port
2022-05-13 10:12:26 +00:00
m . Image = info . Config . Image
2022-05-05 05:46:55 +00:00
m . Origin = info . Config . Labels [ "origin" ]
2022-05-13 10:12:26 +00:00
if len ( m . Origin ) == 0 {
m . Origin = "local"
}
2022-05-05 05:46:55 +00:00
m . NetworkModel = string ( info . HostConfig . NetworkMode )
m . Description = info . Config . Labels [ "desc" ]
2022-07-22 03:02:11 +00:00
m . ContainerName = strings . ReplaceAll ( info . Name , "/" , "" )
2022-05-05 05:46:55 +00:00
m . PortMap = info . Config . Labels [ "web" ]
m . Devices = driver
2021-09-26 02:35:02 +00:00
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
2022-05-05 05:46:55 +00:00
m . EnableUPNP = false
2022-05-13 10:12:26 +00:00
m . Index = info . Config . Labels [ "index" ]
2022-05-05 05:46:55 +00:00
m . Position = false
2022-05-13 10:12:26 +00:00
m . CustomId = info . Config . Labels [ "custom_id" ]
2022-06-08 10:19:45 +00:00
m . Host = info . Config . Labels [ "host" ]
2022-05-13 10:12:26 +00:00
if len ( m . CustomId ) == 0 {
m . CustomId = uuid . NewV4 ( ) . String ( )
}
2022-05-05 05:46:55 +00:00
m . CapAdd = info . HostConfig . CapAdd
m . Cmd = info . Config . Cmd
m . HostName = info . Config . Hostname
m . Privileged = info . HostConfig . Privileged
2022-07-22 03:02:11 +00:00
name := info . Config . Labels [ "name" ]
if len ( name ) == 0 {
name = strings . ReplaceAll ( info . Name , "/" , "" )
}
m . Label = name
2022-02-17 10:43:25 +00:00
2022-06-08 10:19:45 +00:00
m . Protocol = info . Config . Labels [ "protocol" ]
if m . Protocol == "" {
m . Protocol = "http"
}
2022-06-29 03:09:58 +00:00
c . JSON ( http . StatusOK , model . Result { Success : common_err . SUCCESS , Message : common_err . GetMsg ( common_err . SUCCESS ) , Data : m } )
2021-09-26 02:35:02 +00:00
}
////准备安装(暂时不需要)
//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
// }
2022-06-29 03:09:58 +00:00
// c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
2021-09-26 02:35:02 +00:00
//}