Browse Source

feat: Multiple updates

1.Add the function of modifying the WebUI port.
2.Add the function to modify the search engine.
3.Add the multi-language function and add Chinese translation.
4.Add detailed CPU and memory statistics.
link 3 years ago
parent
commit
6c235d3f2a

+ 1 - 1
UI

@@ -1 +1 @@
-Subproject commit f7c46d7379ab31bc70a35900ef6a50f7f3c2ef4f
+Subproject commit a982eb4bddafe0beaa629fcfef9581b8ef1eddf3

+ 3 - 2
middleware/gin.go

@@ -2,8 +2,9 @@ package middleware
 
 
 import (
 import (
 	"fmt"
 	"fmt"
-	"github.com/gin-gonic/gin"
 	"net/http"
 	"net/http"
+
+	"github.com/gin-gonic/gin"
 )
 )
 
 
 func Cors() gin.HandlerFunc {
 func Cors() gin.HandlerFunc {
@@ -17,7 +18,7 @@ func Cors() gin.HandlerFunc {
 		//服务器支持的所有跨域请求的方法
 		//服务器支持的所有跨域请求的方法
 		c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")
 		c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")
 		//允许跨域设置可以返回其他子段,可以自定义字段
 		//允许跨域设置可以返回其他子段,可以自定义字段
-		c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session")
+		c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,Language")
 		// 允许浏览器(客户端)可以解析的头部 (重要)
 		// 允许浏览器(客户端)可以解析的头部 (重要)
 		c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers")
 		c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers")
 		//设置缓存时间
 		//设置缓存时间

+ 1 - 0
model/disk.go

@@ -24,6 +24,7 @@ type LSBLKModel struct {
 	Tran        string       `json:"tran"`
 	Tran        string       `json:"tran"`
 	MinIO       uint64       `json:"min-io"`
 	MinIO       uint64       `json:"min-io"`
 	UsedPercent float64      `json:"used_percent"`
 	UsedPercent float64      `json:"used_percent"`
+	Serial      string       `json:"serial"`
 	Children    []LSBLKModel `json:"children"`
 	Children    []LSBLKModel `json:"children"`
 	//详情特有
 	//详情特有
 	StartSector uint64 `json:"start_sector,omitempty"`
 	StartSector uint64 `json:"start_sector,omitempty"`

+ 8 - 0
model/docker.go

@@ -0,0 +1,8 @@
+package model
+
+type DockerStatsModel struct {
+	Icon  string      `json:"icon"`
+	Title string      `json:"title"`
+	Data  interface{} `json:"data"`
+	Pre   interface{} `json:"pre"`
+}

+ 4 - 0
model/sys_common.go

@@ -68,3 +68,7 @@ type SystemConfig struct {
 	SyncPort   string `json:"sync_port"`
 	SyncPort   string `json:"sync_port"`
 	SyncKey    string `json:"sync_key"`
 	SyncKey    string `json:"sync_key"`
 }
 }
+
+type CasaOSGlobalVariables struct {
+	AddApp bool
+}

+ 2 - 0
pkg/config/init.go

@@ -33,6 +33,8 @@ var ServerInfo = &model.ServerModel{}
 
 
 var SystemConfigInfo = &model.SystemConfig{}
 var SystemConfigInfo = &model.SystemConfig{}
 
 
+var CasaOSGlobalVariables = &model.CasaOSGlobalVariables{}
+
 var Cfg *ini.File
 var Cfg *ini.File
 
 
 //初始化设置,获取系统的部分信息。
 //初始化设置,获取系统的部分信息。

+ 9 - 0
route/init.go

@@ -10,6 +10,7 @@ import (
 	"github.com/IceWhaleTech/CasaOS/model/system_app"
 	"github.com/IceWhaleTech/CasaOS/model/system_app"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	"github.com/IceWhaleTech/CasaOS/pkg/docker"
 	"github.com/IceWhaleTech/CasaOS/pkg/docker"
+	"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/env_helper"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/env_helper"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/port"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/port"
@@ -20,6 +21,7 @@ import (
 
 
 func InitFunction() {
 func InitFunction() {
 	go checkSystemApp()
 	go checkSystemApp()
+	Update2_3()
 }
 }
 
 
 var syncIsExistence = false
 var syncIsExistence = false
@@ -190,3 +192,10 @@ func checkSystemApp() {
 		installSyncthing("44")
 		installSyncthing("44")
 	}
 	}
 }
 }
+func CheckSerialDiskMount() {
+	// 检查挂载点重新挂载
+	// 检查新硬盘是否有多个分区,如有多个分区需提示
+}
+func Update2_3() {
+	command.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/assist.sh")
+}

+ 8 - 1
route/route.go

@@ -194,6 +194,7 @@ func InitRouter() *gin.Engine {
 			v1SysGroup.POST("/config", v1.PostSetSystemConfig)
 			v1SysGroup.POST("/config", v1.PostSetSystemConfig)
 			v1SysGroup.GET("/widget/config", v1.GetWidgetConfig)
 			v1SysGroup.GET("/widget/config", v1.GetWidgetConfig)
 			v1SysGroup.POST("/widget/config", v1.PostSetWidgetConfig)
 			v1SysGroup.POST("/widget/config", v1.PostSetWidgetConfig)
+			v1SysGroup.GET("/port", v1.GetCasaOSPort)
 			v1SysGroup.PUT("/port", v1.PutCasaOSPort)
 			v1SysGroup.PUT("/port", v1.PutCasaOSPort)
 			v1SysGroup.POST("/kill", v1.PostKillCasaOS)
 			v1SysGroup.POST("/kill", v1.PostKillCasaOS)
 		}
 		}
@@ -225,7 +226,7 @@ func InitRouter() *gin.Engine {
 			v1DiskGroup.POST("/format", v1.FormatDisk)
 			v1DiskGroup.POST("/format", v1.FormatDisk)
 
 
 			//添加分区
 			//添加分区
-			v1DiskGroup.POST("/addpart", v1.AddPartition)
+			v1DiskGroup.POST("/part", v1.AddPartition)
 
 
 			//获取可以格式化的内容
 			//获取可以格式化的内容
 			v1DiskGroup.GET("/type", v1.FormatDiskType)
 			v1DiskGroup.GET("/type", v1.FormatDiskType)
@@ -233,6 +234,12 @@ func InitRouter() *gin.Engine {
 			//删除分区
 			//删除分区
 			v1DiskGroup.DELETE("/delpart", v1.RemovePartition)
 			v1DiskGroup.DELETE("/delpart", v1.RemovePartition)
 
 
+			//mount SATA disk
+			v1DiskGroup.POST("/mount", v1.PostMountDisk)
+
+			//umount SATA disk
+			v1DiskGroup.POST("/umount", v1.DeleteUmountDisk)
+
 		}
 		}
 		v1ShareGroup := v1Group.Group("/share")
 		v1ShareGroup := v1Group.Group("/share")
 		v1ShareGroup.Use()
 		v1ShareGroup.Use()

+ 26 - 15
route/v1/disk.go

@@ -2,7 +2,6 @@ package v1
 
 
 import (
 import (
 	"net/http"
 	"net/http"
-	"strconv"
 
 
 	"github.com/IceWhaleTech/CasaOS/model"
 	"github.com/IceWhaleTech/CasaOS/model"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
@@ -110,15 +109,9 @@ func FormatDisk(c *gin.Context) {
 	if len(path) == 0 || len(t) == 0 {
 	if len(path) == 0 || len(t) == 0 {
 		c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
 		c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
 	}
 	}
-
-	//删除挂载点
-	service.MyService.Disk().UmountPointAndRemoveDir(path)
-
 	//格式化磁盘
 	//格式化磁盘
 	service.MyService.Disk().FormatDisk(path, t)
 	service.MyService.Disk().FormatDisk(path, t)
 
 
-	//重新挂载
-
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
 }
 }
 
 
@@ -155,25 +148,43 @@ func RemovePartition(c *gin.Context) {
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
 }
 }
 
 
-// @Summary 添加分区
+// @Summary serial number
 // @Produce  application/json
 // @Produce  application/json
 // @Accept multipart/form-data
 // @Accept multipart/form-data
 // @Tags disk
 // @Tags disk
 // @Security ApiKeyAuth
 // @Security ApiKeyAuth
 // @Param  path formData string true "磁盘路径 例如/dev/sda"
 // @Param  path formData string true "磁盘路径 例如/dev/sda"
-// @Param  size formData string true "需要分区容量大小(MB)"
-// @Param  num formData string true "磁盘符号"
+// @Param  serial formData string true "serial"
 // @Success 200 {string} string "ok"
 // @Success 200 {string} string "ok"
 // @Router /disk/addpart [post]
 // @Router /disk/addpart [post]
 func AddPartition(c *gin.Context) {
 func AddPartition(c *gin.Context) {
 	path := c.PostForm("path")
 	path := c.PostForm("path")
-	size, _ := strconv.Atoi(c.DefaultPostForm("size", "0"))
-	num := c.DefaultPostForm("num", "9")
-	if len(path) == 0 {
+	serial := c.PostForm("serial")
+	if len(path) == 0 || len(serial) == 0 {
 		c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
 		c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
+		return
 	}
 	}
+	service.MyService.Disk().AddPartition(path)
+	c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
+}
+
+func PostMountDisk(c *gin.Context) {
+	// for example: path=/dev/sda1
+	path := c.PostForm("path")
+	//执行挂载目录
+	service.MyService.Disk().MountDisk(path, "volume")
+	//添加到数据库
+
+	c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
+}
+
+func DeleteUmountDisk(c *gin.Context) {
+
+	// for example: path=/dev/sda1
+	path := c.PostForm("path")
+	service.MyService.Disk().UmountPointAndRemoveDir(path)
+
+	//删除数据库记录
 
 
-	//size*1024*1024/512
-	service.MyService.Disk().AddPartition(path, num, uint64(size*1024*2))
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
 }
 }

+ 7 - 2
route/v1/docker.go

@@ -10,6 +10,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/IceWhaleTech/CasaOS/model"
 	"github.com/IceWhaleTech/CasaOS/model"
+	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	"github.com/IceWhaleTech/CasaOS/pkg/docker"
 	"github.com/IceWhaleTech/CasaOS/pkg/docker"
 	upnp2 "github.com/IceWhaleTech/CasaOS/pkg/upnp"
 	upnp2 "github.com/IceWhaleTech/CasaOS/pkg/upnp"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
@@ -420,9 +421,12 @@ func InstallApp(c *gin.Context) {
 		rely := model.MapStrings{}
 		rely := model.MapStrings{}
 
 
 		copier.Copy(&rely, &relyMap)
 		copier.Copy(&rely, &relyMap)
-		for i := 0; i < len(m.Volumes); i++ {
-			m.Volumes[i].Path = docker.GetDir(id, m.Volumes[i].ContainerPath)
+		if m.Origin != "custom" {
+			for i := 0; i < len(m.Volumes); i++ {
+				m.Volumes[i].Path = docker.GetDir(id, m.Volumes[i].ContainerPath)
+			}
 		}
 		}
+
 		portsStr, _ := json2.Marshal(m.Ports)
 		portsStr, _ := json2.Marshal(m.Ports)
 		envsStr, _ := json2.Marshal(m.Envs)
 		envsStr, _ := json2.Marshal(m.Envs)
 		volumesStr, _ := json2.Marshal(m.Volumes)
 		volumesStr, _ := json2.Marshal(m.Volumes)
@@ -462,6 +466,7 @@ func InstallApp(c *gin.Context) {
 		//	m.PortMap = m.Port
 		//	m.PortMap = m.Port
 		//}
 		//}
 		service.MyService.App().SaveContainer(md)
 		service.MyService.App().SaveContainer(md)
+		config.CasaOSGlobalVariables.AddApp = true
 
 
 	}()
 	}()
 
 

+ 18 - 2
route/v1/system.go

@@ -137,14 +137,30 @@ func PostSetWidgetConfig(c *gin.Context) {
 		})
 		})
 }
 }
 
 
