mirror of
https://github.com/IceWhaleTech/CasaOS.git
synced 2025-11-07 15:19:44 +00:00
wip
This commit is contained in:
parent
b0377cc659
commit
8445d5c3bc
@ -1,98 +0,0 @@
|
||||
/*
|
||||
* @Author: LinkLeong link@icewhale.com
|
||||
* @Date: 2022-07-13 10:43:45
|
||||
* @LastEditors: LinkLeong
|
||||
* @LastEditTime: 2022-08-03 14:45:35
|
||||
* @FilePath: /CasaOS/model/disk.go
|
||||
* @Description:
|
||||
* @Website: https://www.casaos.io
|
||||
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||
*/
|
||||
package model
|
||||
|
||||
type LSBLKModel struct {
|
||||
Name string `json:"name"`
|
||||
FsType string `json:"fstype"`
|
||||
Size uint64 `json:"size"`
|
||||
FSSize string `json:"fssize"`
|
||||
Path string `json:"path"`
|
||||
Model string `json:"model"` //设备标识符
|
||||
RM bool `json:"rm"` //是否为可移动设备
|
||||
RO bool `json:"ro"` //是否为只读设备
|
||||
State string `json:"state"`
|
||||
PhySec int `json:"phy-sec"` //物理扇区大小
|
||||
Type string `json:"type"`
|
||||
Vendor string `json:"vendor"` //供应商
|
||||
Rev string `json:"rev"` //修订版本
|
||||
FSAvail string `json:"fsavail"` //可用空间
|
||||
FSUse string `json:"fsuse%"` //已用百分比
|
||||
MountPoint string `json:"mountpoint"`
|
||||
Format string `json:"format"`
|
||||
Health string `json:"health"`
|
||||
HotPlug bool `json:"hotplug"`
|
||||
UUID string `json:"uuid"`
|
||||
FSUsed string `json:"fsused"`
|
||||
Temperature int `json:"temperature"`
|
||||
Tran string `json:"tran"`
|
||||
MinIO uint64 `json:"min-io"`
|
||||
UsedPercent float64 `json:"used_percent"`
|
||||
Serial string `json:"serial"`
|
||||
Children []LSBLKModel `json:"children"`
|
||||
SubSystems string `json:"subsystems"`
|
||||
Label string `json:"label"`
|
||||
//详情特有
|
||||
StartSector uint64 `json:"start_sector,omitempty"`
|
||||
Rota bool `json:"rota"` //true(hhd) false(ssd)
|
||||
DiskType string `json:"disk_type"`
|
||||
EndSector uint64 `json:"end_sector,omitempty"`
|
||||
}
|
||||
|
||||
type Drive struct {
|
||||
Name string `json:"name"`
|
||||
Size uint64 `json:"size"`
|
||||
Model string `json:"model"`
|
||||
Health string `json:"health"`
|
||||
Temperature int `json:"temperature"`
|
||||
DiskType string `json:"disk_type"`
|
||||
NeedFormat bool `json:"need_format"`
|
||||
Serial string `json:"serial"`
|
||||
Path string `json:"path"`
|
||||
ChildrenNumber int `json:"children_number"`
|
||||
}
|
||||
|
||||
type DriveUSB struct {
|
||||
Name string `json:"name"`
|
||||
Size uint64 `json:"size"`
|
||||
Model string `json:"model"`
|
||||
Avail uint64 `json:"avail"`
|
||||
Children []USBChildren `json:"children"`
|
||||
}
|
||||
type USBChildren struct {
|
||||
Name string `json:"name"`
|
||||
Size uint64 `json:"size"`
|
||||
Avail uint64 `json:"avail"`
|
||||
MountPoint string `json:"mount_point"`
|
||||
}
|
||||
|
||||
type Storage struct {
|
||||
MountPoint string `json:"mount_point"`
|
||||
Size string `json:"size"`
|
||||
Avail string `json:"avail"` //可用空间
|
||||
Type string `json:"type"`
|
||||
Path string `json:"path"`
|
||||
DriveName string `json:"drive_name"`
|
||||
Label string `json:"label"`
|
||||
}
|
||||
type Storages struct {
|
||||
DiskName string `json:"disk_name"`
|
||||
Size uint64 `json:"size"`
|
||||
Path string `json:"path"`
|
||||
Children []Storage `json:"children"`
|
||||
}
|
||||
|
||||
type Summary struct {
|
||||
Size uint64 `json:"size"`
|
||||
Avail uint64 `json:"avail"` //可用空间
|
||||
Health bool `json:"health"`
|
||||
Used uint64 `json:"used"`
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* @Author: LinkLeong link@icewhale.com
|
||||
* @Date: 2022-07-15 10:43:00
|
||||
* @LastEditors: LinkLeong
|
||||
* @LastEditTime: 2022-07-15 10:56:17
|
||||
* @FilePath: /CasaOS/model/notify/storage.go
|
||||
* @Description:
|
||||
* @Website: https://www.casaos.io
|
||||
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||
*/
|
||||
package notify
|
||||
|
||||
type StorageMessage struct {
|
||||
Type string `json:"type"` //sata,usb
|
||||
Action string `json:"action"` //remove add
|
||||
Path string `json:"path"`
|
||||
Volume string `json:"volume"`
|
||||
Size uint64 `json:"size"`
|
||||
}
|
||||
@ -1,69 +0,0 @@
|
||||
package model
|
||||
|
||||
//
|
||||
type SmartctlA struct {
|
||||
Smartctl struct {
|
||||
Version []int `json:"version"`
|
||||
SvnRevision string `json:"svn_revision"`
|
||||
PlatformInfo string `json:"platform_info"`
|
||||
BuildInfo string `json:"build_info"`
|
||||
Argv []string `json:"argv"`
|
||||
ExitStatus int `json:"exit_status"`
|
||||
} `json:"smartctl"`
|
||||
Device struct {
|
||||
Name string `json:"name"`
|
||||
InfoName string `json:"info_name"`
|
||||
Type string `json:"type"`
|
||||
Protocol string `json:"protocol"`
|
||||
} `json:"device"`
|
||||
ModelName string `json:"model_name"`
|
||||
SerialNumber string `json:"serial_number"`
|
||||
FirmwareVersion string `json:"firmware_version"`
|
||||
UserCapacity struct {
|
||||
Blocks int `json:"blocks"`
|
||||
Bytes int64 `json:"bytes"`
|
||||
} `json:"user_capacity"`
|
||||
SmartStatus struct {
|
||||
Passed bool `json:"passed"`
|
||||
} `json:"smart_status"`
|
||||
AtaSmartData struct {
|
||||
OfflineDataCollection struct {
|
||||
Status struct {
|
||||
Value int `json:"value"`
|
||||
String string `json:"string"`
|
||||
} `json:"status"`
|
||||
CompletionSeconds int `json:"completion_seconds"`
|
||||
} `json:"offline_data_collection"`
|
||||
SelfTest struct {
|
||||
Status struct {
|
||||
Value int `json:"value"`
|
||||
String string `json:"string"`
|
||||
Passed bool `json:"passed"`
|
||||
} `json:"status"`
|
||||
PollingMinutes struct {
|
||||
Short int `json:"short"`
|
||||
Extended int `json:"extended"`
|
||||
Conveyance int `json:"conveyance"`
|
||||
} `json:"polling_minutes"`
|
||||
} `json:"self_test"`
|
||||
Capabilities struct {
|
||||
Values []int `json:"values"`
|
||||
ExecOfflineImmediateSupported bool `json:"exec_offline_immediate_supported"`
|
||||
OfflineIsAbortedUponNewCmd bool `json:"offline_is_aborted_upon_new_cmd"`
|
||||
OfflineSurfaceScanSupported bool `json:"offline_surface_scan_supported"`
|
||||
SelfTestsSupported bool `json:"self_tests_supported"`
|
||||
ConveyanceSelfTestSupported bool `json:"conveyance_self_test_supported"`
|
||||
SelectiveSelfTestSupported bool `json:"selective_self_test_supported"`
|
||||
AttributeAutosaveEnabled bool `json:"attribute_autosave_enabled"`
|
||||
ErrorLoggingSupported bool `json:"error_logging_supported"`
|
||||
GpLoggingSupported bool `json:"gp_logging_supported"`
|
||||
} `json:"capabilities"`
|
||||
} `json:"ata_smart_data"`
|
||||
PowerOnTime struct {
|
||||
Hours int `json:"hours"`
|
||||
} `json:"power_on_time"`
|
||||
PowerCycleCount int `json:"power_cycle_count"`
|
||||
Temperature struct {
|
||||
Current int `json:"current"`
|
||||
} `json:"temperature"`
|
||||
}
|
||||
@ -2,11 +2,9 @@ package command
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os/exec"
|
||||
"time"
|
||||
)
|
||||
|
||||
func OnlyExec(cmdStr string) {
|
||||
@ -35,8 +33,8 @@ func ExecResultStrArray(cmdStr string) []string {
|
||||
fmt.Println(err)
|
||||
return nil
|
||||
}
|
||||
//str, err := ioutil.ReadAll(stdout)
|
||||
var networklist = []string{}
|
||||
// str, err := ioutil.ReadAll(stdout)
|
||||
networklist := []string{}
|
||||
outputBuf := bufio.NewReader(stdout)
|
||||
for {
|
||||
output, _, err := outputBuf.ReadLine()
|
||||
@ -72,41 +70,3 @@ func ExecResultStr(cmdStr string) string {
|
||||
}
|
||||
return string(str)
|
||||
}
|
||||
|
||||
//执行 lsblk 命令
|
||||
func ExecLSBLK() []byte {
|
||||
output, err := exec.Command("lsblk", "-O", "-J", "-b").Output()
|
||||
if err != nil {
|
||||
fmt.Println("lsblk", err)
|
||||
return nil
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
//执行 lsblk 命令
|
||||
func ExecLSBLKByPath(path string) []byte {
|
||||
output, err := exec.Command("lsblk", path, "-O", "-J", "-b").Output()
|
||||
if err != nil {
|
||||
fmt.Println("lsblk", err)
|
||||
return nil
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
//exec smart
|
||||
func ExecSmartCTLByPath(path string) []byte {
|
||||
timeout := 3
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
|
||||
defer cancel()
|
||||
output, err := exec.CommandContext(ctx, "smartctl", "-a", path, "-j").Output()
|
||||
if err != nil {
|
||||
fmt.Println("smartctl", err)
|
||||
return nil
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func ExecEnabledSMART(path string) {
|
||||
|
||||
exec.Command("smartctl", "-s on", path).Output()
|
||||
}
|
||||
|
||||
608
route/v1/disk.go
608
route/v1/disk.go
@ -1,608 +0,0 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/model/notify"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/encryption"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/shirou/gopsutil/v3/disk"
|
||||
)
|
||||
|
||||
var diskMap = make(map[string]string)
|
||||
|
||||
// @Summary disk list
|
||||
// @Produce application/json
|
||||
// @Accept application/json
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /disk/list [get]
|
||||
func GetDiskList(c *gin.Context) {
|
||||
path := c.Query("path")
|
||||
if len(path) > 0 {
|
||||
m := service.MyService.Disk().GetDiskInfo(path)
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: m})
|
||||
return
|
||||
}
|
||||
t := c.DefaultQuery("type", "")
|
||||
list := service.MyService.Disk().LSBLK(false)
|
||||
if t == "usb" {
|
||||
data := []model.DriveUSB{}
|
||||
for _, v := range list {
|
||||
if v.Tran == "usb" {
|
||||
temp := model.DriveUSB{}
|
||||
temp.Model = v.Model
|
||||
temp.Name = v.Name
|
||||
temp.Size = v.Size
|
||||
for _, child := range v.Children {
|
||||
if len(child.MountPoint) > 0 {
|
||||
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
|
||||
temp.Avail += avail
|
||||
}
|
||||
}
|
||||
data = append(data, temp)
|
||||
}
|
||||
}
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||
return
|
||||
}
|
||||
|
||||
dbList := service.MyService.Disk().GetSerialAll()
|
||||
part := make(map[string]int64, len(dbList))
|
||||
for _, v := range dbList {
|
||||
part[v.MountPoint] = v.CreatedAt
|
||||
}
|
||||
findSystem := 0
|
||||
|
||||
disks := []model.Drive{}
|
||||
storage := []model.Storage{}
|
||||
avail := []model.Drive{}
|
||||
for i := 0; i < len(list); i++ {
|
||||
disk := model.Drive{}
|
||||
if list[i].Rota {
|
||||
disk.DiskType = "HDD"
|
||||
} else {
|
||||
disk.DiskType = "SSD"
|
||||
}
|
||||
disk.Serial = list[i].Serial
|
||||
disk.Name = list[i].Name
|
||||
disk.Size = list[i].Size
|
||||
disk.Path = list[i].Path
|
||||
disk.Model = list[i].Model
|
||||
disk.ChildrenNumber = len(list[i].Children)
|
||||
if len(list[i].Children) > 0 && findSystem == 0 {
|
||||
for j := 0; j < len(list[i].Children); j++ {
|
||||
if len(list[i].Children[j].Children) > 0 {
|
||||
for _, v := range list[i].Children[j].Children {
|
||||
if v.MountPoint == "/" {
|
||||
stor := model.Storage{}
|
||||
stor.MountPoint = v.MountPoint
|
||||
stor.Size = v.FSSize
|
||||
stor.Avail = v.FSAvail
|
||||
stor.Path = v.Path
|
||||
stor.Type = v.FsType
|
||||
stor.DriveName = "System"
|
||||
disk.Model = "System"
|
||||
if strings.Contains(v.SubSystems, "mmc") {
|
||||
disk.DiskType = "MMC"
|
||||
} else if strings.Contains(v.SubSystems, "usb") {
|
||||
disk.DiskType = "USB"
|
||||
}
|
||||
disk.Health = "true"
|
||||
|
||||
disks = append(disks, disk)
|
||||
storage = append(storage, stor)
|
||||
findSystem = 1
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if list[i].Children[j].MountPoint == "/" {
|
||||
stor := model.Storage{}
|
||||
stor.MountPoint = list[i].Children[j].MountPoint
|
||||
stor.Size = list[i].Children[j].FSSize
|
||||
stor.Avail = list[i].Children[j].FSAvail
|
||||
stor.Path = list[i].Children[j].Path
|
||||
stor.Type = list[i].Children[j].FsType
|
||||
stor.DriveName = "System"
|
||||
disk.Model = "System"
|
||||
if strings.Contains(list[i].Children[j].SubSystems, "mmc") {
|
||||
disk.DiskType = "MMC"
|
||||
} else if strings.Contains(list[i].Children[j].SubSystems, "usb") {
|
||||
disk.DiskType = "USB"
|
||||
}
|
||||
disk.Health = "true"
|
||||
|
||||
disks = append(disks, disk)
|
||||
storage = append(storage, stor)
|
||||
findSystem = 1
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if findSystem == 1 {
|
||||
findSystem += 1
|
||||
continue
|
||||
}
|
||||
|
||||
if list[i].Tran == "sata" || list[i].Tran == "nvme" || list[i].Tran == "spi" || list[i].Tran == "sas" || strings.Contains(list[i].SubSystems, "virtio") || (list[i].Tran == "ata" && list[i].Type == "disk") {
|
||||
temp := service.MyService.Disk().SmartCTL(list[i].Path)
|
||||
if reflect.DeepEqual(temp, model.SmartctlA{}) {
|
||||
temp.SmartStatus.Passed = true
|
||||
}
|
||||
isAvail := true
|
||||
for _, v := range list[i].Children {
|
||||
if v.MountPoint != "" {
|
||||
stor := model.Storage{}
|
||||
stor.MountPoint = v.MountPoint
|
||||
stor.Size = v.FSSize
|
||||
stor.Avail = v.FSAvail
|
||||
stor.Path = v.Path
|
||||
stor.Type = v.FsType
|
||||
stor.DriveName = list[i].Name
|
||||
storage = append(storage, stor)
|
||||
isAvail = false
|
||||
}
|
||||
}
|
||||
|
||||
if isAvail {
|
||||
//if len(list[i].Children) == 1 && list[i].Children[0].FsType == "ext4" {
|
||||
disk.NeedFormat = false
|
||||
avail = append(avail, disk)
|
||||
// } else {
|
||||
// disk.NeedFormat = true
|
||||
// avail = append(avail, disk)
|
||||
// }
|
||||
}
|
||||
|
||||
disk.Temperature = temp.Temperature.Current
|
||||
disk.Health = strconv.FormatBool(temp.SmartStatus.Passed)
|
||||
|
||||
disks = append(disks, disk)
|
||||
}
|
||||
}
|
||||
data := make(map[string]interface{}, 3)
|
||||
data["drive"] = disks
|
||||
data["storage"] = storage
|
||||
data["avail"] = avail
|
||||
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||
}
|
||||
|
||||
// @Summary disk list
|
||||
// @Produce application/json
|
||||
// @Accept application/json
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /disk/list [get]
|
||||
func GetDisksUSBList(c *gin.Context) {
|
||||
list := service.MyService.Disk().LSBLK(false)
|
||||
data := []model.DriveUSB{}
|
||||
for _, v := range list {
|
||||
if v.Tran == "usb" {
|
||||
temp := model.DriveUSB{}
|
||||
temp.Model = v.Model
|
||||
temp.Name = v.Label
|
||||
if temp.Name == "" {
|
||||
temp.Name = v.Name
|
||||
}
|
||||
temp.Size = v.Size
|
||||
children := []model.USBChildren{}
|
||||
for _, child := range v.Children {
|
||||
|
||||
if len(child.MountPoint) > 0 {
|
||||
tempChildren := model.USBChildren{}
|
||||
tempChildren.MountPoint = child.MountPoint
|
||||
tempChildren.Size, _ = strconv.ParseUint(child.FSSize, 10, 64)
|
||||
tempChildren.Avail, _ = strconv.ParseUint(child.FSAvail, 10, 64)
|
||||
tempChildren.Name = child.Label
|
||||
if len(tempChildren.Name) == 0 {
|
||||
tempChildren.Name = filepath.Base(child.MountPoint)
|
||||
}
|
||||
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
|
||||
children = append(children, tempChildren)
|
||||
temp.Avail += avail
|
||||
}
|
||||
}
|
||||
|
||||
temp.Children = children
|
||||
data = append(data, temp)
|
||||
}
|
||||
}
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||
|
||||
}
|
||||
|
||||
func DeleteDisksUmount(c *gin.Context) {
|
||||
id := c.GetHeader("user_id")
|
||||
js := make(map[string]string)
|
||||
c.ShouldBind(&js)
|
||||
|
||||
path := js["path"]
|
||||
pwd := js["password"]
|
||||
|
||||
if len(path) == 0 {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
return
|
||||
}
|
||||
user := service.MyService.User().GetUserAllInfoById(id)
|
||||
if user.Id == 0 {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||
return
|
||||
}
|
||||
if encryption.GetMD5ByStr(pwd) != user.Password {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)})
|
||||
return
|
||||
}
|
||||
|
||||
if _, ok := diskMap[path]; ok {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)})
|
||||
return
|
||||
}
|
||||
|
||||
diskInfo := service.MyService.Disk().GetDiskInfo(path)
|
||||
for _, v := range diskInfo.Children {
|
||||
service.MyService.Disk().UmountPointAndRemoveDir(v.Path)
|
||||
//delete data
|
||||
service.MyService.Disk().DeleteMountPoint(v.Path, v.MountPoint)
|
||||
|
||||
service.MyService.Shares().DeleteShareByPath(v.MountPoint)
|
||||
}
|
||||
|
||||
service.MyService.Disk().RemoveLSBLKCache()
|
||||
|
||||
//send notify to client
|
||||
msg := notify.StorageMessage{}
|
||||
msg.Action = "REMOVED"
|
||||
msg.Path = path
|
||||
msg.Volume = ""
|
||||
msg.Size = 0
|
||||
msg.Type = ""
|
||||
service.MyService.Notify().SendStorageBySocket(msg)
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: path})
|
||||
}
|
||||
|
||||
func DeleteDiskUSB(c *gin.Context) {
|
||||
js := make(map[string]string)
|
||||
c.ShouldBind(&js)
|
||||
mountPoint := js["mount_point"]
|
||||
if file.CheckNotExist(mountPoint) {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.DIR_NOT_EXISTS, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS)})
|
||||
return
|
||||
}
|
||||
service.MyService.Disk().UmountUSB(mountPoint)
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: mountPoint})
|
||||
}
|
||||
|
||||
// @Summary get disk list
|
||||
// @Produce application/json
|
||||
// @Accept application/json
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /disk/lists [get]
|
||||
func GetPlugInDisks(c *gin.Context) {
|
||||
|
||||
list := service.MyService.Disk().LSBLK(true)
|
||||
var result []*disk.UsageStat
|
||||
for _, item := range list {
|
||||
result = append(result, service.MyService.Disk().GetDiskInfoByPath(item.Path))
|
||||
}
|
||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: result})
|
||||
}
|
||||
|
||||
// @Summary disk detail
|
||||
// @Produce application/json
|
||||
// @Accept application/json
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @Param path query string true "for example /dev/sda"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /disk/info [get]
|
||||
func GetDiskInfo(c *gin.Context) {
|
||||
path := c.Query("path")
|
||||
if len(path) == 0 {
|
||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
}
|
||||
m := service.MyService.Disk().GetDiskInfo(path)
|
||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: m})
|
||||
}
|
||||
|
||||
// @Summary 获取支持的格式
|
||||
// @Produce application/json
|
||||
// @Accept application/json
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /disk/type [get]
|
||||
func FormatDiskType(c *gin.Context) {
|
||||
var strArr = [4]string{"fat32", "ntfs", "ext4", "exfat"}
|
||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: strArr})
|
||||
|
||||
}
|
||||
|
||||
// @Summary 删除分区
|
||||
// @Produce application/json
|
||||
// @Accept multipart/form-data
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @Param path formData string true "磁盘路径 例如/dev/sda1"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /disk/delpart [delete]
|
||||
func RemovePartition(c *gin.Context) {
|
||||
js := make(map[string]string)
|
||||
c.ShouldBind(&js)
|
||||
path := js["path"]
|
||||
|
||||
if len(path) == 0 {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
}
|
||||
var p = path[:len(path)-1]
|
||||
var n = path[len(path)-1:]
|
||||
service.MyService.Disk().DelPartition(p, n)
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
|
||||
// @Summary add storage
|
||||
// @Produce application/json
|
||||
// @Accept multipart/form-data
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @Param path formData string true "disk path e.g. /dev/sda"
|
||||
// @Param serial formData string true "serial"
|
||||
// @Param name formData string true "name"
|
||||
// @Param format formData bool true "need format(true)"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /disk/storage [post]
|
||||
func PostDiskAddPartition(c *gin.Context) {
|
||||
|
||||
js := make(map[string]interface{})
|
||||
c.ShouldBind(&js)
|
||||
path := js["path"].(string)
|
||||
name := js["name"].(string)
|
||||
format := js["format"].(bool)
|
||||
|
||||
if len(path) == 0 {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
return
|
||||
}
|
||||
if _, ok := diskMap[path]; ok {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)})
|
||||
return
|
||||
}
|
||||
|
||||
//diskInfo := service.MyService.Disk().GetDiskInfo(path)
|
||||
|
||||
// if !file.CheckNotExist("/DATA/" + name) {
|
||||
// // /mnt/name exist
|
||||
// c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.NAME_NOT_AVAILABLE, Message: common_err.GetMsg(common_err.NAME_NOT_AVAILABLE)})
|
||||
// return
|
||||
// }
|
||||
diskMap[path] = "busying"
|
||||
currentDisk := service.MyService.Disk().GetDiskInfo(path)
|
||||
if format {
|
||||
// format := service.MyService.Disk().FormatDisk(path+"1", "ext4")
|
||||
// if len(format) == 0 {
|
||||
// delete(diskMap, path)
|
||||
// c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FORMAT_ERROR, Message: common_err.GetMsg(common_err.FORMAT_ERROR)})
|
||||
// return
|
||||
// }
|
||||
service.MyService.Disk().AddPartition(path)
|
||||
}
|
||||
|
||||
// formatBool := true
|
||||
// for formatBool {
|
||||
// currentDisk = service.MyService.Disk().GetDiskInfo(path)
|
||||
// if len(currentDisk.Children) > 0 {
|
||||
// formatBool = false
|
||||
// break
|
||||
// }
|
||||
// time.Sleep(time.Second)
|
||||
// }
|
||||
currentDisk = service.MyService.Disk().GetDiskInfo(path)
|
||||
// if len(currentDisk.Children) != 1 {
|
||||
// c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_NEEDS_FORMAT, Message: common_err.GetMsg(common_err.DISK_NEEDS_FORMAT)})
|
||||
// return
|
||||
// }
|
||||
fmt.Println(name)
|
||||
if len(name) == 0 {
|
||||
name = "Storage"
|
||||
}
|
||||
fmt.Println(name)
|
||||
for i := 0; i < len(currentDisk.Children); i++ {
|
||||
childrenName := currentDisk.Children[i].Label
|
||||
if len(childrenName) == 0 {
|
||||
//childrenName = name + "_" + currentDisk.Children[i].Name
|
||||
childrenName = name + "_" + strconv.Itoa(i+1)
|
||||
}
|
||||
mountPath := "/DATA/" + childrenName
|
||||
if !file.CheckNotExist(mountPath) {
|
||||
ls := service.MyService.System().GetDirPath(mountPath)
|
||||
if len(ls) > 0 {
|
||||
// exist
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.NAME_NOT_AVAILABLE, Message: common_err.GetMsg(common_err.NAME_NOT_AVAILABLE)})
|
||||
return
|
||||
}
|
||||
}
|
||||
m := model2.SerialDisk{}
|
||||
m.MountPoint = mountPath
|
||||
m.Path = currentDisk.Children[i].Path
|
||||
m.UUID = currentDisk.Children[i].UUID
|
||||
m.State = 0
|
||||
m.CreatedAt = time.Now().Unix()
|
||||
service.MyService.Disk().SaveMountPoint(m)
|
||||
//mount dir
|
||||
service.MyService.Disk().MountDisk(currentDisk.Children[i].Path, mountPath)
|
||||
}
|
||||
|
||||
service.MyService.Disk().RemoveLSBLKCache()
|
||||
|
||||
delete(diskMap, path)
|
||||
|
||||
//send notify to client
|
||||
msg := notify.StorageMessage{}
|
||||
msg.Action = "ADDED"
|
||||
msg.Path = currentDisk.Children[0].Path
|
||||
msg.Volume = "/DATA/"
|
||||
msg.Size = currentDisk.Children[0].Size
|
||||
msg.Type = currentDisk.Children[0].Tran
|
||||
service.MyService.Notify().SendStorageBySocket(msg)
|
||||
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
|
||||
// @Param pwd formData string true "user password"
|
||||
// @Param volume formData string true "mount point"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /disk/format [post]
|
||||
func PostDiskFormat(c *gin.Context) {
|
||||
id := c.GetHeader("user_id")
|
||||
js := make(map[string]string)
|
||||
c.ShouldBind(&js)
|
||||
path := js["path"]
|
||||
t := "ext4"
|
||||
pwd := js["password"]
|
||||
volume := js["volume"]
|
||||
user := service.MyService.User().GetUserAllInfoById(id)
|
||||
if user.Id == 0 {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||
return
|
||||
}
|
||||
if encryption.GetMD5ByStr(pwd) != user.Password {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)})
|
||||
return
|
||||
}
|
||||
|
||||
if len(path) == 0 || len(t) == 0 {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
return
|
||||
}
|
||||
if _, ok := diskMap[path]; ok {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)})
|
||||
return
|
||||
}
|
||||
diskMap[path] = "busying"
|
||||
service.MyService.Disk().UmountPointAndRemoveDir(path)
|
||||
format := service.MyService.Disk().FormatDisk(path, t)
|
||||
if len(format) == 0 {
|
||||
delete(diskMap, path)
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FORMAT_ERROR, Message: common_err.GetMsg(common_err.FORMAT_ERROR)})
|
||||
return
|
||||
}
|
||||
service.MyService.Disk().MountDisk(path, volume)
|
||||
service.MyService.Disk().RemoveLSBLKCache()
|
||||
delete(diskMap, path)
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
|
||||
// @Summary remove mount point
|
||||
// @Produce application/json
|
||||
// @Accept multipart/form-data
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @Param path formData string true "e.g. /dev/sda1"
|
||||
// @Param mount_point formData string true "e.g. /mnt/volume1"
|
||||
// @Param pwd formData string true "user password"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /disk/umount [post]
|
||||
func PostDiskUmount(c *gin.Context) {
|
||||
id := c.GetHeader("user_id")
|
||||
js := make(map[string]string)
|
||||
c.ShouldBind(&js)
|
||||
|
||||
path := js["path"]
|
||||
mountPoint := js["volume"]
|
||||
pwd := js["password"]
|
||||
|
||||
if len(path) == 0 || len(mountPoint) == 0 {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
return
|
||||
}
|
||||
user := service.MyService.User().GetUserAllInfoById(id)
|
||||
if user.Id == 0 {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||
return
|
||||
}
|
||||
if encryption.GetMD5ByStr(pwd) != user.Password {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)})
|
||||
return
|
||||
}
|
||||
|
||||
if _, ok := diskMap[path]; ok {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)})
|
||||
return
|
||||
}
|
||||
|
||||
service.MyService.Disk().UmountPointAndRemoveDir(path)
|
||||
//delete data
|
||||
service.MyService.Disk().DeleteMountPoint(path, mountPoint)
|
||||
service.MyService.Disk().RemoveLSBLKCache()
|
||||
|
||||
//send notify to client
|
||||
msg := notify.StorageMessage{}
|
||||
msg.Action = "REMOVED"
|
||||
msg.Path = path
|
||||
msg.Volume = mountPoint
|
||||
msg.Size = 0
|
||||
msg.Type = ""
|
||||
service.MyService.Notify().SendStorageBySocket(msg)
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
|
||||
// @Summary confirm delete disk
|
||||
// @Produce application/json
|
||||
// @Accept application/json
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @Param id path string true "id"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /disk/remove/{id} [delete]
|
||||
func DeleteDisk(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
service.MyService.Disk().DeleteMount(id)
|
||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
|
||||
// @Summary check mount point
|
||||
// @Produce application/json
|
||||
// @Accept application/json
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /disk/init [get]
|
||||
func GetDiskCheck(c *gin.Context) {
|
||||
|
||||
dbList := service.MyService.Disk().GetSerialAll()
|
||||
list := service.MyService.Disk().LSBLK(true)
|
||||
|
||||
mapList := make(map[string]string)
|
||||
|
||||
for _, v := range list {
|
||||
mapList[v.Serial] = "1"
|
||||
}
|
||||
|
||||
for _, v := range dbList {
|
||||
if _, ok := mapList[v.UUID]; !ok {
|
||||
//disk undefind
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: "disk undefind"})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
285
service/disk.go
285
service/disk.go
@ -1,285 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
json2 "encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||
command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||
"github.com/shirou/gopsutil/v3/disk"
|
||||
"github.com/tidwall/gjson"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type DiskService interface {
|
||||
GetPlugInDisk() []string
|
||||
LSBLK(isUseCache bool) []model.LSBLKModel
|
||||
SmartCTL(path string) model.SmartctlA
|
||||
FormatDisk(path, format string) []string
|
||||
UmountPointAndRemoveDir(path string) []string
|
||||
GetDiskInfo(path string) model.LSBLKModel
|
||||
DelPartition(path, num string) string
|
||||
AddPartition(path string) string
|
||||
GetDiskInfoByPath(path string) *disk.UsageStat
|
||||
MountDisk(path, volume string)
|
||||
GetSerialAll() []model2.SerialDisk
|
||||
SaveMountPoint(m model2.SerialDisk)
|
||||
DeleteMountPoint(path, mountPoint string)
|
||||
DeleteMount(id string)
|
||||
UpdateMountPoint(m model2.SerialDisk)
|
||||
RemoveLSBLKCache()
|
||||
UmountUSB(path string)
|
||||
}
|
||||
type diskService struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func (d *diskService) RemoveLSBLKCache() {
|
||||
key := "system_lsblk"
|
||||
Cache.Delete(key)
|
||||
}
|
||||
func (d *diskService) UmountUSB(path string) {
|
||||
r := command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;UDEVILUmount " + path)
|
||||
fmt.Println(r)
|
||||
}
|
||||
func (d *diskService) SmartCTL(path string) model.SmartctlA {
|
||||
|
||||
key := "system_smart_" + path
|
||||
if result, ok := Cache.Get(key); ok {
|
||||
|
||||
res, ok := result.(model.SmartctlA)
|
||||
if ok {
|
||||
return res
|
||||
}
|
||||
}
|
||||
var m model.SmartctlA
|
||||
str := command2.ExecSmartCTLByPath(path)
|
||||
if str == nil {
|
||||
loger.Error("failed to exec shell ", zap.Any("err", "smartctl exec error"))
|
||||
Cache.Add(key, m, time.Minute*10)
|
||||
return m
|
||||
}
|
||||
|
||||
err := json2.Unmarshal([]byte(str), &m)
|
||||
if err != nil {
|
||||
loger.Error("Failed to unmarshal json", zap.Any("err", err))
|
||||
}
|
||||
if !reflect.DeepEqual(m, model.SmartctlA{}) {
|
||||
Cache.Add(key, m, time.Hour*24)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
//通过脚本获取外挂磁盘
|
||||
func (d *diskService) GetPlugInDisk() []string {
|
||||
return command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;GetPlugInDisk")
|
||||
}
|
||||
|
||||
//格式化硬盘
|
||||
func (d *diskService) FormatDisk(path, format string) []string {
|
||||
r := command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;FormatDisk " + path + " " + format)
|
||||
return r
|
||||
}
|
||||
|
||||
//移除挂载点,删除目录
|
||||
func (d *diskService) UmountPointAndRemoveDir(path string) []string {
|
||||
r := command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;UMountPorintAndRemoveDir " + path)
|
||||
return r
|
||||
}
|
||||
|
||||
//删除分区
|
||||
func (d *diskService) DelPartition(path, num string) string {
|
||||
r := command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;DelPartition " + path + " " + num)
|
||||
fmt.Println(r)
|
||||
return ""
|
||||
}
|
||||
|
||||
//part
|
||||
func (d *diskService) AddPartition(path string) string {
|
||||
command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;AddPartition " + path)
|
||||
return ""
|
||||
}
|
||||
|
||||
func (d *diskService) AddAllPartition(path string) {
|
||||
|
||||
}
|
||||
|
||||
//获取硬盘详情
|
||||
func (d *diskService) GetDiskInfoByPath(path string) *disk.UsageStat {
|
||||
diskInfo, err := disk.Usage(path + "1")
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
diskInfo.UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.UsedPercent), 64)
|
||||
diskInfo.InodesUsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.InodesUsedPercent), 64)
|
||||
return diskInfo
|
||||
}
|
||||
|
||||
//get disk details
|
||||
func (d *diskService) LSBLK(isUseCache bool) []model.LSBLKModel {
|
||||
key := "system_lsblk"
|
||||
var n []model.LSBLKModel
|
||||
|
||||
if result, ok := Cache.Get(key); ok && isUseCache {
|
||||
|
||||
res, ok := result.([]model.LSBLKModel)
|
||||
if ok {
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
str := command2.ExecLSBLK()
|
||||
if str == nil {
|
||||
loger.Error("Failed to exec shell", zap.Any("err", "lsblk exec error"))
|
||||
return nil
|
||||
}
|
||||
var m []model.LSBLKModel
|
||||
err := json2.Unmarshal([]byte(gjson.Get(string(str), "blockdevices").String()), &m)
|
||||
if err != nil {
|
||||
loger.Error("Failed to unmarshal json", zap.Any("err", err))
|
||||
}
|
||||
|
||||
var c []model.LSBLKModel
|
||||
|
||||
var fsused uint64
|
||||
|
||||
var health = true
|
||||
for _, i := range m {
|
||||
if i.Type != "loop" && !i.RO {
|
||||
fsused = 0
|
||||
for _, child := range i.Children {
|
||||
if child.RM {
|
||||
child.Health = strings.TrimSpace(command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;GetDiskHealthState " + child.Path))
|
||||
if strings.ToLower(strings.TrimSpace(child.State)) != "ok" {
|
||||
health = false
|
||||
}
|
||||
f, _ := strconv.ParseUint(child.FSUsed, 10, 64)
|
||||
fsused += f
|
||||
} else {
|
||||
health = false
|
||||
}
|
||||
c = append(c, child)
|
||||
}
|
||||
//i.Format = strings.TrimSpace(command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;GetDiskType " + i.Path))
|
||||
if health {
|
||||
i.Health = "OK"
|
||||
}
|
||||
i.FSUsed = strconv.FormatUint(fsused, 10)
|
||||
i.Children = c
|
||||
if fsused > 0 {
|
||||
i.UsedPercent, err = strconv.ParseFloat(fmt.Sprintf("%.4f", float64(fsused)/float64(i.Size)), 64)
|
||||
if err != nil {
|
||||
loger.Error("Failed to parse float", zap.Any("err", err))
|
||||
}
|
||||
}
|
||||
n = append(n, i)
|
||||
health = true
|
||||
c = []model.LSBLKModel{}
|
||||
fsused = 0
|
||||
}
|
||||
}
|
||||
if len(n) > 0 {
|
||||
Cache.Add(key, n, time.Second*100)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (d *diskService) GetDiskInfo(path string) model.LSBLKModel {
|
||||
str := command2.ExecLSBLKByPath(path)
|
||||
if str == nil {
|
||||
loger.Error("Failed to exec shell", zap.Any("err", "lsblk exec error"))
|
||||
return model.LSBLKModel{}
|
||||
}
|
||||
|
||||
var ml []model.LSBLKModel
|
||||
err := json2.Unmarshal([]byte(gjson.Get(string(str), "blockdevices").String()), &ml)
|
||||
if err != nil {
|
||||
loger.Error("Failed to unmarshal json", zap.Any("err", err))
|
||||
return model.LSBLKModel{}
|
||||
}
|
||||
|
||||
m := model.LSBLKModel{}
|
||||
if len(ml) > 0 {
|
||||
m = ml[0]
|
||||
}
|
||||
return m
|
||||
// 下面为计算是否可以继续分区的部分,暂时不需要
|
||||
chiArr := make(map[string]string)
|
||||
chiList := command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;GetPartitionSectors " + m.Path)
|
||||
if len(chiList) == 0 {
|
||||
loger.Error("chiList length error", zap.Any("err", "chiList length error"))
|
||||
}
|
||||
for i := 0; i < len(chiList); i++ {
|
||||
tempArr := strings.Split(chiList[i], ",")
|
||||
chiArr[tempArr[0]] = chiList[i]
|
||||
}
|
||||
var maxSector uint64 = 0
|
||||
for i := 0; i < len(m.Children); i++ {
|
||||
tempArr := strings.Split(chiArr[m.Children[i].Path], ",")
|
||||
m.Children[i].StartSector, _ = strconv.ParseUint(tempArr[1], 10, 64)
|
||||
m.Children[i].EndSector, _ = strconv.ParseUint(tempArr[2], 10, 64)
|
||||
if m.Children[i].EndSector > maxSector {
|
||||
maxSector = m.Children[i].EndSector
|
||||
}
|
||||
|
||||
}
|
||||
diskEndSector := command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;GetDiskSizeAndSectors " + m.Path)
|
||||
|
||||
if len(diskEndSector) < 2 {
|
||||
loger.Error("diskEndSector length error", zap.Any("err", "diskEndSector length error"))
|
||||
}
|
||||
diskEndSectorInt, _ := strconv.ParseUint(diskEndSector[len(diskEndSector)-1], 10, 64)
|
||||
if (diskEndSectorInt-maxSector)*m.MinIO/1024/1024 > 100 {
|
||||
//添加可以分区情况
|
||||
p := model.LSBLKModel{}
|
||||
p.Path = "可以添加"
|
||||
m.Children = append(m.Children, p)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func (d *diskService) MountDisk(path, volume string) {
|
||||
//fmt.Println("source " + config.AppInfo.ShellPath + "/helper.sh ;do_mount " + path + " " + volume)
|
||||
r := command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;do_mount " + path + " " + volume)
|
||||
fmt.Println(r)
|
||||
}
|
||||
|
||||
func (d *diskService) SaveMountPoint(m model2.SerialDisk) {
|
||||
d.db.Where("uuid = ?", m.UUID).Delete(&model2.SerialDisk{})
|
||||
d.db.Create(&m)
|
||||
}
|
||||
|
||||
func (d *diskService) UpdateMountPoint(m model2.SerialDisk) {
|
||||
d.db.Model(&model2.SerialDisk{}).Where("uui = ?", m.UUID).Update("mount_point", m.MountPoint)
|
||||
}
|
||||
|
||||
func (d *diskService) DeleteMount(id string) {
|
||||
|
||||
d.db.Delete(&model2.SerialDisk{}).Where("id = ?", id)
|
||||
}
|
||||
|
||||
func (d *diskService) DeleteMountPoint(path, mountPoint string) {
|
||||
|
||||
d.db.Where("path = ? AND mount_point = ?", path, mountPoint).Delete(&model2.SerialDisk{})
|
||||
|
||||
command2.OnlyExec("source " + config.AppInfo.ShellPath + "/helper.sh ;do_umount " + path)
|
||||
}
|
||||
|
||||
func (d *diskService) GetSerialAll() []model2.SerialDisk {
|
||||
var m []model2.SerialDisk
|
||||
d.db.Find(&m)
|
||||
return m
|
||||
}
|
||||
|
||||
func NewDiskService(db *gorm.DB) DiskService {
|
||||
return &diskService{db: db}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* @Author: LinkLeong link@icewhale.org
|
||||
* @Date: 2021-12-07 17:14:41
|
||||
* @LastEditors: LinkLeong
|
||||
* @LastEditTime: 2022-08-17 18:46:43
|
||||
* @FilePath: /CasaOS/service/model/o_disk.go
|
||||
* @Description:
|
||||
* @Website: https://www.casaos.io
|
||||
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||
*/
|
||||
package model
|
||||
|
||||
//SerialAdvanced Technology Attachment (STAT)
|
||||
type SerialDisk struct {
|
||||
Id uint `gorm:"column:id;primary_key" json:"id"`
|
||||
UUID string `json:"uuid"`
|
||||
Path string `json:"path"`
|
||||
State int `json:"state"`
|
||||
MountPoint string `json:"mount_point"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
}
|
||||
|
||||
func (p *SerialDisk) TableName() string {
|
||||
return "o_disk"
|
||||
}
|
||||
@ -21,16 +21,17 @@ var Cache *cache.Cache
|
||||
|
||||
var MyService Repository
|
||||
|
||||
var WebSocketConns []*websocket.Conn
|
||||
var NewVersionApp map[string]string
|
||||
var SocketRun bool
|
||||
var (
|
||||
WebSocketConns []*websocket.Conn
|
||||
NewVersionApp map[string]string
|
||||
SocketRun bool
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
App() AppService
|
||||
User() UserService
|
||||
Docker() DockerService
|
||||
Casa() CasaService
|
||||
Disk() DiskService
|
||||
Notify() NotifyServer
|
||||
Rely() RelyService
|
||||
System() SystemService
|
||||
@ -51,7 +52,6 @@ func NewService(db *gorm.DB, RuntimePath string) Repository {
|
||||
user: NewUserService(db),
|
||||
docker: NewDockerService(),
|
||||
casa: NewCasaService(),
|
||||
disk: NewDiskService(db),
|
||||
notify: NewNotifyService(db),
|
||||
rely: NewRelyService(db),
|
||||
system: NewSystemService(),
|
||||
@ -66,7 +66,6 @@ type store struct {
|
||||
user UserService
|
||||
docker DockerService
|
||||
casa CasaService
|
||||
disk DiskService
|
||||
notify NotifyServer
|
||||
rely RelyService
|
||||
system SystemService
|
||||
@ -78,9 +77,11 @@ type store struct {
|
||||
func (c *store) Gateway() gateway.ManagementService {
|
||||
return c.gateway
|
||||
}
|
||||
|
||||
func (s *store) Connections() ConnectionsService {
|
||||
return s.connections
|
||||
}
|
||||
|
||||
func (s *store) Shares() SharesService {
|
||||
return s.shares
|
||||
}
|
||||
@ -92,8 +93,8 @@ func (c *store) Rely() RelyService {
|
||||
func (c *store) System() SystemService {
|
||||
return c.system
|
||||
}
|
||||
func (c *store) Notify() NotifyServer {
|
||||
|
||||
func (c *store) Notify() NotifyServer {
|
||||
return c.notify
|
||||
}
|
||||
|
||||
@ -112,7 +113,3 @@ func (c *store) Docker() DockerService {
|
||||
func (c *store) Casa() CasaService {
|
||||
return c.casa
|
||||
}
|
||||
|
||||
func (c *store) Disk() DiskService {
|
||||
return c.disk
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user