mirror of
https://github.com/harvester/harvester-ui-extension.git
synced 2025-12-13 05:01:43 +00:00
feat: add kubevirt migration setting (#577)
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
This commit is contained in:
parent
5fae6c3087
commit
7e0a9dcd80
154
pkg/harvester/components/settings/kubevirt-migration.vue
Normal file
154
pkg/harvester/components/settings/kubevirt-migration.vue
Normal file
@ -0,0 +1,154 @@
|
||||
<script>
|
||||
import { LabeledInput } from '@components/Form/LabeledInput';
|
||||
import { RadioGroup } from '@components/Form/Radio';
|
||||
import UnitInput from '@shell/components/form/UnitInput';
|
||||
import { MEBIBYTE } from '../../utils/unit';
|
||||
import { Banner } from '@components/Banner';
|
||||
|
||||
export default {
|
||||
name: 'KubevirtMigration',
|
||||
|
||||
components: {
|
||||
LabeledInput,
|
||||
UnitInput,
|
||||
RadioGroup,
|
||||
Banner
|
||||
},
|
||||
|
||||
props: {
|
||||
registerBeforeHook: {
|
||||
type: Function,
|
||||
required: true
|
||||
},
|
||||
value: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
value: '',
|
||||
default: '{}'
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
const migration = this.parseJSON(this.value?.value) || this.parseJSON(this.value?.default) || {};
|
||||
|
||||
return {
|
||||
MEBIBYTE,
|
||||
migration,
|
||||
parseError: null,
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
this.registerBeforeHook?.(this.willSave, 'willSave');
|
||||
},
|
||||
|
||||
methods: {
|
||||
parseJSON(string) {
|
||||
try {
|
||||
return JSON.parse(string);
|
||||
} catch (e) {
|
||||
this.parseError = this.t('kubevirtMigration.parseError', { error: e.message });
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Failed to parse JSON:', e.message);
|
||||
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
updateValue() {
|
||||
if (this.value) {
|
||||
this.value.value = JSON.stringify(this.migration);
|
||||
}
|
||||
},
|
||||
|
||||
useDefault() {
|
||||
if (this.value?.default) {
|
||||
const defaultMigration = this.parseJSON(this.value.default) || {};
|
||||
|
||||
this.migration = defaultMigration;
|
||||
this.updateValue();
|
||||
}
|
||||
},
|
||||
|
||||
async willSave() {
|
||||
this.updateValue();
|
||||
|
||||
return Promise.resolve();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Banner
|
||||
v-if="parseError"
|
||||
color="error"
|
||||
>
|
||||
{{ parseError }}
|
||||
</Banner>
|
||||
|
||||
<div class="migration-field">
|
||||
<LabeledInput
|
||||
v-model:value.number="migration.parallelMigrationsPerCluster"
|
||||
:label="t('harvester.setting.kubevirtMigration.parallelMigrationsPerCluster')"
|
||||
type="number"
|
||||
min="1"
|
||||
/>
|
||||
<LabeledInput
|
||||
v-model:value.number="migration.parallelOutboundMigrationsPerNode"
|
||||
:label="t('harvester.setting.kubevirtMigration.parallelOutboundMigrationsPerNode')"
|
||||
type="number"
|
||||
min="1"
|
||||
/>
|
||||
<UnitInput
|
||||
v-model:value="migration.bandwidthPerMigration"
|
||||
min="0"
|
||||
:label="t('harvester.setting.kubevirtMigration.bandwidthPerMigration')"
|
||||
:mode="mode"
|
||||
:suffix="MEBIBYTE"
|
||||
:tooltip="t('harvester.setting.kubevirtMigration.bandwidthPerMigrationTooltip', _, true)"
|
||||
/>
|
||||
<UnitInput
|
||||
v-model:value="migration.completionTimeoutPerGiB"
|
||||
:label="t('harvester.setting.kubevirtMigration.completionTimeoutPerGiB')"
|
||||
:mode="mode"
|
||||
:suffix="migration.completionTimeoutPerGiB === 1 ? 'Second' : 'Seconds'"
|
||||
min="10"
|
||||
/>
|
||||
<UnitInput
|
||||
v-model:value="migration.progressTimeout"
|
||||
:label="t('harvester.setting.kubevirtMigration.progressTimeout')"
|
||||
:mode="mode"
|
||||
:suffix="migration.progressTimeout === 1 ? 'Second' : 'Seconds'"
|
||||
min="10"
|
||||
/>
|
||||
<div
|
||||
v-for="field in ['allowAutoConverge','allowPostCopy','unsafeMigrationOverride','allowWorkloadDisruption','disableTLS','matchSELinuxLevelOnMigration']"
|
||||
:key="field"
|
||||
>
|
||||
<label
|
||||
class="mb-5"
|
||||
:for="field"
|
||||
>{{ t(`harvester.setting.kubevirtMigration.${field}`) }}</label>
|
||||
<RadioGroup
|
||||
:id="field"
|
||||
v-model:value="migration[field]"
|
||||
:options="[
|
||||
{ label: t('advancedSettings.edit.trueOption'), value: true },
|
||||
{ label: t('advancedSettings.edit.falseOption'), value: false },
|
||||
]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.migration-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
</style>
|
||||
@ -52,7 +52,8 @@ const FEATURE_FLAGS = {
|
||||
'v1.7.0': [
|
||||
'vmMachineTypeAuto',
|
||||
'lhV2VolExpansion',
|
||||
'l2VlanTrunkMode'
|
||||
'l2VlanTrunkMode',
|
||||
'kubevirtMigration'
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
@ -37,7 +37,8 @@ export const HCI_SETTING = {
|
||||
UPGRADE_CONFIG: 'upgrade-config',
|
||||
VM_MIGRATION_NETWORK: 'vm-migration-network',
|
||||
RANCHER_CLUSTER: 'rancher-cluster',
|
||||
MAX_HOTPLUG_RATIO: 'max-hotplug-ratio'
|
||||
MAX_HOTPLUG_RATIO: 'max-hotplug-ratio',
|
||||
KUBEVIRT_MIGRATION: 'kubevirt-migration'
|
||||
};
|
||||
|
||||
export const HCI_ALLOWED_SETTINGS = {
|
||||
@ -115,6 +116,9 @@ export const HCI_ALLOWED_SETTINGS = {
|
||||
[HCI_SETTING.VM_MIGRATION_NETWORK]: {
|
||||
kind: 'json', from: 'import', canReset: true, featureFlag: 'vmNetworkMigration',
|
||||
},
|
||||
[HCI_SETTING.KUBEVIRT_MIGRATION]: {
|
||||
kind: 'json', from: 'import', canReset: true, featureFlag: 'kubevirtMigration',
|
||||
}
|
||||
};
|
||||
|
||||
export const HCI_SINGLE_CLUSTER_ALLOWED_SETTING = {
|
||||
|
||||
@ -296,4 +296,9 @@ export default {
|
||||
:deep() .edit-help code {
|
||||
padding: 1px 5px;
|
||||
}
|
||||
|
||||
::v-deep(.banner__content.closable) {
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1268,6 +1268,21 @@ harvester:
|
||||
ntpServers:
|
||||
isNotIPV4: The address you entered is not IPv4 or host. Please enter a valid IPv4 address or a host address.
|
||||
isDuplicate: There are duplicate NTP server configurations.
|
||||
kubevirtMigration:
|
||||
parseError: "Failed to parse configuration: {error}"
|
||||
parallelMigrationsPerCluster: "Parallel Migrations Per Cluster"
|
||||
parallelOutboundMigrationsPerNode: "Parallel Outbound Migrations Per Node"
|
||||
bandwidthPerMigration: "Bandwidth Per Migration"
|
||||
bandwidthPerMigrationTooltip: '0 is KubeVirt default, representing unlimited bandwidth'
|
||||
completionTimeoutPerGiB: "Completion Timeout Per GiB"
|
||||
progressTimeout: "Progress Timeout"
|
||||
allowAutoConverge: "Allow Auto Converge"
|
||||
allowPostCopy: "Allow Post Copy"
|
||||
unsafeMigrationOverride: "Unsafe Migration Override"
|
||||
allowWorkloadDisruption: "Allow Workload Disruption"
|
||||
disableTLS: "Disable TLS"
|
||||
matchSELinuxLevelOnMigration: "Match SELinux Level On Migration"
|
||||
|
||||
cloudTemplate:
|
||||
label: Cloud Configuration Templates
|
||||
templateType: Template Type
|
||||
@ -1782,6 +1797,7 @@ advancedSettings:
|
||||
'harv-vm-migration-network': 'Segregated network for VM migration traffic.'
|
||||
'harv-rancher-cluster': 'Configure Rancher cluster integration settings for guest cluster management.'
|
||||
'harv-max-hotplug-ratio': 'The ratio for kubevirt to limit the maximum CPU and memory that can be hotplugged to a VM. The value could be an integer between 1 and 20, default to 4.'
|
||||
'harv-kubevirt-migration': 'Configure cluster-wide KubeVirt live migration parameters.'
|
||||
|
||||
typeLabel:
|
||||
kubevirt.io.virtualmachine: |-
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user