CasaOS/route/v1/system.go
2022-12-07 10:57:27 +08:00

381 lines
12 KiB
Go

package v1
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"strconv"
"strings"
"time"
"unsafe"
http2 "github.com/IceWhaleTech/CasaOS-Common/utils/http"
"github.com/IceWhaleTech/CasaOS-Common/utils/port"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
"github.com/IceWhaleTech/CasaOS/pkg/utils/version"
"github.com/IceWhaleTech/CasaOS/service"
model2 "github.com/IceWhaleTech/CasaOS/service/model"
"github.com/IceWhaleTech/CasaOS/types"
"github.com/gin-gonic/gin"
)
// @Summary check version
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/version/check [get]
func GetSystemCheckVersion(c *gin.Context) {
need, version := version.IsNeedUpdate(service.MyService.Casa().GetCasaosVersion())
if need {
installLog := model2.AppNotify{}
installLog.State = 0
installLog.Message = "New version " + version.Version + " is ready, ready to upgrade"
installLog.Type = types.NOTIFY_TYPE_NEED_CONFIRM
installLog.CreatedAt = strconv.FormatInt(time.Now().Unix(), 10)
installLog.UpdatedAt = strconv.FormatInt(time.Now().Unix(), 10)
installLog.Name = "CasaOS System"
service.MyService.Notify().AddLog(installLog)
}
data := make(map[string]interface{}, 3)
data["need_update"] = need
data["version"] = version
data["current_version"] = types.CURRENTVERSION
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 application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/update [post]
func SystemUpdate(c *gin.Context) {
need, version := version.IsNeedUpdate(service.MyService.Casa().GetCasaosVersion())
if need {
service.MyService.System().UpdateSystemVersion(version.Version)
}
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
}
// @Summary get logs
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/error/logs [get]
func GetCasaOSErrorLogs(c *gin.Context) {
line, _ := strconv.Atoi(c.DefaultQuery("line", "100"))
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: service.MyService.System().GetCasaOSLogs(line)})
}
// 系统配置
func GetSystemConfigDebug(c *gin.Context) {
array := service.MyService.System().GetSystemConfigDebug()
disk := service.MyService.System().GetDiskInfo()
sys := service.MyService.System().GetSysInfo()
version := service.MyService.Casa().GetCasaosVersion()
var bugContent string = fmt.Sprintf(`
- OS: %s
- CasaOS Version: %s
- Disk Total: %v
- Disk Used: %v
- System Info: %s
- Remote Version: %s
- Browser: $Browser$
- Version: $Version$
`, sys.OS, types.CURRENTVERSION, disk.Total>>20, disk.Used>>20, array, version.Version)
// array = append(array, fmt.Sprintf("disk,total:%v,used:%v,UsedPercent:%v", disk.Total>>20, disk.Used>>20, disk.UsedPercent))
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: bugContent})
}
// @Summary get casaos server port
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/port [get]
func GetCasaOSPort(c *gin.Context) {
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: config.ServerInfo.HttpPort,
})
}
// @Summary edit casaos server port
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Param port json string true "port"
// @Success 200 {string} string "ok"
// @Router /sys/port [put]
func PutCasaOSPort(c *gin.Context) {
json := make(map[string]string)
c.ShouldBind(&json)
portStr := json["port"]
portNumber, err := strconv.Atoi(portStr)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: err.Error(),
})
return
}
isAvailable := port.IsPortAvailable(portNumber, "tcp")
if !isAvailable {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.PORT_IS_OCCUPIED,
Message: common_err.GetMsg(common_err.PORT_IS_OCCUPIED),
})
return
}
service.MyService.System().UpSystemPort(strconv.Itoa(portNumber))
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
})
}
// @Summary active killing casaos
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/restart [post]
func PostKillCasaOS(c *gin.Context) {
os.Exit(0)
}
// @Summary get system hardware info
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/hardware/info [get]
func GetSystemHardwareInfo(c *gin.Context) {
data := make(map[string]string, 1)
data["drive_model"] = service.MyService.System().GetDeviceTree()
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: data,
})
}
// @Summary system utilization
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/utilization [get]
func GetSystemUtilization(c *gin.Context) {
data := make(map[string]interface{})
cpu := service.MyService.System().GetCpuPercent()
num := service.MyService.System().GetCpuCoreNum()
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"
}
}
cpuData := make(map[string]interface{})
cpuData["percent"] = cpu
cpuData["num"] = num
cpuData["temperature"] = service.MyService.System().GetCPUTemperature()
cpuData["power"] = service.MyService.System().GetCPUPower()
cpuData["model"] = cpuModel
data["cpu"] = cpuData
data["mem"] = service.MyService.System().GetMemInfo()
// 拼装网络信息
netList := service.MyService.System().GetNetInfo()
newNet := []model.IOCountersStat{}
nets := service.MyService.System().GetNet(true)
for _, n := range netList {
for _, netCardName := range nets {
if n.Name == netCardName {
item := *(*model.IOCountersStat)(unsafe.Pointer(&n))
item.State = strings.TrimSpace(service.MyService.System().GetNetState(n.Name))
item.Time = time.Now().Unix()
newNet = append(newNet, item)
break
}
}
}
data["net"] = newNet
for k, v := range service.MyService.Notify().GetSystemTempMap() {
data[k] = v
}
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
}
// @Summary Get notification port
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/socket/port [get]
func GetSystemSocketPort(c *gin.Context) {
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: config.ServerInfo.SocketPort, // @tiger 这里最好封装成 {'port': ...} 的形式,来体现出参的上下文
})
}
// @Summary get cpu info
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/cpu [get]
func GetSystemCupInfo(c *gin.Context) {
cpu := service.MyService.System().GetCpuPercent()
num := service.MyService.System().GetCpuCoreNum()
data := make(map[string]interface{})
data["percent"] = cpu
data["num"] = num
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
}
// @Summary get mem info
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/mem [get]
func GetSystemMemInfo(c *gin.Context) {
mem := service.MyService.System().GetMemInfo()
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: mem})
}
// @Summary get disk info
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/disk [get]
func GetSystemDiskInfo(c *gin.Context) {
disk := service.MyService.System().GetDiskInfo()
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: disk})
}
// @Summary get Net info
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/net [get]
func GetSystemNetInfo(c *gin.Context) {
netList := service.MyService.System().GetNetInfo()
newNet := []model.IOCountersStat{}
for _, n := range netList {
for _, netCardName := range service.MyService.System().GetNet(true) {
if n.Name == netCardName {
item := *(*model.IOCountersStat)(unsafe.Pointer(&n))
item.State = strings.TrimSpace(service.MyService.System().GetNetState(n.Name))
item.Time = time.Now().Unix()
newNet = append(newNet, item)
break
}
}
}
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: newNet})
}
func GetSystemProxy(c *gin.Context) {
url := c.Query("url")
resp, err := http2.Get(url, 30*time.Second)
if err != nil {
return
}
defer resp.Body.Close()
for k, v := range c.Request.Header {
c.Header(k, v[0])
}
rda, _ := ioutil.ReadAll(resp.Body)
// json.NewEncoder(c.Writer).Encode(json.RawMessage(string(rda)))
// 响应状态码
c.Writer.WriteHeader(resp.StatusCode)
// 复制转发的响应Body到响应Body
io.Copy(c.Writer, ioutil.NopCloser(bytes.NewBuffer(rda)))
}
func PutSystemState(c *gin.Context) {
state := c.Param("state")
if state == "off" {
service.MyService.System().SystemShutdown()
} else if state == "restart" {
service.MyService.System().SystemReboot()
}
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: "The operation will be completed shortly."})
}
// @Summary 获取一个可用端口
// @Produce application/json
// @Accept application/json
// @Tags app
// @Param type query string true "端口类型 udp/tcp"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /app/getport [get]
func GetPort(c *gin.Context) {
t := c.DefaultQuery("type", "tcp")
var p int
ok := true
for ok {
p, _ = port.GetAvailablePort(t)
ok = !port.IsPortAvailable(p, t)
}
// @tiger 这里最好封装成 {'port': ...} 的形式,来体现出参的上下文
c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: p})
}
// @Summary 检查端口是否可用
// @Produce application/json
// @Accept application/json
// @Tags app
// @Param port path int true "端口号"
// @Param type query string true "端口类型 udp/tcp"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /app/check/{port} [get]
func PortCheck(c *gin.Context) {
p, _ := strconv.Atoi(c.Param("port"))
t := c.DefaultQuery("type", "tcp")
c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: port.IsPortAvailable(p, t)})
}