+// @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(http.StatusOK,
+		model.Result{
+			Success: oasis_err.SUCCESS,
+			Message: oasis_err.GetMsg(oasis_err.SUCCESS),
+			Data:    config.ServerInfo.HttpPort,
+		})
+}
+
 // @Summary edit casaos server port
 // @Summary edit casaos server port
 // @Produce  application/json
 // @Produce  application/json
 // @Accept application/json
 // @Accept application/json
 // @Tags sys
 // @Tags sys
 // @Security ApiKeyAuth
 // @Security ApiKeyAuth
-// @Param port formData file true "用户头像"
+// @Param port formData string true "port"
 // @Success 200 {string} string "ok"
 // @Success 200 {string} string "ok"
-// @Router /sys/widget/config [post]
+// @Router /sys/port [put]
 func PutCasaOSPort(c *gin.Context) {
 func PutCasaOSPort(c *gin.Context) {
 	port, err := strconv.Atoi(c.PostForm("port"))
 	port, err := strconv.Atoi(c.PostForm("port"))
 	if err != nil {
 	if err != nil {

+ 95 - 41
service/app.go

@@ -2,12 +2,15 @@ package service
 
 
 import (
 import (
 	"context"
 	"context"
+	"encoding/json"
+	"io"
 	"io/ioutil"
 	"io/ioutil"
 	"runtime"
 	"runtime"
 	"strings"
 	"strings"
 	"sync"
 	"sync"
 	"time"
 	"time"
 
 
+	"github.com/IceWhaleTech/CasaOS/model"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
 	loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
 	loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
@@ -16,7 +19,6 @@ import (
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/api/types/filters"
 	client2 "github.com/docker/docker/client"
 	client2 "github.com/docker/docker/client"
 	"github.com/pkg/errors"
 	"github.com/pkg/errors"
-	"github.com/tidwall/sjson"
 	"gorm.io/gorm"
 	"gorm.io/gorm"
 )
 )
 
 
@@ -31,7 +33,9 @@ type AppService interface {
 	GetSimpleContainerInfo(name string) (types.Container, error)
 	GetSimpleContainerInfo(name string) (types.Container, error)
 	DelAppConfigDir(path string)
 	DelAppConfigDir(path string)
 	GetSystemAppList() *[]model2.MyAppList
 	GetSystemAppList() *[]model2.MyAppList
-	GetHardwareUsage() []string
+	GetHardwareUsageSteam()
+	GetHardwareUsage() []model.DockerStatsModel
+	GetAppStats(id string) string
 }
 }
 
 
 type appStruct struct {
 type appStruct struct {
@@ -158,7 +162,6 @@ func (a *appStruct) GetSystemAppList() *[]model2.MyAppList {
 				//Rely:     m.Rely,
 				//Rely:     m.Rely,
 			})
 			})
 		}
 		}
-
 	}
 	}
 
 
 	return &list
 	return &list
