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:
parent
997d912f4d
commit
6c235d3f2a
28 changed files with 640 additions and 309 deletions
2
UI
2
UI
|
@ -1 +1 @@
|
|||
Subproject commit f7c46d7379ab31bc70a35900ef6a50f7f3c2ef4f
|
||||
Subproject commit a982eb4bddafe0beaa629fcfef9581b8ef1eddf3
|
|
@ -2,8 +2,9 @@ package middleware
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
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-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")
|
||||
//设置缓存时间
|
||||
|
|
|
@ -24,6 +24,7 @@ type LSBLKModel struct {
|
|||
Tran string `json:"tran"`
|
||||
MinIO uint64 `json:"min-io"`
|
||||
UsedPercent float64 `json:"used_percent"`
|
||||
Serial string `json:"serial"`
|
||||
Children []LSBLKModel `json:"children"`
|
||||
//详情特有
|
||||
StartSector uint64 `json:"start_sector,omitempty"`
|
||||
|
|
8
model/docker.go
Normal file
8
model/docker.go
Normal 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"`
|
||||
}
|
|
@ -68,3 +68,7 @@ type SystemConfig struct {
|
|||
SyncPort string `json:"sync_port"`
|
||||
SyncKey string `json:"sync_key"`
|
||||
}
|
||||
|
||||
type CasaOSGlobalVariables struct {
|
||||
AddApp bool
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ var ServerInfo = &model.ServerModel{}
|
|||
|
||||
var SystemConfigInfo = &model.SystemConfig{}
|
||||
|
||||
var CasaOSGlobalVariables = &model.CasaOSGlobalVariables{}
|
||||
|
||||
var Cfg *ini.File
|
||||
|
||||
//初始化设置,获取系统的部分信息。
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/IceWhaleTech/CasaOS/model/system_app"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||
"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/file"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/port"
|
||||
|
@ -20,6 +21,7 @@ import (
|
|||
|
||||
func InitFunction() {
|
||||
go checkSystemApp()
|
||||
Update2_3()
|
||||
}
|
||||
|
||||
var syncIsExistence = false
|
||||
|
@ -190,3 +192,10 @@ func checkSystemApp() {
|
|||
installSyncthing("44")
|
||||
}
|
||||
}
|
||||
func CheckSerialDiskMount() {
|
||||
// 检查挂载点重新挂载
|
||||
// 检查新硬盘是否有多个分区,如有多个分区需提示
|
||||
}
|
||||
func Update2_3() {
|
||||
command.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/assist.sh")
|
||||
}
|
||||
|
|
|
@ -194,6 +194,7 @@ func InitRouter() *gin.Engine {
|
|||
v1SysGroup.POST("/config", v1.PostSetSystemConfig)
|
||||
v1SysGroup.GET("/widget/config", v1.GetWidgetConfig)
|
||||
v1SysGroup.POST("/widget/config", v1.PostSetWidgetConfig)
|
||||
v1SysGroup.GET("/port", v1.GetCasaOSPort)
|
||||
v1SysGroup.PUT("/port", v1.PutCasaOSPort)
|
||||
v1SysGroup.POST("/kill", v1.PostKillCasaOS)
|
||||
}
|
||||
|
@ -225,7 +226,7 @@ func InitRouter() *gin.Engine {
|
|||
v1DiskGroup.POST("/format", v1.FormatDisk)
|
||||
|
||||
//添加分区
|
||||
v1DiskGroup.POST("/addpart", v1.AddPartition)
|
||||
v1DiskGroup.POST("/part", v1.AddPartition)
|
||||
|
||||
//获取可以格式化的内容
|
||||
v1DiskGroup.GET("/type", v1.FormatDiskType)
|
||||
|
@ -233,6 +234,12 @@ func InitRouter() *gin.Engine {
|
|||
//删除分区
|
||||
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.Use()
|
||||
|
|
|
@ -2,7 +2,6 @@ package v1
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
||||
|
@ -110,15 +109,9 @@ func FormatDisk(c *gin.Context) {
|
|||
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)})
|
||||
}
|
||||
|
||||
//删除挂载点
|
||||
service.MyService.Disk().UmountPointAndRemoveDir(path)
|
||||
|
||||
//格式化磁盘
|
||||
service.MyService.Disk().FormatDisk(path, t)
|
||||
|
||||
//重新挂载
|
||||
|
||||
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)})
|
||||
}
|
||||
|
||||
// @Summary 添加分区
|
||||
// @Summary serial number
|
||||
// @Produce application/json
|
||||
// @Accept multipart/form-data
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @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"
|
||||
// @Router /disk/addpart [post]
|
||||
func AddPartition(c *gin.Context) {
|
||||
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)})
|
||||
return
|
||||
}
|
||||
|
||||
//size*1024*1024/512
|
||||
service.MyService.Disk().AddPartition(path, num, uint64(size*1024*2))
|
||||
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)
|
||||
|
||||
//删除数据库记录
|
||||
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/docker"
|
||||
upnp2 "github.com/IceWhaleTech/CasaOS/pkg/upnp"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||
|
@ -420,9 +421,12 @@ func InstallApp(c *gin.Context) {
|
|||
rely := model.MapStrings{}
|
||||
|
||||
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)
|
||||
envsStr, _ := json2.Marshal(m.Envs)
|
||||
volumesStr, _ := json2.Marshal(m.Volumes)
|
||||
|
@ -462,6 +466,7 @@ func InstallApp(c *gin.Context) {
|
|||
// m.PortMap = m.Port
|
||||
//}
|
||||
service.MyService.App().SaveContainer(md)
|
||||
config.CasaOSGlobalVariables.AddApp = true
|
||||
|
||||
}()
|
||||
|
||||
|
|
|
@ -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
|
||||
// @Produce application/json
|
||||
// @Accept application/json
|
||||
// @Tags sys
|
||||
// @Security ApiKeyAuth
|
||||
// @Param port formData file true "用户头像"
|
||||
// @Param port formData string true "port"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /sys/widget/config [post]
|
||||
// @Router /sys/port [put]
|
||||
func PutCasaOSPort(c *gin.Context) {
|
||||
port, err := strconv.Atoi(c.PostForm("port"))
|
||||
if err != nil {
|
||||
|
|
144
service/app.go
144
service/app.go
|
@ -2,12 +2,15 @@ package service
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
|
||||
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
||||
|
@ -16,7 +19,6 @@ import (
|
|||
"github.com/docker/docker/api/types/filters"
|
||||
client2 "github.com/docker/docker/client"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tidwall/sjson"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
|
@ -31,7 +33,9 @@ type AppService interface {
|
|||
GetSimpleContainerInfo(name string) (types.Container, error)
|
||||
DelAppConfigDir(path string)
|
||||
GetSystemAppList() *[]model2.MyAppList
|
||||
GetHardwareUsage() []string
|
||||
GetHardwareUsageSteam()
|
||||
GetHardwareUsage() []model.DockerStatsModel
|
||||
GetAppStats(id string) string
|
||||
}
|
||||
|
||||
type appStruct struct {
|
||||
|
@ -158,7 +162,6 @@ func (a *appStruct) GetSystemAppList() *[]model2.MyAppList {
|
|||
//Rely: m.Rely,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return &list
|
||||
|
@ -237,57 +240,108 @@ func (a *appStruct) RemoveContainerById(id string) {
|
|||
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)
|
||||
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()
|
||||
|
||||
lock := &sync.Mutex{}
|
||||
ctx := context.Background()
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
for {
|
||||
lock.Lock()
|
||||
c := count
|
||||
lock.Unlock()
|
||||
|
||||
runtime.Gosched()
|
||||
if c == len(lm) {
|
||||
break
|
||||
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)
|
||||
}
|
||||
}
|
||||
return dataStr
|
||||
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
|
||||
|
|
|
@ -10,8 +10,10 @@ import (
|
|||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||
command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
|
||||
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||
"github.com/shirou/gopsutil/v3/disk"
|
||||
"github.com/tidwall/gjson"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type DiskService interface {
|
||||
|
@ -21,11 +23,14 @@ type DiskService interface {
|
|||
UmountPointAndRemoveDir(path string) string
|
||||
GetDiskInfo(path string) model.LSBLKModel
|
||||
DelPartition(path, num string) string
|
||||
AddPartition(path, num string, size uint64) string
|
||||
AddPartition(path string) string
|
||||
GetDiskInfoByPath(path string) *disk.UsageStat
|
||||
MountDisk(path, volume string)
|
||||
SerialAll(mountPoint string) *[]model2.SerialDisk
|
||||
}
|
||||
type diskService struct {
|
||||
log loger2.OLog
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
//通过脚本获取外挂磁盘
|
||||
|
@ -55,28 +60,17 @@ func (d *diskService) DelPartition(path, num string) string {
|
|||
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)
|
||||
return ""
|
||||
}
|
||||
|
||||
func (d *diskService) AddAllPartition(path string) {
|
||||
|
||||
}
|
||||
|
||||
//获取硬盘详情
|
||||
func (d *diskService) GetDiskInfoByPath(path string) *disk.UsageStat {
|
||||
diskInfo, err := disk.Usage(path + "1")
|
||||
|
@ -111,7 +105,7 @@ func (d *diskService) LSBLK() []model.LSBLKModel {
|
|||
|
||||
var health = true
|
||||
for _, i := range m {
|
||||
if i.Type != "loop" {
|
||||
if i.Type != "loop" && !i.RO {
|
||||
fsused = 0
|
||||
for _, child := range i.Children {
|
||||
if child.RM {
|
||||
|
@ -197,17 +191,21 @@ func (d *diskService) GetDiskInfo(path string) model.LSBLKModel {
|
|||
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) GetPlugInDisk() []string {
|
||||
// return disk.Partitions(false)
|
||||
//}
|
||||
|
||||
func NewDiskService(log loger2.OLog) DiskService {
|
||||
return &diskService{log: log}
|
||||
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) SerialAll(mountPoint string) *[]model2.SerialDisk {
|
||||
var m []model2.SerialDisk
|
||||
d.db.Find(&m)
|
||||
return &m
|
||||
}
|
||||
|
||||
func NewDiskService(log loger2.OLog, db *gorm.DB) DiskService {
|
||||
return &diskService{log: log, db: db}
|
||||
}
|
||||
|
|
|
@ -26,14 +26,10 @@ type AppListDBModel struct {
|
|||
PortMap string `json:"port_map"`
|
||||
Label string `json:"label"`
|
||||
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"`
|
||||
//Ports []model.PortMap `gorm:"type:json" json:"ports"`
|
||||
//Volumes []model.PathMap `gorm:"type:json" json:"volumes"`
|
||||
|
|
14
service/model/o_disk.go
Normal file
14
service/model/o_disk.go
Normal 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"
|
||||
}
|
|
@ -40,7 +40,7 @@ func NewService(db *gorm.DB, log loger2.OLog) Repository {
|
|||
zerotier: NewZeroTierService(),
|
||||
zima: NewZiMaService(),
|
||||
oapi: NewOasisService(),
|
||||
disk: NewDiskService(log),
|
||||
disk: NewDiskService(log, db),
|
||||
notify: NewNotifyService(db),
|
||||
shareDirectory: NewShareDirService(db, log),
|
||||
task: NewTaskService(db, log),
|
||||
|
|
|
@ -1,25 +1,12 @@
|
|||
#!/bin/bash
|
||||
|
||||
#update to v0.2.3
|
||||
version_0_2_3(){
|
||||
#add in v0.2.3
|
||||
version_0_2_3() {
|
||||
((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
|
||||
|
|
100
shell/helper.sh
100
shell/helper.sh
|
@ -103,20 +103,22 @@ DelPartition() {
|
|||
EOF
|
||||
}
|
||||
|
||||
#添加分区
|
||||
#添加分区只有一个分区
|
||||
#param 路径 /dev/sdb
|
||||
#param 磁盘号 最大128
|
||||
#param 磁盘大小 字节 512*2048=1024kb=1M
|
||||
#param 要挂载的目录
|
||||
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}'
|
||||
}
|
||||
|
||||
#检查没有使用的挂载点删除文件夹
|
||||
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服务
|
||||
ReloadSamba() {
|
||||
/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
|
||||
}
|
||||
|
|
|
@ -99,13 +99,13 @@ update() {
|
|||
target_arch="386"
|
||||
;;
|
||||
*armv5*)
|
||||
target_arch="armv5"
|
||||
target_arch="arm-5"
|
||||
;;
|
||||
*armv6*)
|
||||
target_arch="armv6"
|
||||
target_arch="arm-6"
|
||||
;;
|
||||
*armv7*)
|
||||
target_arch="armv7"
|
||||
target_arch="arm-7"
|
||||
;;
|
||||
*)
|
||||
show 1 "Aborted, unsupported or unknown architecture: $unamem"
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
log="logger -t usb-mount.sh -s "
|
||||
|
||||
${log} "变量:$1 $2"
|
||||
|
||||
ACTION=$1
|
||||
|
||||
DEVBASE=$2
|
||||
|
@ -33,7 +31,7 @@ do_mount() {
|
|||
# Figure out a mount point to use
|
||||
# LABEL=${ID_FS_LABEL}
|
||||
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
|
||||
LABEL+="-${DEVBASE}"
|
||||
fi
|
||||
|
@ -44,7 +42,7 @@ do_mount() {
|
|||
DEV_LABEL="${DEVBASE}"
|
||||
fi
|
||||
|
||||
MOUNT_POINT="/media/${DEV_LABEL}"
|
||||
MOUNT_POINT="/mnt/casa_${DEV_LABEL}"
|
||||
|
||||
${log} "Mount point: ${MOUNT_POINT}"
|
||||
|
||||
|
|
|
@ -4,5 +4,5 @@ Description=Mount USB Drive on %i
|
|||
[Service]
|
||||
Type=oneshot
|
||||
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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
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
web/img/add_button.76237e85.svg
Normal file
11
web/img/add_button.76237e85.svg
Normal 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 |
325
web/js/2.js
325
web/js/2.js
File diff suppressed because one or more lines are too long
10
web/js/3.js
10
web/js/3.js
File diff suppressed because one or more lines are too long
10
web/js/4.js
10
web/js/4.js
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
Loading…
Add table
Reference in a new issue