1
0
mirror of https://github.com/IceWhaleTech/CasaOS.git synced 2025-07-03 23:30:39 +02:00
Files
CasaOS/route/v1/system.go

386 lines
12 KiB
Go
Raw Normal View History

2021-09-26 10:35:02 +08:00
package v1
import (
"bytes"
2023-06-07 15:21:22 +08:00
"encoding/json"
2021-09-26 10:35:02 +08:00
"fmt"
"io"
"io/ioutil"
"net/http"
2021-12-06 17:08:36 +08:00
"os"
2023-02-08 18:11:46 +08:00
"runtime"
"strconv"
2021-12-29 16:42:20 +08:00
"strings"
"time"
2021-12-29 16:42:20 +08:00
"unsafe"
http2 "github.com/IceWhaleTech/CasaOS-Common/utils/http"
"github.com/IceWhaleTech/CasaOS-Common/utils/port"
"github.com/IceWhaleTech/CasaOS/common"
2021-09-27 14:17:36 +08:00
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config"
2024-06-04 14:14:55 +08:00
"github.com/IceWhaleTech/CasaOS/pkg/utils"
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
2021-09-27 14:17:36 +08:00
"github.com/IceWhaleTech/CasaOS/pkg/utils/version"
"github.com/IceWhaleTech/CasaOS/service"
model2 "github.com/IceWhaleTech/CasaOS/service/model"
"github.com/IceWhaleTech/CasaOS/types"
2024-06-04 14:14:55 +08:00
"github.com/labstack/echo/v4"
2023-05-15 11:01:21 +08:00
"github.com/tidwall/gjson"
2021-09-26 10:35:02 +08:00
)
2022-05-05 13:46:55 +08:00
// @Summary check version
2021-09-26 10:35:02 +08:00
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
2022-06-13 20:43:19 +08:00
// @Router /sys/version/check [get]
2024-06-04 14:14:55 +08:00
func GetSystemCheckVersion(ctx echo.Context) error {
need, version := version.IsNeedUpdate(service.MyService.Casa().GetCasaosVersion())
2021-09-26 10:35:02 +08:00
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"
2021-09-26 10:35:02 +08:00
service.MyService.Notify().AddLog(installLog)
}
data := make(map[string]interface{}, 3)
data["need_update"] = need
2021-09-26 10:35:02 +08:00
data["version"] = version
data["current_version"] = common.VERSION
2024-06-04 14:14:55 +08:00
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
2021-09-26 10:35:02 +08:00
}
// @Summary 系统信息
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/update [post]
2024-06-04 14:14:55 +08:00
func SystemUpdate(ctx echo.Context) error {
need, version := version.IsNeedUpdate(service.MyService.Casa().GetCasaosVersion())
2021-09-26 10:35:02 +08:00
if need {
service.MyService.System().UpdateSystemVersion(version.Version)
}
2024-06-04 14:14:55 +08:00
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
2021-09-26 10:35:02 +08:00
}
// @Summary get logs
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/error/logs [get]
2024-06-04 14:14:55 +08:00
func GetCasaOSErrorLogs(ctx echo.Context) error {
line, _ := strconv.Atoi(utils.DefaultQuery(ctx, "line", "100"))
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: service.MyService.System().GetCasaOSLogs(line)})
2021-09-26 10:35:02 +08:00
}
// 系统配置
2024-06-04 14:14:55 +08:00
func GetSystemConfigDebug(ctx echo.Context) error {
2021-09-26 10:35:02 +08:00
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, common.VERSION, 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))
2024-06-04 14:14:55 +08:00
return ctx.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]
2024-06-04 14:14:55 +08:00
func GetCasaOSPort(ctx echo.Context) error {
return ctx.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: config.ServerInfo.HttpPort,
})
}
2021-12-06 17:08:36 +08:00
// @Summary edit casaos server port
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
2022-06-13 20:43:19 +08:00
// @Param port json string true "port"
2021-12-06 17:08:36 +08:00
// @Success 200 {string} string "ok"
// @Router /sys/port [put]
2024-06-04 14:14:55 +08:00
func PutCasaOSPort(ctx echo.Context) error {
2022-06-13 20:43:19 +08:00
json := make(map[string]string)
2024-06-04 14:14:55 +08:00
ctx.Bind(&json)
2022-06-13 20:43:19 +08:00
portStr := json["port"]
portNumber, err := strconv.Atoi(portStr)
2021-12-06 17:08:36 +08:00
if err != nil {
2024-06-04 14:14:55 +08:00
return ctx.JSON(common_err.SERVICE_ERROR,
2021-12-06 17:08:36 +08:00
model.Result{
Success: common_err.SERVICE_ERROR,
2021-12-06 17:08:36 +08:00
Message: err.Error(),
})
}
isAvailable := port.IsPortAvailable(portNumber, "tcp")
2021-12-06 17:08:36 +08:00
if !isAvailable {
2024-06-04 14:14:55 +08:00
return ctx.JSON(common_err.SERVICE_ERROR,
2021-12-06 17:08:36 +08:00
model.Result{
Success: common_err.PORT_IS_OCCUPIED,
Message: common_err.GetMsg(common_err.PORT_IS_OCCUPIED),
2021-12-06 17:08:36 +08:00
})
}
service.MyService.System().UpSystemPort(strconv.Itoa(portNumber))
2024-06-04 14:14:55 +08:00
return ctx.JSON(common_err.SUCCESS,
2021-12-06 17:08:36 +08:00
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
2021-12-06 17:08:36 +08:00
})
}
// @Summary active killing casaos
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
2022-06-13 20:43:19 +08:00
// @Router /sys/restart [post]
2024-06-04 14:14:55 +08:00
func PostKillCasaOS(ctx echo.Context) error {
2021-12-06 17:08:36 +08:00
os.Exit(0)
2024-06-04 14:14:55 +08:00
return nil
2021-12-06 17:08:36 +08:00
}
2021-12-29 16:42:20 +08:00
✨ New Feature - [Apps] This is a feature that has been highly requested by the community. Import the original Docker application into CasaOS. Now it's easy to import with just a few clicks! - [Apps] App list supports a custom sorting function! You can arrange apps in different orders by dragging the icons. - [Apps] App custom installation supports Docker Compose configuration import in YAML format. - [Files] Added thumbnail preview function for image files. - [Connect] Multiple CasaConenct devices in the LAN will be transmitted through the LAN network. - [System] Added a switch for auto-mounting USB disk devices. 🎈 Enhancement - [System] Optimized the system update alert, you will see the new version update log from the next version. - [Apps] Added live preview for icons in custom installed apps. - [Apps] Optimized the input of WebUI. - [Files] Completely updated the image preview, now it supports switching all images in the same folder, as well as dragging, zooming, rotating and resetting. - [Widgets] Added color levels for CPU and RAM charts. - [Conenct] Optimized the display of the right-click menu of the Connect friends list. 🎈 Changed - [Files] Change the initial display directory to /DATA 🐞 Fixed - [System] Fixed an issue with Raspberry Pi devices failing to boot using USB disks. (Achieved by disabling USB disk auto-mount) - [Apps] Fixed the issue that some Docker CLI commands failed to import. - [Apps] Fixed the issue that the app is not easily recognized in /DATA/AppData directory and docker command line after installation, it will be shown as the app name. (Newly installed apps only) - [Apps] Fixed the issue that Pi-hole cannot be launched after installation in the app store. - [Apps] Fixed the issue that apps cannot be updated with WatchTower. - [Files] Fixed the issue that when there is an upload task, the task status is lost after closing Files.
2022-05-13 18:12:26 +08:00
// @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]
2024-06-04 14:14:55 +08:00
func GetSystemHardwareInfo(ctx echo.Context) error {
✨ New Feature - [Apps] This is a feature that has been highly requested by the community. Import the original Docker application into CasaOS. Now it's easy to import with just a few clicks! - [Apps] App list supports a custom sorting function! You can arrange apps in different orders by dragging the icons. - [Apps] App custom installation supports Docker Compose configuration import in YAML format. - [Files] Added thumbnail preview function for image files. - [Connect] Multiple CasaConenct devices in the LAN will be transmitted through the LAN network. - [System] Added a switch for auto-mounting USB disk devices. 🎈 Enhancement - [System] Optimized the system update alert, you will see the new version update log from the next version. - [Apps] Added live preview for icons in custom installed apps. - [Apps] Optimized the input of WebUI. - [Files] Completely updated the image preview, now it supports switching all images in the same folder, as well as dragging, zooming, rotating and resetting. - [Widgets] Added color levels for CPU and RAM charts. - [Conenct] Optimized the display of the right-click menu of the Connect friends list. 🎈 Changed - [Files] Change the initial display directory to /DATA 🐞 Fixed - [System] Fixed an issue with Raspberry Pi devices failing to boot using USB disks. (Achieved by disabling USB disk auto-mount) - [Apps] Fixed the issue that some Docker CLI commands failed to import. - [Apps] Fixed the issue that the app is not easily recognized in /DATA/AppData directory and docker command line after installation, it will be shown as the app name. (Newly installed apps only) - [Apps] Fixed the issue that Pi-hole cannot be launched after installation in the app store. - [Apps] Fixed the issue that apps cannot be updated with WatchTower. - [Files] Fixed the issue that when there is an upload task, the task status is lost after closing Files.
2022-05-13 18:12:26 +08:00
data := make(map[string]string, 1)
data["drive_model"] = service.MyService.System().GetDeviceTree()
2023-03-23 12:09:46 +08:00
data["arch"] = runtime.GOARCH
2023-03-15 06:20:58 +00:00
2023-03-15 10:46:12 +08:00
if cpu := service.MyService.System().GetCpuInfo(); len(cpu) > 0 {
2024-06-04 14:14:55 +08:00
return ctx.JSON(common_err.SUCCESS,
2023-03-15 06:20:58 +00:00
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: data,
})
}
2024-06-04 14:14:55 +08:00
return nil
✨ New Feature - [Apps] This is a feature that has been highly requested by the community. Import the original Docker application into CasaOS. Now it's easy to import with just a few clicks! - [Apps] App list supports a custom sorting function! You can arrange apps in different orders by dragging the icons. - [Apps] App custom installation supports Docker Compose configuration import in YAML format. - [Files] Added thumbnail preview function for image files. - [Connect] Multiple CasaConenct devices in the LAN will be transmitted through the LAN network. - [System] Added a switch for auto-mounting USB disk devices. 🎈 Enhancement - [System] Optimized the system update alert, you will see the new version update log from the next version. - [Apps] Added live preview for icons in custom installed apps. - [Apps] Optimized the input of WebUI. - [Files] Completely updated the image preview, now it supports switching all images in the same folder, as well as dragging, zooming, rotating and resetting. - [Widgets] Added color levels for CPU and RAM charts. - [Conenct] Optimized the display of the right-click menu of the Connect friends list. 🎈 Changed - [Files] Change the initial display directory to /DATA 🐞 Fixed - [System] Fixed an issue with Raspberry Pi devices failing to boot using USB disks. (Achieved by disabling USB disk auto-mount) - [Apps] Fixed the issue that some Docker CLI commands failed to import. - [Apps] Fixed the issue that the app is not easily recognized in /DATA/AppData directory and docker command line after installation, it will be shown as the app name. (Newly installed apps only) - [Apps] Fixed the issue that Pi-hole cannot be launched after installation in the app store. - [Apps] Fixed the issue that apps cannot be updated with WatchTower. - [Files] Fixed the issue that when there is an upload task, the task status is lost after closing Files.
2022-05-13 18:12:26 +08:00
}
2022-06-13 20:43:19 +08:00
// @Summary system utilization
2021-12-29 16:42:20 +08:00
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
2022-06-13 20:43:19 +08:00
// @Router /sys/utilization [get]
2024-06-04 14:14:55 +08:00
func GetSystemUtilization(ctx echo.Context) error {
data := make(map[string]interface{})
cpu := service.MyService.System().GetCpuPercent()
num := service.MyService.System().GetCpuCoreNum()
cpuModel := "arm"
2022-11-29 02:25:26 +00:00
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"
}
}
2021-12-29 16:42:20 +08:00
cpuData := make(map[string]interface{})
cpuData["percent"] = cpu
cpuData["num"] = num
cpuData["temperature"] = service.MyService.System().GetCPUTemperature()
cpuData["power"] = service.MyService.System().GetCPUPower()
2022-11-29 02:25:26 +00:00
cpuData["model"] = cpuModel
2021-12-29 16:42:20 +08:00
data["cpu"] = cpuData
data["mem"] = service.MyService.System().GetMemInfo()
2021-12-29 16:42:20 +08:00
// 拼装网络信息
netList := service.MyService.System().GetNetInfo()
2021-12-29 16:42:20 +08:00
newNet := []model.IOCountersStat{}
nets := service.MyService.System().GetNet(true)
2021-12-29 16:42:20 +08:00
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))
2022-04-06 12:10:51 +08:00
item.Time = time.Now().Unix()
2021-12-29 16:42:20 +08:00
newNet = append(newNet, item)
break
}
}
}
data["net"] = newNet
systemMap := service.MyService.Notify().GetSystemTempMap()
systemMap.Range(func(key, value interface{}) bool {
data[key.(string)] = value
return true
})
2024-06-04 14:14:55 +08:00
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
2021-12-29 16:42:20 +08:00
}
2022-06-13 20:43:19 +08:00
// @Summary get cpu info
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/cpu [get]
2024-06-04 14:14:55 +08:00
func GetSystemCupInfo(ctx echo.Context) error {
2022-06-13 20:43:19 +08:00
cpu := service.MyService.System().GetCpuPercent()
num := service.MyService.System().GetCpuCoreNum()
data := make(map[string]interface{})
data["percent"] = cpu
data["num"] = num
2024-06-04 14:14:55 +08:00
return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
2022-06-13 20:43:19 +08:00
}
// @Summary get mem info
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/mem [get]
2024-06-04 14:14:55 +08:00
func GetSystemMemInfo(ctx echo.Context) error {
2022-06-13 20:43:19 +08:00
mem := service.MyService.System().GetMemInfo()
2024-06-04 14:14:55 +08:00
return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: mem})
2022-06-13 20:43:19 +08:00
}
// @Summary get disk info
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/disk [get]
2024-06-04 14:14:55 +08:00
func GetSystemDiskInfo(ctx echo.Context) error {
disk := service.MyService.System().GetDiskInfo()
2024-06-04 14:14:55 +08:00
return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: disk})
2022-06-13 20:43:19 +08:00
}
// @Summary get Net info
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/net [get]
2024-06-04 14:14:55 +08:00
func GetSystemNetInfo(ctx echo.Context) error {
2022-06-13 20:43:19 +08:00
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))
2022-06-13 20:43:19 +08:00
item.Time = time.Now().Unix()
newNet = append(newNet, item)
break
}
}
}
2024-06-04 14:14:55 +08:00
return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: newNet})
}
2024-06-04 14:14:55 +08:00
func GetSystemProxy(ctx echo.Context) error {
url := ctx.QueryParam("url")
resp, err := http2.Get(url, 30*time.Second)
if err != nil {
2024-06-04 14:14:55 +08:00
return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
}
defer resp.Body.Close()
2024-06-04 14:14:55 +08:00
for k, v := range ctx.Request().Header {
ctx.Request().Header.Add(k, v[0])
}
rda, _ := ioutil.ReadAll(resp.Body)
// json.NewEncoder(c.Writer).Encode(json.RawMessage(string(rda)))
// 响应状态码
2024-06-04 14:14:55 +08:00
ctx.Response().Writer.WriteHeader(resp.StatusCode)
// 复制转发的响应Body到响应Body
2024-06-04 14:14:55 +08:00
io.Copy(ctx.Response().Writer, ioutil.NopCloser(bytes.NewBuffer(rda)))
return nil
}
2022-11-29 02:25:26 +00:00
2024-06-04 14:14:55 +08:00
func PutSystemState(ctx echo.Context) error {
state := ctx.Param("state")
2022-12-20 14:05:16 +08:00
if strings.ToLower(state) == "off" {
2022-12-07 10:57:27 +08:00
service.MyService.System().SystemShutdown()
2022-12-20 14:05:16 +08:00
} else if strings.ToLower(state) == "restart" {
2022-12-07 10:57:27 +08:00
service.MyService.System().SystemReboot()
2022-11-29 02:25:26 +00:00
}
2024-06-04 14:14:55 +08:00
return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: "The operation will be completed shortly."})
2022-11-29 02:25:26 +00:00
}
// @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]
2024-06-04 14:14:55 +08:00
func GetPort(ctx echo.Context) error {
t := utils.DefaultQuery(ctx, "type", "tcp")
var p int
ok := true
for ok {
p, _ = port.GetAvailablePort(t)
ok = !port.IsPortAvailable(p, t)
}
// @tiger 这里最好封装成 {'port': ...} 的形式,来体现出参的上下文
2024-06-04 14:14:55 +08:00
return ctx.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]
2024-06-04 14:14:55 +08:00
func PortCheck(ctx echo.Context) error {
p, _ := strconv.Atoi(ctx.Param("port"))
t := utils.DefaultQuery(ctx, "type", "tcp")
return ctx.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: port.IsPortAvailable(p, t)})
}
2023-05-15 11:01:21 +08:00
2024-06-04 14:14:55 +08:00
func GetSystemEntry(ctx echo.Context) error {
2023-05-15 11:01:21 +08:00
entry := service.MyService.System().GetSystemEntry()
2023-06-07 15:21:22 +08:00
str := json.RawMessage(entry)
if !gjson.ValidBytes(str) {
2024-06-04 14:14:55 +08:00
return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: entry, Data: json.RawMessage("[]")})
2023-05-15 11:01:21 +08:00
}
2024-06-04 14:14:55 +08:00
return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: str})
2023-05-15 11:01:21 +08:00
}