mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-01-04 05:56:04 +08:00
feat: Support customizing the number of upgrade backup copies (#10483)
Refs #7361
This commit is contained in:
parent
07d0b37692
commit
0a6163c89b
18 changed files with 168 additions and 19 deletions
|
|
@ -5,9 +5,10 @@ import (
|
|||
)
|
||||
|
||||
type SettingInfo struct {
|
||||
UserName string `json:"userName"`
|
||||
SystemVersion string `json:"systemVersion"`
|
||||
DeveloperMode string `json:"developerMode"`
|
||||
UserName string `json:"userName"`
|
||||
SystemVersion string `json:"systemVersion"`
|
||||
DeveloperMode string `json:"developerMode"`
|
||||
UpgradeBackupCopies string `json:"upgradeBackupCopies"`
|
||||
|
||||
SessionTimeout string `json:"sessionTimeout"`
|
||||
Port string `json:"port"`
|
||||
|
|
|
|||
|
|
@ -145,6 +145,8 @@ func (u *SettingService) Update(key, value string) error {
|
|||
if err := xpack.Sync(constant.SyncLanguage); err != nil {
|
||||
global.LOG.Errorf("sync language to node failed, err: %v", err)
|
||||
}
|
||||
case "UpgradeBackupCopies":
|
||||
dropBackupCopies()
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -190,6 +191,7 @@ func (u *UpgradeService) Upgrade(req dto.Upgrade) error {
|
|||
}
|
||||
|
||||
global.LOG.Info("upgrade successful!")
|
||||
dropBackupCopies()
|
||||
go writeLogs(req.Version)
|
||||
_ = settingRepo.Update("SystemVersion", req.Version)
|
||||
_ = global.AgentDB.Model(&model.Setting{}).Where("key = ?", "SystemVersion").Updates(map[string]interface{}{"value": req.Version}).Error
|
||||
|
|
@ -473,3 +475,32 @@ func loadArch() (string, error) {
|
|||
}
|
||||
return "", fmt.Errorf("unsupported such arch: %s", std)
|
||||
}
|
||||
|
||||
func dropBackupCopies() {
|
||||
backupCopies, _ := settingRepo.GetValueByKey("UpgradeBackupCopies")
|
||||
copies, _ := strconv.Atoi(backupCopies)
|
||||
if copies == 0 {
|
||||
return
|
||||
}
|
||||
backupDir := path.Join(global.CONF.Base.InstallDir, "1panel/tmp/upgrade")
|
||||
upgradeDir, err := os.ReadDir(backupDir)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("read upgrade dir failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
var versions []string
|
||||
for _, item := range upgradeDir {
|
||||
if item.IsDir() && strings.HasPrefix(item.Name(), "v") {
|
||||
versions = append(versions, item.Name())
|
||||
}
|
||||
}
|
||||
if len(versions) <= copies {
|
||||
return
|
||||
}
|
||||
sort.Slice(versions, func(i, j int) bool {
|
||||
return common.ComparePanelVersion(versions[i], versions[j])
|
||||
})
|
||||
for i := copies - 1; i < len(versions); i++ {
|
||||
_ = os.RemoveAll(backupDir + "/" + versions[i])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ func Init() {
|
|||
migrations.AddCronjobGroup,
|
||||
migrations.AddDiskMenu,
|
||||
migrations.AddSimpleNodeGroup,
|
||||
migrations.AddUpgradeBackupCopies,
|
||||
})
|
||||
if err := m.Migrate(); err != nil {
|
||||
global.LOG.Error(err)
|
||||
|
|
|
|||
|
|
@ -535,3 +535,13 @@ var AddSimpleNodeGroup = &gormigrate.Migration{
|
|||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var AddUpgradeBackupCopies = &gormigrate.Migration{
|
||||
ID: "20250925-add-upgrade-backup-copies",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
if err := tx.Create(&model.Setting{Key: "UpgradeBackupCopies", Value: "0"}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ export namespace Setting {
|
|||
email: string;
|
||||
systemIP: string;
|
||||
systemVersion: string;
|
||||
upgradeBackupCopies: string;
|
||||
dockerSockPath: string;
|
||||
developerMode: string;
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ const getVersionLog = () => {
|
|||
if (isOffLine) {
|
||||
return;
|
||||
}
|
||||
releasesRef.value.acceptParams({ version: version });
|
||||
releasesRef.value.acceptParams();
|
||||
};
|
||||
|
||||
const toLxware = () => {
|
||||
|
|
|
|||
|
|
@ -1,18 +1,29 @@
|
|||
<template>
|
||||
<DrawerPro v-model="drawerVisible" :header="$t('setting.release')" @close="handleClose" size="large">
|
||||
<template #buttons>
|
||||
<span>{{ version }}</span>
|
||||
<CopyButton :content="version" type="primary" />
|
||||
</template>
|
||||
<div class="note" v-loading="loading">
|
||||
<el-form ref="formRef" :model="form" :rules="rules">
|
||||
<el-form-item :label="$t('setting.versionItem')" prop="version">
|
||||
<el-input class="p-w-200" disabled v-model="form.version">
|
||||
<template #append>
|
||||
<CopyButton class="w-16" :isIcon="false" :content="form.version" type="primary" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('setting.backupCopies')" prop="backupCopies">
|
||||
<el-input class="p-w-200" type="number" v-model.number="form.backupCopies">
|
||||
<template #append>
|
||||
<el-button @click="onSave(formRef)" class="w-16">{{ $t('commons.button.save') }}</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
<span class="input-help">{{ $t('setting.backupCopiesHelper') }}</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-collapse v-if="notes && notes.length !== 0" v-model="currentVersion" :accordion="true">
|
||||
<div v-for="(item, index) in notes" :key="index">
|
||||
<el-collapse-item :name="index">
|
||||
<template #title>
|
||||
<div>
|
||||
<span class="version">{{ item.version }}</span>
|
||||
<span v-if="!mobile" class="date">{{ item.createdAt }}</span>
|
||||
</div>
|
||||
<span class="version">{{ item.version }}</span>
|
||||
<span v-if="!mobile" class="date">{{ item.createdAt }}</span>
|
||||
<svg-icon class="icon" iconName="p-featureshitu"></svg-icon>
|
||||
<span class="icon-span">{{ item.newCount }}</span>
|
||||
<svg-icon class="icon" iconName="p-youhuawendang"></svg-icon>
|
||||
|
|
@ -46,12 +57,16 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { listReleases } from '@/api/modules/setting';
|
||||
import { getSettingInfo, listReleases, updateSetting } from '@/api/modules/setting';
|
||||
import MdEditor from 'md-editor-v3';
|
||||
import 'md-editor-v3/lib/style.css';
|
||||
import { ref } from 'vue';
|
||||
import { GlobalStore } from '@/store';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import i18n from '@/lang';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
|
||||
const globalStore = GlobalStore();
|
||||
const mobile = computed(() => {
|
||||
|
|
@ -64,17 +79,55 @@ const drawerVisible = ref(false);
|
|||
const currentVersion = ref(0);
|
||||
const notes = ref([]);
|
||||
const loading = ref();
|
||||
const version = ref();
|
||||
const formRef = ref();
|
||||
|
||||
interface DialogProps {
|
||||
version: string;
|
||||
}
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
version.value = params.version;
|
||||
const form = reactive({
|
||||
version: '',
|
||||
backupCopies: 0,
|
||||
});
|
||||
const rules = reactive({
|
||||
version: [Rules.requiredInput],
|
||||
backupCopies: [{ validator: checkBackupCopies, trigger: 'blur', required: true }],
|
||||
});
|
||||
|
||||
const acceptParams = (): void => {
|
||||
search();
|
||||
loadInfo();
|
||||
drawerVisible.value = true;
|
||||
};
|
||||
|
||||
const loadInfo = async () => {
|
||||
const res = await getSettingInfo();
|
||||
form.version = res.data.systemVersion;
|
||||
form.backupCopies = Number(res.data.upgradeBackupCopies) || 0;
|
||||
};
|
||||
|
||||
function checkBackupCopies(rule: any, value: any, callback: any) {
|
||||
if (value === 0) {
|
||||
return callback();
|
||||
}
|
||||
if (value < 3) {
|
||||
return callback(new Error(i18n.global.t('setting.backupCopiesRule')));
|
||||
}
|
||||
callback();
|
||||
}
|
||||
|
||||
const onSave = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
loading.value = true;
|
||||
await updateSetting({ key: 'UpgradeBackupCopies', value: form.backupCopies + '' })
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
drawerVisible.value = false;
|
||||
};
|
||||
|
|
@ -124,6 +177,7 @@ defineExpose({
|
|||
padding: 0px;
|
||||
}
|
||||
.icon {
|
||||
display: inline-block;
|
||||
font-size: 7px;
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1990,6 +1990,10 @@ const message = {
|
|||
'Detected that node {0} is already at the latest upgradable version. Please check the primary node version and try again!',
|
||||
|
||||
about: 'About',
|
||||
versionItem: 'Current Version',
|
||||
backupCopies: 'Number of Copies to Keep',
|
||||
backupCopiesHelper: 'Set the number of upgrade backup copies to keep for version rollback. 0 means keep all.',
|
||||
backupCopiesRule: 'Please keep at least 3 upgrade backup records',
|
||||
release: 'Release Notes',
|
||||
releaseHelper:
|
||||
'Failed to fetch release notes for the current environment. You can manually check the official documentation.',
|
||||
|
|
|
|||
|
|
@ -1994,7 +1994,13 @@ const message = {
|
|||
'La versión del nodo no coincide con la del nodo principal. Actualiza en la gestión de nodos antes de reintentar.',
|
||||
versionCompare:
|
||||
'Se detectó que el nodo {0} ya está en la última versión actualizable. Verifica la versión del nodo principal e inténtalo de nuevo.',
|
||||
|
||||
about: 'Acerca de',
|
||||
versionItem: 'Versión Actual',
|
||||
backupCopies: 'Número de Copias a Conservar',
|
||||
backupCopiesHelper:
|
||||
'Establezca el número de copias de respaldo de actualización para conservar para la reversión de versión. 0 significa conservar todas.',
|
||||
backupCopiesRule: 'Conserve al menos 3 registros de respaldo de actualización',
|
||||
release: 'Notas de lanzamiento',
|
||||
releaseHelper:
|
||||
'No se pudieron obtener las notas de lanzamiento para el entorno actual. Puedes consultarlas manualmente en la documentación oficial.',
|
||||
|
|
|
|||
|
|
@ -1907,6 +1907,11 @@ const message = {
|
|||
'ノード {0} は既にアップグレード可能な最新バージョンです。マスターノードのバージョンを確認後、再試行してください!',
|
||||
|
||||
about: 'について',
|
||||
versionItem: '現在のバージョン',
|
||||
backupCopies: '保持するバックアップ数',
|
||||
backupCopiesHelper:
|
||||
'バージョンロールバック用に保持するアップグレードバックアップの数を設定します。0はすべて保持を意味します。',
|
||||
backupCopiesRule: '少なくとも3つのアップグレードバックアップ記録を保持してください',
|
||||
release: 'バージョン更新履歴',
|
||||
releaseHelper: '現在の環境の更新履歴の取得に異常が発生しました。手動で公式ドキュメントを確認してください。',
|
||||
project: 'GitHub',
|
||||
|
|
|
|||
|
|
@ -1876,6 +1876,11 @@ const message = {
|
|||
'노드 {0}이(가) 이미 업그레이드 가능한 최신 버전입니다. 마스터 노드 버전을 확인 후 다시 시도하세요!',
|
||||
|
||||
about: '정보',
|
||||
versionItem: '현재 버전',
|
||||
backupCopies: '보관할 백업 복사본 수',
|
||||
backupCopiesHelper:
|
||||
'버전 롤백을 위해 보관할 업그레이드 백업 복사본 수를 설정합니다. 0은 모두 보관을 의미합니다.',
|
||||
backupCopiesRule: '최소 3개의 업그레이드 백업 기록을 보관하세요',
|
||||
release: '버전 업데이트 로그',
|
||||
releaseHelper:
|
||||
'현재 환경의 업데이트 로그를 가져오는 중 오류가 발생했습니다. 공식 문서에서 수동으로 확인하실 수 있습니다.',
|
||||
|
|
|
|||
|
|
@ -1963,6 +1963,11 @@ const message = {
|
|||
'Nod {0} telah berada pada versi terkini yang boleh dinaik taraf. Sila periksa versi nod utama dan cuba lagi!',
|
||||
|
||||
about: 'Mengenai',
|
||||
versionItem: 'Versi Semasa',
|
||||
backupCopies: 'Bilangan Salinan untuk Disimpan',
|
||||
backupCopiesHelper:
|
||||
'Tetapkan bilangan salinan sandaran naik taraf untuk disimpan untuk pemulihan versi. 0 bermakna simpan semua.',
|
||||
backupCopiesRule: 'Sila simpan sekurang-kurangnya 3 rekod sandaran naik taraf',
|
||||
release: 'Log Kemaskini Versi',
|
||||
releaseHelper:
|
||||
'Pengambilan log kemaskini untuk persekitaran semasa mengalami异常. Anda boleh menyemak dokumentasi rasmi secara manual.',
|
||||
|
|
|
|||
|
|
@ -1953,6 +1953,11 @@ const message = {
|
|||
'Detectado que o nó {0} já está na última versão atualizável. Por favor, verifique a versão do nó principal e tente novamente!',
|
||||
|
||||
about: 'Sobre',
|
||||
versionItem: 'Versão Atual',
|
||||
backupCopies: 'Número de Cópias a Manter',
|
||||
backupCopiesHelper:
|
||||
'Defina o número de cópias de backup de atualização para manter para reversão de versão. 0 significa manter todas.',
|
||||
backupCopiesRule: 'Mantenha pelo menos 3 registros de backup de atualização',
|
||||
release: 'Registro de Atualizações de Versão',
|
||||
releaseHelper:
|
||||
'Falha ao obter o registro de atualizações para o ambiente atual. Você pode verificar a documentação oficial manualmente.',
|
||||
|
|
|
|||
|
|
@ -1951,6 +1951,11 @@ const message = {
|
|||
'Обнаружено, что узел {0} уже имеет последнюю обновляемую версию. Пожалуйста, проверьте версию основного узла и повторите попытку!',
|
||||
|
||||
about: 'О программе',
|
||||
versionItem: 'Текущая Версия',
|
||||
backupCopies: 'Количество Копий для Сохранения',
|
||||
backupCopiesHelper:
|
||||
'Установите количество копий резервных копий обновления для сохранения для отката версии. 0 означает сохранить все.',
|
||||
backupCopiesRule: 'Пожалуйста, сохраните как минимум 3 записи резервных копий обновления',
|
||||
release: 'Журнал обновлений версий',
|
||||
releaseHelper:
|
||||
'Не удалось получить журнал обновлений для текущей среды. Вы можете вручную проверить официальную документацию.',
|
||||
|
|
|
|||
|
|
@ -2007,7 +2007,13 @@ const message = {
|
|||
versionNotSame: 'Düğüm sürümü ana düğümle uyuşmuyor. Lütfen Düğüm Yönetiminde yükseltin ve tekrar deneyin.',
|
||||
versionCompare:
|
||||
'{0} düğümünün zaten en son yükseltilebilir sürümde olduğu tespit edildi. Lütfen birincil düğüm sürümünü kontrol edin ve tekrar deneyin!',
|
||||
|
||||
about: 'Hakkında',
|
||||
versionItem: 'Mevcut Sürüm',
|
||||
backupCopies: 'Saklanacak Kopya Sayısı',
|
||||
backupCopiesHelper:
|
||||
'Sürüm geri alma için saklanacak yükseltme yedek kopya sayısını ayarlayın. 0, tümünü sakla anlamına gelir.',
|
||||
backupCopiesRule: 'Lütfen en az 3 yükseltme yedek kaydı saklayın',
|
||||
release: 'Sürüm Güncelleme Günlüğü',
|
||||
releaseHelper:
|
||||
'Mevcut ortam için güncelleme günlükleri alınırken hata oluştu. Resmi belgeleri manuel olarak kontrol edebilirsiniz.',
|
||||
|
|
|
|||
|
|
@ -1862,6 +1862,10 @@ const message = {
|
|||
certificate: '證書',
|
||||
|
||||
about: '關於',
|
||||
versionItem: '目前版本',
|
||||
backupCopies: '保留份數',
|
||||
backupCopiesHelper: '設定用於版本回滾的升級備份保留份數。0 表示保留所有。',
|
||||
backupCopiesRule: '請至少保存 3 份升級備份記錄',
|
||||
release: '版本更新日誌',
|
||||
releaseHelper: '目前環境更新日誌取得異常,可手動前往官方文件查看',
|
||||
project: '項目地址',
|
||||
|
|
|
|||
|
|
@ -1854,6 +1854,10 @@ const message = {
|
|||
certificate: '证书',
|
||||
|
||||
about: '关于',
|
||||
versionItem: '当前版本',
|
||||
backupCopies: '保留份数',
|
||||
backupCopiesHelper: '设置用于版本回滚的升级备份保留份数,为 0 则保留所有。',
|
||||
backupCopiesRule: '请至少保存 3 份升级备份记录',
|
||||
release: '版本更新日志',
|
||||
releaseHelper: '当前环境更新日志获取异常,可手动前往官方文档查看',
|
||||
project: '项目地址',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue