From 7aed108422334d1a7b99dffd9da6acec5afb042c Mon Sep 17 00:00:00 2001 From: wujun <897415845@qq.com> Date: Thu, 4 Nov 2021 16:07:36 +0800 Subject: [PATCH] HARVESTER: fixed create multiple vm instance (1504) & migration list filter(1501) --- .../dialog/harvester/MigrationDialog.vue | 2 +- ...erhci.io.virtualmachinetemplateversion.vue | 63 ++++++++++--------- edit/kubevirt.io.virtualmachine/index.vue | 50 ++++++++++----- mixins/harvester-vm/index.js | 2 + models/harvester/node.js | 2 +- 5 files changed, 71 insertions(+), 48 deletions(-) diff --git a/components/dialog/harvester/MigrationDialog.vue b/components/dialog/harvester/MigrationDialog.vue index 8253808a12..4deb0e744c 100644 --- a/components/dialog/harvester/MigrationDialog.vue +++ b/components/dialog/harvester/MigrationDialog.vue @@ -48,7 +48,7 @@ export default { return nodes.filter((n) => { // do not allow to migrate to self node - return n.id !== this.vmi?.status?.nodeName && !n.metadata?.annotations?.[HCI_ANNOTATIONS.MAINTENANCE_STATUS]; + return n.id !== this.vmi?.status?.nodeName && !n.metadata?.annotations?.[HCI_ANNOTATIONS.MAINTENANCE_STATUS] && !n.isUnSchedulable; }).map((n) => { let label = n?.metadata?.name; const value = n?.metadata?.name; diff --git a/edit/harvesterhci.io.virtualmachinetemplateversion.vue b/edit/harvesterhci.io.virtualmachinetemplateversion.vue index cdb316c2b8..c040296136 100644 --- a/edit/harvesterhci.io.virtualmachinetemplateversion.vue +++ b/edit/harvesterhci.io.virtualmachinetemplateversion.vue @@ -144,42 +144,43 @@ export default { const templates = await this.$store.dispatch('harvester/findAll', { type: HCI.VM_TEMPLATE }); const template = templates.find( O => O.metadata.name === this.templateValue.metadata.name); - if (!this.templateId) { - if (this.templateValue?.metadata?.name) { - try { + try { + if (!this.templateId) { + if (this.templateValue?.metadata?.name) { await this.templateValue.save(); - } catch (err) { - this.errors = [err]; + } else { + this.errors = ['"Name" is required']; + buttonCb(false); + + return; } } else { - this.errors = ['"Name" is required']; - buttonCb(false); - - return; + template.save(); } - } else { - template.save(); + + cleanForNew(this.value); + this.customName = randomStr(10); + this.$set(this.value.metadata, 'annotations', { + ...this.value.metadata.annotations, + [HCI_ANNOTATIONS.TEMPLATE_VERSION_CUSTOM_NAME]: this.customName + }); + + const name = this.templateValue.metadata.name || template.metadata.name; + const namespace = this.templateValue.metadata.namespace || template.metadata.namespace; + + if (this.isCreate) { + this.value.metadata.namespace = namespace; + } + + this.$set(this.value.spec, 'templateId', `${ namespace }/${ name }`); + const res = await this.value.save(); + + await this.saveSecret(res); + this.done(); + } catch (e) { + this.errors = [e]; + buttonCb(false); } - - cleanForNew(this.value); - this.customName = randomStr(10); - this.$set(this.value.metadata, 'annotations', { - ...this.value.metadata.annotations, - [HCI_ANNOTATIONS.TEMPLATE_VERSION_CUSTOM_NAME]: this.customName - }); - - const name = this.templateValue.metadata.name || template.metadata.name; - const namespace = this.templateValue.metadata.namespace || template.metadata.namespace; - - if (this.isCreate) { - this.value.metadata.namespace = namespace; - } - - this.$set(this.value.spec, 'templateId', `${ namespace }/${ name }`); - const res = await this.value.save(); - - await this.saveSecret(res); - this.done(); }, onTabChanged({ tab }) { diff --git a/edit/kubevirt.io.virtualmachine/index.vue b/edit/kubevirt.io.virtualmachine/index.vue index c8cd4bf370..95fc9ec28d 100644 --- a/edit/kubevirt.io.virtualmachine/index.vue +++ b/edit/kubevirt.io.virtualmachine/index.vue @@ -19,10 +19,13 @@ import CpuMemory from '@/edit/kubevirt.io.virtualmachine/VirtualMachineCpuMemory import CloudConfig from '@/edit/kubevirt.io.virtualmachine/VirtualMachineCloudConfig'; import NodeScheduling from '@/components/form/NodeScheduling'; +import { clear } from '@/utils/array'; import { clone } from '@/utils/object'; import { HCI } from '@/config/types'; +import { exceptionToErrorsArray } from '@/utils/error'; import { cleanForNew } from '@/plugins/steve/normalize'; import { HCI as HCI_ANNOTATIONS } from '@/config/labels-annotations'; +import { BEFORE_SAVE_HOOKS, AFTER_SAVE_HOOKS } from '@/mixins/child-hook'; import VM_MIXIN from '@/mixins/harvester-vm'; import CreateEditView from '@/mixins/create-edit-view'; @@ -219,11 +222,15 @@ export default { this.$set(this.value.spec.template.spec, 'hostname', this.value.metadata.name); } - await this.save(buttonCb); + try { + await this._save(this.value, buttonCb); + buttonCb(true); - const res = this.$store.getters['harvester/byId'](HCI.VM, `${ this.value.metadata.namespace }/${ this.value.metadata.name }`); - - await this.saveSecret(res); + this.done(); + } catch (e) { + this.errors = exceptionToErrorsArray(e); + buttonCb(false); + } }, async saveMultiple(buttonCb) { @@ -248,25 +255,38 @@ export default { const hostname = `${ baseHostname }${ join }${ suffix }`; this.$set(this.value.spec.template.spec, 'hostname', hostname); - + this.secretName = ''; await this.parseVM(); - const basicValue = await this.$store.dispatch('harvester/create', clone(this.value)); + const basicValue = await this.$store.dispatch('harvester/clone', { resource: this.value }); try { - if (i === 1) { - await this.save(); - } else { - basicValue.save(); - } - const res = this.$store.getters['harvester/byId'](HCI.VM, `${ this.value.metadata.namespace }/${ this.value.metadata.name }`); + await this._save(basicValue); - await this.saveSecret(res); - } catch (err) { - return Promise.reject(new Error(err)); + if (i === this.count) { + buttonCb(true); + this.done(); + } + } catch (e) { + this.errors = exceptionToErrorsArray(e); + buttonCb(false); } } }, + async _save(value) { + if ( this.errors ) { + clear(this.errors); + } + + await this.applyHooks(BEFORE_SAVE_HOOKS); + + const res = await value.save(); + + await this.applyHooks(AFTER_SAVE_HOOKS); + + await this.saveSecret(res); + }, + restartVM() { if ( this.mode === 'edit' && this.value.hasAction('restart')) { const cloneDeepNewVM = clone(this.value); diff --git a/mixins/harvester-vm/index.js b/mixins/harvester-vm/index.js index 3a5cd59c09..8451b00d0c 100644 --- a/mixins/harvester-vm/index.js +++ b/mixins/harvester-vm/index.js @@ -882,6 +882,8 @@ export default { } } catch (e) { new Error(`Function(saveSecret) error ${ e }`); + + return Promise.reject(e); } }, diff --git a/models/harvester/node.js b/models/harvester/node.js index 37d20af04d..ea6fcce03b 100644 --- a/models/harvester/node.js +++ b/models/harvester/node.js @@ -146,7 +146,7 @@ export default class HciNode extends SteveModel { } get isCordoned() { - return !!this.spec.unschedulable; + return this.isUnSchedulable; } get isEnteringMaintenance() {