api, ui: fix NPE with deployVirtualMachine when null boottype (#5387)

* api: fix NPE with deployVirtualMachine when null boottype

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* throw exception for empty bootmode

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* ui: fix boot options

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* check

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
Abhishek Kumar 2021-09-06 18:28:32 +05:30 committed by GitHub
parent 01683ca131
commit f564597e92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 41 deletions

View File

@ -27,8 +27,6 @@ import java.util.Map;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import com.cloud.utils.StringUtils;
import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.affinity.AffinityGroupResponse;
import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.ACL;
@ -70,6 +68,7 @@ import com.cloud.network.Network.IpAddresses;
import com.cloud.offering.DiskOffering; import com.cloud.offering.DiskOffering;
import com.cloud.template.VirtualMachineTemplate; import com.cloud.template.VirtualMachineTemplate;
import com.cloud.uservm.UserVm; import com.cloud.uservm.UserVm;
import com.cloud.utils.StringUtils;
import com.cloud.utils.net.Dhcp; import com.cloud.utils.net.Dhcp;
import com.cloud.utils.net.NetUtils; import com.cloud.utils.net.NetUtils;
import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine;
@ -310,12 +309,18 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG
String mode = bootMode.trim().toUpperCase(); String mode = bootMode.trim().toUpperCase();
return ApiConstants.BootMode.valueOf(mode); return ApiConstants.BootMode.valueOf(mode);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
String errMesg = "Invalid bootMode " + bootMode + "Specified for vm " + getName() String msg = String.format("Invalid %s: %s specified for VM: %s. Valid values are: %s",
+ " Valid values are: "+ Arrays.toString(ApiConstants.BootMode.values()); ApiConstants.BOOT_MODE, bootMode, getName(), Arrays.toString(ApiConstants.BootMode.values()));
s_logger.warn(errMesg); s_logger.error(msg);
throw new InvalidParameterValueException(errMesg); throw new InvalidParameterValueException(msg);
} }
} }
if (ApiConstants.BootType.UEFI.equals(getBootType())) {
String msg = String.format("%s must be specified for the VM with boot type: %s. Valid values are: %s",
ApiConstants.BOOT_MODE, getBootType(), Arrays.toString(ApiConstants.BootMode.values()));
s_logger.error(msg);
throw new InvalidParameterValueException(msg);
}
return null; return null;
} }

View File

@ -487,16 +487,15 @@
<template slot="description" v-if="zoneSelected"> <template slot="description" v-if="zoneSelected">
<span> <span>
{{ $t('label.isadvanced') }} {{ $t('label.isadvanced') }}
<a-switch @change="val => { this.showDetails = val }" :checked="this.showDetails" style="margin-left: 10px"/> <a-switch @change="val => { showDetails = val }" :checked="showDetails" style="margin-left: 10px"/>
</span> </span>
<div style="margin-top: 15px" v-show="this.showDetails"> <div style="margin-top: 15px" v-show="this.showDetails">
<div <div
v-if="vm.templateid && ['KVM', 'VMware', 'XenServer'].includes(hypervisor) && !template.deployasis"> v-if="vm.templateid && ['KVM', 'VMware', 'XenServer'].includes(hypervisor) && !template.deployasis">
<a-form-item :label="$t('label.boottype')"> <a-form-item :label="$t('label.boottype')">
<a-select <a-select
v-decorator="['boottype']" v-decorator="['boottype', { initialValue: options.bootTypes && options.bootTypes.length > 0 ? options.bootTypes[0].id : undefined }]"
@change="fetchBootModes" @change="onBootTypeChange">
>
<a-select-option v-for="bootType in options.bootTypes" :key="bootType.id"> <a-select-option v-for="bootType in options.bootTypes" :key="bootType.id">
{{ bootType.description }} {{ bootType.description }}
</a-select-option> </a-select-option>
@ -504,7 +503,7 @@
</a-form-item> </a-form-item>
<a-form-item :label="$t('label.bootmode')"> <a-form-item :label="$t('label.bootmode')">
<a-select <a-select
v-decorator="['bootmode']"> v-decorator="['bootmode', { initialValue: options.bootModes && options.bootModes.length > 0 ? options.bootModes[0].id : undefined }]">
<a-select-option v-for="bootMode in options.bootModes" :key="bootMode.id"> <a-select-option v-for="bootMode in options.bootModes" :key="bootMode.id">
{{ bootMode.description }} {{ bootMode.description }}
</a-select-option> </a-select-option>
@ -1227,39 +1226,21 @@ export default {
await this.fetchAllTemplates() await this.fetchAllTemplates()
}, },
fetchBootTypes () { fetchBootTypes () {
const bootTypes = [] this.options.bootTypes = [
{ id: 'BIOS', description: 'BIOS' },
bootTypes.push({ { id: 'UEFI', description: 'UEFI' }
id: 'BIOS', ]
description: 'BIOS'
})
bootTypes.push({
id: 'UEFI',
description: 'UEFI'
})
this.options.bootTypes = bootTypes
this.$forceUpdate() this.$forceUpdate()
}, },
fetchBootModes (bootType) { fetchBootModes (bootType) {
const bootModes = [] const bootModes = [
{ id: 'LEGACY', description: 'LEGACY' }
]
if (bootType === 'UEFI') { if (bootType === 'UEFI') {
bootModes.push({ bootModes.unshift(
id: 'LEGACY', { id: 'SECURE', description: 'SECURE' }
description: 'LEGACY' )
})
bootModes.push({
id: 'SECURE',
description: 'SECURE'
})
} else {
bootModes.push({
id: 'LEGACY',
description: 'LEGACY'
})
} }
this.options.bootModes = bootModes this.options.bootModes = bootModes
this.$forceUpdate() this.$forceUpdate()
}, },
@ -2035,6 +2016,10 @@ export default {
}, },
updateIOPSValue (input, value) { updateIOPSValue (input, value) {
this[input] = value this[input] = value
},
onBootTypeChange (value) {
this.fetchBootModes(value)
this.updateFieldValue('bootmode', this.options.bootModes?.[0]?.id || undefined)
} }
} }
} }