mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-11-08 02:36:01 +08:00
144 lines
4 KiB
Go
144 lines
4 KiB
Go
package service
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
|
"github.com/1Panel-dev/1Panel/agent/buserr"
|
|
"github.com/1Panel-dev/1Panel/agent/global"
|
|
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
|
|
"github.com/1Panel-dev/1Panel/agent/app/dto/response"
|
|
)
|
|
|
|
type DiskService struct{}
|
|
|
|
type IDiskService interface {
|
|
GetCompleteDiskInfo() (*response.CompleteDiskInfo, error)
|
|
PartitionDisk(req request.DiskPartitionRequest) (string, error)
|
|
MountDisk(req request.DiskMountRequest) error
|
|
UnmountDisk(req request.DiskUnmountRequest) error
|
|
}
|
|
|
|
func NewIDiskService() IDiskService {
|
|
return &DiskService{}
|
|
}
|
|
|
|
func (s *DiskService) GetCompleteDiskInfo() (*response.CompleteDiskInfo, error) {
|
|
output, err := cmd.RunDefaultWithStdoutBashC("lsblk -P -o NAME,SIZE,TYPE,MOUNTPOINT,FSTYPE,MODEL,SERIAL,TRAN,ROTA")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to execute lsblk command: %v", err)
|
|
}
|
|
|
|
diskInfos, err := parseLsblkOutput(output)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to parse lsblk output: %v", err)
|
|
}
|
|
|
|
result := organizeDiskInfo(diskInfos)
|
|
return &result, nil
|
|
}
|
|
|
|
func (s *DiskService) PartitionDisk(req request.DiskPartitionRequest) (string, error) {
|
|
if !strings.HasPrefix("/dev", req.Device) {
|
|
req.Device = "/dev/" + req.Device
|
|
}
|
|
if !deviceExists(req.Device) {
|
|
return "", buserr.WithName("DeviceNotFound", req.Device)
|
|
}
|
|
|
|
if isDeviceMounted(req.Device) {
|
|
return "", buserr.WithName("DeviceIsMounted", req.Device)
|
|
}
|
|
|
|
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(10 * time.Second))
|
|
if err := cmdMgr.RunBashC(fmt.Sprintf("partprobe %s", req.Device)); err != nil {
|
|
return "", buserr.WithErr("PartitionDiskErr", err)
|
|
}
|
|
|
|
if err := cmdMgr.RunBashC(fmt.Sprintf("parted -s %s mklabel gpt", req.Device)); err != nil {
|
|
return "", buserr.WithErr("PartitionDiskErr", err)
|
|
}
|
|
|
|
if err := cmdMgr.RunBashC(fmt.Sprintf("parted -s %s mkpart primary 1MiB 100%%", req.Device)); err != nil {
|
|
return "", buserr.WithErr("PartitionDiskErr", err)
|
|
}
|
|
|
|
if err := cmdMgr.RunBashC(fmt.Sprintf("partprobe %s", req.Device)); err != nil {
|
|
return "", buserr.WithErr("PartitionDiskErr", err)
|
|
}
|
|
partition := req.Device + "1"
|
|
|
|
formatReq := dto.DiskFormatRequest{
|
|
Device: partition,
|
|
Filesystem: req.Filesystem,
|
|
Label: req.Label,
|
|
}
|
|
if err := formatDisk(formatReq); err != nil {
|
|
return "", buserr.WithErr("FormatDiskErr", err)
|
|
}
|
|
|
|
if req.AutoMount && req.MountPoint != "" {
|
|
mountReq := request.DiskMountRequest{
|
|
Device: partition,
|
|
MountPoint: req.MountPoint,
|
|
Filesystem: req.Filesystem,
|
|
}
|
|
if err := s.MountDisk(mountReq); err != nil {
|
|
return "", buserr.WithErr("MountDiskErr", err)
|
|
}
|
|
}
|
|
|
|
return partition, nil
|
|
}
|
|
|
|
func (s *DiskService) MountDisk(req request.DiskMountRequest) error {
|
|
if !deviceExists(req.Device) {
|
|
return buserr.WithName("DeviceNotFound", req.Device)
|
|
}
|
|
|
|
if err := os.MkdirAll(req.MountPoint, 0755); err != nil {
|
|
return err
|
|
}
|
|
|
|
fileSystem, err := getFilesystemType(req.Device)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if fileSystem == "" {
|
|
formatReq := dto.DiskFormatRequest{
|
|
Device: req.Device,
|
|
Filesystem: req.Filesystem,
|
|
}
|
|
if err := formatDisk(formatReq); err != nil {
|
|
return buserr.WithErr("FormatDiskErr", err)
|
|
}
|
|
}
|
|
|
|
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(1 * time.Minute))
|
|
if err := cmdMgr.RunBashC(fmt.Sprintf("mount -t %s %s %s", req.Filesystem, req.Device, req.MountPoint)); err != nil {
|
|
return buserr.WithErr("MountDiskErr", err)
|
|
}
|
|
|
|
if err := addToFstabWithOptions(req.Device, req.MountPoint, req.Filesystem, ""); err != nil {
|
|
return buserr.WithErr("MountDiskErr", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *DiskService) UnmountDisk(req request.DiskUnmountRequest) error {
|
|
if !isPointMounted(req.MountPoint) {
|
|
return buserr.New("MountDiskErr")
|
|
}
|
|
if err := cmd.RunDefaultBashC(fmt.Sprintf("umount -f %s", req.MountPoint)); err != nil {
|
|
return buserr.WithErr("MountDiskErr", err)
|
|
}
|
|
if err := removeFromFstab(req.MountPoint); err != nil {
|
|
global.LOG.Errorf("remove %s mountPoint err: %v", req.MountPoint, err)
|
|
}
|
|
return nil
|
|
}
|