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.
This commit is contained in:
link 2021-12-09 19:02:41 +08:00
parent 997d912f4d
commit 6c235d3f2a
28 changed files with 640 additions and 309 deletions

2
UI

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

View File

@ -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")
//设置缓存时间 //设置缓存时间

View File

@ -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
model/docker.go Normal file
View File

@ -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"`
}

View File

@ -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
}

View File

@ -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
//初始化设置,获取系统的部分信息。 //初始化设置,获取系统的部分信息。

View File

@ -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")
}

View File

@ -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()

View File

@ -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 serial formData string true "serial"
// @Param num formData string true "磁盘符号"
// @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")) serial := c.PostForm("serial")
num := c.DefaultPostForm("num", "9") if len(path) == 0 || len(serial) == 0 {
if len(path) == 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)
//size*1024*1024/512 c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
service.MyService.Disk().AddPartition(path, num, uint64(size*1024*2)) }
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)
//删除数据库记录
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)})
} }

View File

@ -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++ { if m.Origin != "custom" {
m.Volumes[i].Path = docker.GetDir(id, m.Volumes[i].ContainerPath) 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
}() }()

View File

@ -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 {

View File

@ -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 dataStr []string var isFinish bool = false
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()
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)
}
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
}
func (a *appStruct) GetHardwareUsageSteam() {
var lock = &sync.Mutex{}
if len(dataStr) == 0 {
lock.Lock()
dataStr = make(map[string]model.DockerStatsModel)
lock.Unlock()
}
cli, err := client2.NewClientWithOpts(client2.FromEnv)
if err != nil {
return
} }
defer cli.Close() defer cli.Close()
lock := &sync.Mutex{} ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
var lm []model2.AppListDBModel var lm []model2.AppListDBModel
var count = 0 a.db.Table(model2.CONTAINERTABLENAME).Select("label,icon,container_id").Where("origin != ?", "system").Find(&lm)
a.db.Table(model2.CONTAINERTABLENAME).Select("title,icon,container_id").Find(&lm) var list []types.ContainerStats
for _, v := range lm { for i := 0; i < 100; i++ {
go func(lock *sync.Mutex, id, title, icon string) { if config.CasaOSGlobalVariables.AddApp {
stats, err := cli.ContainerStats(context.Background(), id, false) a.db.Table(model2.CONTAINERTABLENAME).Select("label,icon,container_id").Where("origin != ?", "system").Find(&lm)
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)
}
for {
lock.Lock()
c := count
lock.Unlock()
runtime.Gosched()
if c == len(lm) {
break
} }
} var wg sync.WaitGroup
return dataStr 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

View File

@ -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 ""
} }
//添加分区 //part
func (d *diskService) AddPartition(path, num string, size uint64) string { func (d *diskService) AddPartition(path string) string {
r := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;AddPartition " + path)
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))
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 { func (d *diskService) MountDisk(path, volume string) {
// diskInfo, _ := disk.Usage(path) r := command2.ExecResultStr("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;do_mount " + path + " " + volume)
// diskInfo.UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.UsedPercent), 64) fmt.Print(r)
// diskInfo.InodesUsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.InodesUsedPercent), 64) }
// return diskInfo
//} 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
func NewDiskService(log loger2.OLog) DiskService { d.db.Find(&m)
return &diskService{log: log} return &m
}
func NewDiskService(log loger2.OLog, db *gorm.DB) DiskService {
return &diskService{log: log, db: db}
} }

View File

@ -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"` Envs string `json:"envs"`
//Ports model.PortArrey `json:"ports" bson:"ports"` Ports string `json:"ports"`
//Volumes model.PathArrey `json:"volumes" bson:"volumes"` Volumes string `json:"volumes"`
//Devices model.PathArrey `json:"devices" bson:"devices"` 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
service/model/o_disk.go Normal file
View File

@ -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"
}

View File

@ -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),

View File

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

View File

@ -103,20 +103,22 @@ DelPartition() {
EOF EOF
} }
#添加分区 #添加分区只有一个分区
#param 路径 /dev/sdb #param 路径 /dev/sdb
#param 磁盘号 最大128 #param 要挂载的目录
#param 磁盘大小 字节 512*2048=1024kb=1M
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
}

View File

@ -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"

View File

@ -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}"

View File

@ -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 ExecStart=/casaOS/server/shell/usb-mount.sh add %i
ExecStop=/casaOS/util/shell/usb-mount.sh remove %i ExecStop=/casaOS/server/shell/usb-mount.sh remove %i

View File

@ -1,4 +1,4 @@
package types package types
const CURRENTVERSION = "0.2.2" const CURRENTVERSION = "0.2.3"
const BODY = "<li>ui adjustment</li><li>fixed bugs</li>" 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>"

View File

@ -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>

After

Width:  |  Height:  |  Size: 752 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long