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
20 changes: 20 additions & 0 deletions core/app/api/v2/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/1Panel-dev/1Panel/core/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/core/app/dto"
"github.com/1Panel-dev/1Panel/core/app/repo"
"github.com/1Panel-dev/1Panel/core/constant"
"github.com/1Panel-dev/1Panel/core/global"
"github.com/1Panel-dev/1Panel/core/utils/mfa"
Expand All @@ -32,6 +33,25 @@ func (b *BaseApi) GetSettingInfo(c *gin.Context) {
helper.SuccessWithData(c, setting)
}

// @Tags System Setting
// @Summary Load system setting by key
// @Success 200 {string} info
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /core/settings/by [post]
func (b *BaseApi) GetSettingByKey(c *gin.Context) {
var req dto.SettingKey
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
setting, err := repo.NewISettingRepo().GetValueByKey(req.Key)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, setting)
}

// @Tags System Setting
// @Summary Load system terminal setting info
// @Success 200 {object} dto.TerminalInfo
Expand Down
4 changes: 4 additions & 0 deletions core/app/dto/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ type SettingInfo struct {
ApiKeyValidityTime string `json:"apiKeyValidityTime"`
}

type SettingKey struct {
Key string `json:"key" validate:"required,oneof=ScriptSync"`
}

type SettingUpdate struct {
Key string `json:"key" validate:"required"`
Value string `json:"value"`
Expand Down
5 changes: 4 additions & 1 deletion core/init/cron/cron.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
mathRand "math/rand"
"time"

"github.com/1Panel-dev/1Panel/core/app/repo"
"github.com/1Panel-dev/1Panel/core/constant"
"github.com/1Panel-dev/1Panel/core/global"
"github.com/1Panel-dev/1Panel/core/init/cron/job"
"github.com/1Panel-dev/1Panel/core/utils/common"
Expand All @@ -19,7 +21,8 @@ func Init() {
global.LOG.Errorf("[core] can not add backup token refresh corn job: %s", err.Error())
}

if !global.CONF.Base.IsOffLine {
scriptSync, _ := repo.NewISettingRepo().GetValueByKey("ScriptSync")
if !global.CONF.Base.IsOffLine && scriptSync == constant.StatusEnable {
scriptJob := job.NewScriptJob()
if _, err := global.Cron.AddJob(fmt.Sprintf("%v %v * * *", mathRand.Intn(60), mathRand.Intn(3)), scriptJob); err != nil {
global.LOG.Errorf("[core] can not add script sync corn job: %s", err.Error())
Expand Down
1 change: 1 addition & 0 deletions core/init/migration/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func Init() {
migrations.AddDiskMenu,
migrations.AddSimpleNodeGroup,
migrations.AddUpgradeBackupCopies,
migrations.AddScriptSync,
})
if err := m.Migrate(); err != nil {
global.LOG.Error(err)
Expand Down
10 changes: 10 additions & 0 deletions core/init/migration/migrations/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -545,3 +545,13 @@ var AddUpgradeBackupCopies = &gormigrate.Migration{
return nil
},
}

var AddScriptSync = &gormigrate.Migration{
ID: "20250916-add-script-sync",
Migrate: func(tx *gorm.DB) error {
if err := tx.Create(&model.Setting{Key: "ScriptSync", Value: constant.StatusEnable}).Error; err != nil {
return err
}
return nil
},
}
9 changes: 7 additions & 2 deletions core/init/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ package run

import (
"github.com/1Panel-dev/1Panel/core/app/dto"
"github.com/1Panel-dev/1Panel/core/app/repo"
"github.com/1Panel-dev/1Panel/core/app/service"
"github.com/1Panel-dev/1Panel/core/constant"
"github.com/1Panel-dev/1Panel/core/global"
)

func Init() {
if err := service.NewIScriptService().Sync(dto.OperateByTaskID{}); err != nil {
global.LOG.Errorf("sync scripts from remote failed, err: %v", err)
scriptSync, _ := repo.NewISettingRepo().GetValueByKey("ScriptSync")
if !global.CONF.Base.IsOffLine && scriptSync == constant.StatusEnable {
if err := service.NewIScriptService().Sync(dto.OperateByTaskID{}); err != nil {
global.LOG.Errorf("sync scripts from remote failed, err: %v", err)
}
}
}
1 change: 1 addition & 0 deletions core/router/ro_setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func (s *SettingRouter) InitRouter(Router *gin.RouterGroup) {
{
router.POST("/search", baseApi.GetSettingInfo)
router.POST("/expired/handle", baseApi.HandlePasswordExpired)
settingRouter.POST("/by", baseApi.GetSettingByKey)
settingRouter.POST("/terminal/search", baseApi.GetTerminalSettingInfo)
settingRouter.GET("/search/available", baseApi.GetSystemAvailable)
settingRouter.POST("/update", baseApi.UpdateSetting)
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/api/modules/setting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ export const getAgentSettingByKey = (key: string) => {
export const getSettingInfo = () => {
return http.post<Setting.SettingInfo>(`/core/settings/search`);
};
export const getSettingBy = (key: string) => {
return http.post<string>(`/core/settings/by`, { key: key });
};
export const getTerminalInfo = () => {
return http.post<Setting.TerminalInfo>(`/core/settings/terminal/search`);
};
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/lang/modules/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,12 @@ const message = {
alertTitle: 'Planned Task - {0} 「{1}」 Task Failure Alert',
library: {
script: 'Script',
syncNow: 'Sync Now',
turnOnSync: 'Enable Auto Sync',
turnOnSyncHelper:
'Enabling auto sync will perform automatic synchronization during early morning hours daily',
turnOffSync: 'Disable Auto Sync',
turnOffSyncHelper: 'Disabling auto sync may cause script synchronization delays, confirm?',
isInteractive: 'Interactive',
interactive: 'Interactive script',
interactiveHelper: 'Requires user input during execution and cannot be used in scheduled tasks.',
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/lang/modules/es-es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,13 @@ const message = {
alertTitle: 'Tarea programada - {0} 「{1}」 Alerta de fallo',
library: {
script: 'Script',
syncNow: 'Sincronizar Ahora',
turnOnSync: 'Activar Sincronización Automática',
turnOnSyncHelper:
'Activar la sincronización automática realizará sincronizaciones automáticas durante las primeras horas de la madrugada diariamente',
turnOffSync: 'Desactivar Sincronización Automática',
turnOffSyncHelper:
'Desactivar la sincronización automática puede causar retrasos en la sincronización de scripts, ¿confirmar?',
isInteractive: 'Interactivo',
interactive: 'Script interactivo',
interactiveHelper:
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/lang/modules/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,11 @@ const message = {
alertTitle: '計画タスク - {0}「{1}」タスク障害アラート',
library: {
script: 'スクリプト',
syncNow: '今すぐ同期',
turnOnSync: '自動同期を有効化',
turnOnSyncHelper: '自動同期を有効にすると、毎日未明の時間帯に自動同期が実行されます',
turnOffSync: '自動同期を無効化',
turnOffSyncHelper: '自動同期を無効にするとスクリプトの同期が遅れる可能性がありますが、よろしいですか?',
isInteractive: '対話型',
interactive: '対話型スクリプト',
interactiveHelper: '実行中にユーザー入力が必要で、スケジュールタスクでは使用できません。',
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/lang/modules/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,11 @@ const message = {
alertTitle: '예정된 작업 - {0} 「{1}」 작업 실패 경고',
library: {
script: '스크립트',
syncNow: '지금 동기화',
turnOnSync: '자동 동기화 켜기',
turnOnSyncHelper: '자동 동기화를 켜면 매일 새벽 시간에 자동 동기화가 수행됩니다',
turnOffSync: '자동 동기화 끄기',
turnOffSyncHelper: '자동 동기화를 끄면 스크립트 동기화가 지연될 수 있습니다. 확인하시겠습니까?',
isInteractive: '대화형',
interactive: '대화형 스크립트',
interactiveHelper: '실행 중 사용자 입력이 필요하며 예약 작업에서는 사용할 수 없습니다.',
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/lang/modules/ms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1122,6 +1122,12 @@ const message = {
alertTitle: 'Tugas Terancang - {0} 「{1}」 Amaran Kegagalan Tugas',
library: {
script: 'Skrip',
syncNow: 'Segerakan Sekarang',
turnOnSync: 'Hidupkan Segerakan Auto',
turnOnSyncHelper:
'Menghidupkan segerakan auto akan melakukan penyegerakan automatik pada waktu awal pagi setiap hari',
turnOffSync: 'Matikan Segerakan Auto',
turnOffSyncHelper: 'Mematikan segerakan auto mungkin menyebabkan kelewatan penyegerakan skrip, sahkan?',
isInteractive: 'Interaktif',
interactive: 'Skrip interaktif',
interactiveHelper:
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/lang/modules/pt-br.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,13 @@ const message = {
alertTitle: 'Tarefa Planejada - {0} 「{1}」 Alerta de Falha na Tarefa',
library: {
script: 'Script',
syncNow: 'Sincronizar Agora',
turnOnSync: 'Ativar Sincronização Automática',
turnOnSyncHelper:
'Ativar a sincronização automática realizará sincronizações automáticas durante as primeiras horas da manhã diariamente',
turnOffSync: 'Desativar Sincronização Automática',
turnOffSyncHelper:
'Desativar a sincronização automática pode causar atrasos na sincronização de scripts, confirmar?',
isInteractive: 'Interativo',
interactive: 'Script interativo',
interactiveHelper:
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/lang/modules/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1117,6 +1117,13 @@ const message = {
alertTitle: 'Плановая задача - {0} «{1}» Оповещение о сбое задачи',
library: {
script: 'Скрипт',
syncNow: 'Синхронизировать Сейчас',
turnOnSync: 'Включить Автосинхронизацию',
turnOnSyncHelper:
'Включение автосинхронизации будет выполнять автоматическую синхронизацию в ранние утренние часы ежедневно',
turnOffSync: 'Отключить Автосинхронизацию',
turnOffSyncHelper:
'Отключение автосинхронизации может вызвать задержки синхронизации скриптов, подтвердить?',
isInteractive: 'Интерактивный',
interactive: 'Интерактивный скрипт',
interactiveHelper:
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/lang/modules/tr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1142,6 +1142,13 @@ const message = {
alertTitle: 'Planlanmış Görev - {0} 「{1}」 Görev Başarısızlık Uyarısı',
library: {
script: 'Script',
syncNow: 'Hemen Senkronize Et',
turnOnSync: 'Otomatik Senkronizasyonu Aç',
turnOnSyncHelper:
'Otomatik senkronizasyonu açmak, her gün sabahın erken saatlerinde otomatik senkronizasyon gerçekleştirecektir',
turnOffSync: 'Otomatik Senkronizasyonu Kapat',
turnOffSyncHelper:
'Otomatik senkronizasyonu kapatmak, betik senkronizasyon gecikmelerine neden olabilir, onaylıyor musunuz?',
isInteractive: 'Etkileşimli',
interactive: 'Etkileşimli script',
interactiveHelper: 'Yürütme sırasında kullanıcı girişi gerektirir ve zamanlanmış görevlerde kullanılamaz.',
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/lang/modules/zh-Hant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,11 @@ const message = {
alertTitle: '計畫任務-{0}「{1}」任務失敗告警',
library: {
script: '腳本',
syncNow: '立即同步',
turnOnSync: '開啟自動同步',
turnOnSyncHelper: '開啟自動同步將在每天凌晨時段進行自動同步',
turnOffSync: '關閉自動同步',
turnOffSyncHelper: '關閉自動同步可能導致腳本同步不及時,是否確認?',
isInteractive: '互動式',
interactive: '互動式腳本',
interactiveHelper: '在腳本執行過程中需要使用者輸入參數或做出選擇,且無法用於計劃任務中。',
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/lang/modules/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,11 @@ const message = {
alertTitle: '计划任务-{0}「 {1} 」任务失败告警',
library: {
script: '脚本',
syncNow: '立即同步',
turnOnSync: '开启自动同步',
turnOnSyncHelper: '开启自动同步将在每天凌晨时段进行自动同步',
turnOffSync: '关闭自动同步',
turnOffSyncHelper: '关闭自动同步可能导致脚本同步不及时,是否确认?',
isInteractive: '交互式',
interactive: '交互式脚本',
interactiveHelper: '在脚本执行过程中需要用户输入参数或做出选择,且无法用于计划任务中。',
Expand Down
68 changes: 64 additions & 4 deletions frontend/src/views/cronjob/library/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,26 @@
<el-button type="primary" @click="onOpenDialog('create')">
{{ $t('commons.button.create') }}
</el-button>
<el-button type="primary" plain @click="onSync()">
{{ $t('commons.button.sync') }}
</el-button>
<el-dropdown @command="handleSyncOp" class="mr-2.5">
<el-button type="primary" plain>
{{ $t('commons.button.sync') }}
<el-icon><arrow-down /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="sync">
{{ $t('cronjob.library.syncNow') }}
</el-dropdown-item>
<el-dropdown-item v-if="scriptSync === 'Disable'" command="turnOnSync">
{{ $t('cronjob.library.turnOnSync') }}
</el-dropdown-item>
<el-dropdown-item v-if="scriptSync === 'Enable'" command="turnOffSync">
{{ $t('cronjob.library.turnOffSync') }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>

<el-button type="primary" plain @click="onOpenGroupDialog()">
{{ $t('commons.table.group') }}
</el-button>
Expand Down Expand Up @@ -116,6 +133,7 @@ import { GlobalStore } from '@/store';
import { getGroupList } from '@/api/modules/group';
import CodemirrorDrawer from '@/components/codemirror-pro/drawer.vue';
import { MsgSuccess } from '@/utils/message';
import { getSettingBy, updateSetting } from '@/api/modules/setting';

const globalStore = GlobalStore();
const mobile = computed(() => {
Expand All @@ -129,6 +147,7 @@ const opRef = ref();

const runRef = ref();
const taskLogRef = ref();
const scriptSync = ref();

const data = ref();
const paginationConfig = reactive({
Expand Down Expand Up @@ -194,7 +213,7 @@ const onDelete = async (row: Cronjob.ScriptInfo | null) => {
};

const onSync = async () => {
ElMessageBox.confirm(i18n.global.t('cronjob.library.syncHelper', i18n.global.t('commons.button.sync')), {
ElMessageBox.confirm(i18n.global.t('cronjob.library.syncHelper'), i18n.global.t('commons.button.syncNow'), {
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
Expand All @@ -217,6 +236,46 @@ const openTaskLog = (taskID: string) => {
taskLogRef.value.openWithTaskID(taskID, true, 'local');
};

const loadSyncStatus = async () => {
const res = await getSettingBy('ScriptSync');
scriptSync.value = res.data;
};
const handleSyncOp = async (command: string) => {
let val = 'Enable';
switch (command) {
case 'sync':
onSync();
return;
case 'turnOnSync':
val = 'Enable';
break;
case 'turnOffSync':
val = 'Disable';
break;
default:
return;
}
ElMessageBox.confirm(
i18n.global.t('cronjob.library.' + command + 'Helper'),
i18n.global.t('cronjob.library.' + command),
{
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
},
).then(async () => {
loading.value = true;
await updateSetting({ key: 'ScriptSync', value: val })
.then(() => {
loadSyncStatus();
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
})
.finally(() => {
loading.value = false;
});
});
};

const search = async () => {
let params = {
info: searchInfo.value,
Expand Down Expand Up @@ -297,6 +356,7 @@ const buttons = [

onMounted(() => {
search();
loadSyncStatus();
loadGroupOptions();
});
</script>
Loading