2021-05-08 18:00:33 +08:00
|
|
|
|
package application
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2023-11-07 21:05:21 +08:00
|
|
|
|
"context"
|
2023-09-11 22:59:13 +08:00
|
|
|
|
"errors"
|
2022-07-04 20:21:24 +08:00
|
|
|
|
"fmt"
|
2021-05-08 20:50:34 +08:00
|
|
|
|
"io"
|
|
|
|
|
|
"io/fs"
|
2024-04-06 04:03:38 +00:00
|
|
|
|
"mayfly-go/internal/machine/config"
|
2022-09-09 18:26:08 +08:00
|
|
|
|
"mayfly-go/internal/machine/domain/entity"
|
|
|
|
|
|
"mayfly-go/internal/machine/domain/repository"
|
2023-10-30 17:34:56 +08:00
|
|
|
|
"mayfly-go/internal/machine/mcm"
|
2023-12-13 14:01:13 +08:00
|
|
|
|
"mayfly-go/pkg/base"
|
2024-04-19 11:27:29 +00:00
|
|
|
|
"mayfly-go/pkg/contextx"
|
2023-10-26 17:15:49 +08:00
|
|
|
|
"mayfly-go/pkg/errorx"
|
2023-09-07 16:33:53 +08:00
|
|
|
|
"mayfly-go/pkg/logx"
|
2022-06-02 17:41:11 +08:00
|
|
|
|
"mayfly-go/pkg/model"
|
2024-04-06 04:03:38 +00:00
|
|
|
|
"mayfly-go/pkg/utils/bytex"
|
2024-04-09 12:55:51 +08:00
|
|
|
|
"mayfly-go/pkg/utils/collx"
|
2024-04-06 04:03:38 +00:00
|
|
|
|
"mime/multipart"
|
2021-05-08 20:50:34 +08:00
|
|
|
|
"os"
|
2024-04-06 04:03:38 +00:00
|
|
|
|
"path/filepath"
|
2021-05-08 20:50:34 +08:00
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/pkg/sftp"
|
2021-05-08 18:00:33 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
type MachineFileOpParam struct {
|
2024-04-19 11:27:29 +00:00
|
|
|
|
Ua *model.LoginAccount
|
2024-04-09 12:55:51 +08:00
|
|
|
|
MachineId uint64 `json:"machineId" binding:"required" form:"machineId"`
|
|
|
|
|
|
Protocol int `json:"protocol" binding:"required" form:"protocol"`
|
|
|
|
|
|
AuthCertName string `json:"authCertName" binding:"required" form:"authCertName"` // 授权凭证
|
|
|
|
|
|
Path string `json:"path" form:"path"` // 文件路径
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-07-28 18:03:19 +08:00
|
|
|
|
type MachineFile interface {
|
2023-12-13 14:01:13 +08:00
|
|
|
|
base.App[*entity.MachineFile]
|
|
|
|
|
|
|
2021-05-08 18:00:33 +08:00
|
|
|
|
// 分页获取机器文件信息列表
|
2023-10-26 17:15:49 +08:00
|
|
|
|
GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
|
2021-05-08 18:00:33 +08:00
|
|
|
|
|
|
|
|
|
|
// 根据条件获取
|
|
|
|
|
|
GetMachineFile(condition *entity.MachineFile, cols ...string) error
|
|
|
|
|
|
|
2023-11-07 21:05:21 +08:00
|
|
|
|
Save(ctx context.Context, entity *entity.MachineFile) error
|
2021-05-08 18:00:33 +08:00
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
// 获取机器cli
|
|
|
|
|
|
GetMachineCli(authCertName string) (*mcm.Cli, error)
|
2022-11-18 17:52:30 +08:00
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
GetRdpFilePath(ua *model.LoginAccount, path string) string
|
2024-04-06 04:03:38 +00:00
|
|
|
|
|
2021-05-08 20:50:34 +08:00
|
|
|
|
/** sftp 相关操作 **/
|
|
|
|
|
|
|
2022-07-04 20:21:24 +08:00
|
|
|
|
// 创建目录
|
2024-04-19 11:27:29 +00:00
|
|
|
|
MkDir(ctx context.Context, opParam *MachineFileOpParam) (*mcm.MachineInfo, error)
|
2022-07-04 20:21:24 +08:00
|
|
|
|
|
|
|
|
|
|
// 创建文件
|
2024-04-19 11:27:29 +00:00
|
|
|
|
CreateFile(ctx context.Context, opParam *MachineFileOpParam) (*mcm.MachineInfo, error)
|
2022-07-04 20:21:24 +08:00
|
|
|
|
|
2021-05-08 20:50:34 +08:00
|
|
|
|
// 读取目录
|
2024-04-19 11:27:29 +00:00
|
|
|
|
ReadDir(ctx context.Context, opParam *MachineFileOpParam) ([]fs.FileInfo, error)
|
2021-05-08 20:50:34 +08:00
|
|
|
|
|
2023-07-05 00:26:00 +08:00
|
|
|
|
// 获取指定目录内容大小
|
2024-04-19 11:27:29 +00:00
|
|
|
|
GetDirSize(ctx context.Context, opParam *MachineFileOpParam) (string, error)
|
2023-07-05 00:26:00 +08:00
|
|
|
|
|
|
|
|
|
|
// 获取文件stat
|
2024-04-19 11:27:29 +00:00
|
|
|
|
FileStat(ctx context.Context, opParam *MachineFileOpParam) (string, error)
|
2023-07-05 00:26:00 +08:00
|
|
|
|
|
2021-05-08 20:50:34 +08:00
|
|
|
|
// 读取文件内容
|
2024-04-19 11:27:29 +00:00
|
|
|
|
ReadFile(ctx context.Context, opParam *MachineFileOpParam) (*sftp.File, *mcm.MachineInfo, error)
|
2021-05-08 20:50:34 +08:00
|
|
|
|
|
|
|
|
|
|
// 写文件
|
2024-04-19 11:27:29 +00:00
|
|
|
|
WriteFileContent(ctx context.Context, opParam *MachineFileOpParam, content []byte) (*mcm.MachineInfo, error)
|
2021-05-08 20:50:34 +08:00
|
|
|
|
|
|
|
|
|
|
// 文件上传
|
2024-04-19 11:27:29 +00:00
|
|
|
|
UploadFile(ctx context.Context, opParam *MachineFileOpParam, filename string, reader io.Reader) (*mcm.MachineInfo, error)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
UploadFiles(ctx context.Context, opParam *MachineFileOpParam, basePath string, fileHeaders []*multipart.FileHeader, paths []string) (*mcm.MachineInfo, error)
|
2021-05-08 20:50:34 +08:00
|
|
|
|
|
|
|
|
|
|
// 移除文件
|
2024-04-19 11:27:29 +00:00
|
|
|
|
RemoveFile(ctx context.Context, opParam *MachineFileOpParam, path ...string) (*mcm.MachineInfo, error)
|
2023-09-07 16:33:53 +08:00
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
Copy(ctx context.Context, opParam *MachineFileOpParam, toPath string, path ...string) (*mcm.MachineInfo, error)
|
2023-09-07 16:33:53 +08:00
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
Mv(ctx context.Context, opParam *MachineFileOpParam, toPath string, path ...string) (*mcm.MachineInfo, error)
|
2023-09-07 16:33:53 +08:00
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
Rename(ctx context.Context, opParam *MachineFileOpParam, newname string) (*mcm.MachineInfo, error)
|
2021-05-08 18:00:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-07-28 18:03:19 +08:00
|
|
|
|
type machineFileAppImpl struct {
|
2023-12-13 14:01:13 +08:00
|
|
|
|
base.AppImpl[*entity.MachineFile, repository.MachineFile]
|
|
|
|
|
|
|
2024-01-23 19:30:28 +08:00
|
|
|
|
machineApp Machine `inject:"MachineApp"`
|
2024-01-21 22:52:20 +08:00
|
|
|
|
}
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
2024-01-21 22:52:20 +08:00
|
|
|
|
// 注入MachineFileRepo
|
|
|
|
|
|
func (m *machineFileAppImpl) InjectMachineFileRepo(repo repository.MachineFile) {
|
|
|
|
|
|
m.Repo = repo
|
2021-05-08 18:00:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 分页获取机器脚本信息列表
|
2023-10-26 17:15:49 +08:00
|
|
|
|
func (m *machineFileAppImpl) GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
2024-01-23 19:30:28 +08:00
|
|
|
|
return m.GetRepo().GetPageList(condition, pageParam, toEntity, orderBy...)
|
2021-05-08 18:00:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 根据条件获取
|
2021-07-28 18:03:19 +08:00
|
|
|
|
func (m *machineFileAppImpl) GetMachineFile(condition *entity.MachineFile, cols ...string) error {
|
2024-04-28 23:45:57 +08:00
|
|
|
|
return m.GetByCond(model.NewModelCond(condition).Columns(cols...))
|
2021-05-08 18:00:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-05-08 20:50:34 +08:00
|
|
|
|
// 保存机器文件配置
|
2023-11-07 21:05:21 +08:00
|
|
|
|
func (m *machineFileAppImpl) Save(ctx context.Context, mf *entity.MachineFile) error {
|
2024-05-05 14:53:30 +08:00
|
|
|
|
_, err := m.machineApp.GetById(mf.MachineId, "Name")
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return errorx.NewBiz("该机器不存在")
|
|
|
|
|
|
}
|
2021-05-08 18:00:33 +08:00
|
|
|
|
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if mf.Id != 0 {
|
2024-01-23 19:30:28 +08:00
|
|
|
|
return m.UpdateById(ctx, mf)
|
2021-05-08 18:00:33 +08:00
|
|
|
|
}
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
2024-01-23 19:30:28 +08:00
|
|
|
|
return m.Insert(ctx, mf)
|
2021-05-08 18:00:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
func (m *machineFileAppImpl) ReadDir(ctx context.Context, opParam *MachineFileOpParam) ([]fs.FileInfo, error) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
path := opParam.Path
|
|
|
|
|
|
if !strings.HasSuffix(path, "/") {
|
|
|
|
|
|
path = path + "/"
|
2024-04-06 04:03:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果是rdp,则直接读取本地文件
|
2024-04-09 12:55:51 +08:00
|
|
|
|
if opParam.Protocol == entity.MachineProtocolRdp {
|
2024-04-19 11:27:29 +00:00
|
|
|
|
path = m.GetRdpFilePath(contextx.GetLoginAccount(ctx), path)
|
2024-04-09 12:55:51 +08:00
|
|
|
|
dirs, err := os.ReadDir(path)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return collx.ArrayMap[fs.DirEntry, fs.FileInfo](dirs, func(val fs.DirEntry) fs.FileInfo {
|
|
|
|
|
|
fi, _ := val.Info()
|
|
|
|
|
|
return fi
|
|
|
|
|
|
}), nil
|
2021-05-08 20:50:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
_, sftpCli, err := m.GetMachineSftpCli(opParam)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
2024-04-09 12:55:51 +08:00
|
|
|
|
return sftpCli.ReadDir(path)
|
2021-05-08 20:50:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
func (m *machineFileAppImpl) GetDirSize(ctx context.Context, opParam *MachineFileOpParam) (string, error) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
path := opParam.Path
|
2024-04-06 04:03:38 +00:00
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
if opParam.Protocol == entity.MachineProtocolRdp {
|
2024-04-19 11:27:29 +00:00
|
|
|
|
dirPath := m.GetRdpFilePath(contextx.GetLoginAccount(ctx), path)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
|
|
|
|
|
|
// 递归计算目录下文件大小
|
|
|
|
|
|
var totalSize int64
|
|
|
|
|
|
err := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
|
|
|
|
|
|
if info.IsDir() {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
// 忽略目录本身
|
|
|
|
|
|
if path != dirPath {
|
|
|
|
|
|
totalSize += info.Size()
|
|
|
|
|
|
}
|
|
|
|
|
|
return nil
|
|
|
|
|
|
})
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return "", err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return bytex.FormatSize(totalSize), nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
mcli, err := m.GetMachineCli(opParam.AuthCertName)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return "", err
|
|
|
|
|
|
}
|
2023-09-11 22:59:13 +08:00
|
|
|
|
res, err := mcli.Run(fmt.Sprintf("du -sh %s", path))
|
2023-07-05 00:26:00 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
// 若存在目录为空,则可能会返回如下内容。最后一行即为真正目录内容所占磁盘空间大小
|
|
|
|
|
|
//du: cannot access ‘/proc/19087/fd/3’: No such file or directory\n
|
|
|
|
|
|
//du: cannot access ‘/proc/19087/fdinfo/3’: No such file or directory\n
|
|
|
|
|
|
//18G /\n
|
|
|
|
|
|
if res == "" {
|
2023-10-26 17:15:49 +08:00
|
|
|
|
return "", errorx.NewBiz("获取目录大小失败: %s", err.Error())
|
2023-07-05 00:26:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
strs := strings.Split(res, "\n")
|
|
|
|
|
|
res = strs[len(strs)-2]
|
|
|
|
|
|
|
|
|
|
|
|
if !strings.Contains(res, "\t") {
|
2023-10-26 17:15:49 +08:00
|
|
|
|
return "", errorx.NewBiz(res)
|
2023-07-05 00:26:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// 返回 32K\t/tmp\n
|
2023-10-26 17:15:49 +08:00
|
|
|
|
return strings.Split(res, "\t")[0], nil
|
2023-07-05 00:26:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
func (m *machineFileAppImpl) FileStat(ctx context.Context, opParam *MachineFileOpParam) (string, error) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
path := opParam.Path
|
|
|
|
|
|
if opParam.Protocol == entity.MachineProtocolRdp {
|
2024-04-19 11:27:29 +00:00
|
|
|
|
path = m.GetRdpFilePath(contextx.GetLoginAccount(ctx), path)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
stat, err := os.Stat(path)
|
|
|
|
|
|
return fmt.Sprintf("%v", stat), err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
mcli, err := m.GetMachineCli(opParam.AuthCertName)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return "", err
|
|
|
|
|
|
}
|
2024-04-09 12:55:51 +08:00
|
|
|
|
return mcli.Run(fmt.Sprintf("stat -L %s", path))
|
2023-07-05 00:26:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
func (m *machineFileAppImpl) MkDir(ctx context.Context, opParam *MachineFileOpParam) (*mcm.MachineInfo, error) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
path := opParam.Path
|
2022-07-04 20:21:24 +08:00
|
|
|
|
if !strings.HasSuffix(path, "/") {
|
|
|
|
|
|
path = path + "/"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
if opParam.Protocol == entity.MachineProtocolRdp {
|
2024-04-19 11:27:29 +00:00
|
|
|
|
path = m.GetRdpFilePath(contextx.GetLoginAccount(ctx), path)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
os.MkdirAll(path, os.ModePerm)
|
|
|
|
|
|
return nil, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
mi, sftpCli, err := m.GetMachineSftpCli(opParam)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sftpCli.MkdirAll(path)
|
|
|
|
|
|
return mi, err
|
2022-07-04 20:21:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
func (m *machineFileAppImpl) CreateFile(ctx context.Context, opParam *MachineFileOpParam) (*mcm.MachineInfo, error) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
path := opParam.Path
|
|
|
|
|
|
if opParam.Protocol == entity.MachineProtocolRdp {
|
2024-04-19 11:27:29 +00:00
|
|
|
|
path = m.GetRdpFilePath(contextx.GetLoginAccount(ctx), path)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
file, err := os.Create(path)
|
|
|
|
|
|
defer file.Close()
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-12 07:53:42 +00:00
|
|
|
|
mi, sftpCli, err := m.GetMachineSftpCli(opParam)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
2023-10-26 17:15:49 +08:00
|
|
|
|
file, err := sftpCli.Create(path)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, errorx.NewBiz("创建文件失败: %s", err.Error())
|
|
|
|
|
|
}
|
2022-07-04 20:21:24 +08:00
|
|
|
|
defer file.Close()
|
2023-10-26 17:15:49 +08:00
|
|
|
|
return mi, err
|
2022-07-04 20:21:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
func (m *machineFileAppImpl) ReadFile(ctx context.Context, opParam *MachineFileOpParam) (*sftp.File, *mcm.MachineInfo, error) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
mi, sftpCli, err := m.GetMachineSftpCli(opParam)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-05-08 20:50:34 +08:00
|
|
|
|
// 读取文件内容
|
2024-04-09 12:55:51 +08:00
|
|
|
|
fc, err := sftpCli.Open(opParam.Path)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
return fc, mi, err
|
2021-05-08 20:50:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 写文件内容
|
2024-04-19 11:27:29 +00:00
|
|
|
|
func (m *machineFileAppImpl) WriteFileContent(ctx context.Context, opParam *MachineFileOpParam, content []byte) (*mcm.MachineInfo, error) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
path := opParam.Path
|
|
|
|
|
|
if opParam.Protocol == entity.MachineProtocolRdp {
|
2024-04-19 11:27:29 +00:00
|
|
|
|
path = m.GetRdpFilePath(contextx.GetLoginAccount(ctx), path)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
file, err := os.Create(path)
|
|
|
|
|
|
defer file.Close()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
file.Write(content)
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
mi, sftpCli, err := m.GetMachineSftpCli(opParam)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
f, err := sftpCli.OpenFile(path, os.O_WRONLY|os.O_TRUNC|os.O_CREATE|os.O_RDWR)
|
2023-09-11 22:59:13 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return mi, err
|
|
|
|
|
|
}
|
2021-05-08 20:50:34 +08:00
|
|
|
|
defer f.Close()
|
|
|
|
|
|
f.Write(content)
|
2023-09-11 22:59:13 +08:00
|
|
|
|
return mi, err
|
2021-05-08 20:50:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 上传文件
|
2024-04-19 11:27:29 +00:00
|
|
|
|
func (m *machineFileAppImpl) UploadFile(ctx context.Context, opParam *MachineFileOpParam, filename string, reader io.Reader) (*mcm.MachineInfo, error) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
path := opParam.Path
|
2021-05-08 20:50:34 +08:00
|
|
|
|
if !strings.HasSuffix(path, "/") {
|
|
|
|
|
|
path = path + "/"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
if opParam.Protocol == entity.MachineProtocolRdp {
|
2024-04-19 11:27:29 +00:00
|
|
|
|
path = m.GetRdpFilePath(contextx.GetLoginAccount(ctx), path)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
file, err := os.Create(path + filename)
|
|
|
|
|
|
defer file.Close()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
io.Copy(file, reader)
|
|
|
|
|
|
return nil, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
mi, sftpCli, err := m.GetMachineSftpCli(opParam)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
createfile, err := sftpCli.Create(path + filename)
|
2023-09-11 22:59:13 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return mi, err
|
|
|
|
|
|
}
|
2021-05-08 20:50:34 +08:00
|
|
|
|
defer createfile.Close()
|
2022-01-28 11:30:11 +08:00
|
|
|
|
io.Copy(createfile, reader)
|
2023-09-11 22:59:13 +08:00
|
|
|
|
return mi, err
|
2021-05-08 20:50:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
func (m *machineFileAppImpl) UploadFiles(ctx context.Context, opParam *MachineFileOpParam, basePath string, fileHeaders []*multipart.FileHeader, paths []string) (*mcm.MachineInfo, error) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
if opParam.Protocol == entity.MachineProtocolRdp {
|
2024-04-19 11:27:29 +00:00
|
|
|
|
baseFolder := m.GetRdpFilePath(contextx.GetLoginAccount(ctx), basePath)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
|
|
|
|
|
|
for i, fileHeader := range fileHeaders {
|
|
|
|
|
|
file, err := fileHeader.Open()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
|
|
|
|
// 创建文件夹
|
|
|
|
|
|
rdpBaseDir := basePath
|
|
|
|
|
|
if !strings.HasSuffix(rdpBaseDir, "/") {
|
|
|
|
|
|
rdpBaseDir = rdpBaseDir + "/"
|
|
|
|
|
|
}
|
|
|
|
|
|
rdpDir := filepath.Dir(rdpBaseDir + paths[i])
|
2024-04-19 11:27:29 +00:00
|
|
|
|
m.MkDir(ctx, &MachineFileOpParam{
|
2024-04-09 12:55:51 +08:00
|
|
|
|
MachineId: opParam.MachineId,
|
|
|
|
|
|
Protocol: opParam.Protocol,
|
|
|
|
|
|
Path: rdpDir,
|
|
|
|
|
|
})
|
2024-04-06 04:03:38 +00:00
|
|
|
|
|
|
|
|
|
|
// 创建文件
|
|
|
|
|
|
if !strings.HasSuffix(baseFolder, "/") {
|
|
|
|
|
|
baseFolder = baseFolder + "/"
|
|
|
|
|
|
}
|
|
|
|
|
|
fileAbsPath := baseFolder + paths[i]
|
|
|
|
|
|
createFile, err := os.Create(fileAbsPath)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
defer createFile.Close()
|
|
|
|
|
|
|
|
|
|
|
|
// 复制文件内容
|
|
|
|
|
|
io.Copy(createFile, file)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return nil, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-05-08 20:50:34 +08:00
|
|
|
|
// 删除文件
|
2024-04-19 11:27:29 +00:00
|
|
|
|
func (m *machineFileAppImpl) RemoveFile(ctx context.Context, opParam *MachineFileOpParam, path ...string) (*mcm.MachineInfo, error) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
if opParam.Protocol == entity.MachineProtocolRdp {
|
|
|
|
|
|
for _, pt := range path {
|
2024-04-19 11:27:29 +00:00
|
|
|
|
pt = m.GetRdpFilePath(contextx.GetLoginAccount(ctx), pt)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
os.RemoveAll(pt)
|
|
|
|
|
|
}
|
|
|
|
|
|
return nil, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
mcli, err := m.GetMachineCli(opParam.AuthCertName)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
2023-10-30 17:34:56 +08:00
|
|
|
|
minfo := mcli.Info
|
2023-09-07 16:33:53 +08:00
|
|
|
|
|
|
|
|
|
|
// 优先使用命令删除(速度快),sftp需要递归遍历删除子文件等
|
2024-04-09 12:55:51 +08:00
|
|
|
|
res, err := mcli.Run(fmt.Sprintf("rm -rf %s", strings.Join(path, " ")))
|
2023-09-07 16:33:53 +08:00
|
|
|
|
if err == nil {
|
2023-09-11 22:59:13 +08:00
|
|
|
|
return minfo, nil
|
2023-09-07 16:33:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
logx.Errorf("使用命令rm删除文件失败: %s", res)
|
2021-05-08 20:50:34 +08:00
|
|
|
|
|
2023-10-26 17:15:49 +08:00
|
|
|
|
sftpCli, err := mcli.GetSftpCli()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return minfo, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
for _, p := range path {
|
2023-09-11 22:59:13 +08:00
|
|
|
|
err = sftpCli.RemoveAll(p)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
2021-05-08 20:50:34 +08:00
|
|
|
|
}
|
2023-09-11 22:59:13 +08:00
|
|
|
|
return minfo, err
|
2023-09-07 16:33:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
func (m *machineFileAppImpl) Copy(ctx context.Context, opParam *MachineFileOpParam, toPath string, path ...string) (*mcm.MachineInfo, error) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
if opParam.Protocol == entity.MachineProtocolRdp {
|
|
|
|
|
|
for _, pt := range path {
|
2024-04-19 11:27:29 +00:00
|
|
|
|
srcPath := m.GetRdpFilePath(contextx.GetLoginAccount(ctx), pt)
|
|
|
|
|
|
targetPath := m.GetRdpFilePath(contextx.GetLoginAccount(ctx), toPath+pt)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
|
|
|
|
|
|
// 打开源文件
|
|
|
|
|
|
srcFile, err := os.Open(srcPath)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
fmt.Println("Error opening source file:", err)
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
// 创建目标文件
|
|
|
|
|
|
destFile, err := os.Create(targetPath)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
fmt.Println("Error creating destination file:", err)
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
io.Copy(destFile, srcFile)
|
|
|
|
|
|
}
|
|
|
|
|
|
return nil, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
mcli, err := m.GetMachineCli(opParam.AuthCertName)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-30 17:34:56 +08:00
|
|
|
|
mi := mcli.Info
|
2024-04-09 12:55:51 +08:00
|
|
|
|
res, err := mcli.Run(fmt.Sprintf("cp -r %s %s", strings.Join(path, " "), toPath))
|
2023-09-11 22:59:13 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return mi, errors.New(res)
|
|
|
|
|
|
}
|
|
|
|
|
|
return mi, err
|
2023-09-07 16:33:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
func (m *machineFileAppImpl) Mv(ctx context.Context, opParam *MachineFileOpParam, toPath string, path ...string) (*mcm.MachineInfo, error) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
if opParam.Protocol == entity.MachineProtocolRdp {
|
|
|
|
|
|
for _, pt := range path {
|
2024-04-06 04:03:38 +00:00
|
|
|
|
// 获取文件名
|
|
|
|
|
|
filename := filepath.Base(pt)
|
2024-04-09 12:55:51 +08:00
|
|
|
|
if !strings.HasSuffix(toPath, "/") {
|
|
|
|
|
|
toPath += "/"
|
2024-04-06 04:03:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
srcPath := m.GetRdpFilePath(contextx.GetLoginAccount(ctx), pt)
|
|
|
|
|
|
targetPath := m.GetRdpFilePath(contextx.GetLoginAccount(ctx), toPath+filename)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
os.Rename(srcPath, targetPath)
|
|
|
|
|
|
}
|
|
|
|
|
|
return nil, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
mcli, err := m.GetMachineCli(opParam.AuthCertName)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-30 17:34:56 +08:00
|
|
|
|
mi := mcli.Info
|
2024-04-09 12:55:51 +08:00
|
|
|
|
res, err := mcli.Run(fmt.Sprintf("mv %s %s", strings.Join(path, " "), toPath))
|
2023-09-11 22:59:13 +08:00
|
|
|
|
if err != nil {
|
2023-10-26 17:15:49 +08:00
|
|
|
|
return mi, errorx.NewBiz(res)
|
2023-09-11 22:59:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
return mi, err
|
2021-05-08 20:50:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
func (m *machineFileAppImpl) Rename(ctx context.Context, opParam *MachineFileOpParam, newname string) (*mcm.MachineInfo, error) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
oldname := opParam.Path
|
|
|
|
|
|
if opParam.Protocol == entity.MachineProtocolRdp {
|
2024-04-19 11:27:29 +00:00
|
|
|
|
oldname = m.GetRdpFilePath(contextx.GetLoginAccount(ctx), oldname)
|
|
|
|
|
|
newname = m.GetRdpFilePath(contextx.GetLoginAccount(ctx), newname)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
return nil, os.Rename(oldname, newname)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
mi, sftpCli, err := m.GetMachineSftpCli(opParam)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return mi, sftpCli.Rename(oldname, newname)
|
2022-11-18 17:52:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-09-11 22:59:13 +08:00
|
|
|
|
// 获取文件机器cli
|
2024-04-09 12:55:51 +08:00
|
|
|
|
func (m *machineFileAppImpl) GetMachineCli(authCertName string) (*mcm.Cli, error) {
|
|
|
|
|
|
return m.machineApp.GetCliByAc(authCertName)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取文件机器 sftp cli
|
2024-04-09 12:55:51 +08:00
|
|
|
|
func (m *machineFileAppImpl) GetMachineSftpCli(opParam *MachineFileOpParam) (*mcm.MachineInfo, *sftp.Client, error) {
|
|
|
|
|
|
mcli, err := m.GetMachineCli(opParam.AuthCertName)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, nil, err
|
2021-05-08 20:50:34 +08:00
|
|
|
|
}
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
|
|
|
|
|
sftpCli, err := mcli.GetSftpCli()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-30 17:34:56 +08:00
|
|
|
|
return mcli.Info, sftpCli, nil
|
2021-05-08 20:50:34 +08:00
|
|
|
|
}
|
2024-04-06 04:03:38 +00:00
|
|
|
|
|
2024-04-19 11:27:29 +00:00
|
|
|
|
func (m *machineFileAppImpl) GetRdpFilePath(ua *model.LoginAccount, path string) string {
|
|
|
|
|
|
return fmt.Sprintf("%s/%s%s", config.GetMachine().GuacdFilePath, ua.Username, path)
|
2024-04-06 04:03:38 +00:00
|
|
|
|
}
|