@@ -237,57 +240,108 @@ func (a *appStruct) RemoveContainerById(id string) {
 	a.db.Table(model2.CONTAINERTABLENAME).Where("custom_id = ?", id).Delete(&model2.AppListDBModel{})
 	a.db.Table(model2.CONTAINERTABLENAME).Where("custom_id = ?", id).Delete(&model2.AppListDBModel{})
 }
 }
 
 
-func (a *appStruct) GetHardwareUsage() []string {
+var dataStr map[string]model.DockerStatsModel
+
+var isFinish bool = false
 
 
-	var dataStr []string
+func (a *appStruct) GetAppStats(id string) string {
 	cli, err := client2.NewClientWithOpts(client2.FromEnv)
 	cli, err := client2.NewClientWithOpts(client2.FromEnv)
 	if err != nil {
 	if err != nil {
-		return dataStr
+		return ""
 	}
 	}
 	defer cli.Close()
 	defer cli.Close()
+	con, err := cli.ContainerStats(context.Background(), id, false)
+	if err != nil {
+		return err.Error()
+	}
+	defer con.Body.Close()
+	c, _ := ioutil.ReadAll(con.Body)
+	return string(c)
+}
 
 
-	lock := &sync.Mutex{}
-	var lm []model2.AppListDBModel
-	var count = 0
-	a.db.Table(model2.CONTAINERTABLENAME).Select("title,icon,container_id").Find(&lm)
-	for _, v := range lm {
-		go func(lock *sync.Mutex, id, title, icon string) {
-			stats, err := cli.ContainerStats(context.Background(), id, false)
-			if err != nil {
-				lock.Lock()
-				count++
-				lock.Unlock()
-				return
-			}
-			defer stats.Body.Close()
-			statsByte, err := ioutil.ReadAll(stats.Body)
-			if err != nil {
-				lock.Lock()
-				count++
-				lock.Unlock()
-				return
-			}
-			lock.Lock()
-			statsByte, _ = sjson.SetBytes(statsByte, "icon", icon)
-			statsByte, _ = sjson.SetBytes(statsByte, "title", title)
-			dataStr = append(dataStr, string(statsByte))
-			count++
-			lock.Unlock()
-		}(lock, v.ContainerId, v.Title, v.Icon)
+func (a *appStruct) GetHardwareUsage() []model.DockerStatsModel {
+
+	steam := true
+	for !isFinish {
+		if steam {
+			steam = false
+			go func() {
+				a.GetHardwareUsageSteam()
+			}()
+		}
+		// 切一下,再次分配任务
+		runtime.Gosched()
 	}
 	}
+	list := []model.DockerStatsModel{}
+	for _, v := range dataStr {
+		list = append(list, v)
+	}
+
+	return list
 
 
-	for {
+}
+
+func (a *appStruct) GetHardwareUsageSteam() {
+	var lock = &sync.Mutex{}
+	if len(dataStr) == 0 {
 		lock.Lock()
 		lock.Lock()
-		c := count
+		dataStr = make(map[string]model.DockerStatsModel)
 		lock.Unlock()
 		lock.Unlock()
+	}
 
 
-		runtime.Gosched()
-		if c == len(lm) {
-			break
-		}
+	cli, err := client2.NewClientWithOpts(client2.FromEnv)
+	if err != nil {
+		return
 	}
 	}
-	return dataStr
+	defer cli.Close()
 
 
+	ctx := context.Background()
+	ctx, cancel := context.WithCancel(ctx)
+
+	var lm []model2.AppListDBModel
+	a.db.Table(model2.CONTAINERTABLENAME).Select("label,icon,container_id").Where("origin != ?", "system").Find(&lm)
+	var list []types.ContainerStats
+	for i := 0; i < 100; i++ {
+		if config.CasaOSGlobalVariables.AddApp {
+			a.db.Table(model2.CONTAINERTABLENAME).Select("label,icon,container_id").Where("origin != ?", "system").Find(&lm)
+		}
+		var wg sync.WaitGroup
+		for _, v := range lm {
+			wg.Add(1)
+			go func(v model2.AppListDBModel, lock *sync.Mutex) {
+				defer wg.Done()
+				stats, err := cli.ContainerStats(ctx, v.ContainerId, true)
+				if err != nil {
+					return
+				}
+				decode := json.NewDecoder(stats.Body)
+				var data interface{}
+				if err := decode.Decode(&data); err == io.EOF {
+					return
+				}
+				lock.Lock()
+				dockerStats := model.DockerStatsModel{}
+				dockerStats.Pre = dataStr[v.ContainerId].Data
+
+				dockerStats.Data = data
+				dockerStats.Icon = v.Icon
+				dockerStats.Title = v.Label
+				dataStr[v.ContainerId] = dockerStats
+				lock.Unlock()
+			}(v, lock)
+		}
+		wg.Wait()
+		isFinish = true
+		if i == 99 {
+			for _, v := range list {
+				v.Body.Close()
+			}
+
+		}
+		time.Sleep(time.Second * 2)
+	}
+	isFinish = false
+	cancel()
 }
 }
 
 
 // init install
 // init install

