fix: Support configurable docker config file snapshotting (#9363)

This commit is contained in:
ssongliu 2025-07-01 15:49:32 +08:00 committed by GitHub
parent c522295c56
commit 08f53a4a37
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 44 additions and 23 deletions

View file

@ -23,6 +23,7 @@ type SnapshotCreate struct {
BackupData []DataTree `json:"backupData"`
PanelData []DataTree `json:"panelData"`
WithDockerConf bool `json:"withDockerConf"`
WithMonitorData bool `json:"withMonitorData"`
WithLoginLog bool `json:"withLoginLog"`
WithOperationLog bool `json:"withOperationLog"`
@ -37,6 +38,7 @@ type SnapshotData struct {
BackupData []DataTree `json:"backupData"`
PanelData []DataTree `json:"panelData"`
WithDockerConf bool `json:"withDockerConf"`
WithMonitorData bool `json:"withMonitorData"`
WithLoginLog bool `json:"withLoginLog"`
WithOperationLog bool `json:"withOperationLog"`

View file

@ -15,9 +15,11 @@ type Snapshot struct {
TaskRecoverID string `json:"taskRecoverID"`
TaskRollbackID string `json:"taskRollbackID"`
AppData string `json:"appData"`
PanelData string `json:"panelData"`
BackupData string `json:"backupData"`
AppData string `json:"appData"`
PanelData string `json:"panelData"`
BackupData string `json:"backupData"`
WithDockerConf bool `json:"withDockerConf"`
WithMonitorData bool `json:"withMonitorData"`
WithLoginLog bool `json:"withLoginLog"`
WithOperationLog bool `json:"withOperationLog"`

View file

@ -110,6 +110,7 @@ func (u *SnapshotService) LoadSnapshotData() (dto.SnapshotData, error) {
if err != nil {
return data, err
}
data.WithDockerConf = true
data.PanelData, err = loadPanelFile(fileOp)
if err != nil {
return data, err

View file

@ -51,6 +51,7 @@ func (u *SnapshotService) SnapshotCreate(parentTask *task.Task, req dto.Snapshot
AppData: string(appItem),
PanelData: string(panelItem),
BackupData: string(backupItem),
WithDockerConf: req.WithDockerConf,
WithMonitorData: req.WithMonitorData,
WithLoginLog: req.WithLoginLog,
WithOperationLog: req.WithOperationLog,
@ -148,7 +149,7 @@ func handleSnapshot(req dto.SnapshotCreate, taskItem *task.Task, jobID, retry, t
if len(req.InterruptStep) == 0 || req.InterruptStep == "SnapBaseInfo" {
taskItem.AddSubTaskWithAliasAndOps(
"SnapBaseInfo",
func(t *task.Task) error { return snapBaseData(itemHelper, baseDir) },
func(t *task.Task) error { return snapBaseData(itemHelper, baseDir, req.WithDockerConf) },
nil, int(retry), time.Duration(timeout)*time.Second,
)
req.InterruptStep = ""
@ -287,7 +288,7 @@ func loadDbConn(snap *snapHelper, targetDir string, req dto.SnapshotCreate) erro
return nil
}
func snapBaseData(snap snapHelper, targetDir string) error {
func snapBaseData(snap snapHelper, targetDir string, withDockerConf bool) error {
snap.Task.Log("---------------------- 2 / 8 ----------------------")
snap.Task.LogStart(i18n.GetMsgByKey("SnapBaseInfo"))
@ -324,11 +325,13 @@ func snapBaseData(snap snapHelper, targetDir string) error {
return err
}
if snap.FileOp.Stat(constant.DaemonJsonPath) {
err = snap.FileOp.CopyFile(constant.DaemonJsonPath, targetDir)
snap.Task.LogWithStatus(i18n.GetWithName("SnapCopy", constant.DaemonJsonPath), err)
if err != nil {
return err
if withDockerConf {
if snap.FileOp.Stat(constant.DaemonJsonPath) {
err = snap.FileOp.CopyFile(constant.DaemonJsonPath, targetDir)
snap.Task.LogWithStatus(i18n.GetWithName("SnapCopy", constant.DaemonJsonPath), err)
if err != nil {
return err
}
}
}

View file

@ -392,14 +392,10 @@ func recoverBaseData(src string, itemHelper *snapRecoverHelper) error {
return err
}
daemonJsonPath := constant.DaemonJsonPath
_, errSrc := os.Stat(path.Join(src, "daemon.json"))
_, errPath := os.Stat(daemonJsonPath)
if os.IsNotExist(errSrc) && os.IsNotExist(errPath) {
if !itemHelper.FileOp.Stat(path.Join(src, "daemon.json")) {
itemHelper.Task.Log(i18n.GetMsgByKey("RecoverDaemonJsonEmpty"))
return nil
}
if errSrc == nil {
} else {
err = itemHelper.FileOp.CopyFile(path.Join(src, "daemon.json"), "/etc/docker")
itemHelper.Task.Log(i18n.GetMsgByKey("RecoverDaemonJson"))
if err != nil {

View file

@ -78,7 +78,10 @@ func (u *SnapshotService) SnapshotRollback(req dto.SnapshotRecover) error {
taskItem.AddSubTask(
i18n.GetWithName("SnapCopy", constant.DaemonJsonPath),
func(t *task.Task) error {
return FileOp.CopyFile(path.Join(baseDir, "daemon.json"), "/etc/docker")
if FileOp.Stat(path.Join(baseDir, "daemon.json")) {
return FileOp.CopyFile(path.Join(baseDir, "daemon.json"), "/etc/docker")
}
return nil
},
nil,
)

View file

@ -337,7 +337,7 @@ var UpdatePHPRuntime = &gormigrate.Migration{
},
}
var AddSnapshotIgnore = &gormigrate.Migration{
ID: "20250627-add-snapshot-ignore",
ID: "20250628-add-snapshot-ignore",
Migrate: func(tx *gorm.DB) error {
return tx.AutoMigrate(
&model.Snapshot{},

View file

@ -1828,6 +1828,7 @@ const message = {
systemLog: 'Retain System Log',
taskLog: 'Retain Task Log',
monitorData: 'Retain Monitoring Data',
dockerConf: 'Retain Docker Configuration',
selectAllImage: 'Backup All Application Images',
logLabel: 'Log',
agentLabel: 'Node Configuration',

View file

@ -1749,6 +1749,7 @@ const message = {
systemLog: 'システムログを保持',
taskLog: 'タスクログを保持',
monitorData: '監視データを保持',
dockerConf: 'Docker設定保持',
selectAllImage: 'すべてのアプリイメージをバックアップ',
logLabel: 'ログ',
agentLabel: 'ノード設定',

View file

@ -1722,6 +1722,7 @@ const message = {
systemLog: '시스템 로그 유지',
taskLog: '작업 로그 유지',
monitorData: '모니터링 데이터 유지',
dockerConf: 'Docker 설정',
selectAllImage: '모든 이미지를 백업',
logLabel: '로그',
agentLabel: '노드 설정',

View file

@ -1805,6 +1805,7 @@ const message = {
systemLog: 'Simpan log sistem',
taskLog: 'Simpan log tugas',
monitorData: 'Simpan data pemantauan',
dockerConf: 'Simpan Konfigurasi Docker',
selectAllImage: 'Simpan semua imej aplikasi',
logLabel: 'Log',
agentLabel: 'Konfigurasi Nod',

View file

@ -1790,6 +1790,7 @@ const message = {
systemLog: 'Manter logs do sistema',
taskLog: 'Manter logs de tarefas',
monitorData: 'Manter dados de monitoramento',
dockerConf: 'Manter Configuração do Docker',
selectAllImage: 'Fazer backup de todas as imagens de aplicativos',
logLabel: 'Log',
agentLabel: 'Configuração do ',

View file

@ -1787,6 +1787,7 @@ const message = {
systemLog: 'Сохранять системный журнал',
taskLog: 'Сохранять журнал задач',
monitorData: 'Сохранять данные мониторинга',
dockerConf: 'Сохранять Конфигурация Docker',
selectAllImage: 'Резервное копирование всех образов приложений',
logLabel: 'Журнал',
agentLabel: 'Конфигурация узла',

View file

@ -1638,6 +1638,7 @@ const message = {
systemLog: '保留系統日誌',
taskLog: '保留任務日誌',
monitorData: '保留監控數據',
dockerConf: '保留 Docker 配置',
selectAllImage: '備份所有應用鏡像',
logLabel: '日誌',
agentLabel: '節點配置',

View file

@ -1629,6 +1629,7 @@ const message = {
stepBackupData: '备份数据',
stepOtherData: '其他数据',
monitorData: '监控数据',
dockerConf: 'Docker 配置',
selectAllImage: '备份所有应用镜像',
logLabel: '日志',
agentLabel: '节点配置',

View file

@ -134,11 +134,13 @@
<span class="status-label">{{ $t('commons.table.interval') }}</span>
</template>
<el-button link v-if="!currentRecord?.interval" :loading="true" />
<span class="status-count" v-if="currentRecord?.interval! <= 1000">
{{ currentRecord?.interval }} ms
</span>
<span class="status-count" v-if="currentRecord?.interval! > 1000">
{{ currentRecord?.interval! / 1000 }} s
<span v-else>
<span class="status-count" v-if="currentRecord?.interval! <= 1000">
{{ currentRecord?.interval }} ms
</span>
<span class="status-count" v-if="currentRecord?.interval! > 1000">
{{ currentRecord?.interval! / 1000 }} s
</span>
</span>
</el-form-item>
<el-form-item class="description">

View file

@ -126,6 +126,9 @@
</div>
</fu-step>
<fu-step id="otherData" :title="$t('setting.stepOtherData')">
<div class="ml-5">
<el-checkbox v-model="form.withDockerConf" :label="$t('setting.dockerConf')" size="large" />
</div>
<div class="ml-5">
<el-checkbox v-model="form.withOperationLog" :label="$t('logs.operation')" size="large" />
</div>
@ -195,6 +198,7 @@ const form = reactive({
secret: '',
backupAllImage: false,
withDockerConf: true,
withLoginLog: false,
withOperationLog: false,
withSystemLog: false,