|
@@ -2,17 +2,11 @@ package diskcapacity
|
|
|
|
|
|
import (
|
|
import (
|
|
"encoding/json"
|
|
"encoding/json"
|
|
- "errors"
|
|
|
|
"net/http"
|
|
"net/http"
|
|
"path/filepath"
|
|
"path/filepath"
|
|
- "runtime"
|
|
|
|
- "strings"
|
|
|
|
- "log"
|
|
|
|
- "strconv"
|
|
|
|
- "os/exec"
|
|
|
|
|
|
|
|
"imuslab.com/arozos/mod/common"
|
|
"imuslab.com/arozos/mod/common"
|
|
- "imuslab.com/arozos/mod/disk/diskspace"
|
|
|
|
|
|
+ "imuslab.com/arozos/mod/disk/diskcapacity/dftool"
|
|
"imuslab.com/arozos/mod/user"
|
|
"imuslab.com/arozos/mod/user"
|
|
)
|
|
)
|
|
|
|
|
|
@@ -28,14 +22,6 @@ type Resolver struct {
|
|
UserHandler *user.UserHandler
|
|
UserHandler *user.UserHandler
|
|
}
|
|
}
|
|
|
|
|
|
-type Capacity struct {
|
|
|
|
- PhysicalDevice string //The ID of the physical device, like C:/ or /dev/sda1
|
|
|
|
- MountingHierarchy string //The Mounting Hierarchy of the vroot
|
|
|
|
- Used int64 //Used capacity in bytes
|
|
|
|
- Avilable int64 //Avilable capacity in bytes
|
|
|
|
- Total int64 //Total capacity in bytes
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
//Create a new Capacity Resolver with the given user handler
|
|
//Create a new Capacity Resolver with the given user handler
|
|
func NewCapacityResolver(u *user.UserHandler) *Resolver {
|
|
func NewCapacityResolver(u *user.UserHandler) *Resolver {
|
|
return &Resolver{
|
|
return &Resolver{
|
|
@@ -78,7 +64,7 @@ func (cr *Resolver) HandleCapacityResolving(w http.ResponseWriter, r *http.Reque
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
-func (cr *Resolver) ResolveCapacityInfo(username string, vpath string) (*Capacity, error) {
|
|
|
|
|
|
+func (cr *Resolver) ResolveCapacityInfo(username string, vpath string) (*dftool.Capacity, error) {
|
|
//Resolve the vpath for this user
|
|
//Resolve the vpath for this user
|
|
userinfo, err := cr.UserHandler.GetUserInfoFromUsername(username)
|
|
userinfo, err := cr.UserHandler.GetUserInfoFromUsername(username)
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -91,83 +77,6 @@ func (cr *Resolver) ResolveCapacityInfo(username string, vpath string) (*Capacit
|
|
}
|
|
}
|
|
|
|
|
|
realpath = filepath.ToSlash(filepath.Clean(realpath))
|
|
realpath = filepath.ToSlash(filepath.Clean(realpath))
|
|
- return cr.GetCapacityInfo(realpath)
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-func (cr *Resolver) GetCapacityInfo(realpath string) (*Capacity, error) {
|
|
|
|
- rpathAbs, err := filepath.Abs(realpath)
|
|
|
|
- if err != nil {
|
|
|
|
- return nil, err
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if runtime.GOOS == "windows" {
|
|
|
|
- //Windows
|
|
|
|
- //Extract disk ID from path
|
|
|
|
- rpathAbs = filepath.ToSlash(filepath.Clean(rpathAbs))
|
|
|
|
- diskRoot := strings.Split(rpathAbs, "/")[0]
|
|
|
|
-
|
|
|
|
- //Match the disk space info generated from diskspace
|
|
|
|
- logicDiskInfo := diskspace.GetAllLogicDiskInfo()
|
|
|
|
- for _, ldi := range logicDiskInfo {
|
|
|
|
- if strings.TrimSpace(ldi.Device) == strings.TrimSpace(diskRoot) {
|
|
|
|
- //Matching device ID
|
|
|
|
- return &Capacity{
|
|
|
|
- PhysicalDevice: ldi.Device,
|
|
|
|
- Used: ldi.Used,
|
|
|
|
- Avilable: ldi.Available,
|
|
|
|
- Total: ldi.Volume,
|
|
|
|
- }, nil
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
- //Assume Linux or Mac
|
|
|
|
- //Use command: df -P {abs_path}
|
|
|
|
- cmd := exec.Command("df", "-P", rpathAbs)
|
|
|
|
- log.Println("df", "-P", rpathAbs)
|
|
|
|
- out, err := cmd.CombinedOutput()
|
|
|
|
- if err != nil {
|
|
|
|
- return nil, err
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //Get the last line of the output
|
|
|
|
- diskInfo := strings.TrimSpace(string(out))
|
|
|
|
- tmp := strings.Split(diskInfo, "\n")
|
|
|
|
- targetDiskInfo := strings.Join(tmp[len(tmp) - 1:], " ");
|
|
|
|
- for strings.Contains(targetDiskInfo, " "){
|
|
|
|
- targetDiskInfo = strings.ReplaceAll(targetDiskInfo, " ", " ")
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- diskInfoSlice := strings.Split(targetDiskInfo, " ")
|
|
|
|
-
|
|
|
|
- if len(diskInfoSlice) < 4{
|
|
|
|
- return nil, errors.New("Malformed output for df -P")
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //Extract capacity information from df output
|
|
|
|
- total, err := strconv.ParseInt(diskInfoSlice[1], 10, 64)
|
|
|
|
- if err != nil{
|
|
|
|
- return nil, errors.New("Malformed output for df -P")
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- used, err := strconv.ParseInt(diskInfoSlice[2], 10, 64)
|
|
|
|
- if err != nil{
|
|
|
|
- return nil, errors.New("Malformed output for df -P")
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- availbe, err := strconv.ParseInt(diskInfoSlice[3], 10, 64)
|
|
|
|
- if err != nil{
|
|
|
|
- return nil, errors.New("Malformed output for df -P")
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //Return the capacity info struct, capacity is reported in 1024 bytes block
|
|
|
|
- return &Capacity{
|
|
|
|
- PhysicalDevice: diskInfoSlice[0],
|
|
|
|
- Used: used * 1024,
|
|
|
|
- Avilable: availbe * 1024,
|
|
|
|
- Total: total * 1024,
|
|
|
|
- }, nil
|
|
|
|
- }
|
|
|
|
|
|
|
|
- return nil, errors.New("Unable to resolve matching disk capacity information")
|
|
|
|
|
|
+ return dftool.GetCapacityInfoFromPath(realpath)
|
|
}
|
|
}
|