mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 14:08:06 +08:00
feat: Increase version restrictions for node switching (#7631)
This commit is contained in:
parent
c7936e656b
commit
6122aa3a3d
@ -3,7 +3,7 @@ package configs
|
|||||||
type System struct {
|
type System struct {
|
||||||
Mode string `mapstructure:"mode"`
|
Mode string `mapstructure:"mode"`
|
||||||
|
|
||||||
Port string `mapstructure:"version"`
|
Port string `mapstructure:"port"`
|
||||||
Version string `mapstructure:"version"`
|
Version string `mapstructure:"version"`
|
||||||
BaseDir string `mapstructure:"base_dir"`
|
BaseDir string `mapstructure:"base_dir"`
|
||||||
EncryptKey string `mapstructure:"encrypt_key"`
|
EncryptKey string `mapstructure:"encrypt_key"`
|
||||||
|
@ -31,6 +31,7 @@ require (
|
|||||||
github.com/minio/minio-go/v7 v7.0.74
|
github.com/minio/minio-go/v7 v7.0.74
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.4.0
|
github.com/nicksnyder/go-i18n/v2 v2.4.0
|
||||||
github.com/opencontainers/image-spec v1.1.0
|
github.com/opencontainers/image-spec v1.1.0
|
||||||
|
github.com/oschwald/maxminddb-golang v1.13.1
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/pkg/sftp v1.13.6
|
github.com/pkg/sftp v1.13.6
|
||||||
@ -171,7 +172,6 @@ require (
|
|||||||
github.com/nwaples/rardecode/v2 v2.0.0-beta.2 // indirect
|
github.com/nwaples/rardecode/v2 v2.0.0-beta.2 // indirect
|
||||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
|
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
|
||||||
github.com/oschwald/maxminddb-golang v1.13.1 // indirect
|
|
||||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||||
github.com/pierrec/lz4/v4 v4.1.15 // indirect
|
github.com/pierrec/lz4/v4 v4.1.15 // indirect
|
||||||
|
@ -227,5 +227,6 @@ export namespace Setting {
|
|||||||
id: number;
|
id: number;
|
||||||
addr: string;
|
addr: string;
|
||||||
status: string;
|
status: string;
|
||||||
|
version: string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1743,6 +1743,10 @@ const message = {
|
|||||||
upgradeNow: 'Upgrade now',
|
upgradeNow: 'Upgrade now',
|
||||||
source: 'Download source',
|
source: 'Download source',
|
||||||
hasNewVersion: 'New version Available',
|
hasNewVersion: 'New version Available',
|
||||||
|
versionHigher:
|
||||||
|
'Detected that node {0} version is higher than the main node, switching is not supported at this time. Please upgrade the main node system version and try again!',
|
||||||
|
versionLower:
|
||||||
|
'Detected that node {0} version is lower than the main node, switching is not supported at this time. Please upgrade the system version of this node and try again!',
|
||||||
|
|
||||||
about: 'About',
|
about: 'About',
|
||||||
project: 'Project Address',
|
project: 'Project Address',
|
||||||
|
@ -1548,6 +1548,8 @@ const message = {
|
|||||||
upgradeNow: '立即更新',
|
upgradeNow: '立即更新',
|
||||||
source: '下載源',
|
source: '下載源',
|
||||||
hasNewVersion: '有新版本',
|
hasNewVersion: '有新版本',
|
||||||
|
versionHigher: '檢測到節點 {0} 版本高於主節點,暫不支持切換,請先升級主節點系統版本後重試!',
|
||||||
|
versionLower: '檢測到節點 {0} 版本低於主節點,暫不支持切換,請先升級該節點系統版本後重試!',
|
||||||
|
|
||||||
safe: '安全',
|
safe: '安全',
|
||||||
bindInfo: '監聽地址',
|
bindInfo: '監聽地址',
|
||||||
|
@ -1546,6 +1546,8 @@ const message = {
|
|||||||
upgradeNow: '立即更新',
|
upgradeNow: '立即更新',
|
||||||
source: '下载源',
|
source: '下载源',
|
||||||
hasNewVersion: '有新版本',
|
hasNewVersion: '有新版本',
|
||||||
|
versionHigher: '检测到节点 {0} 版本高于主节点,暂不支持切换,请先升级主节点系统版本后重试!',
|
||||||
|
versionLower: '检测到节点 {0} 版本低于主节点,暂不支持切换,请先升级该节点系统版本后重试!',
|
||||||
|
|
||||||
safe: '安全',
|
safe: '安全',
|
||||||
bindInfo: '监听地址',
|
bindInfo: '监听地址',
|
||||||
|
@ -8,10 +8,8 @@
|
|||||||
>
|
>
|
||||||
<Logo :isCollapse="isCollapse" />
|
<Logo :isCollapse="isCollapse" />
|
||||||
<div class="el-dropdown-link flex justify-between items-center">
|
<div class="el-dropdown-link flex justify-between items-center">
|
||||||
<el-button type="text" @click="openChangeNode" @mouseenter="openChangeNode">
|
<el-button link class="ml-4" @click="openChangeNode" @mouseenter="openChangeNode">
|
||||||
<span>
|
{{ loadCurrentName() }}
|
||||||
{{ loadCurrentName() }}
|
|
||||||
</span>
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<div>
|
<div>
|
||||||
<el-dropdown
|
<el-dropdown
|
||||||
@ -25,11 +23,12 @@
|
|||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item command="local">
|
<el-dropdown-item command="local">
|
||||||
<SvgIcon class="ico" iconName="p-host" />
|
<el-button link icon="CircleCheck" type="success" />
|
||||||
{{ $t('terminal.local') }}
|
{{ $t('terminal.local') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item v-for="item in nodes" :key="item.name" :command="item.name">
|
<el-dropdown-item v-for="item in nodes" :key="item.name" :command="item.name">
|
||||||
<SvgIcon class="ico" iconName="p-host" />
|
<el-button v-if="item.status === 'Healthy'" link icon="CircleCheck" type="success" />
|
||||||
|
<el-button v-else link icon="Warning" type="danger" />
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
@ -74,16 +73,18 @@ import { logOutApi } from '@/api/modules/auth';
|
|||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { DropdownInstance, ElMessageBox } from 'element-plus';
|
import { DropdownInstance, ElMessageBox } from 'element-plus';
|
||||||
import { GlobalStore, MenuStore } from '@/store';
|
import { GlobalStore, MenuStore } from '@/store';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||||
import { isString } from '@vueuse/core';
|
import { isString } from '@vueuse/core';
|
||||||
import { getSettingInfo, listNodeOptions } from '@/api/modules/setting';
|
import { getSettingInfo, listNodeOptions } from '@/api/modules/setting';
|
||||||
import { countExecutingTask } from '@/api/modules/log';
|
import { countExecutingTask } from '@/api/modules/log';
|
||||||
|
import { compareVersion } from '@/utils/version';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const menuStore = MenuStore();
|
const menuStore = MenuStore();
|
||||||
const globalStore = GlobalStore();
|
const globalStore = GlobalStore();
|
||||||
const nodes = ref([]);
|
const nodes = ref([]);
|
||||||
const nodeChangeRef = ref<DropdownInstance>();
|
const nodeChangeRef = ref<DropdownInstance>();
|
||||||
|
const version = ref();
|
||||||
defineProps({
|
defineProps({
|
||||||
menuRouter: {
|
menuRouter: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -172,8 +173,32 @@ const loadNodes = async () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
const changeNode = (command: string) => {
|
const changeNode = (command: string) => {
|
||||||
globalStore.currentNode = command || 'local';
|
if (globalStore.currentNode === command) {
|
||||||
location.reload();
|
return;
|
||||||
|
}
|
||||||
|
if (command == 'local') {
|
||||||
|
globalStore.currentNode = command || 'local';
|
||||||
|
location.reload();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const item of nodes.value) {
|
||||||
|
if (item.name == command) {
|
||||||
|
if (version.value == item.version) {
|
||||||
|
globalStore.currentNode = command || 'local';
|
||||||
|
location.reload();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let compareItem = compareVersion(item.version, version.value);
|
||||||
|
if (compareItem) {
|
||||||
|
MsgError(i18n.global.t('setting.versionHigher', [command]));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!compareItem) {
|
||||||
|
MsgError(i18n.global.t('setting.versionLower', [command]));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function extractLabels(node: Node, result: string[]): void {
|
function extractLabels(node: Node, result: string[]): void {
|
||||||
@ -195,6 +220,7 @@ function getCheckedLabels(json: Node): string[] {
|
|||||||
|
|
||||||
const search = async () => {
|
const search = async () => {
|
||||||
const res = await getSettingInfo();
|
const res = await getSettingInfo();
|
||||||
|
version.value = res.data.systemVersion;
|
||||||
const json: Node = JSON.parse(res.data.xpackHideMenu);
|
const json: Node = JSON.parse(res.data.xpackHideMenu);
|
||||||
if (json.isCheck === false) {
|
if (json.isCheck === false) {
|
||||||
json.children.forEach((child: any) => {
|
json.children.forEach((child: any) => {
|
||||||
|
42
frontend/src/utils/version.ts
Normal file
42
frontend/src/utils/version.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
export function compareVersion(version1: string, version2: string): boolean {
|
||||||
|
const v1s = extractNumbers(version1);
|
||||||
|
const v2s = extractNumbers(version2);
|
||||||
|
|
||||||
|
const maxLen = Math.max(v1s.length, v2s.length);
|
||||||
|
v1s.push(...new Array(maxLen - v1s.length).fill('0'));
|
||||||
|
v2s.push(...new Array(maxLen - v2s.length).fill('0'));
|
||||||
|
|
||||||
|
for (let i = 0; i < maxLen; i++) {
|
||||||
|
const v1 = parseInt(v1s[i], 10);
|
||||||
|
const v2 = parseInt(v2s[i], 10);
|
||||||
|
if (v1 !== v2) {
|
||||||
|
return v1 > v2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractNumbers(version: string): string[] {
|
||||||
|
const numbers: string[] = [];
|
||||||
|
let start = -1;
|
||||||
|
for (let i = 0; i < version.length; i++) {
|
||||||
|
if (isDigit(version[i])) {
|
||||||
|
if (start === -1) {
|
||||||
|
start = i;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (start !== -1) {
|
||||||
|
numbers.push(version.slice(start, i));
|
||||||
|
start = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (start !== -1) {
|
||||||
|
numbers.push(version.slice(start));
|
||||||
|
}
|
||||||
|
return numbers;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isDigit(char: string): boolean {
|
||||||
|
return /^\d$/.test(char);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user