+ 29 - 31
service/disk.go

@@ -10,8 +10,10 @@ import (
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
 	command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
 	loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
 	loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
+	model2 "github.com/IceWhaleTech/CasaOS/service/model"
 	"github.com/shirou/gopsutil/v3/disk"
 	"github.com/shirou/gopsutil/v3/disk"
 	"github.com/tidwall/gjson"
 	"github.com/tidwall/gjson"
+	"gorm.io/gorm"
 )
 )
 
 
 type DiskService interface {
 type DiskService interface {
@@ -21,11 +23,14 @@ type DiskService interface {
 	UmountPointAndRemoveDir(path string) string
 	UmountPointAndRemoveDir(path string) string
 	GetDiskInfo(path string) model.LSBLKModel
 	GetDiskInfo(path string) model.LSBLKModel
 	DelPartition(path, num string) string
 	DelPartition(path, num string) string
-	AddPartition(path, num string, size uint64) string
+	AddPartition(path string) string
 	GetDiskInfoByPath(path string) *disk.UsageStat
 	GetDiskInfoByPath(path string) *disk.UsageStat
+	MountDisk(path, volume string)
+	SerialAll(mountPoint string) *[]model2.SerialDisk
 }
 }
 type diskService struct {
 type diskService struct {
 	log loger2.OLog
 	log loger2.OLog
+	db  *gorm.DB
 }
 }
 
 
 //通过脚本获取外挂磁盘
 //通过脚本获取外挂磁盘
@@ -55,28 +60,17 @@ func (d *diskService) DelPartition(path, num string) string {
 	return ""
 	return ""
 }
 }
 
 
-//添加分区
-func (d *diskService) AddPartition(path, num string, size uint64) string {
-
-	var maxSector uint64 = 0
-
-	chiList := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetPartitionSectors " + path)
-	if len(chiList) == 0 {
-		d.log.Error("chiList length error")
-	}
-	for i := 0; i < len(chiList); i++ {
-		tempArr := strings.Split(chiList[i], ",")
-		tempSector, _ := strconv.ParseUint(tempArr[2], 10, 64)
-		if tempSector > maxSector {
-			maxSector = tempSector
-		}
-	}
-
-	r := command2.ExecResultStrArray("source ./shell/helper.sh ;AddPartition " + path + " " + num + " " + strconv.FormatUint(maxSector+1, 10) + " " + strconv.FormatUint(size+maxSector+1, 10))
+//part
+func (d *diskService) AddPartition(path string) string {
+	r := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;AddPartition " + path)
 	fmt.Println(r)
 	fmt.Println(r)
 	return ""
 	return ""
 }
 }
 
 
+func (d *diskService) AddAllPartition(path string) {
+
+}
+
 //获取硬盘详情
 //获取硬盘详情
 func (d *diskService) GetDiskInfoByPath(path string) *disk.UsageStat {
 func (d *diskService) GetDiskInfoByPath(path string) *disk.UsageStat {
 	diskInfo, err := disk.Usage(path + "1")
 	diskInfo, err := disk.Usage(path + "1")
@@ -111,7 +105,7 @@ func (d *diskService) LSBLK() []model.LSBLKModel {
 
 
 	var health = true
 	var health = true
 	for _, i := range m {
 	for _, i := range m {
-		if i.Type != "loop" {
+		if i.Type != "loop" && !i.RO {
 			fsused = 0
 			fsused = 0
 			for _, child := range i.Children {
 			for _, child := range i.Children {
 				if child.RM {
 				if child.RM {
@@ -197,17 +191,21 @@ func (d *diskService) GetDiskInfo(path string) model.LSBLKModel {
 	return m
 	return m
 }
 }
 
 
-//func GetDiskInfo(path string) *disk.UsageStat {
-//	diskInfo, _ := disk.Usage(path)
-//	diskInfo.UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.UsedPercent), 64)
-//	diskInfo.InodesUsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.InodesUsedPercent), 64)
-//	return diskInfo
-//}
+func (d *diskService) MountDisk(path, volume string) {
+	r := command2.ExecResultStr("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;do_mount " + path + " " + volume)
+	fmt.Print(r)
+}
+
+func (d *diskService) SaveMountPoint(m model2.SerialDisk) {
+	d.db.Save(&m)
+}
 
 
-//func (d *diskService) GetPlugInDisk() []string {
-//	return disk.Partitions(false)
-//}
+func (d *diskService) SerialAll(mountPoint string) *[]model2.SerialDisk {
+	var m []model2.SerialDisk
+	d.db.Find(&m)
+	return &m
+}
 
 
-func NewDiskService(log loger2.OLog) DiskService {
-	return &diskService{log: log}
+func NewDiskService(log loger2.OLog, db *gorm.DB) DiskService {
+	return &diskService{log: log, db: db}
 }
 }

+ 4 - 8
service/model/o_container.go

@@ -26,14 +26,10 @@ type AppListDBModel struct {
 	PortMap    string `json:"port_map"`
 	PortMap    string `json:"port_map"`
 	Label      string `json:"label"`
 	Label      string `json:"label"`
 	EnableUPNP bool   `json:"enable_upnp"`
 	EnableUPNP bool   `json:"enable_upnp"`
-	//Envs       model.EnvArrey  `json:"envs" bson:"envs"`
-	//Ports      model.PortArrey `json:"ports" bson:"ports"`
-	//Volumes    model.PathArrey `json:"volumes" bson:"volumes"`
-	//Devices    model.PathArrey `json:"devices" bson:"devices"`
-	Envs    string `json:"envs"`
-	Ports   string `json:"ports"`
-	Volumes string `json:"volumes"`
-	Devices string `json:"devices"`
+	Envs       string `json:"envs"`
+	Ports      string `json:"ports"`
+	Volumes    string `json:"volumes"`
+	Devices    string `json:"devices"`
 	//Envs      []model.Env      `json:"envs"`
 	//Envs      []model.Env      `json:"envs"`
 	//Ports     []model.PortMap  `gorm:"type:json" json:"ports"`
 	//Ports     []model.PortMap  `gorm:"type:json" json:"ports"`
 	//Volumes   []model.PathMap  `gorm:"type:json" json:"volumes"`
 	//Volumes   []model.PathMap  `gorm:"type:json" json:"volumes"`

+ 14 - 0
service/model/o_disk.go

@@ -0,0 +1,14 @@
+package model
+
+//SerialAdvanced Technology Attachment (STAT)
+type SerialDisk struct {
+	Id         uint   `gorm:"column:id;primary_key" json:"id"`
+	DiskId     string `json:"disk_id"`
+	Path       string `json:"path"`
+	State      int    `json:"state"`
+	MountPoint string `json:"mount_point"`
+}
+
+func (p *SerialDisk) TableName() string {
+	return "o_disk"
+}

+ 1 - 1
service/service.go

@@ -40,7 +40,7 @@ func NewService(db *gorm.DB, log loger2.OLog) Repository {
 		zerotier:       NewZeroTierService(),
 		zerotier:       NewZeroTierService(),
 		zima:           NewZiMaService(),
 		zima:           NewZiMaService(),
 		oapi:           NewOasisService(),
 		oapi:           NewOasisService(),
-		disk:           NewDiskService(log),
+		disk:           NewDiskService(log, db),
 		notify:         NewNotifyService(db),
 		notify:         NewNotifyService(db),
 		shareDirectory: NewShareDirService(db, log),
 		shareDirectory: NewShareDirService(db, log),
 		task:           NewTaskService(db, log),
 		task:           NewTaskService(db, log),

+ 6 - 19
shell/assist.sh

@@ -1,25 +1,12 @@
 #!/bin/bash
 #!/bin/bash
 
 
-#update to v0.2.3
-version_0_2_3(){
+#add in v0.2.3
+version_0_2_3() {
   ((EUID)) && sudo_cmd="sudo"
   ((EUID)) && sudo_cmd="sudo"
-
-#copy file to path
-  if [ ! -s "/etc/udev/rules.d/11-usb-mount.rules" ]; then
-    $sudo_cmd cp /casaOS/server/shell/11-usb-mount.rules /etc/udev/rules.d/
-  fi
-
-  if [ ! -s "/casaOS/util/shell/usb-mount.sh" ]; then
-    $sudo_cmd cp /casaOS/server/shell/usb-mount.sh /casaOS/util/shell/
-    $sudo_cmd chmod +x /casaOS/util/shell/usb-mount.sh
-  fi
-  if [ ! -s "/etc/systemd/system/cp /casaOS/server/shell/usb-mount@.service" ]; then
-     $sudo_cmd cp /casaOS/server/shell/usb-mount@.service /etc/systemd/system/
-  fi
-
-
-
+  $sudo_cmd cp -rf /casaOS/server/shell/11-usb-mount.rules /etc/udev/rules.d/
+  $sudo_cmd chmod +x /casaOS/server/shell/usb-mount.sh
+  $sudo_cmd cp -rf /casaOS/server/shell/usb-mount@.service /etc/systemd/system/
 
 
 }
 }
 
 
-version_0_2_3
+version_0_2_3

+ 89 - 11
shell/helper.sh

@@ -103,20 +103,22 @@ DelPartition() {
 EOF
 EOF
 }
 }
 
 
-#添加分区
+#添加分区只有一个分区
 #param 路径   /dev/sdb
 #param 路径   /dev/sdb
-#param 磁盘号   最大128
-#param 磁盘大小 字节   512*2048=1024kb=1M
+#param 要挂载的目录
 AddPartition() {
 AddPartition() {
-  #  fdisk $1 <<EOF
-  #  n
-  #  $2
-  #  $3
-  #  $4
-  #  wq
-  #EOF
 
 
-  parted $1 mkpart primary ext4 s3 s4
+  DelPartition $1
+  parted -s $1 mklabel gpt
+
+  parted -s $1 mkpart primary ext4 0 100%
+
+  mkfs.ext4 $11
+
+  partprobe $1
+
+  #  mount $11 $2
+
 }
 }
 
 
 #磁盘类型
 #磁盘类型
@@ -151,7 +153,83 @@ GetPartitionSectors() {
   fdisk $1 -l | grep "/dev/sda[1-9]" | awk 'BEGIN{OFS=","}{print $1,$2,$3,$4}'
   fdisk $1 -l | grep "/dev/sda[1-9]" | awk 'BEGIN{OFS=","}{print $1,$2,$3,$4}'
 }
 }
 
 
+#检查没有使用的挂载点删除文件夹
+AutoRemoveUnuseDir() {
+  DIRECTORY="/mnt/"
+  dir=$(ls -l $DIRECTORY | awk '/^d/ {print $NF}')
+  for i in $dir; do
+
+    path="$DIRECTORY$i"
+    mountStr=$(mountpoint $path)
+    notMountpoint="is not a mountpoint"
+    if [[ $mountStr =~ $notMountpoint ]]; then
+      if [ "$(ls -A $path)" = "" ]; then
+        rm -fr $path
+      else
+        echo "$path is not empty"
+      fi
+    fi
+  done
+}
+
 #重载samba服务
 #重载samba服务
 ReloadSamba() {
 ReloadSamba() {
   /etc/init.d/smbd reload
   /etc/init.d/smbd reload
 }
 }
+
+# $1=sda1
+# $2=volume{1}
+do_mount() {
+  DEVBASE=$1
+  DEVICE="${DEVBASE}"
+  # See if this drive is already mounted, and if so where
+  MOUNT_POINT=$(mount | grep ${DEVICE} | awk '{ print $3 }')
+
+  if [ -n "${MOUNT_POINT}" ]; then
+    ${log} "Warning: ${DEVICE} is already mounted at ${MOUNT_POINT}"
+    exit 1
+  fi
+
+  # Get info for this drive: $ID_FS_LABEL and $ID_FS_TYPE
+  eval $(blkid -o udev ${DEVICE} | grep -i -e "ID_FS_LABEL" -e "ID_FS_TYPE")
+
+  LABEL=$2
+  if grep -q " /media/${LABEL} " /etc/mtab; then
+    # Already in use, make a unique one
+    LABEL+="-${DEVBASE}"
+  fi
+  DEV_LABEL="${LABEL}"
+
+  # Use the device name in case the drive doesn't have label
+  if [ -z ${DEV_LABEL} ]; then
+    DEV_LABEL="${DEVBASE}"
+  fi
+
+  MOUNT_POINT="/media/${DEV_LABEL}"
+
+  ${log} "Mount point: ${MOUNT_POINT}"
+
+  mkdir -p ${MOUNT_POINT}
+
+  case ${ID_FS_TYPE} in
+  vfat)
+    mount -t vfat -o rw,relatime,users,gid=100,umask=000,shortname=mixed,utf8=1,flush ${DEVICE} ${MOUNT_POINT}
+    ;;
+  ext[2-4])
+    mount -o noatime ${DEVICE} ${MOUNT_POINT} >/dev/null 2>&1
+    ;;
+  exfat)
+    mount -t exfat ${DEVICE} ${MOUNT_POINT} >/dev/null 2>&1
+    ;;
+  ntfs)
+    ntfs-3g ${DEVICE} ${MOUNT_POINT}
+    ;;
+  iso9660)
+    mount -t iso9660 ${DEVICE} ${MOUNT_POINT}
+    ;;
+  *)
+    /bin/rmdir "${MOUNT_POINT}"
+    exit 0
+    ;;
+  esac
+}

+ 3 - 3
shell/tools.sh

@@ -99,13 +99,13 @@ update() {
     target_arch="386"
     target_arch="386"
     ;;
     ;;
   *armv5*)
   *armv5*)
-    target_arch="armv5"
+    target_arch="arm-5"
     ;;
     ;;
   *armv6*)
   *armv6*)
-    target_arch="armv6"
+    target_arch="arm-6"
     ;;
     ;;
   *armv7*)
   *armv7*)
