Skip to content

Commit c392b72

Browse files
authored
fix: Fix file decompression issue (#12684)
Refs #12675
1 parent 50a70ef commit c392b72

4 files changed

Lines changed: 130 additions & 17 deletions

File tree

agent/app/service/file.go

Lines changed: 120 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ import (
4040
"golang.org/x/text/transform"
4141

4242
"github.com/1Panel-dev/1Panel/agent/global"
43-
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
4443
"github.com/1Panel-dev/1Panel/agent/utils/common"
4544
"github.com/1Panel-dev/1Panel/agent/utils/files"
4645
terminalai "github.com/1Panel-dev/1Panel/agent/utils/terminal/ai"
@@ -478,7 +477,7 @@ func preflightCompressTool(compressType files.CompressType) error {
478477

479478
func preflightDecompressTool(decompressType files.CompressType) error {
480479
switch decompressType {
481-
case files.Tar, files.Zip, files.TarGz, files.Rar, files.X7z:
480+
case files.Rar, files.X7z:
482481
_, err := files.NewExtractShellArchiver(decompressType)
483482
return err
484483
default:
@@ -541,7 +540,7 @@ func (f *FileService) DeCompress(c request.FileDeCompress) error {
541540
if err := fo.CreateDir(c.Dst, constant.DirPerm); err != nil {
542541
return err
543542
}
544-
if err := cmd.NewCommandMgr(cmd.WithContext(t.TaskCtx)).RunBashCf("cp -rfp '%s'/. '%s'", tempDst, c.Dst); err != nil {
543+
if err := copyDecompressTree(t.TaskCtx, tempDst, c.Dst); err != nil {
545544
return err
546545
}
547546
success = true
@@ -552,6 +551,124 @@ func (f *FileService) DeCompress(c request.FileDeCompress) error {
552551
return nil
553552
}
554553

554+
func copyDecompressTree(ctx context.Context, srcDir, dstDir string) error {
555+
entries, err := os.ReadDir(srcDir)
556+
if err != nil {
557+
return err
558+
}
559+
for _, entry := range entries {
560+
if err := copyDecompressEntry(ctx, filepath.Join(srcDir, entry.Name()), filepath.Join(dstDir, entry.Name())); err != nil {
561+
return err
562+
}
563+
}
564+
return nil
565+
}
566+
567+
func copyDecompressEntry(ctx context.Context, srcPath, dstPath string) (retErr error) {
568+
if err := ctx.Err(); err != nil {
569+
return err
570+
}
571+
info, err := os.Lstat(srcPath)
572+
if err != nil {
573+
return err
574+
}
575+
576+
if info.Mode()&os.ModeSymlink != 0 {
577+
if err := os.RemoveAll(dstPath); err != nil {
578+
return err
579+
}
580+
if err := os.MkdirAll(filepath.Dir(dstPath), constant.DirPerm); err != nil {
581+
return err
582+
}
583+
target, err := os.Readlink(srcPath)
584+
if err != nil {
585+
return err
586+
}
587+
if err := os.Symlink(target, dstPath); err != nil {
588+
return err
589+
}
590+
return applyDecompressOwnership(srcPath, dstPath)
591+
}
592+
593+
if info.IsDir() {
594+
dstInfo, err := os.Lstat(dstPath)
595+
keepExistingDir := err == nil && dstInfo.IsDir() && dstInfo.Mode()&os.ModeSymlink == 0
596+
if err != nil && !os.IsNotExist(err) {
597+
return err
598+
}
599+
if !keepExistingDir {
600+
if err := os.RemoveAll(dstPath); err != nil {
601+
return err
602+
}
603+
if err := os.MkdirAll(dstPath, info.Mode().Perm()); err != nil {
604+
return err
605+
}
606+
if err := applyDecompressOwnership(srcPath, dstPath); err != nil {
607+
return err
608+
}
609+
}
610+
entries, err := os.ReadDir(srcPath)
611+
if err != nil {
612+
return err
613+
}
614+
for _, entry := range entries {
615+
if err := copyDecompressEntry(ctx, filepath.Join(srcPath, entry.Name()), filepath.Join(dstPath, entry.Name())); err != nil {
616+
return err
617+
}
618+
}
619+
if keepExistingDir {
620+
return nil
621+
}
622+
return os.Chtimes(dstPath, info.ModTime(), info.ModTime())
623+
}
624+
625+
if err := os.RemoveAll(dstPath); err != nil {
626+
return err
627+
}
628+
if err := os.MkdirAll(filepath.Dir(dstPath), constant.DirPerm); err != nil {
629+
return err
630+
}
631+
632+
srcFile, err := os.Open(srcPath)
633+
if err != nil {
634+
return err
635+
}
636+
defer srcFile.Close()
637+
638+
dstFile, err := os.OpenFile(dstPath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, info.Mode().Perm())
639+
if err != nil {
640+
return err
641+
}
642+
defer func() {
643+
if cerr := dstFile.Close(); cerr != nil && retErr == nil {
644+
retErr = cerr
645+
}
646+
}()
647+
648+
if _, err := io.Copy(dstFile, srcFile); err != nil {
649+
return err
650+
}
651+
if err := applyDecompressOwnership(srcPath, dstPath); err != nil {
652+
return err
653+
}
654+
return os.Chtimes(dstPath, info.ModTime(), info.ModTime())
655+
}
656+
657+
func applyDecompressOwnership(srcPath, dstPath string) error {
658+
info, err := os.Lstat(srcPath)
659+
if err != nil {
660+
return err
661+
}
662+
stat, ok := info.Sys().(*unix.Stat_t)
663+
if !ok {
664+
return nil
665+
}
666+
if info.Mode()&os.ModeSymlink != 0 {
667+
return os.Lchown(dstPath, int(stat.Uid), int(stat.Gid))
668+
}
669+
return os.Chown(dstPath, int(stat.Uid), int(stat.Gid))
670+
}
671+
555672
func (f *FileService) GetContent(op request.FileContentReq) (response.FileInfo, error) {
556673
info, err := files.NewFileInfo(files.FileOption{
557674
Path: op.Path,

agent/utils/files/file_op.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,7 @@ func (f FileOp) decompressWithSDK(ctx context.Context, srcFile string, dst strin
950950
} else {
951951
parentDir := path.Dir(filePath)
952952
if !f.Stat(parentDir) {
953-
if err := f.Fs.MkdirAll(parentDir, info.Mode()); err != nil {
953+
if err := f.Fs.MkdirAll(parentDir, constant.DirPerm); err != nil {
954954
return err
955955
}
956956
}
@@ -1116,7 +1116,7 @@ func (f FileOp) tryDecompressTarGz(ctx context.Context, srcFile string, dst stri
11161116
} else {
11171117
parentDir := filepath.Dir(filePath)
11181118
if !f.Stat(parentDir) {
1119-
if err := f.Fs.MkdirAll(parentDir, info.Mode()); err != nil {
1119+
if err := f.Fs.MkdirAll(parentDir, constant.DirPerm); err != nil {
11201120
return err
11211121
}
11221122
}

frontend/src/views/host/file-management/compress/index.vue

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,15 +205,13 @@ const loadTaskInfo = async () => {
205205
emitTaskChange();
206206
if (!taskInfo.value || taskInfo.value.status !== 'Executing') {
207207
stopTaskPolling();
208-
currentTaskID.value = '';
209-
taskInfo.value = null;
210-
emitTaskChange();
208+
resetDrawerState();
209+
em('close', false);
211210
}
212211
} catch (error) {
213212
stopTaskPolling();
214-
currentTaskID.value = '';
215-
taskInfo.value = null;
216-
emitTaskChange();
213+
resetDrawerState();
214+
em('close', false);
217215
}
218216
};
219217

frontend/src/views/host/file-management/decompress/index.vue

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -187,15 +187,13 @@ const loadTaskInfo = async () => {
187187
emitTaskChange();
188188
if (!taskInfo.value || taskInfo.value.status !== 'Executing') {
189189
stopTaskPolling();
190-
currentTaskID.value = '';
191-
taskInfo.value = null;
192-
emitTaskChange();
190+
resetDrawerState();
191+
em('close', false);
193192
}
194193
} catch {
195194
stopTaskPolling();
196-
currentTaskID.value = '';
197-
taskInfo.value = null;
198-
emitTaskChange();
195+
resetDrawerState();
196+
em('close', false);
199197
}
200198
};
201199

0 commit comments

Comments
 (0)