system.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. package v1
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "io/ioutil"
  8. "net/http"
  9. "os"
  10. "runtime"
  11. "strconv"
  12. "strings"
  13. "time"
  14. "unsafe"
  15. http2 "github.com/IceWhaleTech/CasaOS-Common/utils/http"
  16. "github.com/IceWhaleTech/CasaOS-Common/utils/port"
  17. "github.com/IceWhaleTech/CasaOS/common"
  18. "github.com/IceWhaleTech/CasaOS/model"
  19. "github.com/IceWhaleTech/CasaOS/pkg/config"
  20. "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
  21. "github.com/IceWhaleTech/CasaOS/pkg/utils/version"
  22. "github.com/IceWhaleTech/CasaOS/service"
  23. model2 "github.com/IceWhaleTech/CasaOS/service/model"
  24. "github.com/IceWhaleTech/CasaOS/types"
  25. "github.com/gin-gonic/gin"
  26. "github.com/tidwall/gjson"
  27. )
  28. // @Summary check version
  29. // @Produce application/json
  30. // @Accept application/json
  31. // @Tags sys
  32. // @Security ApiKeyAuth
  33. // @Success 200 {string} string "ok"
  34. // @Router /sys/version/check [get]
  35. func GetSystemCheckVersion(c *gin.Context) {
  36. need, version := version.IsNeedUpdate(service.MyService.Casa().GetCasaosVersion())
  37. if need {
  38. installLog := model2.AppNotify{}
  39. installLog.State = 0
  40. installLog.Message = "New version " + version.Version + " is ready, ready to upgrade"
  41. installLog.Type = types.NOTIFY_TYPE_NEED_CONFIRM
  42. installLog.CreatedAt = strconv.FormatInt(time.Now().Unix(), 10)
  43. installLog.UpdatedAt = strconv.FormatInt(time.Now().Unix(), 10)
  44. installLog.Name = "CasaOS System"
  45. service.MyService.Notify().AddLog(installLog)
  46. }
  47. data := make(map[string]interface{}, 3)
  48. data["need_update"] = need
  49. data["version"] = version
  50. data["current_version"] = common.VERSION
  51. c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
  52. }
  53. // @Summary 系统信息
  54. // @Produce application/json
  55. // @Accept application/json
  56. // @Tags sys
  57. // @Security ApiKeyAuth
  58. // @Success 200 {string} string "ok"
  59. // @Router /sys/update [post]
  60. func SystemUpdate(c *gin.Context) {
  61. need, version := version.IsNeedUpdate(service.MyService.Casa().GetCasaosVersion())
  62. if need {
  63. service.MyService.System().UpdateSystemVersion(version.Version)
  64. }
  65. c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
  66. }
  67. // @Summary get logs
  68. // @Produce application/json
  69. // @Accept application/json
  70. // @Tags sys
  71. // @Security ApiKeyAuth
  72. // @Success 200 {string} string "ok"
  73. // @Router /sys/error/logs [get]
  74. func GetCasaOSErrorLogs(c *gin.Context) {
  75. line, _ := strconv.Atoi(c.DefaultQuery("line", "100"))
  76. c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: service.MyService.System().GetCasaOSLogs(line)})
  77. }
  78. // 系统配置
  79. func GetSystemConfigDebug(c *gin.Context) {
  80. array := service.MyService.System().GetSystemConfigDebug()
  81. disk := service.MyService.System().GetDiskInfo()
  82. sys := service.MyService.System().GetSysInfo()
  83. version := service.MyService.Casa().GetCasaosVersion()
  84. var bugContent string = fmt.Sprintf(`
  85. - OS: %s
  86. - CasaOS Version: %s
  87. - Disk Total: %v
  88. - Disk Used: %v
  89. - System Info: %s
  90. - Remote Version: %s
  91. - Browser: $Browser$
  92. - Version: $Version$
  93. `, sys.OS, common.VERSION, disk.Total>>20, disk.Used>>20, array, version.Version)
  94. // array = append(array, fmt.Sprintf("disk,total:%v,used:%v,UsedPercent:%v", disk.Total>>20, disk.Used>>20, disk.UsedPercent))
  95. c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: bugContent})
  96. }
  97. // @Summary get casaos server port
  98. // @Produce application/json
  99. // @Accept application/json
  100. // @Tags sys
  101. // @Security ApiKeyAuth
  102. // @Success 200 {string} string "ok"
  103. // @Router /sys/port [get]
  104. func GetCasaOSPort(c *gin.Context) {
  105. c.JSON(common_err.SUCCESS,
  106. model.Result{
  107. Success: common_err.SUCCESS,
  108. Message: common_err.GetMsg(common_err.SUCCESS),
  109. Data: config.ServerInfo.HttpPort,
  110. })
  111. }
  112. // @Summary edit casaos server port
  113. // @Produce application/json
  114. // @Accept application/json
  115. // @Tags sys
  116. // @Security ApiKeyAuth
  117. // @Param port json string true "port"
  118. // @Success 200 {string} string "ok"
  119. // @Router /sys/port [put]
  120. func PutCasaOSPort(c *gin.Context) {
  121. json := make(map[string]string)
  122. c.ShouldBind(&json)
  123. portStr := json["port"]
  124. portNumber, err := strconv.Atoi(portStr)
  125. if err != nil {
  126. c.JSON(common_err.SERVICE_ERROR,
  127. model.Result{
  128. Success: common_err.SERVICE_ERROR,
  129. Message: err.Error(),
  130. })
  131. return
  132. }
  133. isAvailable := port.IsPortAvailable(portNumber, "tcp")
  134. if !isAvailable {
  135. c.JSON(common_err.SERVICE_ERROR,
  136. model.Result{
  137. Success: common_err.PORT_IS_OCCUPIED,
  138. Message: common_err.GetMsg(common_err.PORT_IS_OCCUPIED),
  139. })
  140. return
  141. }
  142. service.MyService.System().UpSystemPort(strconv.Itoa(portNumber))
  143. c.JSON(common_err.SUCCESS,
  144. model.Result{
  145. Success: common_err.SUCCESS,
  146. Message: common_err.GetMsg(common_err.SUCCESS),
  147. })
  148. }
  149. // @Summary active killing casaos
  150. // @Produce application/json
  151. // @Accept application/json
  152. // @Tags sys
  153. // @Security ApiKeyAuth
  154. // @Success 200 {string} string "ok"
  155. // @Router /sys/restart [post]
  156. func PostKillCasaOS(c *gin.Context) {
  157. os.Exit(0)
  158. }
  159. // @Summary get system hardware info
  160. // @Produce application/json
  161. // @Accept application/json
  162. // @Tags sys
  163. // @Security ApiKeyAuth
  164. // @Success 200 {string} string "ok"
  165. // @Router /sys/hardware/info [get]
  166. func GetSystemHardwareInfo(c *gin.Context) {
  167. data := make(map[string]string, 1)
  168. data["drive_model"] = service.MyService.System().GetDeviceTree()
  169. data["arch"] = runtime.GOARCH
  170. if cpu := service.MyService.System().GetCpuInfo(); len(cpu) > 0 {
  171. c.JSON(common_err.SUCCESS,
  172. model.Result{
  173. Success: common_err.SUCCESS,
  174. Message: common_err.GetMsg(common_err.SUCCESS),
  175. Data: data,
  176. })
  177. }
  178. }
  179. // @Summary system utilization
  180. // @Produce application/json
  181. // @Accept application/json
  182. // @Tags sys
  183. // @Security ApiKeyAuth
  184. // @Success 200 {string} string "ok"
  185. // @Router /sys/utilization [get]
  186. func GetSystemUtilization(c *gin.Context) {
  187. data := make(map[string]interface{})
  188. cpu := service.MyService.System().GetCpuPercent()
  189. num := service.MyService.System().GetCpuCoreNum()
  190. cpuModel := "arm"
  191. if cpu := service.MyService.System().GetCpuInfo(); len(cpu) > 0 {
  192. if strings.Count(strings.ToLower(strings.TrimSpace(cpu[0].ModelName)), "intel") > 0 {
  193. cpuModel = "intel"
  194. } else if strings.Count(strings.ToLower(strings.TrimSpace(cpu[0].ModelName)), "amd") > 0 {
  195. cpuModel = "amd"
  196. }
  197. }
  198. cpuData := make(map[string]interface{})
  199. cpuData["percent"] = cpu
  200. cpuData["num"] = num
  201. cpuData["temperature"] = service.MyService.System().GetCPUTemperature()
  202. cpuData["power"] = service.MyService.System().GetCPUPower()
  203. cpuData["model"] = cpuModel
  204. data["cpu"] = cpuData
  205. data["mem"] = service.MyService.System().GetMemInfo()
  206. // 拼装网络信息
  207. netList := service.MyService.System().GetNetInfo()
  208. newNet := []model.IOCountersStat{}
  209. nets := service.MyService.System().GetNet(true)
  210. for _, n := range netList {
  211. for _, netCardName := range nets {
  212. if n.Name == netCardName {
  213. item := *(*model.IOCountersStat)(unsafe.Pointer(&n))
  214. item.State = strings.TrimSpace(service.MyService.System().GetNetState(n.Name))
  215. item.Time = time.Now().Unix()
  216. newNet = append(newNet, item)
  217. break
  218. }
  219. }
  220. }
  221. data["net"] = newNet
  222. systemMap := service.MyService.Notify().GetSystemTempMap()
  223. systemMap.Range(func(key, value interface{}) bool {
  224. data[key.(string)] = value
  225. return true
  226. })
  227. c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
  228. }
  229. // @Summary get cpu info
  230. // @Produce application/json
  231. // @Accept application/json
  232. // @Tags sys
  233. // @Security ApiKeyAuth
  234. // @Success 200 {string} string "ok"
  235. // @Router /sys/cpu [get]
  236. func GetSystemCupInfo(c *gin.Context) {
  237. cpu := service.MyService.System().GetCpuPercent()
  238. num := service.MyService.System().GetCpuCoreNum()
  239. data := make(map[string]interface{})
  240. data["percent"] = cpu
  241. data["num"] = num
  242. c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
  243. }
  244. // @Summary get mem info
  245. // @Produce application/json
  246. // @Accept application/json
  247. // @Tags sys
  248. // @Security ApiKeyAuth
  249. // @Success 200 {string} string "ok"
  250. // @Router /sys/mem [get]
  251. func GetSystemMemInfo(c *gin.Context) {
  252. mem := service.MyService.System().GetMemInfo()
  253. c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: mem})
  254. }
  255. // @Summary get disk info
  256. // @Produce application/json
  257. // @Accept application/json
  258. // @Tags sys
  259. // @Security ApiKeyAuth
  260. // @Success 200 {string} string "ok"
  261. // @Router /sys/disk [get]
  262. func GetSystemDiskInfo(c *gin.Context) {
  263. disk := service.MyService.System().GetDiskInfo()
  264. c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: disk})
  265. }
  266. // @Summary get Net info
  267. // @Produce application/json
  268. // @Accept application/json
  269. // @Tags sys
  270. // @Security ApiKeyAuth
  271. // @Success 200 {string} string "ok"
  272. // @Router /sys/net [get]
  273. func GetSystemNetInfo(c *gin.Context) {
  274. netList := service.MyService.System().GetNetInfo()
  275. newNet := []model.IOCountersStat{}
  276. for _, n := range netList {
  277. for _, netCardName := range service.MyService.System().GetNet(true) {
  278. if n.Name == netCardName {
  279. item := *(*model.IOCountersStat)(unsafe.Pointer(&n))
  280. item.State = strings.TrimSpace(service.MyService.System().GetNetState(n.Name))
  281. item.Time = time.Now().Unix()
  282. newNet = append(newNet, item)
  283. break
  284. }
  285. }
  286. }
  287. c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: newNet})
  288. }
  289. func GetSystemProxy(c *gin.Context) {
  290. url := c.Query("url")
  291. resp, err := http2.Get(url, 30*time.Second)
  292. if err != nil {
  293. return
  294. }
  295. defer resp.Body.Close()
  296. for k, v := range c.Request.Header {
  297. c.Header(k, v[0])
  298. }
  299. rda, _ := ioutil.ReadAll(resp.Body)
  300. // json.NewEncoder(c.Writer).Encode(json.RawMessage(string(rda)))
  301. // 响应状态码
  302. c.Writer.WriteHeader(resp.StatusCode)
  303. // 复制转发的响应Body到响应Body
  304. io.Copy(c.Writer, ioutil.NopCloser(bytes.NewBuffer(rda)))
  305. }
  306. func PutSystemState(c *gin.Context) {
  307. state := c.Param("state")
  308. if strings.ToLower(state) == "off" {
  309. service.MyService.System().SystemShutdown()
  310. } else if strings.ToLower(state) == "restart" {
  311. service.MyService.System().SystemReboot()
  312. }
  313. c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: "The operation will be completed shortly."})
  314. }
  315. // @Summary 获取一个可用端口
  316. // @Produce application/json
  317. // @Accept application/json
  318. // @Tags app
  319. // @Param type query string true "端口类型 udp/tcp"
  320. // @Security ApiKeyAuth
  321. // @Success 200 {string} string "ok"
  322. // @Router /app/getport [get]
  323. func GetPort(c *gin.Context) {
  324. t := c.DefaultQuery("type", "tcp")
  325. var p int
  326. ok := true
  327. for ok {
  328. p, _ = port.GetAvailablePort(t)
  329. ok = !port.IsPortAvailable(p, t)
  330. }
  331. // @tiger 这里最好封装成 {'port': ...} 的形式,来体现出参的上下文
  332. c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: p})
  333. }
  334. // @Summary 检查端口是否可用
  335. // @Produce application/json
  336. // @Accept application/json
  337. // @Tags app
  338. // @Param port path int true "端口号"
  339. // @Param type query string true "端口类型 udp/tcp"
  340. // @Security ApiKeyAuth
  341. // @Success 200 {string} string "ok"
  342. // @Router /app/check/{port} [get]
  343. func PortCheck(c *gin.Context) {
  344. p, _ := strconv.Atoi(c.Param("port"))
  345. t := c.DefaultQuery("type", "tcp")
  346. c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: port.IsPortAvailable(p, t)})
  347. }
  348. func GetSystemEntry(c *gin.Context) {
  349. entry := service.MyService.System().GetSystemEntry()
  350. str := json.RawMessage(entry)
  351. if !gjson.ValidBytes(str) {
  352. c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: entry, Data: json.RawMessage("[]")})
  353. return
  354. }
  355. c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: str})
  356. }