package v1 import ( "bytes" "encoding/json" "fmt" "io" "io/ioutil" "net/http" "os" "runtime" "strconv" "strings" "time" "unsafe" http2 "github.com/IceWhaleTech/CasaOS-Common/utils/http" "github.com/IceWhaleTech/CasaOS-Common/utils/port" "github.com/IceWhaleTech/CasaOS/common" "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" "github.com/tidwall/gjson" ) // @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"] = common.VERSION 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, 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)) 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() data["arch"] = runtime.GOARCH if cpu := service.MyService.System().GetCpuInfo(); len(cpu) > 0 { 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 systemMap := service.MyService.Notify().GetSystemTempMap() systemMap.Range(func(key, value interface{}) bool { data[key.(string)] = value return true }) c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) } // @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 strings.ToLower(state) == "off" { service.MyService.System().SystemShutdown() } else if strings.ToLower(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)}) } func GetSystemEntry(c *gin.Context) { entry := service.MyService.System().GetSystemEntry() str := json.RawMessage(entry) if !gjson.ValidBytes(str) { c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: entry, Data: json.RawMessage("[]")}) return } c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: str}) }