mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-12-10 04:16:29 +08:00
fix: Fix the problem of abnormal script execution (#8510)
This commit is contained in:
parent
8bd712d891
commit
1b8e049ad3
24 changed files with 64 additions and 27 deletions
|
|
@ -160,7 +160,13 @@ func (u *UpgradeService) Upgrade(req dto.Upgrade) error {
|
|||
return
|
||||
}
|
||||
|
||||
if err := files.CopyItem(false, true, path.Join(tmpDir, "1panel*.service"), "/etc/systemd/system"); err != nil {
|
||||
if err := files.CopyItem(false, true, path.Join(tmpDir, "1panel-core.service"), "/etc/systemd/system"); err != nil {
|
||||
global.LOG.Errorf("upgrade 1panel.service failed, err: %v", err)
|
||||
_ = settingRepo.Update("SystemStatus", "Free")
|
||||
u.handleRollback(originalDir, 3)
|
||||
return
|
||||
}
|
||||
if err := files.CopyItem(false, true, path.Join(tmpDir, "1panel-agent.service"), "/etc/systemd/system"); err != nil {
|
||||
global.LOG.Errorf("upgrade 1panel.service failed, err: %v", err)
|
||||
_ = settingRepo.Update("SystemStatus", "Free")
|
||||
u.handleRollback(originalDir, 3)
|
||||
|
|
@ -192,13 +198,19 @@ func (u *UpgradeService) Rollback(req dto.OperateByID) error {
|
|||
}
|
||||
|
||||
func (u *UpgradeService) handleBackup(originalDir string) error {
|
||||
if err := files.CopyItem(false, true, "/usr/local/bin/1panel*", originalDir); err != nil {
|
||||
if err := files.CopyItem(false, true, "/usr/local/bin/1panel-core", originalDir); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := files.CopyItem(false, true, "/usr/local/bin/1panel-agent", originalDir); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := files.CopyItem(false, true, "/usr/local/bin/1pctl", originalDir); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := files.CopyItem(false, true, "/etc/systemd/system/1panel*.service", originalDir); err != nil {
|
||||
if err := files.CopyItem(false, true, "/etc/systemd/system/1panel-core.service", originalDir); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := files.CopyItem(false, true, "/etc/systemd/system/1panel-agent.service", originalDir); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := files.CopyItem(true, true, path.Join(global.CONF.Base.InstallDir, "1panel/db"), originalDir); err != nil {
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ SyncNode: "Sync node data"
|
|||
SyncPackageData: "Package sync data [{{ .detail }}]"
|
||||
SyncPackageEncrypt: "Data package encryption"
|
||||
SyncRequest: "Request node sync API"
|
||||
SyncFailedRetry: "Node data sync failed (attempt {{ .index }}), {{ .err }}"
|
||||
SyncFailedRetry: "Node data sync timeout (attempt {{ .index }}), retrying..."
|
||||
SyncFailed: "Sync failed, please manually sync in the node list!"
|
||||
|
||||
#upgrade node
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ SyncNode: "ノードデータ同期"
|
|||
SyncPackageData: "同期データのパッケージ化 [{{ .detail }}]"
|
||||
SyncPackageEncrypt: "データパッケージの暗号化"
|
||||
SyncRequest: "ノード同期APIをリクエスト"
|
||||
SyncFailedRetry: "ノードデータ同期失敗 ({{ .index }}回目), {{ .err }}"
|
||||
SyncFailedRetry: "ノードデータ同期タイムアウト ({{ .index }}回目)、再試行中..."
|
||||
SyncFailed: "同期に失敗しました、ノードリストで手動同期してください!"
|
||||
|
||||
#upgrade node
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ SyncNode: "노드 데이터 동기화"
|
|||
SyncPackageData: "동기화 데이터 패키징 [{{ .detail }}]"
|
||||
SyncPackageEncrypt: "데이터 패키지 암호화"
|
||||
SyncRequest: "노드 동기화 API 요청"
|
||||
SyncFailedRetry: "노드 데이터 동기화 실패 ({{ .index }}번째 시도), {{ .err }}"
|
||||
SyncFailedRetry: "노드 데이터 동기화 시간 초과 ({{ .index }}번째 시도), 재시도 중..."
|
||||
SyncFailed: "동기화 실패, 노드 목록에서 수동 동기화를 실행하세요!"
|
||||
|
||||
#upgrade node
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ SyncNode: "Segerakkan data nod"
|
|||
SyncPackageData: "Pakej data segerak [{{ .detail }}]"
|
||||
SyncPackageEncrypt: "Enkripsi pakej data"
|
||||
SyncRequest: "Permintaan API segerak nod"
|
||||
SyncFailedRetry: "Gagal segerak data nod (percubaan ke-{{ .index }}), {{ .err }}"
|
||||
SyncFailedRetry: "Segerakan data nod tamat masa (percubaan ke-{{ .index }}), mencuba semula..."
|
||||
SyncFailed: "Segerakan gagal, sila segerakkan secara manual dalam senarai nod!"
|
||||
|
||||
#upgrade node
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ SyncNode: "Sincronizar dados do nó"
|
|||
SyncPackageData: "Empacotar dados de sincronização [{{ .detail }}]"
|
||||
SyncPackageEncrypt: "Criptografia de pacote de dados"
|
||||
SyncRequest: "Solicitar API de sincronização de nó"
|
||||
SyncFailedRetry: "Falha na sincronização de dados do nó (tentativa {{ .index }}), {{ .err }}"
|
||||
SyncFailedRetry: "Tempo esgotado na sincronização de dados do nó (tentativa {{ .index }}), tentando novamente..."
|
||||
SyncFailed: "Falha na sincronização, por favor sincronize manualmente na lista de nós!"
|
||||
|
||||
#upgrade node
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ SyncNode: "Синхронизация данных узла"
|
|||
SyncPackageData: "Упаковка данных синхронизации [{{ .detail }}]"
|
||||
SyncPackageEncrypt: "Шифрование пакета данных"
|
||||
SyncRequest: "Запрос API синхронизации узла"
|
||||
SyncFailedRetry: "Ошибка синхронизации данных узла (попытка {{ .index }}), {{ .err }}"
|
||||
SyncFailedRetry: "Таймаут синхронизации данных узла (попытка {{ .index }}), повторная попытка..."
|
||||
SyncFailed: "Ошибка синхронизации, выполните ручную синхронизацию в списке узлов!"
|
||||
|
||||
#upgrade node
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ SyncNode: "同步節點數據"
|
|||
SyncPackageData: "打包同步數據 [{{ .detail }}]"
|
||||
SyncPackageEncrypt: "數據包加密"
|
||||
SyncRequest: "請求節點同步接口"
|
||||
SyncFailedRetry: "第 {{ .index }} 次同步節點數據失敗,{{ .err }}"
|
||||
SyncFailedRetry: "第 {{ .index }} 次同步節點數據失敗逾時,正在重試..."
|
||||
SyncFailed: "同步失敗,請在節點列表中手動同步!"
|
||||
|
||||
#upgrade node
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ SyncNode: "同步节点数据"
|
|||
SyncPackageData: "打包同步数据 [{{ .detail }}]"
|
||||
SyncPackageEncrypt: "数据包加密"
|
||||
SyncRequest: "请求节点同步接口"
|
||||
SyncFailedRetry: "第 {{ .index }} 次同步节点数据失败,{{ .err }}"
|
||||
SyncFailedRetry: "第 {{ .index }} 次同步节点数据失败超时,正在重试..."
|
||||
SyncFailed: "同步失败,请在节点列表中手动同步!"
|
||||
|
||||
#upgrade node
|
||||
|
|
|
|||
|
|
@ -32,14 +32,14 @@ func NewCommand(script string) (*LocalCommand, error) {
|
|||
} else {
|
||||
cmd.Env = append(os.Environ(), "TERM=xterm")
|
||||
}
|
||||
cmd.Env = append(cmd.Env, "1PANEL_INIT_SCRIPT="+script)
|
||||
cmd.Env = append(cmd.Env, "INIT_SCRIPT="+script)
|
||||
pty, err := pty.Start(cmd)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to start command")
|
||||
}
|
||||
if len(script) != 0 {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
_, _ = pty.Write([]byte("bash -c \"$1PANEL_INIT_SCRIPT\"\n"))
|
||||
_, _ = pty.Write([]byte("bash -c \"$INIT_SCRIPT\"\n"))
|
||||
}
|
||||
|
||||
lcmd := &LocalCommand{
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ func NewLogicSshWsSession(cols, rows int, sshClient *ssh.Client, wsConn *websock
|
|||
}
|
||||
if len(initCmd) != 0 {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
_, _ = stdinP.Write([]byte(initCmd + "\n"))
|
||||
_, _ = stdinP.Write([]byte(" clear &&" + initCmd + "\n"))
|
||||
}
|
||||
return &LogicSshWsSession{
|
||||
stdinPipe: stdinP,
|
||||
|
|
|
|||
|
|
@ -347,6 +347,7 @@ const message = {
|
|||
ssl: 'Certificate',
|
||||
database: 'Database',
|
||||
aiTools: 'AI',
|
||||
mcp: 'MCP',
|
||||
container: 'Container',
|
||||
cronjob: 'Cronjob',
|
||||
system: 'System',
|
||||
|
|
@ -1891,7 +1892,7 @@ const message = {
|
|||
license: 'License',
|
||||
bindNode: 'Bind Node',
|
||||
menuSetting: 'Menu Settings',
|
||||
menuSettingHelper: 'If only 1 menu is kept, the sidebar will directly display that menu.',
|
||||
menuSettingHelper: 'When only 1 submenu exists, the menu bar will display only that submenu',
|
||||
showAll: 'Show All',
|
||||
hideALL: 'Hide All',
|
||||
ifShow: 'Whether to Show',
|
||||
|
|
|
|||
|
|
@ -339,6 +339,7 @@ const message = {
|
|||
ssl: '証明書|証明書',
|
||||
database: 'データベース|データベース',
|
||||
aiTools: 'AI',
|
||||
mcp: 'MCP',
|
||||
container: 'コンテナ|コンテナ',
|
||||
cronjob: 'クロンジョブ|クロンの仕事',
|
||||
system: 'システム',
|
||||
|
|
@ -1799,7 +1800,7 @@ const message = {
|
|||
license: 'ライセンス',
|
||||
bindNode: 'ノードをバインド',
|
||||
menuSetting: 'メニュー設定',
|
||||
menuSettingHelper: '1つのメニューだけを保持する場合、サイドバーにはそのメニューが直接表示されます。',
|
||||
menuSettingHelper: 'サブメニューが1つしか存在しない場合、メニューバーにはそのサブメニューのみが表示されます',
|
||||
showAll: 'すべてを表示します',
|
||||
hideALL: 'すべてを隠します',
|
||||
ifShow: '表示するかどうか',
|
||||
|
|
|
|||
|
|
@ -341,6 +341,7 @@ const message = {
|
|||
ssl: '인증서 | 인증서들',
|
||||
database: '데이터베이스 | 데이터베이스들',
|
||||
aiTools: 'AI',
|
||||
mcp: 'MCP',
|
||||
container: '컨테이너 | 컨테이너들',
|
||||
cronjob: '크론 작업 | 크론 작업들',
|
||||
system: '시스템',
|
||||
|
|
@ -1771,7 +1772,7 @@ const message = {
|
|||
license: '라이선스',
|
||||
bindNode: '노드 바인딩',
|
||||
menuSetting: '메뉴 설정',
|
||||
menuSettingHelper: '메뉴를 1개만 유지하면 사이드바에 해당 메뉴가 직접 표시됩니다.',
|
||||
menuSettingHelper: '하위 메뉴가 1개만 존재할 경우, 메뉴 바에는 해당 하위 메뉴만 표시됩니다',
|
||||
showAll: '모두 표시',
|
||||
hideALL: '모두 숨기기',
|
||||
ifShow: '표시 여부',
|
||||
|
|
|
|||
|
|
@ -347,6 +347,7 @@ const message = {
|
|||
ssl: 'Certificate | Certificates',
|
||||
database: 'Database | Databases',
|
||||
aiTools: 'AI',
|
||||
mcp: 'MCP',
|
||||
container: 'Container | Containers',
|
||||
cronjob: 'Cron Job | Cron Jobs',
|
||||
system: 'System',
|
||||
|
|
@ -1856,7 +1857,7 @@ const message = {
|
|||
license: 'Lesen',
|
||||
bindNode: 'Ikatan Nod',
|
||||
menuSetting: 'Tetapan Menu',
|
||||
menuSettingHelper: 'Jika hanya 1 menu yang disimpan, bar sisi akan langsung menampilkan menu tersebut.',
|
||||
menuSettingHelper: 'Apabila hanya terdapat 1 submenu, bar menu hanya akan memaparkan submenu tersebut',
|
||||
showAll: 'Papar Semua',
|
||||
hideALL: 'Sembunyikan Semua',
|
||||
ifShow: 'Sama ada untuk Dipaparkan',
|
||||
|
|
|
|||
|
|
@ -345,6 +345,7 @@ const message = {
|
|||
ssl: 'Certificado | Certificados',
|
||||
database: 'Banco de Dados | Bancos de Dados',
|
||||
aiTools: 'AI',
|
||||
mcp: 'MCP',
|
||||
container: 'Container | Containers',
|
||||
cronjob: 'Tarefa Cron | Tarefas Cron',
|
||||
system: 'Sistema',
|
||||
|
|
@ -1842,7 +1843,7 @@ const message = {
|
|||
license: 'Licença',
|
||||
bindNode: 'Vincular Nó',
|
||||
menuSetting: 'Configurações do Menu',
|
||||
menuSettingHelper: 'Se apenas 1 menu for mantido, a barra lateral exibirá diretamente esse menu.',
|
||||
menuSettingHelper: 'Quando apenas 1 submenu existir, a barra de menus exibirá apenas esse submenu',
|
||||
showAll: 'Mostrar Tudo',
|
||||
hideALL: 'Ocultar Tudo',
|
||||
ifShow: 'Exibir?',
|
||||
|
|
|
|||
|
|
@ -342,6 +342,7 @@ const message = {
|
|||
ssl: 'Сертификат | Сертификаты',
|
||||
database: 'База данных | Базы данных',
|
||||
aiTools: 'AI',
|
||||
mcp: 'MCP',
|
||||
container: 'Контейнер | Контейнеры',
|
||||
cronjob: 'Cron | Задачи Cron',
|
||||
system: 'Система',
|
||||
|
|
@ -1841,7 +1842,7 @@ const message = {
|
|||
license: 'Лицензия',
|
||||
bindNode: 'Привязать Узел',
|
||||
menuSetting: 'Настройки меню',
|
||||
menuSettingHelper: 'Если оставить только 1 меню, боковая панель будет напрямую отображать это меню.',
|
||||
menuSettingHelper: 'Если существует только 1 подменю, в панели меню будет отображаться только это подменю',
|
||||
showAll: 'Показать все',
|
||||
hideALL: 'Скрыть все',
|
||||
ifShow: 'Показывать',
|
||||
|
|
|
|||
|
|
@ -341,6 +341,7 @@ const message = {
|
|||
ssl: '證書',
|
||||
database: '數據庫',
|
||||
aiTools: 'AI',
|
||||
mcp: 'MCP',
|
||||
container: '容器',
|
||||
cronjob: '計劃任務',
|
||||
system: '系統',
|
||||
|
|
@ -1758,7 +1759,7 @@ const message = {
|
|||
license: '許可證',
|
||||
bindNode: '綁定節點',
|
||||
menuSetting: '菜單設定',
|
||||
menuSettingHelper: '如果只保留 1 個菜單,則側邊欄會直接顯示該菜單。',
|
||||
menuSettingHelper: '當只存在 1 個子選單時,選單列將僅展示該子選單',
|
||||
showAll: '全部顯示',
|
||||
hideALL: '全部隱藏',
|
||||
ifShow: '是否顯示',
|
||||
|
|
|
|||
|
|
@ -339,6 +339,7 @@ const message = {
|
|||
ssl: '证书',
|
||||
database: '数据库',
|
||||
aiTools: 'AI',
|
||||
mcp: 'MCP',
|
||||
container: '容器',
|
||||
cronjob: '计划任务',
|
||||
system: '系统',
|
||||
|
|
@ -1751,7 +1752,7 @@ const message = {
|
|||
license: '许可证',
|
||||
bindNode: '绑定节点',
|
||||
menuSetting: '菜单设置',
|
||||
menuSettingHelper: '如果只保留 1 个菜单,则侧边栏会直接显示该菜单',
|
||||
menuSettingHelper: '当只存在 1 个子菜单时,菜单栏将仅展示该子菜单',
|
||||
showAll: '全部显示',
|
||||
hideALL: '全部隐藏',
|
||||
ifShow: '是否显示',
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<el-input
|
||||
v-if="showNodes() && nodeOptions?.length > 5"
|
||||
v-if="showNodes() && nodes?.length > 5"
|
||||
suffix-icon="Search"
|
||||
v-model="filter"
|
||||
@input="changeFilter"
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const databaseRouter = {
|
|||
name: 'MCPServer',
|
||||
component: () => import('@/views/ai/mcp/server/index.vue'),
|
||||
meta: {
|
||||
title: 'MCP',
|
||||
title: 'menu.mcp',
|
||||
requiresAuth: true,
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -19,7 +19,12 @@
|
|||
<el-select v-model="group" @change="search()" clearable class="p-w-200">
|
||||
<template #prefix>{{ $t('commons.table.group') }}</template>
|
||||
<div v-for="item in groupOptions" :key="item.id">
|
||||
<el-option :label="item.name" :value="item.id" />
|
||||
<el-option
|
||||
v-if="item.name === 'Default'"
|
||||
:label="$t('commons.table.default')"
|
||||
:value="item.id"
|
||||
/>
|
||||
<el-option v-else :label="item.name" :value="item.id" />
|
||||
</div>
|
||||
</el-select>
|
||||
<TableSearch @search="search()" v-model:searchName="searchInfo" />
|
||||
|
|
@ -47,7 +52,10 @@
|
|||
<el-button class="mr-3" size="small" v-if="row.isSystem">system</el-button>
|
||||
<span v-if="row.groupBelong">
|
||||
<el-button size="small" v-for="(item, index) in row.groupBelong" :key="index">
|
||||
{{ item }}
|
||||
<span v-if="item === 'Default'">
|
||||
{{ $t('commons.table.default') }}
|
||||
</span>
|
||||
<span v-else>{{ item }}</span>
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,14 @@
|
|||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.table.group')" prop="groupList">
|
||||
<el-select filterable v-model="dialogData.rowData!.groupList" multiple>
|
||||
<el-option v-for="item in groupOptions" :key="item.id" :label="item.name" :value="item.id" />
|
||||
<div v-for="item in groupOptions" :key="item.id">
|
||||
<el-option
|
||||
v-if="item.name === 'Default'"
|
||||
:label="$t('commons.table.default')"
|
||||
:value="item.id"
|
||||
/>
|
||||
<el-option v-else :label="item.name" :value="item.id" />
|
||||
</div>
|
||||
</el-select>
|
||||
<span class="input-help">{{ $t('cronjob.library.groupHelper') }}</span>
|
||||
</el-form-item>
|
||||
|
|
|
|||
|
|
@ -218,6 +218,8 @@ const emit = defineEmits(['search']);
|
|||
const acceptParams = (): void => {
|
||||
form.downloadAccountID = '';
|
||||
form.fromAccounts = [];
|
||||
form.description = '';
|
||||
form.secret = '';
|
||||
nowIndex.value = 0;
|
||||
search();
|
||||
loadBackups();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue