Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 45 additions & 2 deletions agent/utils/files/file_op.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package files
import (
"archive/zip"
"bufio"
"compress/gzip"
"context"
"crypto/tls"
"encoding/json"
Expand Down Expand Up @@ -597,10 +598,10 @@ func getFormat(cType CompressType) archiver.CompressedArchive {
format.Archival = archiver.Zip{
Compression: zip.Deflate,
}
case Bz2:
case Bz2, TarBz2:
format.Compression = archiver.Bz2{}
format.Archival = archiver.Tar{}
case Xz:
case Xz, TarXz:
format.Compression = archiver.Xz{}
format.Archival = archiver.Tar{}
}
Expand Down Expand Up @@ -680,6 +681,13 @@ func decodeGBK(input string) (string, error) {

func (f FileOp) decompressWithSDK(srcFile string, dst string, cType CompressType) error {
format := getFormat(cType)
if cType == Gz {
err := f.DecompressGzFile(srcFile, dst)
if err != nil {
return err
}
}

handler := func(ctx context.Context, archFile archiver.File) error {
info := archFile.FileInfo
if isIgnoreFile(archFile.Name()) {
Expand Down Expand Up @@ -794,6 +802,41 @@ func ZipFile(files []archiver.File, dst afero.File) error {
return nil
}

func (f FileOp) DecompressGzFile(srcFile, dst string) error {
in, err := f.Fs.Open(srcFile)
if err != nil {
return fmt.Errorf("open source file failed: %w", err)
}
defer in.Close()

gr, err := gzip.NewReader(in)
if err != nil {
return fmt.Errorf("gzip reader creation failed: %w", err)
}
defer gr.Close()

outName := strings.TrimSuffix(filepath.Base(srcFile), ".gz")
outPath := filepath.Join(dst, outName)
parentDir := filepath.Dir(outPath)
if !f.Stat(parentDir) {
if err := f.Fs.MkdirAll(parentDir, 0755); err != nil {
return err
}
}

fw, err := f.Fs.OpenFile(outPath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0644)
if err != nil {
return fmt.Errorf("create output file failed: %w", err)
}
defer fw.Close()

if _, err := io.Copy(fw, gr); err != nil {
return fmt.Errorf("copy content failed: %w", err)
}

return nil
}

func (f FileOp) TarGzCompressPro(withDir bool, src, dst, secret, exclusionRules string) error {
if !f.Stat(path.Dir(dst)) {
if err := f.Fs.MkdirAll(path.Dir(dst), constant.FilePerm); err != nil {
Expand Down
2 changes: 2 additions & 0 deletions agent/utils/files/fileinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -460,9 +460,11 @@ const (
Zip CompressType = "zip"
Gz CompressType = "gz"
Bz2 CompressType = "bz2"
TarBz2 CompressType = "tar.bz2"
Tar CompressType = "tar"
TarGz CompressType = "tar.gz"
Xz CompressType = "xz"
TarXz CompressType = "tar.xz"
SdkZip CompressType = "sdkZip"
SdkTarGz CompressType = "sdkTarGz"
Rar CompressType = "rar"
Expand Down
4 changes: 4 additions & 0 deletions agent/utils/files/tar_gz.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package files

import (
"fmt"
"os"
"path/filepath"
"strings"

Expand All @@ -17,6 +18,9 @@ func NewTarGzArchiver() ShellArchiver {
}

func (t TarGzArchiver) Extract(filePath, dstDir string, secret string) error {
if err := os.MkdirAll(dstDir, 0755); err != nil {
return fmt.Errorf("failed to create destination dir: %w", err)
}
var err error
commands := ""
if len(secret) != 0 {
Expand Down
8 changes: 6 additions & 2 deletions frontend/src/enums/files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,26 @@ export enum CompressType {
Zip = 'zip',
Gz = 'gz',
Bz2 = 'bz2',
TarBz2 = 'tar.bz2',
Tar = 'tar',
TGz = 'tgz',
TarGz = 'tar.gz',
Xz = 'xz',
TarXz = 'tar.xz',
Rar = 'rar',
'7z' = '7z',
}

export enum CompressExtension {
zip = '.zip',
gz = '.gz',
bz2 = '.tar.bz2',
'tar.bz2' = '.tar.bz2',
bz2 = '.bz2',
tar = '.tar',
tgz = '.tgz',
'tar.gz' = '.tar.gz',
xz = '.tar.xz',
'tar.xz' = '.tar.xz',
xz = '.xz',
rar = '.rar',
'7z' = '.7z',
}
Expand Down
1 change: 1 addition & 0 deletions frontend/src/global/mimetype.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const Mimetypes = new Map([
['application/octet-stream', CompressType.Tar],
['application/x-rar-compressed', CompressType.Rar],
['application/vnd.rar', CompressType.Rar],
['application/rar', CompressType.Rar],
['application/x-7z-compressed', CompressType['7z']],
]);

Expand Down
13 changes: 2 additions & 11 deletions frontend/src/views/host/file-management/decompress/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import { File } from '@/api/interface/file';
import { FormInstance, FormRules } from 'element-plus';
import { Rules } from '@/global/form-rules';
import { deCompressFile } from '@/api/modules/files';
import { Mimetypes } from '@/global/mimetype';
import FileList from '@/components/file-list/index.vue';
import { MsgSuccess } from '@/utils/message';

Expand All @@ -48,7 +47,7 @@ interface CompressProps {
dst: string;
name: string;
path: string;
mimeType: string;
type: string;
}

const rules = reactive<FormRules>({
Expand All @@ -72,14 +71,6 @@ const handleClose = () => {
em('close', open);
};

const getFileType = (mime: string): string => {
if (Mimetypes.get(mime) != undefined) {
return String(Mimetypes.get(mime));
} else {
return '';
}
};

const getLinkPath = (path: string) => {
form.value.dst = path;
};
Expand All @@ -103,7 +94,7 @@ const submit = async (formEl: FormInstance | undefined) => {
};

const acceptParams = (props: CompressProps) => {
form.value.type = getFileType(props.mimeType);
form.value.type = props.type;
form.value.dst = props.dst;
form.value.path = props.path;
name.value = props.name;
Expand Down
14 changes: 10 additions & 4 deletions frontend/src/views/host/file-management/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ import VscodeOpenDialog from '@/components/vscode-open/index.vue';
import { debounce } from 'lodash-es';
import TerminalDialog from './terminal/index.vue';
import { Dashboard } from '@/api/interface/dashboard';
import { CompressExtension, MimetypeByExtensionObject } from '@/enums/files';
import { CompressExtension } from '@/enums/files';
import type { TabPaneName } from 'element-plus';

const globalStore = GlobalStore();
Expand Down Expand Up @@ -733,7 +733,7 @@ let pointer = -1;

const fileCreate = reactive({ path: '/', isDir: false, mode: 0o755 });
const fileCompress = reactive({ files: [''], name: '', dst: '', operate: 'compress' });
const fileDeCompress = reactive({ path: '', name: '', dst: '', mimeType: '' });
const fileDeCompress = reactive({ path: '', name: '', dst: '', type: '' });
const fileEdit = reactive({ content: '', path: '', name: '', language: 'plaintext', extension: '' });
const filePreview = reactive({ path: '', name: '', extension: '', fileType: '', imageFiles: [], currentNode: '' });
const codeReq = reactive({ path: '', expand: false, page: 1, pageSize: 100, isDetail: false });
Expand Down Expand Up @@ -1186,9 +1186,9 @@ const openDeCompress = (item: File.File) => {
MsgWarning(i18n.global.t('file.canNotDeCompress'));
return;
}
fileDeCompress.mimeType = item.mimeType;
fileDeCompress.type = Mimetypes.get(item.mimeType);
if (CompressExtension[Mimetypes.get(item.mimeType)] != item.extension) {
fileDeCompress.mimeType = MimetypeByExtensionObject[item.extension];
fileDeCompress.type = getEnumKeyByValue(item.extension);
}

fileDeCompress.name = item.name;
Expand All @@ -1198,6 +1198,12 @@ const openDeCompress = (item: File.File) => {
deCompressRef.value.acceptParams(fileDeCompress);
};

function getEnumKeyByValue(value: string): keyof typeof CompressExtension | undefined {
return (Object.keys(CompressExtension) as Array<keyof typeof CompressExtension>).find(
(k) => CompressExtension[k] === value,
);
}

const openView = (item: File.File) => {
const fileType = getFileType(item.extension);
if (fileType === 'image') {
Expand Down
Loading