mirror of
https://github.com/harvester/harvester-ui-extension.git
synced 2025-12-13 21:21:44 +00:00
add feature flag config
This commit is contained in:
parent
aa3c9268e3
commit
77d7f13836
54
pkg/harvester/config/feature-flags.js
Normal file
54
pkg/harvester/config/feature-flags.js
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
|
||||||
|
// https://github.com/harvester/harvester/wiki/Roadmap
|
||||||
|
const FEATURES = {
|
||||||
|
cpuPinning: false,
|
||||||
|
usbPassthrough: false,
|
||||||
|
volumeEncryption: false,
|
||||||
|
schedulingVMBackup: false,
|
||||||
|
vmSnapshotQuota: false,
|
||||||
|
longhornV2LVMSupport: false,
|
||||||
|
improveMaintainMode: false,
|
||||||
|
autoRotateRke2CertsSetting: false,
|
||||||
|
kubeconfigDefaultTokenTTLMinutesSetting: false,
|
||||||
|
supportBundleNodeCollectionTimeoutSetting: false
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://github.com/harvester/dashboard/releases/tag/v1.3.0
|
||||||
|
const releaseV130 = { ...FEATURES };
|
||||||
|
|
||||||
|
// https://github.com/harvester/dashboard/releases/tag/v1.3.1
|
||||||
|
const releaseV131 = {
|
||||||
|
...releaseV130,
|
||||||
|
autoRotateRke2CertsSetting: true,
|
||||||
|
supportBundleNodeCollectionTimeoutSetting: true
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://github.com/harvester/dashboard/releases/tag/v1.3.2
|
||||||
|
const releaseV132 = {
|
||||||
|
...releaseV131,
|
||||||
|
kubeconfigDefaultTokenTTLMinutesSetting: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: change to https://github.com/harvester/dashboard/releases/tag/v1.4.0 after v1.4.0 release
|
||||||
|
// https://github.com/harvester/dashboard/releases/tag/v1.4.0-rc5
|
||||||
|
// https://github.com/harvester/dashboard/releases/tag/v1.4.0-rc4
|
||||||
|
// https://github.com/harvester/dashboard/releases/tag/v1.4.0-rc3
|
||||||
|
// https://github.com/harvester/dashboard/releases/tag/v1.4.0-rc2
|
||||||
|
// https://github.com/harvester/dashboard/releases/tag/v1.4.0-rc1
|
||||||
|
const releaseV140 = {
|
||||||
|
...releaseV132,
|
||||||
|
cpuPinning: true,
|
||||||
|
usbPassthrough: true,
|
||||||
|
volumeEncryption: true,
|
||||||
|
schedulingVMBackup: true,
|
||||||
|
vmSnapshotQuota: true,
|
||||||
|
longhornV2LVMSupport: true,
|
||||||
|
improveMaintainMode: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RELEASE_FEATURES = {
|
||||||
|
'v1.4.0': releaseV140,
|
||||||
|
'v1.3.2': releaseV132,
|
||||||
|
'v1.3.1': releaseV132,
|
||||||
|
'v1.3.0': releaseV130,
|
||||||
|
};
|
||||||
@ -247,7 +247,7 @@ export default {
|
|||||||
|
|
||||||
<div class="row mb-20">
|
<div class="row mb-20">
|
||||||
<div
|
<div
|
||||||
v-if="!value.isEtcd"
|
v-if="!value.isEtcd && value.isCPUManagerEnabled"
|
||||||
class="col span-6"
|
class="col span-6"
|
||||||
>
|
>
|
||||||
<LabelValue
|
<LabelValue
|
||||||
|
|||||||
@ -197,6 +197,10 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
showCpuPinningBanner() {
|
showCpuPinningBanner() {
|
||||||
|
if (!this.value.cpuPinningFeatureEnabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.mode === 'edit') {
|
if (this.mode === 'edit') {
|
||||||
return this.cpuPinning !== !!this.cloneVM.spec.template.spec.domain.cpu.dedicatedCpuPlacement;
|
return this.cpuPinning !== !!this.cloneVM.spec.template.spec.domain.cpu.dedicatedCpuPlacement;
|
||||||
}
|
}
|
||||||
@ -832,6 +836,7 @@ export default {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
v-if="value.cpuPinningFeatureEnabled"
|
||||||
v-model:value="cpuPinning"
|
v-model:value="cpuPinning"
|
||||||
:disabled="!enableCpuPinningCheckbox"
|
:disabled="!enableCpuPinningCheckbox"
|
||||||
class="check"
|
class="check"
|
||||||
|
|||||||
@ -128,18 +128,17 @@ export default {
|
|||||||
|
|
||||||
out.splice(-1, 0, storageHeader);
|
out.splice(-1, 0, storageHeader);
|
||||||
}
|
}
|
||||||
|
if (this.rows.every((node) => node.cpuPinningFeatureEnabled)) {
|
||||||
out.push({
|
out.push({
|
||||||
name: 'cpuManager',
|
name: 'cpuManager',
|
||||||
labelKey: 'harvester.tableHeaders.cpuManager',
|
labelKey: 'harvester.tableHeaders.cpuManager',
|
||||||
value: 'id',
|
value: 'id',
|
||||||
formatter: 'HarvesterCPUPinning',
|
formatter: 'HarvesterCPUPinning',
|
||||||
formatterOpts: { rows: this.rows },
|
formatterOpts: { rows: this.rows },
|
||||||
width: 150,
|
width: 150,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
if (this.hasLonghornSchema) {
|
if (this.hasLonghornSchema) {
|
||||||
out.push({
|
out.push({
|
||||||
name: 'diskState',
|
name: 'diskState',
|
||||||
|
|||||||
@ -14,8 +14,8 @@ import { findBy, isArray } from '@shell/utils/array';
|
|||||||
import { ucFirst } from '@shell/utils/string';
|
import { ucFirst } from '@shell/utils/string';
|
||||||
import HarvesterResource from '../harvester';
|
import HarvesterResource from '../harvester';
|
||||||
import { PRODUCT_NAME as HARVESTER_PRODUCT } from '../../config/harvester';
|
import { PRODUCT_NAME as HARVESTER_PRODUCT } from '../../config/harvester';
|
||||||
|
|
||||||
import { HCI } from '../../types';
|
import { HCI } from '../../types';
|
||||||
|
import { featureEnabled } from '../../utils/server';
|
||||||
|
|
||||||
const ALLOW_SYSTEM_LABEL_KEYS = [
|
const ALLOW_SYSTEM_LABEL_KEYS = [
|
||||||
'topology.kubernetes.io/zone',
|
'topology.kubernetes.io/zone',
|
||||||
@ -61,7 +61,7 @@ export default class HciNode extends HarvesterResource {
|
|||||||
|
|
||||||
const enableCPUManager = {
|
const enableCPUManager = {
|
||||||
action: 'enableCPUManager',
|
action: 'enableCPUManager',
|
||||||
enabled: this.hasAction('enableCPUManager') && !this.isCPUManagerEnableInProgress && !this.isCPUManagerEnabled && !this.isEtcd, // witness node doesn't have CPU manager
|
enabled: this.cpuPinningFeatureEnabled && this.hasAction('enableCPUManager') && !this.isCPUManagerEnableInProgress && !this.isCPUManagerEnabled && !this.isEtcd, // witness node doesn't have CPU manager
|
||||||
icon: 'icon icon-fw icon-os-management',
|
icon: 'icon icon-fw icon-os-management',
|
||||||
label: this.t('harvester.action.enableCPUManager'),
|
label: this.t('harvester.action.enableCPUManager'),
|
||||||
total: 1
|
total: 1
|
||||||
@ -69,7 +69,7 @@ export default class HciNode extends HarvesterResource {
|
|||||||
|
|
||||||
const disableCPUManager = {
|
const disableCPUManager = {
|
||||||
action: 'disableCPUManager',
|
action: 'disableCPUManager',
|
||||||
enabled: this.hasAction('disableCPUManager') && !this.isCPUManagerEnableInProgress && this.isCPUManagerEnabled && !this.isEtcd,
|
enabled: this.cpuPinningFeatureEnabled && this.hasAction('disableCPUManager') && !this.isCPUManagerEnableInProgress && this.isCPUManagerEnabled && !this.isEtcd,
|
||||||
icon: 'icon icon-fw icon-os-management',
|
icon: 'icon icon-fw icon-os-management',
|
||||||
label: this.t('harvester.action.disableCPUManager'),
|
label: this.t('harvester.action.disableCPUManager'),
|
||||||
total: 1
|
total: 1
|
||||||
@ -370,6 +370,10 @@ export default class HciNode extends HarvesterResource {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get cpuPinningFeatureEnabled() {
|
||||||
|
return featureEnabled(this.$rootGetters, 'cpuPinning');
|
||||||
|
}
|
||||||
|
|
||||||
get isCPUManagerEnabled() {
|
get isCPUManagerEnabled() {
|
||||||
return this.metadata?.labels?.[HCI_ANNOTATIONS.CPU_MANAGER] === 'true';
|
return this.metadata?.labels?.[HCI_ANNOTATIONS.CPU_MANAGER] === 'true';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import { BACKUP_TYPE } from '../config/types';
|
|||||||
import { HCI } from '../types';
|
import { HCI } from '../types';
|
||||||
import HarvesterResource from './harvester';
|
import HarvesterResource from './harvester';
|
||||||
import { LVM_DRIVER } from './harvester/storage.k8s.io.storageclass';
|
import { LVM_DRIVER } from './harvester/storage.k8s.io.storageclass';
|
||||||
|
import { featureEnabled } from '../utils/server';
|
||||||
|
|
||||||
export const OFF = 'Off';
|
export const OFF = 'Off';
|
||||||
|
|
||||||
@ -480,6 +481,10 @@ export default class VirtVm extends HarvesterResource {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get cpuPinningFeatureEnabled() {
|
||||||
|
return featureEnabled(this.$rootGetters, 'cpuPinning');
|
||||||
|
}
|
||||||
|
|
||||||
get isCpuPinning() {
|
get isCpuPinning() {
|
||||||
return this.spec?.template?.spec?.domain?.cpu?.dedicatedCpuPlacement === true;
|
return this.spec?.template?.spec?.domain?.cpu?.dedicatedCpuPlacement === true;
|
||||||
}
|
}
|
||||||
|
|||||||
24
pkg/harvester/utils/server.js
Normal file
24
pkg/harvester/utils/server.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import semver from 'semver';
|
||||||
|
import { HCI } from '../types';
|
||||||
|
import { RELEASE_FEATURES } from '../config/feature-flags';
|
||||||
|
|
||||||
|
export function serverVersion(getters) {
|
||||||
|
// e.g v1.4.0
|
||||||
|
if (process.env.VUE_APP_SERVER_VERSION) {
|
||||||
|
return process.env.VUE_APP_SERVER_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const v = getters['harvester/byId'](HCI.SETTING, 'server-version')?.value;
|
||||||
|
|
||||||
|
return `v${ semver.major(v) }.${ semver.minor(v) }.${ semver.patch(v) }`;
|
||||||
|
} catch (error) {}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
export const featureEnabled = (getters, featureKey) => {
|
||||||
|
const version = serverVersion(getters);
|
||||||
|
|
||||||
|
return !!RELEASE_FEATURES[version]?.[featureKey] || false;
|
||||||
|
};
|
||||||
Loading…
x
Reference in New Issue
Block a user