Storage Manager
Fix the app store classification problem Fix the application market classification problem
This commit is contained in:
parent
9675eff69e
commit
fcb906aa85
15 changed files with 482 additions and 120 deletions
|
@ -21,6 +21,7 @@ type LSBLKModel struct {
|
|||
Health string `json:"health"`
|
||||
HotPlug bool `json:"hotplug"`
|
||||
FSUsed string `json:"fsused"`
|
||||
Temperature int `json:"temperature"`
|
||||
Tran string `json:"tran"`
|
||||
MinIO uint64 `json:"min-io"`
|
||||
UsedPercent float64 `json:"used_percent"`
|
||||
|
@ -28,5 +29,7 @@ type LSBLKModel struct {
|
|||
Children []LSBLKModel `json:"children"`
|
||||
//详情特有
|
||||
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"`
|
||||
}
|
||||
|
|
69
model/smartctl_model.go
Normal file
69
model/smartctl_model.go
Normal file
|
@ -0,0 +1,69 @@
|
|||
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,9 +2,11 @@ package command
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os/exec"
|
||||
"time"
|
||||
)
|
||||
|
||||
func OnlyExec(cmdStr string) {
|
||||
|
@ -85,7 +87,26 @@ func ExecLSBLK() []byte {
|
|||
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()
|
||||
}
|
||||
|
|
|
@ -21,6 +21,13 @@ const (
|
|||
//zerotier
|
||||
GET_TOKEN_ERROR = 30001
|
||||
|
||||
//disk
|
||||
NAME_NOT_AVAILABLE = 40001
|
||||
DISK_NEEDS_FORMAT = 40002
|
||||
DISK_BUSYING = 40003
|
||||
REMOVE_MOUNT_POINT_ERROR = 40004
|
||||
FORMAT_ERROR = 40005
|
||||
|
||||
//app
|
||||
UNINSTALL_APP_ERROR = 50001
|
||||
PULL_IMAGE_ERROR = 50002
|
||||
|
@ -37,34 +44,41 @@ const (
|
|||
var MsgFlags = map[int]string{
|
||||
SUCCESS: "ok",
|
||||
ERROR: "fail",
|
||||
INVALID_PARAMS: "Invalid params",
|
||||
ERROR_AUTH_TOKEN: "error auth token",
|
||||
INVALID_PARAMS: "Parameters Error",
|
||||
ERROR_AUTH_TOKEN: "Error auth token",
|
||||
|
||||
//user
|
||||
PWD_INVALID: "Password invalid",
|
||||
PWD_INVALID: "Invalid password",
|
||||
PWD_IS_EMPTY: "Password is empty",
|
||||
PWD_INVALID_OLD: "Old Password invalid",
|
||||
ACCOUNT_LOCK: "Account Lock",
|
||||
PWD_INVALID_OLD: "Invalid old password",
|
||||
ACCOUNT_LOCK: "Account is locked",
|
||||
|
||||
//system
|
||||
DIR_ALREADY_EXISTS: "Directory already exists",
|
||||
DIR_ALREADY_EXISTS: "Folder already exists",
|
||||
FILE_ALREADY_EXISTS: "File already exists",
|
||||
FILE_OR_DIR_EXISTS: "File or directory already exists",
|
||||
FILE_OR_DIR_EXISTS: "File or folder already exists",
|
||||
PORT_IS_OCCUPIED: "Port is occupied",
|
||||
|
||||
//zerotier
|
||||
GET_TOKEN_ERROR: "Get token error,Please log in to zerotier's official website to confirm whether the account is available",
|
||||
|
||||
//app
|
||||
UNINSTALL_APP_ERROR: "uninstall app error",
|
||||
PULL_IMAGE_ERROR: "pull image error",
|
||||
DEVICE_NOT_EXIST: "device not exist",
|
||||
UNINSTALL_APP_ERROR: "Error uninstalling app",
|
||||
PULL_IMAGE_ERROR: "Error pulling image",
|
||||
DEVICE_NOT_EXIST: "Device does not exist",
|
||||
|
||||
//disk
|
||||
NAME_NOT_AVAILABLE: "Name not available",
|
||||
DISK_NEEDS_FORMAT: "Drive needs to be formatted",
|
||||
REMOVE_MOUNT_POINT_ERROR: "Failed to remove mount point",
|
||||
DISK_BUSYING: "Drive is busy",
|
||||
FORMAT_ERROR: "Formatting failed, please check if the directory is occupied",
|
||||
|
||||
//
|
||||
FILE_DOES_NOT_EXIST: "file does not exist",
|
||||
FILE_DOES_NOT_EXIST: "File does not exist",
|
||||
|
||||
FILE_READ_ERROR: "file read error",
|
||||
SHORTCUTS_URL_ERROR: "url error",
|
||||
FILE_READ_ERROR: "File read error",
|
||||
SHORTCUTS_URL_ERROR: "URL error",
|
||||
}
|
||||
|
||||
//获取错误信息
|
||||
|
|
|
@ -3,6 +3,7 @@ package route
|
|||
import (
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
|
@ -34,10 +35,9 @@ func installSyncthing(appId string) {
|
|||
m := model.CustomizationPostData{}
|
||||
var dockerImage string
|
||||
var dockerImageVersion string
|
||||
|
||||
appInfo = service.MyService.OAPI().GetServerAppInfo(appId)
|
||||
|
||||
appInfo = service.MyService.OAPI().GetServerAppInfo(appId, "system")
|
||||
dockerImage = appInfo.Image
|
||||
dockerImageVersion = appInfo.ImageVersion
|
||||
|
||||
if len(appInfo.ImageVersion) == 0 {
|
||||
dockerImageVersion = "latest"
|
||||
|
@ -84,9 +84,9 @@ func installSyncthing(appId string) {
|
|||
err := service.MyService.Docker().DockerPullImage(dockerImage+":"+dockerImageVersion, installLog)
|
||||
if err != nil {
|
||||
//pull image error
|
||||
fmt.Println("pull image error", err, dockerImage, dockerImageVersion)
|
||||
return
|
||||
}
|
||||
|
||||
for !service.MyService.Docker().IsExistImage(dockerImage + ":" + dockerImageVersion) {
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
|
@ -101,8 +101,8 @@ func installSyncthing(appId string) {
|
|||
m.Volumes = appInfo.Volumes
|
||||
|
||||
containerId, err := service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, id, m, appInfo.NetworkModel)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("container create error", err)
|
||||
// create container error
|
||||
return
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ func checkSystemApp() {
|
|||
path := ""
|
||||
for _, i := range paths {
|
||||
if i.ContainerPath == "/config" {
|
||||
path = docker.GetDir(v.CustomId, i.Path) + "config.xml"
|
||||
path = docker.GetDir(v.CustomId, i.Path) + "/config.xml"
|
||||
for i := 0; i < 10; i++ {
|
||||
if file.CheckNotExist(path) {
|
||||
time.Sleep(1 * time.Second)
|
||||
|
@ -197,21 +197,37 @@ func CheckSerialDiskMount() {
|
|||
|
||||
list := service.MyService.Disk().LSBLK()
|
||||
mountPoint := make(map[string]string, len(dbList))
|
||||
|
||||
//remount
|
||||
for _, v := range dbList {
|
||||
mountPoint[v.Path] = v.MountPoint
|
||||
}
|
||||
for _, v := range list {
|
||||
command.ExecEnabledSMART(v.Path)
|
||||
if v.Children != nil {
|
||||
for _, h := range v.Children {
|
||||
mountPoint[h.MountPoint] = "1"
|
||||
if len(h.MountPoint) == 0 && len(v.Children) == 1 && h.FsType == "ext4" {
|
||||
if m, ok := mountPoint[h.Path]; ok {
|
||||
//mount point check
|
||||
volume := m
|
||||
if !file.CheckNotExist(m) {
|
||||
for i := 0; file.CheckNotExist(volume); i++ {
|
||||
volume = m + strconv.Itoa(i+1)
|
||||
}
|
||||
}
|
||||
service.MyService.Disk().MountDisk(h.Path, volume)
|
||||
if volume != m {
|
||||
ms := model2.SerialDisk{}
|
||||
ms.Serial = v.Serial
|
||||
service.MyService.Disk().UpdateMountPoint(ms)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//remount
|
||||
for _, item := range dbList {
|
||||
if _, ok := mountPoint[item.MountPoint]; !ok {
|
||||
service.MyService.Disk().MountDisk(item.Path, item.MountPoint)
|
||||
}
|
||||
}
|
||||
service.MyService.Disk().RemoveLSBLKCache()
|
||||
command.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;AutoRemoveUnuseDir")
|
||||
|
||||
}
|
||||
func Update2_3() {
|
||||
|
|
|
@ -218,17 +218,23 @@ func InitRouter() *gin.Engine {
|
|||
v1DiskGroup.Use()
|
||||
{
|
||||
v1DiskGroup.GET("/check", v1.GetDiskCheck)
|
||||
//获取磁盘列表
|
||||
v1DiskGroup.GET("/list", v1.GetPlugInDisk)
|
||||
|
||||
v1DiskGroup.GET("/list", v1.GetDiskList)
|
||||
|
||||
//获取磁盘详情
|
||||
v1DiskGroup.GET("/info", v1.GetDiskInfo)
|
||||
|
||||
//格式化磁盘
|
||||
//format storage
|
||||
v1DiskGroup.POST("/format", v1.FormatDisk)
|
||||
|
||||
//添加分区
|
||||
v1DiskGroup.POST("/part", v1.AddPartition)
|
||||
// add storage
|
||||
v1DiskGroup.POST("/storage", v1.AddPartition)
|
||||
|
||||
//mount SATA disk
|
||||
v1DiskGroup.POST("/mount", v1.PostMountDisk)
|
||||
|
||||
//umount sata disk
|
||||
v1DiskGroup.POST("/umount", v1.PostDiskUmount)
|
||||
|
||||
//获取可以格式化的内容
|
||||
v1DiskGroup.GET("/type", v1.FormatDiskType)
|
||||
|
@ -236,12 +242,6 @@ func InitRouter() *gin.Engine {
|
|||
//删除分区
|
||||
v1DiskGroup.DELETE("/delpart", v1.RemovePartition)
|
||||
|
||||
//mount SATA disk
|
||||
v1DiskGroup.POST("/mount", v1.PostMountDisk)
|
||||
|
||||
//umount SATA disk
|
||||
v1DiskGroup.POST("/umount", v1.PostDiskUmount)
|
||||
v1DiskGroup.DELETE("/remove/:id", v1.DeleteDisk)
|
||||
}
|
||||
v1ShareGroup := v1Group.Group("/share")
|
||||
v1ShareGroup.Use()
|
||||
|
|
|
@ -36,24 +36,24 @@ func AppList(c *gin.Context) {
|
|||
categoryId := c.DefaultQuery("category_id", "0")
|
||||
key := c.DefaultQuery("key", "")
|
||||
recommend, list, community := service.MyService.OAPI().GetServerList(index, size, t, categoryId, key)
|
||||
for i := 0; i < len(recommend); i++ {
|
||||
ct, _ := service.MyService.Docker().DockerListByImage(recommend[i].Image, recommend[i].ImageVersion)
|
||||
if ct != nil {
|
||||
list[i].State = ct.State
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(list); i++ {
|
||||
ct, _ := service.MyService.Docker().DockerListByImage(list[i].Image, list[i].ImageVersion)
|
||||
if ct != nil {
|
||||
list[i].State = ct.State
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(community); i++ {
|
||||
ct, _ := service.MyService.Docker().DockerListByImage(community[i].Image, community[i].ImageVersion)
|
||||
if ct != nil {
|
||||
list[i].State = ct.State
|
||||
}
|
||||
}
|
||||
// for i := 0; i < len(recommend); i++ {
|
||||
// ct, _ := service.MyService.Docker().DockerListByImage(recommend[i].Image, recommend[i].ImageVersion)
|
||||
// if ct != nil {
|
||||
// recommend[i].State = ct.State
|
||||
// }
|
||||
// }
|
||||
// for i := 0; i < len(list); i++ {
|
||||
// ct, _ := service.MyService.Docker().DockerListByImage(list[i].Image, list[i].ImageVersion)
|
||||
// if ct != nil {
|
||||
// list[i].State = ct.State
|
||||
// }
|
||||
// }
|
||||
// for i := 0; i < len(community); i++ {
|
||||
// ct, _ := service.MyService.Docker().DockerListByImage(community[i].Image, community[i].ImageVersion)
|
||||
// if ct != nil {
|
||||
// community[i].State = ct.State
|
||||
// }
|
||||
// }
|
||||
data := make(map[string]interface{}, 3)
|
||||
data["recommend"] = recommend
|
||||
data["list"] = list
|
||||
|
@ -137,7 +137,7 @@ func AppUsageList(c *gin.Context) {
|
|||
func AppInfo(c *gin.Context) {
|
||||
|
||||
id := c.Param("id")
|
||||
info := service.MyService.OAPI().GetServerAppInfo(id)
|
||||
info := service.MyService.OAPI().GetServerAppInfo(id, "")
|
||||
if info.NetworkModel != "host" {
|
||||
for i := 0; i < len(info.Ports); i++ {
|
||||
if p, _ := strconv.Atoi(info.Ports[i].ContainerPort); port2.IsPortAvailable(p, info.Ports[i].Protocol) {
|
||||
|
|
159
route/v1/disk.go
159
route/v1/disk.go
|
@ -2,9 +2,13 @@ package v1
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||
|
@ -12,18 +16,53 @@ import (
|
|||
"github.com/shirou/gopsutil/v3/disk"
|
||||
)
|
||||
|
||||
// @Summary 获取磁盘列表
|
||||
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 GetPlugInDisk(c *gin.Context) {
|
||||
|
||||
func GetDiskList(c *gin.Context) {
|
||||
list := service.MyService.Disk().LSBLK()
|
||||
newList := []model.LSBLKModel{}
|
||||
for i := len(list) - 1; i >= 0; i-- {
|
||||
if list[i].Rota {
|
||||
list[i].DiskType = "HDD"
|
||||
} else {
|
||||
list[i].DiskType = "SSD"
|
||||
}
|
||||
if list[i].Tran == "sata" {
|
||||
temp := service.MyService.Disk().SmartCTL(list[i].Path)
|
||||
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: list})
|
||||
if reflect.DeepEqual(temp, model.SmartctlA{}) {
|
||||
continue
|
||||
}
|
||||
if len(list[i].Children) == 1 && len(list[i].Children[0].MountPoint) > 0 {
|
||||
pathArr := strings.Split(list[i].Children[0].MountPoint, "/")
|
||||
if len(pathArr) == 3 {
|
||||
list[i].Children[0].Name = pathArr[2]
|
||||
}
|
||||
}
|
||||
|
||||
list[i].Temperature = temp.Temperature.Current
|
||||
list[i].Health = strconv.FormatBool(temp.SmartStatus.Passed)
|
||||
|
||||
newList = append(newList, list[i])
|
||||
} else if len(list[i].Children) > 0 && list[i].Children[0].MountPoint == "/" {
|
||||
//system
|
||||
list[i].Children[0].Name = "System"
|
||||
list[i].Model = "System"
|
||||
list[i].DiskType = "EMMC"
|
||||
list[i].Health = "true"
|
||||
newList = append(newList, list[i])
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: newList})
|
||||
}
|
||||
|
||||
// @Summary get disk list
|
||||
|
@ -60,25 +99,46 @@ func GetDiskInfo(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: m})
|
||||
}
|
||||
|
||||
// @Summary format disk
|
||||
// @Summary format storage
|
||||
// @Produce application/json
|
||||
// @Accept multipart/form-data
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @Param path formData string true "for example /dev/sda1"
|
||||
// @Param path formData string true "e.g. /dev/sda1"
|
||||
// @Param pwd formData string true "user password"
|
||||
// @Param volume formData string true "mount point"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /disk/format [post]
|
||||
func FormatDisk(c *gin.Context) {
|
||||
path := c.PostForm("path")
|
||||
t := "ext4"
|
||||
pwd := c.PostForm("pwd")
|
||||
volume := c.PostForm("volume")
|
||||
|
||||
t := c.PostForm("type")
|
||||
if pwd != config.UserInfo.PWD {
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.PWD_INVALID, Message: oasis_err.GetMsg(oasis_err.PWD_INVALID)})
|
||||
return
|
||||
}
|
||||
|
||||
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)})
|
||||
return
|
||||
}
|
||||
service.MyService.Disk().FormatDisk(path, t)
|
||||
|
||||
if _, ok := diskMap[path]; ok {
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.DISK_BUSYING, Message: oasis_err.GetMsg(oasis_err.DISK_BUSYING)})
|
||||
return
|
||||
}
|
||||
diskMap[path] = "busying"
|
||||
service.MyService.Disk().UmountPointAndRemoveDir(path)
|
||||
format := service.MyService.Disk().FormatDisk(path, t)
|
||||
if len(format) == 0 {
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.FORMAT_ERROR, Message: oasis_err.GetMsg(oasis_err.FORMAT_ERROR)})
|
||||
delete(diskMap, path)
|
||||
return
|
||||
}
|
||||
service.MyService.Disk().MountDisk(path, volume)
|
||||
service.MyService.Disk().RemoveLSBLKCache()
|
||||
delete(diskMap, path)
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
||||
}
|
||||
|
||||
|
@ -115,23 +175,64 @@ func RemovePartition(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
||||
}
|
||||
|
||||
// @Summary serial number
|
||||
// @Summary add storage
|
||||
// @Produce application/json
|
||||
// @Accept multipart/form-data
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @Param path formData string true "磁盘路径 例如/dev/sda"
|
||||
// @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/addpart [post]
|
||||
// @Router /disk/storage [post]
|
||||
func AddPartition(c *gin.Context) {
|
||||
name := c.PostForm("name")
|
||||
path := c.PostForm("path")
|
||||
serial := c.PostForm("serial")
|
||||
if len(path) == 0 || len(serial) == 0 {
|
||||
format, _ := strconv.ParseBool(c.PostForm("format"))
|
||||
if len(name) == 0 || 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
|
||||
}
|
||||
service.MyService.Disk().AddPartition(path)
|
||||
if _, ok := diskMap[serial]; ok {
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.DISK_BUSYING, Message: oasis_err.GetMsg(oasis_err.DISK_BUSYING)})
|
||||
return
|
||||
}
|
||||
if !file.CheckNotExist("/mnt/" + name) {
|
||||
// /mnt/name exist
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.NAME_NOT_AVAILABLE, Message: oasis_err.GetMsg(oasis_err.NAME_NOT_AVAILABLE)})
|
||||
return
|
||||
}
|
||||
diskMap[serial] = "busying"
|
||||
currentDisk := service.MyService.Disk().GetDiskInfo(path)
|
||||
if !format {
|
||||
if len(currentDisk.Children) != 1 || !(len(currentDisk.Children) > 0 && currentDisk.Children[0].FsType == "ext4") {
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.DISK_NEEDS_FORMAT, Message: oasis_err.GetMsg(oasis_err.DISK_NEEDS_FORMAT)})
|
||||
delete(diskMap, serial)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
service.MyService.Disk().AddPartition(path)
|
||||
}
|
||||
|
||||
mountPath := "/mnt/" + name
|
||||
|
||||
service.MyService.Disk().MountDisk(path, mountPath)
|
||||
|
||||
m := model2.SerialDisk{}
|
||||
m.MountPoint = mountPath
|
||||
m.Path = path + "1"
|
||||
m.Serial = serial
|
||||
m.State = 0
|
||||
service.MyService.Disk().SaveMountPoint(m)
|
||||
|
||||
//mount dir
|
||||
service.MyService.Disk().MountDisk(path+"1", mountPath)
|
||||
|
||||
service.MyService.Disk().RemoveLSBLKCache()
|
||||
|
||||
delete(diskMap, serial)
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
||||
}
|
||||
|
||||
|
@ -165,13 +266,13 @@ func PostMountDisk(c *gin.Context) {
|
|||
|
||||
//mount dir
|
||||
service.MyService.Disk().MountDisk(path, mountPath)
|
||||
//save to data
|
||||
|
||||
m := model2.SerialDisk{}
|
||||
m.MountPoint = mountPath
|
||||
m.Path = path
|
||||
m.Serial = serial
|
||||
m.State = 0
|
||||
service.MyService.Disk().SaveMountPoint(m)
|
||||
//service.MyService.Disk().SaveMountPoint(m)
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
||||
}
|
||||
|
||||
|
@ -180,19 +281,35 @@ func PostMountDisk(c *gin.Context) {
|
|||
// @Accept multipart/form-data
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @Param path formData string true "for example: /dev/sda1"
|
||||
// @Param mount_point formData string true "for example: /mnt/volume1"
|
||||
// @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) {
|
||||
|
||||
//
|
||||
path := c.PostForm("path")
|
||||
mountPoint := c.PostForm("mount_point")
|
||||
service.MyService.Disk().UmountPointAndRemoveDir(path)
|
||||
mountPoint := c.PostForm("volume")
|
||||
pwd := c.PostForm("pwd")
|
||||
|
||||
if len(path) == 0 || len(mountPoint) == 0 {
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
|
||||
return
|
||||
}
|
||||
if pwd != config.UserInfo.PWD {
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.PWD_INVALID, Message: oasis_err.GetMsg(oasis_err.PWD_INVALID)})
|
||||
return
|
||||
}
|
||||
|
||||
if _, ok := diskMap[path]; ok {
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.DISK_BUSYING, Message: oasis_err.GetMsg(oasis_err.DISK_BUSYING)})
|
||||
return
|
||||
}
|
||||
|
||||
service.MyService.Disk().UmountPointAndRemoveDir(path)
|
||||
//delete data
|
||||
service.MyService.Disk().DeleteMountPoint(path, mountPoint)
|
||||
service.MyService.Disk().RemoveLSBLKCache()
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
||||
}
|
||||
|
||||
|
|
|
@ -174,7 +174,7 @@ func InstallApp(c *gin.Context) {
|
|||
dockerImageVersion = "latest"
|
||||
}
|
||||
if m.Origin != "custom" {
|
||||
appInfo = service.MyService.OAPI().GetServerAppInfo(appId)
|
||||
appInfo = service.MyService.OAPI().GetServerAppInfo(appId, "")
|
||||
|
||||
} else {
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -107,9 +108,33 @@ func GetSystemConfigDebug(c *gin.Context) {
|
|||
|
||||
array := service.MyService.System().GetSystemConfigDebug()
|
||||
disk := service.MyService.ZiMa().GetDiskInfo()
|
||||
array = append(array, fmt.Sprintf("disk,total:%v,used:%v,UsedPercent:%v", disk.Total>>20, disk.Used>>20, disk.UsedPercent))
|
||||
sys := service.MyService.ZiMa().GetSysInfo()
|
||||
//todo 准备sync需要显示的数据(镜像,容器)
|
||||
var systemAppStatus string
|
||||
images := service.MyService.Docker().IsExistImage("linuxserver/syncthing")
|
||||
systemAppStatus += "Sync img: " + strconv.FormatBool(images) + "\n\t"
|
||||
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: array})
|
||||
list := service.MyService.App().GetSystemAppList()
|
||||
for _, v := range *list {
|
||||
systemAppStatus += v.Image + ",\n\t"
|
||||
}
|
||||
systemAppStatus += "Sync Key: " + config.SystemConfigInfo.SyncKey + "\n\t"
|
||||
|
||||
var bugContent string = fmt.Sprintf(`
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: %s
|
||||
- CasaOS Version: %s
|
||||
- Disk Total: %v
|
||||
- Disk Used: %v
|
||||
- Sync State: %s
|
||||
- System Info: %s
|
||||
- Browser: $Browser$
|
||||
- Version: $Version$
|
||||
`, sys.OS, types.CURRENTVERSION, disk.Total>>20, disk.Used>>20, systemAppStatus, array)
|
||||
|
||||
// array = append(array, fmt.Sprintf("disk,total:%v,used:%v,UsedPercent:%v", disk.Total>>20, disk.Used>>20, disk.UsedPercent))
|
||||
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: bugContent})
|
||||
}
|
||||
func Sys(c *gin.Context) {
|
||||
service.DockerPull()
|
||||
|
@ -237,7 +262,42 @@ func Info(c *gin.Context) {
|
|||
var data = make(map[string]interface{}, 5)
|
||||
|
||||
list := service.MyService.Disk().LSBLK()
|
||||
data["disk"] = list
|
||||
|
||||
newList := []model.LSBLKModel{}
|
||||
for i := len(list) - 1; i >= 0; i-- {
|
||||
if list[i].Rota {
|
||||
list[i].DiskType = "HDD"
|
||||
} else {
|
||||
list[i].DiskType = "SSD"
|
||||
}
|
||||
if list[i].Tran == "sata" {
|
||||
|
||||
temp := service.MyService.Disk().SmartCTL(list[i].Path)
|
||||
if reflect.DeepEqual(temp, model.SmartctlA{}) {
|
||||
continue
|
||||
}
|
||||
if len(list[i].Children) == 1 && len(list[i].Children[0].MountPoint) > 0 {
|
||||
pathArr := strings.Split(list[i].Children[0].MountPoint, "/")
|
||||
if len(pathArr) == 3 {
|
||||
list[i].Children[0].Name = pathArr[2]
|
||||
}
|
||||
}
|
||||
|
||||
list[i].Temperature = temp.Temperature.Current
|
||||
list[i].Health = strconv.FormatBool(temp.SmartStatus.Passed)
|
||||
newList = append(newList, list[i])
|
||||
} else if len(list[i].Children) > 0 && list[i].Children[0].MountPoint == "/" {
|
||||
//system
|
||||
list[i].Children[0].Name = "System"
|
||||
list[i].Model = "System"
|
||||
list[i].DiskType = "EMMC"
|
||||
list[i].Health = "true"
|
||||
newList = append(newList, list[i])
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
data["disk"] = newList
|
||||
cpu := service.MyService.ZiMa().GetCpuPercent()
|
||||
num := service.MyService.ZiMa().GetCpuCoreNum()
|
||||
cpuData := make(map[string]interface{})
|
||||
|
|
|
@ -16,7 +16,7 @@ type CasaService interface {
|
|||
GetServerList(index, size, tp, categoryId, key string) (recommend, list, community []model.ServerAppList)
|
||||
GetServerCategoryList() []model.ServerCategoryList
|
||||
GetTaskList(size int) []model2.TaskDBModel
|
||||
GetServerAppInfo(id string) model.ServerAppList
|
||||
GetServerAppInfo(id, t string) model.ServerAppList
|
||||
ShareAppFile(body []byte) string
|
||||
}
|
||||
|
||||
|
@ -88,13 +88,12 @@ func (o *casaService) GetServerCategoryList() []model.ServerCategoryList {
|
|||
|
||||
return list
|
||||
}
|
||||
func (o *casaService) GetServerAppInfo(id string) model.ServerAppList {
|
||||
func (o *casaService) GetServerAppInfo(id, t string) model.ServerAppList {
|
||||
|
||||
head := make(map[string]string)
|
||||
|
||||
head["Authorization"] = GetToken()
|
||||
|
||||
infoS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/info/"+id, head)
|
||||
infoS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/info/"+id+"?t="+t, head)
|
||||
|
||||
info := model.ServerAppList{}
|
||||
json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
|
||||
|
|
|
@ -3,6 +3,7 @@ package service
|
|||
import (
|
||||
json2 "encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -20,8 +21,9 @@ import (
|
|||
type DiskService interface {
|
||||
GetPlugInDisk() []string
|
||||
LSBLK() []model.LSBLKModel
|
||||
FormatDisk(path, format string) string
|
||||
UmountPointAndRemoveDir(path string) string
|
||||
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
|
||||
|
@ -31,30 +33,60 @@ type DiskService interface {
|
|||
SaveMountPoint(m model2.SerialDisk)
|
||||
DeleteMountPoint(path, mountPoint string)
|
||||
DeleteMount(id string)
|
||||
UpdateMountPoint(m model2.SerialDisk)
|
||||
RemoveLSBLKCache()
|
||||
}
|
||||
type diskService struct {
|
||||
log loger2.OLog
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func (d *diskService) RemoveLSBLKCache() {
|
||||
key := "system_lsblk"
|
||||
Cache.Delete(key)
|
||||
}
|
||||
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 {
|
||||
d.log.Error("smartctl exec error,smartctl")
|
||||
return m
|
||||
}
|
||||
|
||||
err := json2.Unmarshal([]byte(str), &m)
|
||||
if err != nil {
|
||||
d.log.Error("json ummarshal error", err)
|
||||
}
|
||||
if !reflect.DeepEqual(m, model.SmartctlA{}) {
|
||||
Cache.Add(key, m, time.Second*10)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
//通过脚本获取外挂磁盘
|
||||
func (d *diskService) GetPlugInDisk() []string {
|
||||
return command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetPlugInDisk")
|
||||
}
|
||||
|
||||
//格式化硬盘
|
||||
func (d *diskService) FormatDisk(path, format string) string {
|
||||
|
||||
func (d *diskService) FormatDisk(path, format string) []string {
|
||||
r := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;FormatDisk " + path + " " + format)
|
||||
fmt.Println(r)
|
||||
return ""
|
||||
return r
|
||||
}
|
||||
|
||||
//移除挂载点,删除目录
|
||||
func (d *diskService) UmountPointAndRemoveDir(path string) string {
|
||||
func (d *diskService) UmountPointAndRemoveDir(path string) []string {
|
||||
r := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;UMountPorintAndRemoveDir " + path)
|
||||
fmt.Println(r)
|
||||
return ""
|
||||
return r
|
||||
}
|
||||
|
||||
//删除分区
|
||||
|
@ -66,8 +98,7 @@ func (d *diskService) DelPartition(path, num string) string {
|
|||
|
||||
//part
|
||||
func (d *diskService) AddPartition(path string) string {
|
||||
r := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;AddPartition " + path)
|
||||
fmt.Println(r)
|
||||
command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;AddPartition " + path)
|
||||
return ""
|
||||
}
|
||||
|
||||
|
@ -78,11 +109,10 @@ 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)
|
||||
}
|
||||
fmt.Println(path)
|
||||
fmt.Println(diskInfo)
|
||||
diskInfo.UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.UsedPercent), 64)
|
||||
diskInfo.InodesUsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.InodesUsedPercent), 64)
|
||||
return diskInfo
|
||||
|
@ -91,7 +121,6 @@ func (d *diskService) GetDiskInfoByPath(path string) *disk.UsageStat {
|
|||
//get disk details
|
||||
func (d *diskService) LSBLK() []model.LSBLKModel {
|
||||
key := "system_lsblk"
|
||||
|
||||
var n []model.LSBLKModel
|
||||
|
||||
if result, ok := Cache.Get(key); ok {
|
||||
|
@ -151,7 +180,7 @@ func (d *diskService) LSBLK() []model.LSBLKModel {
|
|||
}
|
||||
}
|
||||
if len(n) > 0 {
|
||||
Cache.Add(key, n, time.Second*10)
|
||||
Cache.Add(key, n, time.Second*100)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
@ -162,6 +191,7 @@ func (d *diskService) GetDiskInfo(path string) model.LSBLKModel {
|
|||
d.log.Error("lsblk exec error,str")
|
||||
return model.LSBLKModel{}
|
||||
}
|
||||
|
||||
var ml []model.LSBLKModel
|
||||
err := json2.Unmarshal([]byte(gjson.Get(string(str), "blockdevices").String()), &ml)
|
||||
if err != nil {
|
||||
|
@ -169,9 +199,13 @@ func (d *diskService) GetDiskInfo(path string) model.LSBLKModel {
|
|||
d.log.Error("json ummarshal error", err)
|
||||
return model.LSBLKModel{}
|
||||
}
|
||||
//todo 需要判断长度
|
||||
m := ml[0]
|
||||
//声明数组
|
||||
|
||||
m := model.LSBLKModel{}
|
||||
if len(ml) > 0 {
|
||||
m = ml[0]
|
||||
}
|
||||
return m
|
||||
// 下面为计算是否可以继续分区的部分,暂时不需要
|
||||
chiArr := make(map[string]string)
|
||||
chiList := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetPartitionSectors " + m.Path)
|
||||
if len(chiList) == 0 {
|
||||
|
@ -182,7 +216,6 @@ func (d *diskService) GetDiskInfo(path string) model.LSBLKModel {
|
|||
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], ",")
|
||||
|
@ -191,13 +224,13 @@ func (d *diskService) GetDiskInfo(path string) model.LSBLKModel {
|
|||
if m.Children[i].EndSector > maxSector {
|
||||
maxSector = m.Children[i].EndSector
|
||||
}
|
||||
|
||||
}
|
||||
diskEndSector := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetDiskSizeAndSectors " + m.Path)
|
||||
|
||||
if len(diskEndSector) < 2 {
|
||||
d.log.Error("diskEndSector length error")
|
||||
}
|
||||
|
||||
diskEndSectorInt, _ := strconv.ParseUint(diskEndSector[len(diskEndSector)-1], 10, 64)
|
||||
if (diskEndSectorInt-maxSector)*m.MinIO/1024/1024 > 100 {
|
||||
//添加可以分区情况
|
||||
|
@ -214,9 +247,14 @@ func (d *diskService) MountDisk(path, volume string) {
|
|||
}
|
||||
|
||||
func (d *diskService) SaveMountPoint(m model2.SerialDisk) {
|
||||
d.db.Where("serial = ?", m.Serial).Delete(&model2.SerialDisk{})
|
||||
d.db.Create(&m)
|
||||
}
|
||||
|
||||
func (d *diskService) UpdateMountPoint(m model2.SerialDisk) {
|
||||
d.db.Model(&model2.SerialDisk{}).Where("serial = ?", m.Serial).Update("mount_point", m.MountPoint)
|
||||
}
|
||||
|
||||
func (d *diskService) DeleteMount(id string) {
|
||||
|
||||
d.db.Delete(&model2.SerialDisk{}).Where("id = ?", id)
|
||||
|
@ -224,7 +262,7 @@ func (d *diskService) DeleteMount(id string) {
|
|||
|
||||
func (d *diskService) DeleteMountPoint(path, mountPoint string) {
|
||||
|
||||
d.db.Delete(&model2.SerialDisk{}).Where("path= ? && mount_point = ?", path, mountPoint)
|
||||
d.db.Where("path = ? AND mount_point = ?", path, mountPoint).Delete(&model2.SerialDisk{})
|
||||
|
||||
command2.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;do_umount " + path)
|
||||
}
|
||||
|
|
|
@ -9,4 +9,33 @@ version_0_2_3() {
|
|||
|
||||
}
|
||||
|
||||
# add in v0.2.5
|
||||
readonly CASA_DEPANDS="curl smartmontools"
|
||||
version_0_2_5{
|
||||
install_depends "$CASA_DEPANDS"
|
||||
}
|
||||
|
||||
|
||||
#Install Depends
|
||||
install_depends() {
|
||||
((EUID)) && sudo_cmd="sudo"
|
||||
if [[ ! -x "$(command -v '$1')" ]]; then
|
||||
show 2 "Install the necessary dependencies: $1"
|
||||
packagesNeeded=$1
|
||||
if [ -x "$(command -v apk)" ]; then
|
||||
$sudo_cmd apk add --no-cache $packagesNeeded
|
||||
elif [ -x "$(command -v apt-get)" ]; then
|
||||
$sudo_cmd apt-get -y -q install $packagesNeeded
|
||||
elif [ -x "$(command -v dnf)" ]; then
|
||||
$sudo_cmd dnf install $packagesNeeded
|
||||
elif [ -x "$(command -v zypper)" ]; then
|
||||
$sudo_cmd zypper install $packagesNeeded
|
||||
else
|
||||
show 1 "Package manager not found. You must manually install: $packagesNeeded"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
version_0_2_3
|
||||
|
||||
version_0_2_5
|
||||
|
|
|
@ -73,10 +73,8 @@ UMountPorintAndRemoveDir() {
|
|||
if [[ -z ${MOUNT_POINT} ]]; then
|
||||
${log} "Warning: ${DEVICE} is not mounted"
|
||||
else
|
||||
umount -l ${DEVICE}
|
||||
${log} "Unmounted ${DEVICE} from ${MOUNT_POINT}"
|
||||
umount -lf ${DEVICE}
|
||||
/bin/rmdir "${MOUNT_POINT}"
|
||||
sed -i.bak "\@${MOUNT_POINT}@d" /var/log/usb-mount.track
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -89,11 +87,11 @@ FormatDisk() {
|
|||
elif [ "$2" == "ntfs" ]; then
|
||||
mkfs.ntfs $1
|
||||
elif [ "$2" == "ext4" ]; then
|
||||
mkfs.ext4 -F $1
|
||||
mkfs.ext4 -m 1 -F $1
|
||||
elif [ "$2" == "exfat" ]; then
|
||||
mkfs.exfat $1
|
||||
else
|
||||
mkfs.ext4 -F $1
|
||||
mkfs.ext4 -m 1 -F $1
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -118,12 +116,10 @@ AddPartition() {
|
|||
|
||||
parted -s $1 mkpart primary ext4 0 100%
|
||||
|
||||
mkfs.ext4 $11
|
||||
mkfs.ext4 -m 1 $11
|
||||
|
||||
partprobe $1
|
||||
|
||||
# mount $11 $2
|
||||
|
||||
}
|
||||
|
||||
#磁盘类型
|
||||
|
@ -148,14 +144,14 @@ GetDiskHealthState() {
|
|||
#result bytes
|
||||
#result sectors
|
||||
GetDiskSizeAndSectors() {
|
||||
fdisk $1 -l | grep "/dev/sda:" | awk -F, 'BEGIN {OFS="\n"}{print $2,$3}' | awk '{print $1}'
|
||||
fdisk $1 -l | grep "$1:" | awk -F, 'BEGIN {OFS="\n"}{print $2,$3}' | awk '{print $1}'
|
||||
}
|
||||
|
||||
#获取磁盘分区数据扇区
|
||||
#param 磁盘路径 /dev/sda
|
||||
#result start,end,sectors
|
||||
GetPartitionSectors() {
|
||||
fdisk $1 -l | grep "/dev/sda[1-9]" | awk 'BEGIN{OFS=","}{print $1,$2,$3,$4}'
|
||||
fdisk $1 -l | grep "$1[1-9]" | awk 'BEGIN{OFS=","}{print $1,$2,$3,$4}'
|
||||
}
|
||||
|
||||
#检查没有使用的挂载点删除文件夹
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package types
|
||||
|
||||
const CURRENTVERSION = "0.2.4"
|
||||
const BODY = "<li>New App Store</li><li>Fix minor bugs</li>"
|
||||
const CURRENTVERSION = "0.2.5"
|
||||
const BODY = "<li>Storage Manager</li><li>File synchronization issues</li><li>Fix the app store classification problem</li>"
|
||||
|
|
Loading…
Reference in a new issue