-    target_arch="armv7"
+    target_arch="arm-7"
     ;;
     ;;
   *)
   *)
     show 1 "Aborted, unsupported or unknown architecture: $unamem"
     show 1 "Aborted, unsupported or unknown architecture: $unamem"

+ 2 - 4
shell/usb-mount.sh

@@ -5,8 +5,6 @@
 
 
 log="logger -t usb-mount.sh -s "
 log="logger -t usb-mount.sh -s "
 
 
-${log} "变量:$1 $2"
-
 ACTION=$1
 ACTION=$1
 
 
 DEVBASE=$2
 DEVBASE=$2
@@ -33,7 +31,7 @@ do_mount() {
   # Figure out a mount point to use
   # Figure out a mount point to use
   # LABEL=${ID_FS_LABEL}
   # LABEL=${ID_FS_LABEL}
   LABEL=${DEVBASE}
   LABEL=${DEVBASE}
-  if grep -q " /media/${LABEL} " /etc/mtab; then
+  if grep -q " /mnt/casa_${LABEL} " /etc/mtab; then
     # Already in use, make a unique one
     # Already in use, make a unique one
     LABEL+="-${DEVBASE}"
     LABEL+="-${DEVBASE}"
   fi
   fi
@@ -44,7 +42,7 @@ do_mount() {
     DEV_LABEL="${DEVBASE}"
     DEV_LABEL="${DEVBASE}"
   fi
   fi
 
 
-  MOUNT_POINT="/media/${DEV_LABEL}"
+  MOUNT_POINT="/mnt/casa_${DEV_LABEL}"
 
 
   ${log} "Mount point: ${MOUNT_POINT}"
   ${log} "Mount point: ${MOUNT_POINT}"
 
 

+ 2 - 2
shell/usb-mount@.service

@@ -4,5 +4,5 @@ Description=Mount USB Drive on %i
 [Service]
 [Service]
 Type=oneshot
 Type=oneshot
 RemainAfterExit=true
 RemainAfterExit=true
-ExecStart=/casaOS/util/shell/usb-mount.sh add %i
-ExecStop=/casaOS/util/shell/usb-mount.sh remove %i
+ExecStart=/casaOS/server/shell/usb-mount.sh add %i
+ExecStop=/casaOS/server/shell/usb-mount.sh remove %i

+ 2 - 2
types/system.go

@@ -1,4 +1,4 @@
 package types
 package types
 
 
-const CURRENTVERSION = "0.2.2"
-const BODY = "<li>ui adjustment</li><li>fixed bugs</li>"
+const CURRENTVERSION = "0.2.3"
+const BODY = "<li>Add detailed CPU and memory statistics.</li><li>Add the multi-language function and add Chinese translation.</li><li>Add the function to modify the search engine.</li><li>Add the function of modifying the WebUI port</li><li>fixed some bugs</li><li>Preprocessing usb automounting</li><li>Update update script</li>"

+ 11 - 0
web/img/add_button.76237e85.svg

@@ -0,0 +1,11 @@
+<svg width="72" height="72" viewBox="0 0 72 72" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect opacity="0.32" x="0.435625" y="0.435625" width="71.1288" height="71.1288" rx="7.56437" fill="white" stroke="url(#paint0_linear_812_2050)" stroke-width="0.87125"/>
+<path d="M36.0606 22L36.0239 50" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M22 36H50" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<defs>
+<linearGradient id="paint0_linear_812_2050" x1="77.6757" y1="64.5405" x2="35.9839" y2="53.5747" gradientUnits="userSpaceOnUse">
+<stop stop-color="#CBEFFF" stop-opacity="0.16"/>
+<stop offset="1" stop-color="white" stop-opacity="0"/>
+</linearGradient>
+</defs>
+</svg>

File diff suppressed because it is too large
+ 0 - 0
web/js/2.js


File diff suppressed because it is too large
+ 0 - 0
web/js/3.js


File diff suppressed because it is too large
+ 0 - 0
web/js/4.js


File diff suppressed because it is too large
+ 0 - 0
web/js/app.js


File diff suppressed because it is too large
+ 8 - 0
web/js/chunk-vendors.js


Some files were not shown because too many files changed in this diff