mirror of
https://github.com/IceWhaleTech/CasaOS.git
synced 2025-12-23 04:54:41 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c00655d14 | ||
|
|
eb36c262db | ||
|
|
29d1861545 | ||
|
|
3c9b410693 | ||
|
|
4c3b41433b | ||
|
|
1fd13668c0 | ||
|
|
d1ab7261a6 | ||
|
|
0fc65bcb3a | ||
|
|
f1ce8bfd99 | ||
|
|
3f472f1864 | ||
|
|
229d94cae7 | ||
|
|
c28e1bbf93 | ||
|
|
a840029000 | ||
|
|
aad2646cf2 | ||
|
|
ca1f8ad73e | ||
|
|
dea02763a2 | ||
|
|
ea67385a64 | ||
|
|
fa2daa2767 | ||
|
|
fcb906aa85 |
2
UI
2
UI
Submodule UI updated: f3088b6354...8146d1f4cb
@@ -21,12 +21,46 @@ type LSBLKModel struct {
|
|||||||
Health string `json:"health"`
|
Health string `json:"health"`
|
||||||
HotPlug bool `json:"hotplug"`
|
HotPlug bool `json:"hotplug"`
|
||||||
FSUsed string `json:"fsused"`
|
FSUsed string `json:"fsused"`
|
||||||
|
Temperature int `json:"temperature"`
|
||||||
Tran string `json:"tran"`
|
Tran string `json:"tran"`
|
||||||
MinIO uint64 `json:"min-io"`
|
MinIO uint64 `json:"min-io"`
|
||||||
UsedPercent float64 `json:"used_percent"`
|
UsedPercent float64 `json:"used_percent"`
|
||||||
Serial string `json:"serial"`
|
Serial string `json:"serial"`
|
||||||
Children []LSBLKModel `json:"children"`
|
Children []LSBLKModel `json:"children"`
|
||||||
|
SubSystems string `json:"subsystems"`
|
||||||
//详情特有
|
//详情特有
|
||||||
StartSector uint64 `json:"start_sector,omitempty"`
|
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"`
|
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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Storage struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
MountPoint string `json:"mountpoint"`
|
||||||
|
Size string `json:"size"`
|
||||||
|
Avail string `json:"avail"` //可用空间
|
||||||
|
Type string `json:"type"`
|
||||||
|
CreatedAt int64 `json:"create_at"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
DriveName string `json:"drive_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Summary struct {
|
||||||
|
Size uint64 `json:"size"`
|
||||||
|
Avail uint64 `json:"avail"` //可用空间
|
||||||
|
Health bool `json:"health"`
|
||||||
|
Used uint64 `json:"used"`
|
||||||
|
}
|
||||||
|
|||||||
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"`
|
||||||
|
}
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
type Path struct {
|
type Path struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
IsDir bool `json:"is_dir"`
|
IsDir bool `json:"is_dir"`
|
||||||
|
Date time.Time `json:"date"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ package command
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func OnlyExec(cmdStr string) {
|
func OnlyExec(cmdStr string) {
|
||||||
@@ -85,7 +87,27 @@ func ExecLSBLK() []byte {
|
|||||||
func ExecLSBLKByPath(path string) []byte {
|
func ExecLSBLKByPath(path string) []byte {
|
||||||
output, err := exec.Command("lsblk", path, "-O", "-J", "-b").Output()
|
output, err := exec.Command("lsblk", path, "-O", "-J", "-b").Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("lsblk", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return output
|
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)
|
||||||
|
fmt.Println("output", string(output))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExecEnabledSMART(path string) {
|
||||||
|
|
||||||
|
exec.Command("smartctl", "-s on", path).Output()
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,13 @@ const (
|
|||||||
//zerotier
|
//zerotier
|
||||||
GET_TOKEN_ERROR = 30001
|
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
|
//app
|
||||||
UNINSTALL_APP_ERROR = 50001
|
UNINSTALL_APP_ERROR = 50001
|
||||||
PULL_IMAGE_ERROR = 50002
|
PULL_IMAGE_ERROR = 50002
|
||||||
@@ -37,34 +44,41 @@ const (
|
|||||||
var MsgFlags = map[int]string{
|
var MsgFlags = map[int]string{
|
||||||
SUCCESS: "ok",
|
SUCCESS: "ok",
|
||||||
ERROR: "fail",
|
ERROR: "fail",
|
||||||
INVALID_PARAMS: "Invalid params",
|
INVALID_PARAMS: "Parameters Error",
|
||||||
ERROR_AUTH_TOKEN: "error auth token",
|
ERROR_AUTH_TOKEN: "Error auth token",
|
||||||
|
|
||||||
//user
|
//user
|
||||||
PWD_INVALID: "Password invalid",
|
PWD_INVALID: "Invalid password",
|
||||||
PWD_IS_EMPTY: "Password is empty",
|
PWD_IS_EMPTY: "Password is empty",
|
||||||
PWD_INVALID_OLD: "Old Password invalid",
|
PWD_INVALID_OLD: "Invalid old password",
|
||||||
ACCOUNT_LOCK: "Account Lock",
|
ACCOUNT_LOCK: "Account is locked",
|
||||||
|
|
||||||
//system
|
//system
|
||||||
DIR_ALREADY_EXISTS: "Directory already exists",
|
DIR_ALREADY_EXISTS: "Folder already exists",
|
||||||
FILE_ALREADY_EXISTS: "File 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",
|
PORT_IS_OCCUPIED: "Port is occupied",
|
||||||
|
|
||||||
//zerotier
|
//zerotier
|
||||||
GET_TOKEN_ERROR: "Get token error,Please log in to zerotier's official website to confirm whether the account is available",
|
GET_TOKEN_ERROR: "Get token error,Please log in to zerotier's official website to confirm whether the account is available",
|
||||||
|
|
||||||
//app
|
//app
|
||||||
UNINSTALL_APP_ERROR: "uninstall app error",
|
UNINSTALL_APP_ERROR: "Error uninstalling app",
|
||||||
PULL_IMAGE_ERROR: "pull image error",
|
PULL_IMAGE_ERROR: "Error pulling image",
|
||||||
DEVICE_NOT_EXIST: "device not exist",
|
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",
|
FILE_READ_ERROR: "File read error",
|
||||||
SHORTCUTS_URL_ERROR: "url error",
|
SHORTCUTS_URL_ERROR: "URL error",
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取错误信息
|
//获取错误信息
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package route
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -34,10 +35,9 @@ func installSyncthing(appId string) {
|
|||||||
m := model.CustomizationPostData{}
|
m := model.CustomizationPostData{}
|
||||||
var dockerImage string
|
var dockerImage string
|
||||||
var dockerImageVersion string
|
var dockerImageVersion string
|
||||||
|
appInfo = service.MyService.OAPI().GetServerAppInfo(appId, "system")
|
||||||
appInfo = service.MyService.OAPI().GetServerAppInfo(appId)
|
|
||||||
|
|
||||||
dockerImage = appInfo.Image
|
dockerImage = appInfo.Image
|
||||||
|
dockerImageVersion = appInfo.ImageVersion
|
||||||
|
|
||||||
if len(appInfo.ImageVersion) == 0 {
|
if len(appInfo.ImageVersion) == 0 {
|
||||||
dockerImageVersion = "latest"
|
dockerImageVersion = "latest"
|
||||||
@@ -84,9 +84,9 @@ func installSyncthing(appId string) {
|
|||||||
err := service.MyService.Docker().DockerPullImage(dockerImage+":"+dockerImageVersion, installLog)
|
err := service.MyService.Docker().DockerPullImage(dockerImage+":"+dockerImageVersion, installLog)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//pull image error
|
//pull image error
|
||||||
|
fmt.Println("pull image error", err, dockerImage, dockerImageVersion)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for !service.MyService.Docker().IsExistImage(dockerImage + ":" + dockerImageVersion) {
|
for !service.MyService.Docker().IsExistImage(dockerImage + ":" + dockerImageVersion) {
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
}
|
}
|
||||||
@@ -101,8 +101,8 @@ func installSyncthing(appId string) {
|
|||||||
m.Volumes = appInfo.Volumes
|
m.Volumes = appInfo.Volumes
|
||||||
|
|
||||||
containerId, err := service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, id, m, appInfo.NetworkModel)
|
containerId, err := service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, id, m, appInfo.NetworkModel)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("container create error", err)
|
||||||
// create container error
|
// create container error
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -170,7 +170,7 @@ func checkSystemApp() {
|
|||||||
path := ""
|
path := ""
|
||||||
for _, i := range paths {
|
for _, i := range paths {
|
||||||
if i.ContainerPath == "/config" {
|
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++ {
|
for i := 0; i < 10; i++ {
|
||||||
if file.CheckNotExist(path) {
|
if file.CheckNotExist(path) {
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
@@ -197,21 +197,37 @@ func CheckSerialDiskMount() {
|
|||||||
|
|
||||||
list := service.MyService.Disk().LSBLK()
|
list := service.MyService.Disk().LSBLK()
|
||||||
mountPoint := make(map[string]string, len(dbList))
|
mountPoint := make(map[string]string, len(dbList))
|
||||||
|
//remount
|
||||||
|
for _, v := range dbList {
|
||||||
|
mountPoint[v.Path] = v.MountPoint
|
||||||
|
}
|
||||||
for _, v := range list {
|
for _, v := range list {
|
||||||
|
command.ExecEnabledSMART(v.Path)
|
||||||
if v.Children != nil {
|
if v.Children != nil {
|
||||||
for _, h := range v.Children {
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
service.MyService.Disk().RemoveLSBLKCache()
|
||||||
//remount
|
command.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;AutoRemoveUnuseDir")
|
||||||
for _, item := range dbList {
|
|
||||||
if _, ok := mountPoint[item.MountPoint]; !ok {
|
|
||||||
service.MyService.Disk().MountDisk(item.Path, item.MountPoint)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
func Update2_3() {
|
func Update2_3() {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func InitRouter() *gin.Engine {
|
|||||||
|
|
||||||
r.GET("/v1/guide/check", v1.GetGuideCheck)
|
r.GET("/v1/guide/check", v1.GetGuideCheck)
|
||||||
|
|
||||||
r.GET("/debug", v1.GetSystemConfigDebug)
|
r.GET("/v1/debug", v1.GetSystemConfigDebug)
|
||||||
//set user
|
//set user
|
||||||
r.POST("/v1/user/setusernamepwd", v1.Set_Name_Pwd)
|
r.POST("/v1/user/setusernamepwd", v1.Set_Name_Pwd)
|
||||||
//get user info
|
//get user info
|
||||||
@@ -205,7 +205,7 @@ func InitRouter() *gin.Engine {
|
|||||||
v1FileGroup.PUT("/rename", v1.RenamePath)
|
v1FileGroup.PUT("/rename", v1.RenamePath)
|
||||||
v1FileGroup.GET("/read", v1.GetFilerContent)
|
v1FileGroup.GET("/read", v1.GetFilerContent)
|
||||||
v1FileGroup.POST("/upload", v1.PostFileUpload)
|
v1FileGroup.POST("/upload", v1.PostFileUpload)
|
||||||
v1FileGroup.GET("/dirpath", v1.DirPath)
|
v1FileGroup.GET("/catalog", v1.DirPath)
|
||||||
//创建目录
|
//创建目录
|
||||||
v1FileGroup.POST("/mkdir", v1.MkdirAll)
|
v1FileGroup.POST("/mkdir", v1.MkdirAll)
|
||||||
v1FileGroup.POST("/create", v1.PostCreateFile)
|
v1FileGroup.POST("/create", v1.PostCreateFile)
|
||||||
@@ -218,17 +218,23 @@ func InitRouter() *gin.Engine {
|
|||||||
v1DiskGroup.Use()
|
v1DiskGroup.Use()
|
||||||
{
|
{
|
||||||
v1DiskGroup.GET("/check", v1.GetDiskCheck)
|
v1DiskGroup.GET("/check", v1.GetDiskCheck)
|
||||||
//获取磁盘列表
|
|
||||||
v1DiskGroup.GET("/list", v1.GetPlugInDisk)
|
v1DiskGroup.GET("/list", v1.GetDiskList)
|
||||||
|
|
||||||
//获取磁盘详情
|
//获取磁盘详情
|
||||||
v1DiskGroup.GET("/info", v1.GetDiskInfo)
|
v1DiskGroup.GET("/info", v1.GetDiskInfo)
|
||||||
|
|
||||||
//格式化磁盘
|
//format storage
|
||||||
v1DiskGroup.POST("/format", v1.FormatDisk)
|
v1DiskGroup.POST("/format", v1.FormatDisk)
|
||||||
|
|
||||||
//添加分区
|
// add storage
|
||||||
v1DiskGroup.POST("/part", v1.AddPartition)
|
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)
|
v1DiskGroup.GET("/type", v1.FormatDiskType)
|
||||||
@@ -236,12 +242,6 @@ func InitRouter() *gin.Engine {
|
|||||||
//删除分区
|
//删除分区
|
||||||
v1DiskGroup.DELETE("/delpart", v1.RemovePartition)
|
v1DiskGroup.DELETE("/delpart", v1.RemovePartition)
|
||||||
|
|
||||||
//mount SATA disk
|
|
||||||
v1DiskGroup.POST("/mount", v1.PostMountDisk)
|
|
||||||
|
|
||||||
//umount SATA disk
|
|
||||||
v1DiskGroup.POST("/umount", v1.PostDiskUmount)
|
|
||||||
v1DiskGroup.DELETE("/remove/:id", v1.DeleteDisk)
|
|
||||||
}
|
}
|
||||||
v1ShareGroup := v1Group.Group("/share")
|
v1ShareGroup := v1Group.Group("/share")
|
||||||
v1ShareGroup.Use()
|
v1ShareGroup.Use()
|
||||||
|
|||||||
@@ -36,24 +36,24 @@ func AppList(c *gin.Context) {
|
|||||||
categoryId := c.DefaultQuery("category_id", "0")
|
categoryId := c.DefaultQuery("category_id", "0")
|
||||||
key := c.DefaultQuery("key", "")
|
key := c.DefaultQuery("key", "")
|
||||||
recommend, list, community := service.MyService.OAPI().GetServerList(index, size, t, categoryId, key)
|
recommend, list, community := service.MyService.OAPI().GetServerList(index, size, t, categoryId, key)
|
||||||
for i := 0; i < len(recommend); i++ {
|
// for i := 0; i < len(recommend); i++ {
|
||||||
ct, _ := service.MyService.Docker().DockerListByImage(recommend[i].Image, recommend[i].ImageVersion)
|
// ct, _ := service.MyService.Docker().DockerListByImage(recommend[i].Image, recommend[i].ImageVersion)
|
||||||
if ct != nil {
|
// if ct != nil {
|
||||||
list[i].State = ct.State
|
// recommend[i].State = ct.State
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
for i := 0; i < len(list); i++ {
|
// for i := 0; i < len(list); i++ {
|
||||||
ct, _ := service.MyService.Docker().DockerListByImage(list[i].Image, list[i].ImageVersion)
|
// ct, _ := service.MyService.Docker().DockerListByImage(list[i].Image, list[i].ImageVersion)
|
||||||
if ct != nil {
|
// if ct != nil {
|
||||||
list[i].State = ct.State
|
// list[i].State = ct.State
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
for i := 0; i < len(community); i++ {
|
// for i := 0; i < len(community); i++ {
|
||||||
ct, _ := service.MyService.Docker().DockerListByImage(community[i].Image, community[i].ImageVersion)
|
// ct, _ := service.MyService.Docker().DockerListByImage(community[i].Image, community[i].ImageVersion)
|
||||||
if ct != nil {
|
// if ct != nil {
|
||||||
list[i].State = ct.State
|
// community[i].State = ct.State
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
data := make(map[string]interface{}, 3)
|
data := make(map[string]interface{}, 3)
|
||||||
data["recommend"] = recommend
|
data["recommend"] = recommend
|
||||||
data["list"] = list
|
data["list"] = list
|
||||||
@@ -137,7 +137,7 @@ func AppUsageList(c *gin.Context) {
|
|||||||
func AppInfo(c *gin.Context) {
|
func AppInfo(c *gin.Context) {
|
||||||
|
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
info := service.MyService.OAPI().GetServerAppInfo(id)
|
info := service.MyService.OAPI().GetServerAppInfo(id, "")
|
||||||
if info.NetworkModel != "host" {
|
if info.NetworkModel != "host" {
|
||||||
for i := 0; i < len(info.Ports); i++ {
|
for i := 0; i < len(info.Ports); i++ {
|
||||||
if p, _ := strconv.Atoi(info.Ports[i].ContainerPort); port2.IsPortAvailable(p, info.Ports[i].Protocol) {
|
if p, _ := strconv.Atoi(info.Ports[i].ContainerPort); port2.IsPortAvailable(p, info.Ports[i].Protocol) {
|
||||||
|
|||||||
225
route/v1/disk.go
225
route/v1/disk.go
@@ -2,9 +2,14 @@ package v1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
"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/pkg/utils/oasis_err"
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||||
@@ -12,18 +17,115 @@ import (
|
|||||||
"github.com/shirou/gopsutil/v3/disk"
|
"github.com/shirou/gopsutil/v3/disk"
|
||||||
)
|
)
|
||||||
|
|
||||||
// @Summary 获取磁盘列表
|
var diskMap = make(map[string]string)
|
||||||
|
|
||||||
|
// @Summary disk list
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
// @Tags disk
|
// @Tags disk
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /disk/list [get]
|
// @Router /disk/list [get]
|
||||||
func GetPlugInDisk(c *gin.Context) {
|
func GetDiskList(c *gin.Context) {
|
||||||
|
|
||||||
list := service.MyService.Disk().LSBLK()
|
list := service.MyService.Disk().LSBLK()
|
||||||
|
dbList := service.MyService.Disk().GetSerialAll()
|
||||||
|
part := make(map[string]int64, len(dbList))
|
||||||
|
for _, v := range dbList {
|
||||||
|
part[v.MountPoint] = v.CreatedAt
|
||||||
|
}
|
||||||
|
findSystem := 0
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: list})
|
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
|
||||||
|
|
||||||
|
if len(list[i].Children) > 0 && findSystem == 0 {
|
||||||
|
for j := 0; j < len(list[i].Children); j++ {
|
||||||
|
if list[i].Children[j].MountPoint == "/" {
|
||||||
|
stor := model.Storage{}
|
||||||
|
stor.Name = "System"
|
||||||
|
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" {
|
||||||
|
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 {
|
||||||
|
stor := model.Storage{}
|
||||||
|
stor.MountPoint = list[i].Children[0].MountPoint
|
||||||
|
stor.Size = list[i].Children[0].FSSize
|
||||||
|
stor.Avail = list[i].Children[0].FSAvail
|
||||||
|
stor.Path = list[i].Children[0].Path
|
||||||
|
stor.Type = list[i].Children[0].FsType
|
||||||
|
stor.DriveName = list[i].Name
|
||||||
|
pathArr := strings.Split(list[i].Children[0].MountPoint, "/")
|
||||||
|
if len(pathArr) == 3 {
|
||||||
|
stor.Name = pathArr[2]
|
||||||
|
}
|
||||||
|
if t, ok := part[list[i].Children[0].MountPoint]; ok {
|
||||||
|
stor.CreatedAt = t
|
||||||
|
}
|
||||||
|
storage = append(storage, stor)
|
||||||
|
} else {
|
||||||
|
//todo 长度有问题
|
||||||
|
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(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: data})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary get disk list
|
// @Summary get disk list
|
||||||
@@ -60,25 +162,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})
|
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
|
// @Produce application/json
|
||||||
// @Accept multipart/form-data
|
// @Accept multipart/form-data
|
||||||
// @Tags disk
|
// @Tags disk
|
||||||
// @Security ApiKeyAuth
|
// @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"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /disk/format [post]
|
// @Router /disk/format [post]
|
||||||
func FormatDisk(c *gin.Context) {
|
func FormatDisk(c *gin.Context) {
|
||||||
path := c.PostForm("path")
|
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 {
|
if len(path) == 0 || len(t) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
|
||||||
return
|
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)})
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,23 +238,65 @@ func RemovePartition(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary serial number
|
// @Summary add storage
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept multipart/form-data
|
// @Accept multipart/form-data
|
||||||
// @Tags disk
|
// @Tags disk
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Param path formData string true "磁盘路径 例如/dev/sda"
|
// @Param path formData string true "disk path e.g. /dev/sda"
|
||||||
// @Param serial formData string true "serial"
|
// @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"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /disk/addpart [post]
|
// @Router /disk/storage [post]
|
||||||
func AddPartition(c *gin.Context) {
|
func AddPartition(c *gin.Context) {
|
||||||
|
name := c.PostForm("name")
|
||||||
path := c.PostForm("path")
|
path := c.PostForm("path")
|
||||||
serial := c.PostForm("serial")
|
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)})
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
|
||||||
return
|
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("/DATA/" + 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 := "/DATA/" + name
|
||||||
|
|
||||||
|
service.MyService.Disk().MountDisk(path, mountPath)
|
||||||
|
|
||||||
|
m := model2.SerialDisk{}
|
||||||
|
m.MountPoint = mountPath
|
||||||
|
m.Path = path + "1"
|
||||||
|
m.Serial = serial
|
||||||
|
m.State = 0
|
||||||
|
m.CreatedAt = time.Now().Unix()
|
||||||
|
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)})
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +314,7 @@ func PostMountDisk(c *gin.Context) {
|
|||||||
path := c.PostForm("path")
|
path := c.PostForm("path")
|
||||||
serial := c.PostForm("serial")
|
serial := c.PostForm("serial")
|
||||||
|
|
||||||
mountPath := "/mnt/volume"
|
mountPath := "/DATA/volume"
|
||||||
var list = service.MyService.Disk().GetSerialAll()
|
var list = service.MyService.Disk().GetSerialAll()
|
||||||
var pathMapList = make(map[string]string, len(list))
|
var pathMapList = make(map[string]string, len(list))
|
||||||
for _, v := range list {
|
for _, v := range list {
|
||||||
@@ -165,13 +330,13 @@ func PostMountDisk(c *gin.Context) {
|
|||||||
|
|
||||||
//mount dir
|
//mount dir
|
||||||
service.MyService.Disk().MountDisk(path, mountPath)
|
service.MyService.Disk().MountDisk(path, mountPath)
|
||||||
//save to data
|
|
||||||
m := model2.SerialDisk{}
|
m := model2.SerialDisk{}
|
||||||
m.MountPoint = mountPath
|
m.MountPoint = mountPath
|
||||||
m.Path = path
|
m.Path = path
|
||||||
m.Serial = serial
|
m.Serial = serial
|
||||||
m.State = 0
|
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)})
|
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,19 +345,35 @@ func PostMountDisk(c *gin.Context) {
|
|||||||
// @Accept multipart/form-data
|
// @Accept multipart/form-data
|
||||||
// @Tags disk
|
// @Tags disk
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Param path formData string true "for example: /dev/sda1"
|
// @Param path formData string true "e.g. /dev/sda1"
|
||||||
// @Param mount_point formData string true "for example: /mnt/volume1"
|
// @Param mount_point formData string true "e.g. /mnt/volume1"
|
||||||
|
// @Param pwd formData string true "user password"
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /disk/umount [post]
|
// @Router /disk/umount [post]
|
||||||
func PostDiskUmount(c *gin.Context) {
|
func PostDiskUmount(c *gin.Context) {
|
||||||
|
|
||||||
//
|
|
||||||
path := c.PostForm("path")
|
path := c.PostForm("path")
|
||||||
mountPoint := c.PostForm("mount_point")
|
mountPoint := c.PostForm("volume")
|
||||||
service.MyService.Disk().UmountPointAndRemoveDir(path)
|
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
|
//delete data
|
||||||
service.MyService.Disk().DeleteMountPoint(path, mountPoint)
|
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)})
|
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"
|
dockerImageVersion = "latest"
|
||||||
}
|
}
|
||||||
if m.Origin != "custom" {
|
if m.Origin != "custom" {
|
||||||
appInfo = service.MyService.OAPI().GetServerAppInfo(appId)
|
appInfo = service.MyService.OAPI().GetServerAppInfo(appId, "")
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -107,9 +108,33 @@ func GetSystemConfigDebug(c *gin.Context) {
|
|||||||
|
|
||||||
array := service.MyService.System().GetSystemConfigDebug()
|
array := service.MyService.System().GetSystemConfigDebug()
|
||||||
disk := service.MyService.ZiMa().GetDiskInfo()
|
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 length: " + strconv.Itoa(len(config.SystemConfigInfo.SyncKey))
|
||||||
|
|
||||||
|
var bugContent string = fmt.Sprintf(`
|
||||||
|
- 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) {
|
func Sys(c *gin.Context) {
|
||||||
service.DockerPull()
|
service.DockerPull()
|
||||||
@@ -237,7 +262,56 @@ func Info(c *gin.Context) {
|
|||||||
var data = make(map[string]interface{}, 5)
|
var data = make(map[string]interface{}, 5)
|
||||||
|
|
||||||
list := service.MyService.Disk().LSBLK()
|
list := service.MyService.Disk().LSBLK()
|
||||||
data["disk"] = list
|
|
||||||
|
summary := model.Summary{}
|
||||||
|
healthy := true
|
||||||
|
findSystem := 0
|
||||||
|
|
||||||
|
for i := 0; i < len(list); i++ {
|
||||||
|
if len(list[i].Children) > 0 && findSystem == 0 {
|
||||||
|
for j := 0; j < len(list[i].Children); j++ {
|
||||||
|
if list[i].Children[j].MountPoint == "/" {
|
||||||
|
s, _ := strconv.ParseUint(list[i].Children[j].FSSize, 10, 64)
|
||||||
|
a, _ := strconv.ParseUint(list[i].Children[j].FSAvail, 10, 64)
|
||||||
|
u, _ := strconv.ParseUint(list[i].Children[j].FSUsed, 10, 64)
|
||||||
|
summary.Size += s
|
||||||
|
summary.Avail += a
|
||||||
|
summary.Used += u
|
||||||
|
findSystem = 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if findSystem == 1 {
|
||||||
|
findSystem += 1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if list[i].Tran == "sata" {
|
||||||
|
temp := service.MyService.Disk().SmartCTL(list[i].Path)
|
||||||
|
if reflect.DeepEqual(temp, model.SmartctlA{}) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
//list[i].Temperature = temp.Temperature.Current
|
||||||
|
if !temp.SmartStatus.Passed {
|
||||||
|
healthy = false
|
||||||
|
}
|
||||||
|
if len(list[i].Children) > 0 {
|
||||||
|
for _, v := range list[i].Children {
|
||||||
|
s, _ := strconv.ParseUint(v.FSSize, 10, 64)
|
||||||
|
a, _ := strconv.ParseUint(v.FSAvail, 10, 64)
|
||||||
|
u, _ := strconv.ParseUint(v.FSUsed, 10, 64)
|
||||||
|
summary.Size += s
|
||||||
|
summary.Avail += a
|
||||||
|
summary.Used += u
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
summary.Health = healthy
|
||||||
|
data["disk"] = summary
|
||||||
cpu := service.MyService.ZiMa().GetCpuPercent()
|
cpu := service.MyService.ZiMa().GetCpuPercent()
|
||||||
num := service.MyService.ZiMa().GetCpuCoreNum()
|
num := service.MyService.ZiMa().GetCpuCoreNum()
|
||||||
cpuData := make(map[string]interface{})
|
cpuData := make(map[string]interface{})
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type CasaService interface {
|
|||||||
GetServerList(index, size, tp, categoryId, key string) (recommend, list, community []model.ServerAppList)
|
GetServerList(index, size, tp, categoryId, key string) (recommend, list, community []model.ServerAppList)
|
||||||
GetServerCategoryList() []model.ServerCategoryList
|
GetServerCategoryList() []model.ServerCategoryList
|
||||||
GetTaskList(size int) []model2.TaskDBModel
|
GetTaskList(size int) []model2.TaskDBModel
|
||||||
GetServerAppInfo(id string) model.ServerAppList
|
GetServerAppInfo(id, t string) model.ServerAppList
|
||||||
ShareAppFile(body []byte) string
|
ShareAppFile(body []byte) string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,13 +88,12 @@ func (o *casaService) GetServerCategoryList() []model.ServerCategoryList {
|
|||||||
|
|
||||||
return list
|
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 := make(map[string]string)
|
||||||
|
|
||||||
head["Authorization"] = GetToken()
|
head["Authorization"] = GetToken()
|
||||||
|
infoS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/info/"+id+"?t="+t, head)
|
||||||
infoS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/info/"+id, head)
|
|
||||||
|
|
||||||
info := model.ServerAppList{}
|
info := model.ServerAppList{}
|
||||||
json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
|
json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package service
|
|||||||
import (
|
import (
|
||||||
json2 "encoding/json"
|
json2 "encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -20,8 +21,9 @@ import (
|
|||||||
type DiskService interface {
|
type DiskService interface {
|
||||||
GetPlugInDisk() []string
|
GetPlugInDisk() []string
|
||||||
LSBLK() []model.LSBLKModel
|
LSBLK() []model.LSBLKModel
|
||||||
FormatDisk(path, format string) string
|
SmartCTL(path string) model.SmartctlA
|
||||||
UmountPointAndRemoveDir(path string) string
|
FormatDisk(path, format string) []string
|
||||||
|
UmountPointAndRemoveDir(path string) []string
|
||||||
GetDiskInfo(path string) model.LSBLKModel
|
GetDiskInfo(path string) model.LSBLKModel
|
||||||
DelPartition(path, num string) string
|
DelPartition(path, num string) string
|
||||||
AddPartition(path string) string
|
AddPartition(path string) string
|
||||||
@@ -31,30 +33,60 @@ type DiskService interface {
|
|||||||
SaveMountPoint(m model2.SerialDisk)
|
SaveMountPoint(m model2.SerialDisk)
|
||||||
DeleteMountPoint(path, mountPoint string)
|
DeleteMountPoint(path, mountPoint string)
|
||||||
DeleteMount(id string)
|
DeleteMount(id string)
|
||||||
|
UpdateMountPoint(m model2.SerialDisk)
|
||||||
|
RemoveLSBLKCache()
|
||||||
}
|
}
|
||||||
type diskService struct {
|
type diskService struct {
|
||||||
log loger2.OLog
|
log loger2.OLog
|
||||||
db *gorm.DB
|
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 {
|
func (d *diskService) GetPlugInDisk() []string {
|
||||||
return command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetPlugInDisk")
|
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)
|
r := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;FormatDisk " + path + " " + format)
|
||||||
fmt.Println(r)
|
return r
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//移除挂载点,删除目录
|
//移除挂载点,删除目录
|
||||||
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)
|
r := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;UMountPorintAndRemoveDir " + path)
|
||||||
fmt.Println(r)
|
return r
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//删除分区
|
//删除分区
|
||||||
@@ -66,8 +98,7 @@ func (d *diskService) DelPartition(path, num string) string {
|
|||||||
|
|
||||||
//part
|
//part
|
||||||
func (d *diskService) AddPartition(path string) string {
|
func (d *diskService) AddPartition(path string) string {
|
||||||
r := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;AddPartition " + path)
|
command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;AddPartition " + path)
|
||||||
fmt.Println(r)
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,11 +109,10 @@ func (d *diskService) AddAllPartition(path string) {
|
|||||||
//获取硬盘详情
|
//获取硬盘详情
|
||||||
func (d *diskService) GetDiskInfoByPath(path string) *disk.UsageStat {
|
func (d *diskService) GetDiskInfoByPath(path string) *disk.UsageStat {
|
||||||
diskInfo, err := disk.Usage(path + "1")
|
diskInfo, err := disk.Usage(path + "1")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
fmt.Println(path)
|
|
||||||
fmt.Println(diskInfo)
|
|
||||||
diskInfo.UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.UsedPercent), 64)
|
diskInfo.UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.UsedPercent), 64)
|
||||||
diskInfo.InodesUsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.InodesUsedPercent), 64)
|
diskInfo.InodesUsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.InodesUsedPercent), 64)
|
||||||
return diskInfo
|
return diskInfo
|
||||||
@@ -91,7 +121,6 @@ func (d *diskService) GetDiskInfoByPath(path string) *disk.UsageStat {
|
|||||||
//get disk details
|
//get disk details
|
||||||
func (d *diskService) LSBLK() []model.LSBLKModel {
|
func (d *diskService) LSBLK() []model.LSBLKModel {
|
||||||
key := "system_lsblk"
|
key := "system_lsblk"
|
||||||
|
|
||||||
var n []model.LSBLKModel
|
var n []model.LSBLKModel
|
||||||
|
|
||||||
if result, ok := Cache.Get(key); ok {
|
if result, ok := Cache.Get(key); ok {
|
||||||
@@ -151,7 +180,7 @@ func (d *diskService) LSBLK() []model.LSBLKModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(n) > 0 {
|
if len(n) > 0 {
|
||||||
Cache.Add(key, n, time.Second*10)
|
Cache.Add(key, n, time.Second*100)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
@@ -162,6 +191,7 @@ func (d *diskService) GetDiskInfo(path string) model.LSBLKModel {
|
|||||||
d.log.Error("lsblk exec error,str")
|
d.log.Error("lsblk exec error,str")
|
||||||
return model.LSBLKModel{}
|
return model.LSBLKModel{}
|
||||||
}
|
}
|
||||||
|
|
||||||
var ml []model.LSBLKModel
|
var ml []model.LSBLKModel
|
||||||
err := json2.Unmarshal([]byte(gjson.Get(string(str), "blockdevices").String()), &ml)
|
err := json2.Unmarshal([]byte(gjson.Get(string(str), "blockdevices").String()), &ml)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -169,9 +199,13 @@ func (d *diskService) GetDiskInfo(path string) model.LSBLKModel {
|
|||||||
d.log.Error("json ummarshal error", err)
|
d.log.Error("json ummarshal error", err)
|
||||||
return model.LSBLKModel{}
|
return model.LSBLKModel{}
|
||||||
}
|
}
|
||||||
//todo 需要判断长度
|
|
||||||
m := ml[0]
|
m := model.LSBLKModel{}
|
||||||
//声明数组
|
if len(ml) > 0 {
|
||||||
|
m = ml[0]
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
// 下面为计算是否可以继续分区的部分,暂时不需要
|
||||||
chiArr := make(map[string]string)
|
chiArr := make(map[string]string)
|
||||||
chiList := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetPartitionSectors " + m.Path)
|
chiList := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetPartitionSectors " + m.Path)
|
||||||
if len(chiList) == 0 {
|
if len(chiList) == 0 {
|
||||||
@@ -182,7 +216,6 @@ func (d *diskService) GetDiskInfo(path string) model.LSBLKModel {
|
|||||||
tempArr := strings.Split(chiList[i], ",")
|
tempArr := strings.Split(chiList[i], ",")
|
||||||
chiArr[tempArr[0]] = chiList[i]
|
chiArr[tempArr[0]] = chiList[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
var maxSector uint64 = 0
|
var maxSector uint64 = 0
|
||||||
for i := 0; i < len(m.Children); i++ {
|
for i := 0; i < len(m.Children); i++ {
|
||||||
tempArr := strings.Split(chiArr[m.Children[i].Path], ",")
|
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 {
|
if m.Children[i].EndSector > maxSector {
|
||||||
maxSector = m.Children[i].EndSector
|
maxSector = m.Children[i].EndSector
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
diskEndSector := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetDiskSizeAndSectors " + m.Path)
|
diskEndSector := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetDiskSizeAndSectors " + m.Path)
|
||||||
|
|
||||||
if len(diskEndSector) < 2 {
|
if len(diskEndSector) < 2 {
|
||||||
d.log.Error("diskEndSector length error")
|
d.log.Error("diskEndSector length error")
|
||||||
}
|
}
|
||||||
|
|
||||||
diskEndSectorInt, _ := strconv.ParseUint(diskEndSector[len(diskEndSector)-1], 10, 64)
|
diskEndSectorInt, _ := strconv.ParseUint(diskEndSector[len(diskEndSector)-1], 10, 64)
|
||||||
if (diskEndSectorInt-maxSector)*m.MinIO/1024/1024 > 100 {
|
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) {
|
func (d *diskService) SaveMountPoint(m model2.SerialDisk) {
|
||||||
|
d.db.Where("serial = ?", m.Serial).Delete(&model2.SerialDisk{})
|
||||||
d.db.Create(&m)
|
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) {
|
func (d *diskService) DeleteMount(id string) {
|
||||||
|
|
||||||
d.db.Delete(&model2.SerialDisk{}).Where("id = ?", id)
|
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) {
|
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)
|
command2.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;do_umount " + path)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ type SerialDisk struct {
|
|||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
State int `json:"state"`
|
State int `json:"state"`
|
||||||
MountPoint string `json:"mount_point"`
|
MountPoint string `json:"mount_point"`
|
||||||
|
CreatedAt int64 `json:"created_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *SerialDisk) TableName() string {
|
func (p *SerialDisk) TableName() string {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||||
@@ -86,10 +87,10 @@ func (c *zima) GetDirPath(path string) []model.Path {
|
|||||||
|
|
||||||
if strings.Count(path, "/") > 0 {
|
if strings.Count(path, "/") > 0 {
|
||||||
for _, l := range ls {
|
for _, l := range ls {
|
||||||
dirs = append(dirs, model.Path{Name: l.Name(), Path: path + "/" + l.Name(), IsDir: l.IsDir()})
|
dirs = append(dirs, model.Path{Name: l.Name(), Path: path + "/" + l.Name(), IsDir: l.IsDir(), Date: l.ModTime()})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dirs = append(dirs, model.Path{Name: "DATA", Path: "/DATA/", IsDir: true})
|
dirs = append(dirs, model.Path{Name: "DATA", Path: "/DATA/", IsDir: true, Date: time.Now()})
|
||||||
}
|
}
|
||||||
return dirs
|
return dirs
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,4 +9,35 @@ version_0_2_3() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# add in v0.2.5
|
||||||
|
|
||||||
|
readonly CASA_DEPANDS="curl smartmontools parted fdisk partprobe"
|
||||||
|
|
||||||
|
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_3
|
||||||
|
|
||||||
|
version_0_2_5
|
||||||
|
|||||||
@@ -73,10 +73,8 @@ UMountPorintAndRemoveDir() {
|
|||||||
if [[ -z ${MOUNT_POINT} ]]; then
|
if [[ -z ${MOUNT_POINT} ]]; then
|
||||||
${log} "Warning: ${DEVICE} is not mounted"
|
${log} "Warning: ${DEVICE} is not mounted"
|
||||||
else
|
else
|
||||||
umount -l ${DEVICE}
|
umount -lf ${DEVICE}
|
||||||
${log} "Unmounted ${DEVICE} from ${MOUNT_POINT}"
|
|
||||||
/bin/rmdir "${MOUNT_POINT}"
|
/bin/rmdir "${MOUNT_POINT}"
|
||||||
sed -i.bak "\@${MOUNT_POINT}@d" /var/log/usb-mount.track
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,11 +87,11 @@ FormatDisk() {
|
|||||||
elif [ "$2" == "ntfs" ]; then
|
elif [ "$2" == "ntfs" ]; then
|
||||||
mkfs.ntfs $1
|
mkfs.ntfs $1
|
||||||
elif [ "$2" == "ext4" ]; then
|
elif [ "$2" == "ext4" ]; then
|
||||||
mkfs.ext4 -F $1
|
mkfs.ext4 -m 1 -F $1
|
||||||
elif [ "$2" == "exfat" ]; then
|
elif [ "$2" == "exfat" ]; then
|
||||||
mkfs.exfat $1
|
mkfs.exfat $1
|
||||||
else
|
else
|
||||||
mkfs.ext4 -F $1
|
mkfs.ext4 -m 1 -F $1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,12 +116,10 @@ AddPartition() {
|
|||||||
|
|
||||||
parted -s $1 mkpart primary ext4 0 100%
|
parted -s $1 mkpart primary ext4 0 100%
|
||||||
|
|
||||||
mkfs.ext4 $11
|
mkfs.ext4 -m 1 $11
|
||||||
|
|
||||||
partprobe $1
|
partprobe $1
|
||||||
|
|
||||||
# mount $11 $2
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#磁盘类型
|
#磁盘类型
|
||||||
@@ -148,14 +144,14 @@ GetDiskHealthState() {
|
|||||||
#result bytes
|
#result bytes
|
||||||
#result sectors
|
#result sectors
|
||||||
GetDiskSizeAndSectors() {
|
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
|
#param 磁盘路径 /dev/sda
|
||||||
#result start,end,sectors
|
#result start,end,sectors
|
||||||
GetPartitionSectors() {
|
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 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
|
|
||||||
# copy to /casaOS/util/shell path
|
# copy to /casaOS/util/shell path
|
||||||
# chmod 755
|
# chmod 755
|
||||||
@@ -30,23 +30,32 @@ do_mount() {
|
|||||||
|
|
||||||
# Figure out a mount point to use
|
# Figure out a mount point to use
|
||||||
# LABEL=${ID_FS_LABEL}
|
# LABEL=${ID_FS_LABEL}
|
||||||
LABEL=${DEVBASE}
|
# LABEL=${DEVBASE}
|
||||||
if grep -q " /mnt/casa_${LABEL} " /etc/mtab; then
|
# if grep -q " /DATA/USB_${LABEL} " /etc/mtab; then
|
||||||
# Already in use, make a unique one
|
# # Already in use, make a unique one
|
||||||
LABEL+="-${DEVBASE}"
|
# LABEL+="-${DEVBASE}"
|
||||||
fi
|
# fi
|
||||||
DEV_LABEL="${LABEL}"
|
# DEV_LABEL="${LABEL}"
|
||||||
|
|
||||||
# Use the device name in case the drive doesn't have label
|
# # Use the device name in case the drive doesn't have label
|
||||||
if [ -z ${DEV_LABEL} ]; then
|
# if [ -z ${DEV_LABEL} ]; then
|
||||||
DEV_LABEL="${DEVBASE}"
|
# DEV_LABEL="${DEVBASE}"
|
||||||
fi
|
# fi
|
||||||
|
|
||||||
MOUNT_POINT="/mnt/casa_${DEV_LABEL}"
|
MOUNT_POINT="/DATA/USB_Storage1"
|
||||||
|
arr=("/DATA/USB_Storage1" "/DATA/USB_Storage2" "/DATA/USB_Storage3" "/DATA/USB_Storage4" "/DATA/USB_Storage5" "/DATA/USB_Storage6" "/DATA/USB_Storage7" "/DATA/USB_Storage8" "/DATA/USB_Storage9" "/DATA/USB_Storage10" "/DATA/USB_Storage11" "/DATA/USB_Storage12")
|
||||||
|
for folder in ${arr[@]}; do
|
||||||
|
#如果文件夹不存在,创建文件夹
|
||||||
|
if [ ! -d "$folder" ]; then
|
||||||
|
mkdir -p ${folder}
|
||||||
|
MOUNT_POINT=$folder
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
${log} "Mount point: ${MOUNT_POINT}"
|
${log} "Mount point: ${MOUNT_POINT}"
|
||||||
|
|
||||||
mkdir -p ${MOUNT_POINT}
|
|
||||||
|
|
||||||
# # Global mount options
|
# # Global mount options
|
||||||
# OPTS="rw,relatime"
|
# OPTS="rw,relatime"
|
||||||
@@ -84,7 +93,7 @@ do_mount() {
|
|||||||
mount -t iso9660 ${DEVICE} ${MOUNT_POINT}
|
mount -t iso9660 ${DEVICE} ${MOUNT_POINT}
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
/bin/rmdir "${MOUNT_POINT}"
|
/bin/rmdir "${MOUNT_POINT}"
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
const CURRENTVERSION = "0.2.5"
|
const CURRENTVERSION = "0.2.6"
|
||||||
const BODY = "<li>New App Store</li><li>Fix minor bugs</li>"
|
|
||||||
|
const BODY = "<li>Fix a disk that cannot be formatted under certain circumstances</li>"
|
||||||
|
|||||||
BIN
web/img/storage.d487ddb6.png
Normal file
BIN
web/img/storage.d487ddb6.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
651
web/js/2.js
651
web/js/2.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
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user