mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2024-11-27 20:49:03 +08:00
fix: 解决解压 .tar 文件失败的问题 (#2562)
This commit is contained in:
parent
8efe0c8bed
commit
90af56511c
@ -76,3 +76,14 @@ func WithNameAndErr(Key string, name string, err error) BusinessError {
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
func WithName(Key string, name string) BusinessError {
|
||||
paramMap := map[string]interface{}{}
|
||||
if name != "" {
|
||||
paramMap["name"] = name
|
||||
}
|
||||
return BusinessError{
|
||||
Msg: Key,
|
||||
Map: paramMap,
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +89,7 @@ var (
|
||||
ErrFileIsExit = "ErrFileIsExit"
|
||||
ErrFileUpload = "ErrFileUpload"
|
||||
ErrFileDownloadDir = "ErrFileDownloadDir"
|
||||
ErrCmdNotFound = "ErrCmdNotFound"
|
||||
)
|
||||
|
||||
// mysql
|
||||
|
@ -62,6 +62,7 @@ ErrLinkPathNotFound: "Target path does not exist!"
|
||||
ErrFileIsExit: "File already exists!"
|
||||
ErrFileUpload: "Failed to upload file {{.name}} {{.detail}}"
|
||||
ErrFileDownloadDir: "Download folder not supported"
|
||||
ErrCmdNotFound: "{{ .name}} command does not exist, please install this command on the host first"
|
||||
|
||||
#website
|
||||
ErrDomainIsExist: "Domain is already exist"
|
||||
|
@ -62,6 +62,7 @@ ErrLinkPathNotFound: "目標路徑不存在!"
|
||||
ErrFileIsExit: "文件已存在!"
|
||||
ErrFileUpload: "{{ .name }} 上傳文件失敗 {{ .detail}}"
|
||||
ErrFileDownloadDir: "不支持下載文件夾"
|
||||
ErrCmdNotFound: "{{ .name}} 命令不存在,請先在宿主機安裝此命令"
|
||||
|
||||
#website
|
||||
ErrDomainIsExist: "域名已存在"
|
||||
|
@ -62,6 +62,7 @@ ErrLinkPathNotFound: "目标路径不存在!"
|
||||
ErrFileIsExit: "文件已存在!"
|
||||
ErrFileUpload: "{{ .name }} 上传文件失败 {{ .detail}}"
|
||||
ErrFileDownloadDir: "不支持下载文件夹"
|
||||
ErrCmdNotFound: "{{ .name}} 命令不存在,请先在宿主机安装此命令"
|
||||
|
||||
#website
|
||||
ErrDomainIsExist: "域名已存在"
|
||||
|
31
backend/utils/files/archiver.go
Normal file
31
backend/utils/files/archiver.go
Normal file
@ -0,0 +1,31 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||
)
|
||||
|
||||
type ShellArchiver interface {
|
||||
Compress() error
|
||||
Extract(dstDir string) error
|
||||
}
|
||||
|
||||
func NewShellArchiver(compressType CompressType) (*TarArchiver, error) {
|
||||
switch compressType {
|
||||
case Tar:
|
||||
if err := checkCmdAvailability("tar"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewTarArchiver(compressType), nil
|
||||
default:
|
||||
return nil, buserr.New("unsupported compress type")
|
||||
}
|
||||
}
|
||||
|
||||
func checkCmdAvailability(cmdStr string) error {
|
||||
if cmd.Which(cmdStr) {
|
||||
return nil
|
||||
}
|
||||
return buserr.WithName(cmdStr, constant.ErrCmdNotFound)
|
||||
}
|
@ -339,19 +339,7 @@ func (f FileOp) GetDirSize(path string) (float64, error) {
|
||||
return dirSize, nil
|
||||
}
|
||||
|
||||
type CompressType string
|
||||
|
||||
const (
|
||||
Zip CompressType = "zip"
|
||||
Gz CompressType = "gz"
|
||||
Bz2 CompressType = "bz2"
|
||||
Tar CompressType = "tar"
|
||||
TarGz CompressType = "tar.gz"
|
||||
Xz CompressType = "xz"
|
||||
)
|
||||
|
||||
func getFormat(cType CompressType) archiver.CompressedArchive {
|
||||
|
||||
format := archiver.CompressedArchive{}
|
||||
switch cType {
|
||||
case Tar:
|
||||
@ -426,58 +414,68 @@ func decodeGBK(input string) (string, error) {
|
||||
}
|
||||
|
||||
func (f FileOp) Decompress(srcFile string, dst string, cType CompressType) error {
|
||||
format := getFormat(cType)
|
||||
|
||||
handler := func(ctx context.Context, archFile archiver.File) error {
|
||||
info := archFile.FileInfo
|
||||
if isIgnoreFile(archFile.Name()) {
|
||||
return nil
|
||||
switch cType {
|
||||
case Tar:
|
||||
shellArchiver, err := NewShellArchiver(cType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fileName := archFile.NameInArchive
|
||||
var err error
|
||||
if header, ok := archFile.Header.(cZip.FileHeader); ok {
|
||||
if header.NonUTF8 && header.Flags == 0 {
|
||||
fileName, err = decodeGBK(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
shellArchiver.FilePath = srcFile
|
||||
return shellArchiver.Extract(dst)
|
||||
default:
|
||||
format := getFormat(cType)
|
||||
handler := func(ctx context.Context, archFile archiver.File) error {
|
||||
info := archFile.FileInfo
|
||||
if isIgnoreFile(archFile.Name()) {
|
||||
return nil
|
||||
}
|
||||
fileName := archFile.NameInArchive
|
||||
var err error
|
||||
if header, ok := archFile.Header.(cZip.FileHeader); ok {
|
||||
if header.NonUTF8 && header.Flags == 0 {
|
||||
fileName, err = decodeGBK(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
filePath := filepath.Join(dst, fileName)
|
||||
if archFile.FileInfo.IsDir() {
|
||||
if err := f.Fs.MkdirAll(filePath, info.Mode()); err != nil {
|
||||
filePath := filepath.Join(dst, fileName)
|
||||
if archFile.FileInfo.IsDir() {
|
||||
if err := f.Fs.MkdirAll(filePath, info.Mode()); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
parentDir := path.Dir(filePath)
|
||||
if !f.Stat(parentDir) {
|
||||
if err := f.Fs.MkdirAll(parentDir, info.Mode()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
fr, err := archFile.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
parentDir := path.Dir(filePath)
|
||||
if !f.Stat(parentDir) {
|
||||
if err := f.Fs.MkdirAll(parentDir, info.Mode()); err != nil {
|
||||
return err
|
||||
}
|
||||
defer fr.Close()
|
||||
fw, err := f.Fs.OpenFile(filePath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, info.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fw.Close()
|
||||
if _, err := io.Copy(fw, fr); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
fr, err := archFile.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fr.Close()
|
||||
fw, err := f.Fs.OpenFile(filePath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, info.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fw.Close()
|
||||
if _, err := io.Copy(fw, fr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
input, err := f.Fs.Open(srcFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return format.Extract(context.Background(), input, nil, handler)
|
||||
}
|
||||
input, err := f.Fs.Open(srcFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return format.Extract(context.Background(), input, nil, handler)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f FileOp) Backup(srcFile string) (string, error) {
|
||||
|
@ -335,3 +335,14 @@ func min(x, y int) int {
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
type CompressType string
|
||||
|
||||
const (
|
||||
Zip CompressType = "zip"
|
||||
Gz CompressType = "gz"
|
||||
Bz2 CompressType = "bz2"
|
||||
Tar CompressType = "tar"
|
||||
TarGz CompressType = "tar.gz"
|
||||
Xz CompressType = "xz"
|
||||
)
|
||||
|
40
backend/utils/files/tar.go
Normal file
40
backend/utils/files/tar.go
Normal file
@ -0,0 +1,40 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type TarArchiver struct {
|
||||
Cmd string
|
||||
FilePath string
|
||||
CompressType CompressType
|
||||
}
|
||||
|
||||
func NewTarArchiver(compressType CompressType) *TarArchiver {
|
||||
return &TarArchiver{
|
||||
Cmd: "tar",
|
||||
CompressType: compressType,
|
||||
}
|
||||
}
|
||||
|
||||
func (t TarArchiver) Compress(SourcePaths []string) error {
|
||||
return cmd.ExecCmd(fmt.Sprintf("%s %s %s %s", t.Cmd, t.getOptionStr("compress"), t.FilePath, strings.Join(SourcePaths, " ")))
|
||||
}
|
||||
|
||||
func (t TarArchiver) Extract(dstDir string) error {
|
||||
return cmd.ExecCmd(fmt.Sprintf("%s %s %s -C %s", t.Cmd, t.getOptionStr("extract"), t.FilePath, dstDir))
|
||||
}
|
||||
|
||||
func (t TarArchiver) getOptionStr(Option string) string {
|
||||
switch t.CompressType {
|
||||
case Tar:
|
||||
if Option == "compress" {
|
||||
return "cvf"
|
||||
} else {
|
||||
return "xf"
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
@ -15,6 +15,7 @@ export const Mimetypes = new Map([
|
||||
['application/x-gzip-compressed', CompressType.TarGz],
|
||||
['gzip/document', CompressType.TarGz],
|
||||
['application/x-xz', CompressType.Xz],
|
||||
['application/octet-stream', CompressType.Tar],
|
||||
]);
|
||||
|
||||
export const Languages = [
|
||||
|
@ -502,6 +502,7 @@ const openCompress = (items: File.File[]) => {
|
||||
};
|
||||
|
||||
const openDeCompress = (item: File.File) => {
|
||||
console.log(item.mimeType);
|
||||
if (Mimetypes.get(item.mimeType) == undefined) {
|
||||
MsgWarning(i18n.global.t('file.canNotDeCompress'));
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user