Repository: 1Panel-dev/1Panel
Pull request #8234: fix: Fix backup compression failure
Author: login: ssongliu
Labels: name: do-not-merge/release-note-label-needed
name: approved
name: dev-v2
Created: 2025-03-24T14:03:20Z | Merged: 2025-03-25T02:11:32Z



Diff:
diff --git a/agent/app/service/backup_website.go b/agent/app/service/backup_website.go
index ec24dca06c81..a602f8dbec64 100644
--- a/agent/app/service/backup_website.go
+++ b/agent/app/service/backup_website.go
@@ -184,7 +184,7 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
 		}
 		taskName := i18n.GetMsgByKey("TaskRecover") + i18n.GetMsgByKey("websiteDir")
 		t.Log(taskName)
-		if err = fileOp.TarGzExtractPro(fmt.Sprintf("%s/%s.web.tar.gz", tmpPath, website.Alias), GetOpenrestyDir(SitesRootDir), secret); err != nil {
+		if err = fileOp.TarGzExtractPro(fmt.Sprintf("%s/%s.web.tar.gz", tmpPath, website.Alias), GetOpenrestyDir(SitesRootDir), ""); err != nil {
 			t.LogFailedWithErr(taskName, err)
 			return err
 		}
diff --git a/agent/app/service/cronjob_backup.go b/agent/app/service/cronjob_backup.go
index 8ccf4093e1ae..795cdcae10e4 100644
--- a/agent/app/service/cronjob_backup.go
+++ b/agent/app/service/cronjob_backup.go
@@ -80,7 +80,7 @@ func (u *CronjobService) handleWebsite(cronjob model.Cronjob, startTime time.Tim
 		record.From = "cronjob"
 		record.Type = "website"
 		record.CronjobID = cronjob.ID
-		record.Name = web.PrimaryDomain
+		record.Name = web.Alias
 		record.DetailName = web.Alias
 		record.DownloadAccountID, record.SourceAccountIDs = cronjob.DownloadAccountID, cronjob.SourceAccountIDs
 		backupDir := path.Join(global.Dir.TmpDir, fmt.Sprintf("website/%s", web.PrimaryDomain))
@@ -150,7 +150,7 @@ func (u *CronjobService) handleDirectory(cronjob model.Cronjob, startTime time.T
 	if err != nil {
 		return err
 	}
-	fileName := fmt.Sprintf("directory%s_%s.tar.gz", strings.ReplaceAll(cronjob.SourceDir, "/", "_"), startTime.Format(constant.DateTimeSlimLayout)+common.RandStrAndNum(5))
+	fileName := fmt.Sprintf("%s.tar.gz", startTime.Format(constant.DateTimeSlimLayout)+common.RandStrAndNum(5))
 	backupDir := path.Join(global.Dir.TmpDir, fmt.Sprintf("%s/%s", cronjob.Type, cronjob.Name))
 
 	fileOp := files.NewFileOp()
@@ -160,7 +160,7 @@ func (u *CronjobService) handleDirectory(cronjob model.Cronjob, startTime time.T
 		}
 	} else {
 		fileLists := strings.Split(cronjob.SourceDir, ",")
-		if err := fileOp.Compress(fileLists, backupDir, fileName, files.TarGz, cronjob.Secret); err != nil {
+		if err := fileOp.TarGzFilesWithCompressPro(fileLists, path.Join(backupDir, fileName), cronjob.Secret); err != nil {
 			return err
 		}
 	}
diff --git a/agent/utils/files/file_op.go b/agent/utils/files/file_op.go
index 5cd7c68aefa2..e034f05491d5 100644
--- a/agent/utils/files/file_op.go
+++ b/agent/utils/files/file_op.go
@@ -7,7 +7,6 @@ import (
 	"crypto/tls"
 	"encoding/json"
 	"fmt"
-	"github.com/1Panel-dev/1Panel/agent/buserr"
 	"io"
 	"io/fs"
 	"net/http"
@@ -19,6 +18,8 @@ import (
 	"strings"
 	"time"
 
+	"github.com/1Panel-dev/1Panel/agent/buserr"
+
 	"github.com/1Panel-dev/1Panel/agent/constant"
 	"github.com/1Panel-dev/1Panel/agent/utils/cmd"
 	"github.com/1Panel-dev/1Panel/agent/utils/req_helper"
@@ -758,6 +759,28 @@ func (f FileOp) TarGzCompressPro(withDir bool, src, dst, secret, exclusionRules
 	return cmd.ExecCmdWithDir(commands, workdir)
 }
 
+func (f FileOp) TarGzFilesWithCompressPro(list []string, dst, secret string) error {
+	if !f.Stat(path.Dir(dst)) {
+		if err := f.Fs.MkdirAll(path.Dir(dst), constant.FilePerm); err != nil {
+			return err
+		}
+	}
+
+	var filelist []string
+	for _, item := range list {
+		filelist = append(filelist, "-C "+path.Dir(item)+" "+path.Base(item))
+	}
+	commands := ""
+	if len(secret) != 0 {
+		commands = fmt.Sprintf("tar --warning=no-file-changed --ignore-failed-read -zcf - %s | openssl enc -aes-256-cbc -salt -k '%s' -out %s", strings.Join(filelist, " "), secret, dst)
+		global.LOG.Debug(strings.ReplaceAll(commands, fmt.Sprintf(" %s ", secret), "******"))
+	} else {
+		commands = fmt.Sprintf("tar --warning=no-file-changed --ignore-failed-read -zcf %s %s", dst, strings.Join(filelist, " "))
+		global.LOG.Debug(commands)
+	}
+	return cmd.ExecCmd(commands)
+}
+
 func (f FileOp) TarGzExtractPro(src, dst string, secret string) error {
 	if _, err := os.Stat(path.Dir(dst)); err != nil && os.IsNotExist(err) {
 		if err = os.MkdirAll(path.Dir(dst), os.ModePerm); err != nil {
diff --git a/frontend/src/components/backup/index.vue b/frontend/src/components/backup/index.vue
index f4ea7ac1c283..f7ec0347f2f4 100644
--- a/frontend/src/components/backup/index.vue
+++ b/frontend/src/components/backup/index.vue
@@ -78,7 +78,7 @@
         size="small"
         @close="handleBackupClose"
     >
-        <el-form ref="backupForm" label-position="left" v-loading="loading">
+        <el-form ref="backupForm" @submit.prevent label-position="left" v-loading="loading">
             <el-form-item
                 :label="$t('setting.compressPassword')"
                 class="mt-10"
diff --git a/frontend/src/components/log/hightlight-log/index.vue b/frontend/src/components/log/hightlight-log/index.vue
index 596198c582d5..3d246e8d972d 100644
--- a/frontend/src/components/log/hightlight-log/index.vue
+++ b/frontend/src/components/log/hightlight-log/index.vue
@@ -37,7 +37,7 @@ const initLog = async () => {
     if (editorRef.value && scrollerElement.value == undefined) {
         const parentElement = editorRef.value.$el as HTMLElement;
         scrollerElement.value = parentElement.querySelector('.hljs') as HTMLElement;
-        scrollerElement.value.style['min-height'] = '500px';
+        scrollerElement.value.style['min-height'] = '100px';
         scrollerElement.value.style['max-height'] = 'calc(100vh - ' + props.heightDiff + 'px)';
     }
 };
diff --git a/frontend/src/views/container/setting/sock-path/index.vue b/frontend/src/views/container/setting/sock-path/index.vue
index 1270c7eaaeeb..c3b1224cbed2 100644
--- a/frontend/src/views/container/setting/sock-path/index.vue
+++ b/frontend/src/views/container/setting/sock-path/index.vue
@@ -32,7 +32,7 @@
 import { reactive, ref } from 'vue';
 import i18n from '@/lang';
 import { MsgSuccess } from '@/utils/message';
-import { updateSetting } from '@/api/modules/setting';
+import { updateAgentSetting } from '@/api/modules/setting';
 import { ElMessageBox, FormInstance } from 'element-plus';
 
 const emit = defineEmits<{ (e: 'search'): void }>();
@@ -85,7 +85,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
                     ? form.dockerSockPath
                     : 'unix://' + form.dockerSockPath,
             };
-            await updateSetting(params)
+            await updateAgentSetting(params)
                 .then(() => {
                     loading.value = false;
                     handleClose();
diff --git a/frontend/src/views/log/operation/index.vue b/frontend/src/views/log/operation/index.vue
index d56f33b82f21..5973fbf6e5a8 100644
--- a/frontend/src/views/log/operation/index.vue
+++ b/frontend/src/views/log/operation/index.vue
@@ -12,28 +12,37 @@
             <template #rightToolBar>
                 <el-select v-model="searchGroup" @change="search()" clearable class="p-w-200">
                     <template #prefix>{{ $t('logs.resource') }}</template>
-                    <el-option :label="$t('commons.table.all')" value=""></el-option>
-                    <el-option :label="$t('logs.detail.apps')" value="apps"></el-option>
-                    <el-option :label="$t('logs.detail.websites')" value="websites"></el-option>
-                    <el-option :label="$t('logs.detail.runtimes')" value="runtimes"></el-option>
-                    <el-option :label="$t('logs.detail.databases')" value="databases"></el-option>
-                    <el-option :label="$t('logs.detail.containers')" value="containers"></el-option>
-                    <el-option :label="$t('logs.detail.cronjobs')" value="cronjobs"></el-option>
-                    <el-option :label="$t('logs.detail.files')" value="files"></el-option>
-                    <el-option :label="$t('logs.detail.hosts')" value="hosts"></el-option>
-                    <el-option :label="$t('logs.detail.process')" value="process"></el-option>
-                    <el-option :label="$t('logs.detail.logs')" value="logs"></el-option>
-                    <el-option :label="$t('logs.detail.settings')" value="settings"></el-option>
+                    <el-option :label="$t('commons.table.all')" value="" />
+                    <el-option :label="$t('logs.detail.apps')" value="apps" />
+                    <el-option :label="$t('logs.detail.websites')" value="websites" />
+                    <el-option :label="$t('logs.detail.runtimes')" value="runtimes" />
+                    <el-option :label="$t('logs.detail.ai')" value="ai" />
+                    <el-option :label="$t('logs.detail.databases')" value="databases" />
+                    <el-option :label="$t('logs.detail.containers')" value="containers" />
+                    <el-option :label="$t('menu.system')" value="hosts" />
+                    <el-option :label="$t('logs.detail.files')" value="files" />
+                    <el-option :label="$t('logs.detail.cronjobs')" value="cronjobs" />
+                    <el-option :label="$t('logs.detail.toolbox')" value="toolbox" />
+                    <el-option :label="$t('logs.detail.process')" value="process" />
+                    <el-option :label="$t('logs.detail.nodes')" value="nodes" />
+                    <el-option :label="$t('logs.detail.tampers')" value="tampers" />
+                    <el-option :label="$t('logs.detail.xsetting')" value="xsetting" />
+                    <el-option :label="$t('logs.detail.licenses')" value="licenses" />
+                    <el-option :label="$t('logs.detail.logs')" value="logs" />
+                    <el-option :label="$t('logs.detail.settings')" value="settings" />
+                    <el-option :label="$t('logs.detail.backups')" value="backups" />
+                    <el-option :label="$t('logs.detail.groups')" value="groups" />
+                    <el-option :label="$t('logs.detail.commands')" value="commands" />
                 </el-select>
                 <el-select v-model="searchStatus" @change="search()" clearable class="p-w-200">
-                    <template #prefix>{{ $t('xpack.node.node') }}</template>
-                    <el-option :label="$t('commons.table.all')" value=""></el-option>
-                    <el-option :label="$t('commons.status.success')" value="Success"></el-option>
-                    <el-option :label="$t('commons.status.failed')" value="Failed"></el-option>
+                    <template #prefix>{{ $t('commons.table.status') }}</template>
+                    <el-option :label="$t('commons.table.all')" value="" />
+                    <el-option :label="$t('commons.status.success')" value="Success" />
+                    <el-option :label="$t('commons.status.failed')" value="Failed" />
                 </el-select>
                 <el-select v-model="searchNode" @change="search()" clearable class="p-w-200">
                     <template #prefix>{{ $t('xpack.node.node') }}</template>
-                    <el-option :label="$t('commons.table.all')" value=""></el-option>
+                    <el-option :label="$t('commons.table.all')" value="" />
                     <el-option :label="$t('xpack.node.master')" value="local" />
                     <el-option v-for="(node, index) in nodes" :key="index" :label="node.name" :value="node.name" />
                 </el-select>
@@ -181,7 +190,7 @@ const replacements = {
     '[delete]': 'commons.button.delete',
     '[get]': 'commons.button.get',
     '[operate]': 'commons.table.operate',
-    '[UserName]': 'commons.button.username',
+    '[UserName]': 'commons.login.username',
     '[PanelName]': 'setting.title',
     '[Language]': 'setting.language',
     '[Theme]': 'setting.theme',
diff --git a/frontend/src/views/toolbox/clam/record/index.vue b/frontend/src/views/toolbox/clam/record/index.vue
index 29875c071c5e..867d51fe4850 100644
--- a/frontend/src/views/toolbox/clam/record/index.vue
+++ b/frontend/src/views/toolbox/clam/record/index.vue
@@ -138,7 +138,7 @@
                                         <el-option :value="500" :label="500" />
                                         <el-option :value="1000" :label="1000" />
                                     </el-select>
-                                    <LogPro v-model="logContent"></LogPro>
+                                    <HighlightLog :modelValue="logContent" />
                                 </el-row>
                             </el-form>
                         </el-col>
@@ -164,6 +164,7 @@ import { ElMessageBox } from 'element-plus';
 import { MsgSuccess } from '@/utils/message';
 import { shortcuts } from '@/utils/shortcuts';
 import { Toolbox } from '@/api/interface/toolbox';
+import HighlightLog from '@/components/log/hightlight-log/index.vue';
 import { cleanClamRecord, getClamRecordLog, handleClamScan, searchClamRecord } from '@/api/modules/toolbox';
 import { useRouter } from 'vue-router';
 const router = useRouter();
diff --git a/frontend/src/views/toolbox/clam/setting/index.vue b/frontend/src/views/toolbox/clam/setting/index.vue
index 157839ff8d4e..fb0ecd49a6bd 100644
--- a/frontend/src/views/toolbox/clam/setting/index.vue
+++ b/frontend/src/views/toolbox/clam/setting/index.vue
@@ -1,30 +1,22 @@
 <template>
     <div v-loading="loading">
-        <LayoutContent>
+        <LayoutContent backName="Clam">
             <template #app>
                 <ClamStatus v-model:loading="loading" />
             </template>
-            <template #title>
-                <back-button name="Clam" header="ClamAV">
-                    <template #leftToolBar>
-                        <el-button type="primary" :plain="activeName !== 'clamd'" @click="search('clamd')">
-                            {{ $t('toolbox.clam.clamConf') }}
-                        </el-button>
-                        <el-button type="primary" :plain="activeName !== 'freshclam'" @click="search('freshclam')">
-                            {{ $t('toolbox.clam.freshClam') }}
-                        </el-button>
-                        <el-button type="primary" :plain="activeName !== 'clamd-log'" @click="search('clamd-log')">
-                            {{ $t('toolbox.clam.clamLog') }}
-                        </el-button>
-                        <el-button
-                            type="primary"
-                            :plain="activeName !== 'freshclam-log'"
-                            @click="search('freshclam-log')"
-                        >
-                            {{ $t('toolbox.clam.freshClamLog') }}
-                        </el-button>
-                    </template>
-                </back-button>
+            <template #leftToolBar>
+                <el-button type="primary" :plain="activeName !== 'clamd'" @click="search('clamd')">
+                    {{ $t('toolbox.clam.clamConf') }}
+                </el-button>
+                <el-button type="primary" :plain="activeName !== 'freshclam'" @click="search('freshclam')">
+                    {{ $t('toolbox.clam.freshClam') }}
+                </el-button>
+                <el-button type="primary" :plain="activeName !== 'clamd-log'" @click="search('clamd-log')">
+                    {{ $t('toolbox.clam.clamLog') }}
+                </el-button>
+                <el-button type="primary" :plain="activeName !== 'freshclam-log'" @click="search('freshclam-log')">
+                    {{ $t('toolbox.clam.freshClamLog') }}
+                </el-button>
             </template>
 
             <template #main>
diff --git a/frontend/src/views/toolbox/clam/status/index.vue b/frontend/src/views/toolbox/clam/status/index.vue
index f4795c37bd8b..c46412759492 100644
--- a/frontend/src/views/toolbox/clam/status/index.vue
+++ b/frontend/src/views/toolbox/clam/status/index.vue
@@ -124,7 +124,7 @@ const onOperate = async (service: string, operation: string) => {
             ' ' + service + ' ',
             i18n.global.t('commons.operate.' + operation),
         ]),
-        i18n.global.t('app.' + operation),
+        i18n.global.t('commons.operate.' + operation),
         {
             confirmButtonText: i18n.global.t('commons.button.confirm'),
             cancelButtonText: i18n.global.t('commons.button.cancel'),
diff --git a/frontend/src/views/toolbox/device/hosts/index.vue b/frontend/src/views/toolbox/device/hosts/index.vue
index dd4dd4b3f89e..35421b307a71 100644
--- a/frontend/src/views/toolbox/device/hosts/index.vue
+++ b/frontend/src/views/toolbox/device/hosts/index.vue
@@ -34,7 +34,6 @@
                 placeholder="# The hosts configuration file does not exist or is empty (/etc/hosts)"
                 v-model="hostsConf"
                 :heightDiff="300"
-                :disabled="true"
             ></CodemirrorPro>
         </div>
         <template #footer>


Reviews:
user: login: wanghe-fit2cloud
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-24T14:03:35Z
user: login: wanghe-fit2cloud
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-24T14:03:40Z
user: login: wanghe-fit2cloud
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-24T14:03:53Z
user: login: wanghe-fit2cloud
body: /lgtm
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-25T02:10:27Z

Review comments:
diff_hunk: @@ -181,7 +190,7 @@ const replacements = {
     '[delete]': 'commons.button.delete',
     '[get]': 'commons.button.get',
     '[operate]': 'commons.table.operate',
-    '[UserName]': 'commons.button.username',
+    '[UserName]': 'commons.login.username',
     '[PanelName]': 'setting.title',
     '[Language]': 'setting.language',
     '[Theme]': 'setting.theme',
path: frontend/src/views/log/operation/index.vue
user: login: wanghe-fit2cloud
body: The code provides several improvements:

1. **Optimized Option List**:
   - Replaced long lists of log types with more concise options to reduce clutter.

2. **Consistently Named Prefixes**:
   - Changed the "Node" prefix in one `el-select` component to match conventions used elsewhere (`status`, `all`).

3. **Changed Text for Username**:
   - Corrected spelling error for username placeholder text from 'username' to 'username'.

4. **Removed Unnecessary HTML Entity Escaping**:
   - Removed unnecessary backslashes (e.g., `\[\`) that could interfere with Vue.js syntax interpretation.

These changes enhance readability, usability, and consistency across multiple components within the application.
created_at: 2025-03-24T14:03:35Z
author_association: MEMBER
diff_hunk: @@ -1,30 +1,22 @@
 <template>
     <div v-loading="loading">
-        <LayoutContent>
+        <LayoutContent backName="Clam">
             <template #app>
                 <ClamStatus v-model:loading="loading" />
             </template>
-            <template #title>
-                <back-button name="Clam" header="ClamAV">
-                    <template #leftToolBar>
-                        <el-button type="primary" :plain="activeName !== 'clamd'" @click="search('clamd')">
-                            {{ $t('toolbox.clam.clamConf') }}
-                        </el-button>
-                        <el-button type="primary" :plain="activeName !== 'freshclam'" @click="search('freshclam')">
-                            {{ $t('toolbox.clam.freshClam') }}
-                        </el-button>
-                        <el-button type="primary" :plain="activeName !== 'clamd-log'" @click="search('clamd-log')">
-                            {{ $t('toolbox.clam.clamLog') }}
-                        </el-button>
-                        <el-button
-                            type="primary"
-                            :plain="activeName !== 'freshclam-log'"
-                            @click="search('freshclam-log')"
-                        >
-                            {{ $t('toolbox.clam.freshClamLog') }}
-                        </el-button>
-                    </template>
-                </back-button>
+            <template #leftToolBar>
+                <el-button type="primary" :plain="activeName !== 'clamd'" @click="search('clamd')">
+                    {{ $t('toolbox.clam.clamConf') }}
+                </el-button>
+                <el-button type="primary" :plain="activeName !== 'freshclam'" @click="search('freshclam')">
+                    {{ $t('toolbox.clam.freshClam') }}
+                </el-button>
+                <el-button type="primary" :plain="activeName !== 'clamd-log'" @click="search('clamd-log')">
+                    {{ $t('toolbox.clam.clamLog') }}
+                </el-button>
+                <el-button type="primary" :plain="activeName !== 'freshclam-log'" @click="search('freshclam-log')">
+                    {{ $t('toolbox.clam.freshClamLog') }}
+                </el-button>
             </template>
 
             <template #main>
path: frontend/src/views/toolbox/clam/setting/index.vue
user: login: wanghe-fit2cloud
body: ### Code Diff Review

**Differences:**

#### Layout Content Changes:

1. **Template Slot**: The slot named `app` is replaced with another template slot named `leftToolBar`. This change implies that the layout content might now be structured slightly differently.

2. **Back Button and Tool Bar**: The `<back-button>` component's left toolbar section has been duplicated within the new `leftToolBar` slot. Ensure this duplication aligns with the intended functionality or design of the interface.

**Potential Issues:**
- **Redundancy**: While this duplication may not cause functional issues alone, it could introduce visual clutter if there needs to be only one set of buttons. A review should ensure that duplicating the left toolbar does not lead to inconsistencies.
- **Accessibility**: Consider how screen readers will handle two instances of the left toolbar, especially if they navigate through the app content using tab keys.

**Optimization Suggestions (if any):**
- **Simplify Duplication**: If these buttons have similar functionalities, consider simplifying their handling through methods like event bubbling or a more efficient data structure instead of duplicating elements.
- **Dynamic Toolbar Management**: Implement logic to dynamically show/hide toolbars based on certain conditions or view modes, avoiding redundancy when necessary.
created_at: 2025-03-24T14:03:40Z
author_association: MEMBER
diff_hunk: @@ -758,6 +759,28 @@ func (f FileOp) TarGzCompressPro(withDir bool, src, dst, secret, exclusionRules
 	return cmd.ExecCmdWithDir(commands, workdir)
 }
 
+func (f FileOp) TarGzFilesWithCompressPro(list []string, dst, secret string) error {
+	if !f.Stat(path.Dir(dst)) {
+		if err := f.Fs.MkdirAll(path.Dir(dst), constant.FilePerm); err != nil {
+			return err
+		}
+	}
+
+	var filelist []string
+	for _, item := range list {
+		filelist = append(filelist, "-C "+path.Dir(item)+" "+path.Base(item))
+	}
+	commands := ""
+	if len(secret) != 0 {
+		commands = fmt.Sprintf("tar --warning=no-file-changed --ignore-failed-read -zcf - %s | openssl enc -aes-256-cbc -salt -k '%s' -out %s", strings.Join(filelist, " "), secret, dst)
+		global.LOG.Debug(strings.ReplaceAll(commands, fmt.Sprintf(" %s ", secret), "******"))
+	} else {
+		commands = fmt.Sprintf("tar --warning=no-file-changed --ignore-failed-read -zcf %s %s", dst, strings.Join(filelist, " "))
+		global.LOG.Debug(commands)
+	}
+	return cmd.ExecCmd(commands)
+}
+
 func (f FileOp) TarGzExtractPro(src, dst string, secret string) error {
 	if _, err := os.Stat(path.Dir(dst)); err != nil && os.IsNotExist(err) {
 		if err = os.MkdirAll(path.Dir(dst), os.ModePerm); err != nil {
path: agent/utils/files/file_op.go
user: login: wanghe-fit2cloud
body: In the provided code snippet, there are several small improvements and corrections that can be made:

1. **Remove Unused Import**: The `crypto/tls` package is not used anywhere in the code, so it can be removed to simplify dependencies.

   ```diff
   -import "crypto/tls"
   ```

2. **Consistent Indentation**: Ensure consistent indentation throughout the file to make reading easier.

3. **Optimize Error Handling**: In some functions like `TarGzCompressPro`, handle errors more thoroughly by using `global LOG.Error`.

4. **Variable Naming Consistency**: Consistently use either lowercase or uppercase variable names. For example, keep `dst` as lower case while other variables are camel case.

Here's the updated diff:

```diff
@@ -7,7 +7,6 @@ import (
 	"crypto/tls"
 	"encoding/json"
 	"fmt"
-	"github.com/1Panel-dev/1Panel/agent/buserr"
 	"io"
 	"io/fs"
 	"net/http"
@@ -19,6 +18,8 @@ import (
 	"strings"
 	"time"
 
+	"github.com/1Panel-dev/1Panel/agent/buusr" // Remove unused import
+
 	"github.com/1Panel-dev/1Panel/agent/constant"
 	"github.com/1Panel-dev/1Panel/agent/utils/cmd"
@@ -758,6 +759,28 @@ func (f FileOp) TarGzCompressPro(withDir bool, src, dst, secret, exclusionRules
 	return cmd.ExecCmdWithDir(commands, workdir)
 }

+func (f FileOp) TarGzFilesWithCompressPro(list []string, dest string, secret string) error {
+	if !f.Stat(path.Dir(dest)) {
+		err := f.Fs.MkdirAll(path.Dir(dest), constant.FilePerm)
+		if err != nil {
+			return global.LOG.Errorf("Failed to create directory: %+v", err)
+		}
+	}
+
+	var filelist []string
+	for _, item := range list {
+		filelist = append(filelist, "-C "+path.Dir(item)+” ”+path.Base(item))
+	}
+	commands := ""
+	if len(secret) != 0 {
+		cmdTemplate := "tar --warning=no-file-changed --ignore-failed-read -zcf - %s | openssl enc -aes-256-cbc -salt -k '%s' -out %s"
+		encrypted := strings.Join(filelist, “\t”) // Use tabs instead of spaces for better readability if needed
+		commandWithSecret := fmt.Sprintf(cmdTemplate, encrypted, secret, dest)
+		global.LOG.Debugf("Executing command with secrets masked: %s", strings.Replace(commandWithSecret, secret, "", -1)) // Mask secrets during logging
+		commands = commandWithSecret
+	} else {
+		commands = fmt.Sprintf("tar --warning=no-file-changed --ignore-failed-read -zcf %s %s", dest, strings.Join(filelist, " "))
+	}
+	return cmd.ExecCmd(commands)
+}

 func (f FileOp) TarGzExtractPro(src, dest stri
e appropriate handling of errors should always return useful and relevant information. It will also help maintainers understand what went wrong quickly when debugging.

6. **Comments for Readability**: Adding comments above longer functions or sections of code can improve readability and understanding of their purpose. This especially applies to areas where complex logic occurs.

These changes aim to clean up the codebase, making it more robust and understandable.
created_at: 2025-03-24T14:03:53Z
author_association: MEMBER

PR comments:
user: login: f2c-ci-robot[bot]
created_at: 2025-03-24T14:03:25Z
body: Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our [release note process](https://git.k8s.io/community/contributors/guide/release-notes.md) to remove it.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>
author_association: NONE
user: login: sonarqubecloud[bot]
created_at: 2025-03-24T14:04:56Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=1Panel-dev_1Panel&pullRequest=8234) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [2 New issues](https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&pullRequest=8234&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&pullRequest=8234&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=1Panel-dev_1Panel&pullRequest=8234&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=1Panel-dev_1Panel&pullRequest=8234&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=1Panel-dev_1Panel&pullRequest=8234&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=1Panel-dev_1Panel&pullRequest=8234)


author_association: NONE
user: login: wanghe-fit2cloud
created_at: 2025-03-25T02:10:36Z
body: /approve
author_association: MEMBER
user: login: f2c-ci-robot[bot]
created_at: 2025-03-25T02:10:43Z
body: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/1Panel-dev/1Panel/pull/8234#issuecomment-2749865233" title="Approved">wanghe-fit2cloud</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=1Panel-dev%2F1Panel).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/1Panel-dev/1Panel/blob/dev-v2/OWNERS)~~ [wanghe-fit2cloud]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
author_association: NONE