From 4152f7cd435f93f8bfb46f0f911b18f2b4ea78a1 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Thu, 25 Jun 2026 10:55:01 +0530 Subject: [PATCH 1/2] wip: vm flow error changes UserVmManagerImpl Signed-off-by: Abhishek Kumar --- client/conf/error-messages.json.in | 413 +++++- .../java/com/cloud/vm/UserVmManagerImpl.java | 1151 +++++++++-------- 2 files changed, 999 insertions(+), 565 deletions(-) diff --git a/client/conf/error-messages.json.in b/client/conf/error-messages.json.in index aea5cc7ad4f9..3bf03d106bb2 100644 --- a/client/conf/error-messages.json.in +++ b/client/conf/error-messages.json.in @@ -21,5 +21,416 @@ "vm.deploy.template.associated.not.usable": "Unable to deploy Instance as the associated Template cannot be used.", "vm.deploy.template.not.found": "Unable to deploy Instance as the specified Template is not found.", "vm.deploy.volume.not.found": "Unable to deploy Instance as the specified Volume is not found.", - "vm.deploy.zone.not.found": "Unable to deploy Instance as the specified zone is not found." + "vm.deploy.zone.not.found": "Unable to deploy Instance as the specified zone is not found.", + "vm.resetpassword.failed": "Failed to reset password for the Instance {{instance}}.", + "vm.resetpassword.vm.not.found": "Unable to reset password as the specified Instance is not found.", + "vm.resetpassword.template.not.password.enabled": "Unable to reset password for the Instance {{instance}}, the Template {{template}} is not password enabled.", + "vm.resetpassword.vm.not.right.state": "Unable to reset password for the Instance {{instance}} as it is not in the right state. Current state: {{instanceState}}.", + "vm.resetpassword.vm.not.stopped": "Unable to reset password for the Instance {{instance}} as it is not in Stopped state. Current state: {{instanceState}}.", + "vm.resetpassword.network.service.not.found": "Unable to reset password for the Instance {{instance}} as its default Network {{network}} does not supports the service {{networkService}}.", + "vm.resetuserdata.vm.not.found": "Unable to reset userdata as the specified Instance is not found.", + "vm.resetuserdata.vm.sharedfs.operation.not.supported": "Unable to reset userdata as the operation is not supported for Shared FileSystem Instance {{instance}}.", + "vm.resetuserdata.vm.operation.not.supported": "Unable to reset userdata as the operation is not supported for Instance {{instance}}.", + "vm.resetuserdata.vm.not.stopped": "Unable to reset userdata as the Instance {{instance}} as it is not in Stopped state. Current state {{instanceState}}.", + "vm.resetsshkey.failed": "Failed to reset SSH Key for the Instance {{instance}}.", + "vm.resetsshkey.vm.not.found": "Unable to reset SSH Key as the specified Instance is not found.", + "vm.resetsshkey.vm.sharedfs.operation.not.supported": "Unable to reset SSH Key as the operation is not supported for Shared FileSystem Instance {{instance}}.", + "vm.resetsshkey.vm.operation.not.supported": "Unable to reset SSH Key as the operation is not supported for Instance {{instance}}.", + "vm.resetsshkey.vm.not.right.state": "Unable to reset SSH Key for the Instance {{instance}} as it is not in the right state. Current state: {{instanceState}}.", + "vm.resetsshkey.vm.not.stopped": "Unable to reset SSH Key as the Instance {{instance}} as it is not in Stopped state. Current state {{instanceState}}.", + "vm.resetsshkey.key.not.specified": "'keypair' or 'keypairs' must be specified.", + "vm.resetsshkey.key.not.all.found": "Unable to reset SSH Key as the Instance {{instance}} as not all the specified keypairs found.", + "vm.resetsshkey.network.service.not.found": "Unable to reset SSH Key for the Instance {{instance}} as its default Network {{network}} does not supports the service {{networkService}}.", + "vm.forcereboot.failed": "Unable to force reboot the Instance {{instance}}.", + "vm.forcereboot.host.not.found": "Unable to force reboot the Instance {{instance}} as Host for it is not found.", + "vm.forcereboot.host.not.right.state": "Unable to force reboot the Instance {{instance}} as Host is not in the right state.", + "vm.forcereboot.host.not.right.state.admin": "Unable to force reboot the Instance {{instance}} as Host {{host}} is not in the right state. Current state: {{hostState}}.", + "vm.forcereboot.router.concurrent.start": "Unable to force reboot the Instance {{instance}} as concurrent operations on starting router: {{routerError}}.", + "vm.forcereboot.router.start.failed": "Unable to force reboot the Instance {{instance}} as starting router failed due to: {{routerError}}.", + "vm.stop.agent.no.contact": "Unable to contact the agent to stop the Instance {{instance}}.", + "vm.upgrade.vm.not.right.state": "Unable to upgrade Instance {{instance}} in state {{instanceState}}; make sure the Instance is stopped.", + "vm.upgrade.serviceoffering.not.active": "Unable to upgrade Instance {{instance}} with an inactive service offering {{serviceOffering}}.", + "vm.validate.serviceoffering.invalid.cpu.cores": "Invalid cpu cores value for service offering {{serviceOffering}}, please choose another service offering with cpu cores between 1 and {{maxCPUCores}}.", + "vm.validate.serviceoffering.invalid.memory": "Invalid memory value for service offering {{serviceOffering}}, please choose another service offering with memory between 32 and {{maxMemory}} MB.", + "vm.validate.serviceoffering.custom.params.missing": "Need to specify custom parameter values cpu, cpu speed and memory when using custom service offering {{serviceOffering}}.", + "vm.validate.serviceoffering.invalid.params.cpu.cores": "Invalid CPU cores value for service offering {{serviceOffering}}, specify a value between {{minCPUCores}} and {{maxCPUCores}}.", + "vm.validate.serviceoffering.cpu.cores.not.dynamic": "CPU cores cannot be customized for service offering {{serviceOffering}} as they have been already predefined to {{cpuCores}}.", + "vm.validate.serviceoffering.invalid.params.cpu.speed": "Invalid CPU speed value for service offering {{serviceOffering}}, specify a value between 1 and {{maxCPUSpeed}}.", + "vm.validate.serviceoffering.cpu.speed.not.dynamic": "CPU speed cannot be customized for service offering {{serviceOffering}} as they have been already predefined to {{cpuSpeed}} MHz.", + "vm.validate.serviceoffering.invalid.params.memory": "Invalid memory value for service offering {{serviceOffering}}, specify a value between {{minMemory}} and {{maxMemory}} MB.", + "vm.validate.serviceoffering.memory.not.dynamic": "Memory cannot be customized for service offering {{serviceOffering}} as it has been already predefined to {{memory}} MB.", + "vm.addnic.vm.not.found": "Unable to add NIC as the specified Instance is not found.", + "vm.addnic.vm.having.snapshots": "Unable to add NIC to the Instance {{instance}} as it has Instance Snapshots.", + "vm.addnic.network.not.found": "Unable to add NIC to the Instance {{instance}} as the specified Network not found.", + "vm.addnic.network.sharedfs.account.scope": "Unable to add NIC to the Instance {{instance}} as shared network {{network}} which is not Account scoped and not belonging to the same account can not be added to a Shared FileSystem Instance.", + "vm.addnic.network.nic.mac.exists": "Unable to add NIC to the Instance {{instance}} as a NIC with same MAC address {{macAddress}} already exists in the Network {{network}}.", + "vm.addnic.ip.invalid": "Invalid format for IP address parameter {{ipAddress}}.", + "vm.addnic.zone.basic.not.allowed": "Zone {{zone}}, has a NetworkType of Basic. Can't add a new NIC to a Instance on a Basic Network.", + "vm.addnic.zone.mismatch": "Instance {{instance}} is in Zone {{instanceZone}} but the Network {{network}} is in Zone {{networkZone}}.", + "vm.addnic.hostname.duplicate": "Network {{network}} already has an Instance with host name: {{hostname}}.", + "vm.addnic.resource.unavailable": "Unable to add NIC to the Instance {{instance}}: {{error}}.", + "vm.addnic.insufficient.capacity": "Insufficient capacity when adding NIC to Instance {{instance}}: {{error}}.", + "vm.addnic.concurrent.operation": "Concurrent operations on adding NIC to Instance {{instance}}: {{error}}.", + "vm.addnic.cleanup.failed": "Error while cleaning up NIC: {{error}}.", + "vm.addnic.mac.generation.failed": "A MAC address cannot be generated for the NIC in the Network {{network}}.", + "vm.addnic.already.exists": "A NIC already exists for Instance {{instance}} in Network: {{network}}.", + "vm.removenic.vm.not.found": "Unable to remove NIC as the specified Instance is not found.", + "vm.removenic.vm.having.snapshots": "Unable to remove NIC from the Instance {{instance}} as it has Instance Snapshots.", + "vm.removenic.nic.not.found": "Unable to remove NIC from the Instance {{instance}} as the specified NIC is not found.", + "vm.removenic.network.not.found": "Unable to remove NIC {{nic}} from the Instance {{instance}} as a network for the NIC is not found.", + "vm.removenic.zone.basic.not.allowed": "Zone {{zone}}, has a NetworkType of Basic. Can't remove a NIC from a Instance on a Basic Network.", + "vm.removenic.nic.not.attached": "Unable to remove NIC {{nic}} from the Instance {{instance}} as it is not attached.", + "vm.removenic.default.nic": "Unable to remove NIC {{nic}} from the Instance {{instance}} in Network {{network}} it is the default NIC for the Instance.", + "vm.removenic.nic.with.rules": "Unable to remove NIC {{nic}} from the Instance {{instance}} in Network {{network}}, as it has associated Port forwarding or Load balancer or Static NAT rules.", + "vm.removenic.resource.unavailable": "Unable to remove NIC for the Network {{network}} from the Instance {{instance}}: {{error}}.", + "vm.removenic.concurrent.operation": "Concurrent operations on removing the Network {{network}} from the Instance {{instance}}: {{error}}.", + "vm.removenic.failed": "Unable to remove the NIC {{nic}} from the Instance {{instance}}.", + "vm.updatenic.vm.not.found": "Unable to update NIC as the specified Instance is not found.", + "vm.updatenic.vm.having.snapshots": "Unable to update NIC for the Instance {{instance}} as it has Instance Snapshots.", + "vm.updatenic.nic.not.found": "Unable to update NIC for the Instance {{instance}} as the specified NIC is not found.", + "vm.updatenic.nic.network.not.found": "Unable to update NIC {{nic}} for the Instance {{instance}} as the Network for the NIC is not found.", + "vm.updatenic.zone.basic.not.allowed": "Zone {{zone}}, has a NetworkType of Basic. Can't change default NIC on a Basic Network.", + "vm.updatenic.nic.not.attached": "Unable to update NIC {{nic}} for the Instance {{instance}} as the NIC is not attached to the Instance.", + "vm.updatenic.nic.already.default": "NIC {{nic}} is already the default for the Instance {{instance}}.", + "vm.updatenic.vm.not.running.or.stopped": "Unable to update NIC {{nic}} for the Instance {{instance}} as the Instance not Running or Stopped.", + "vm.updatenic.nic.profile.not.found": "Unable to update NIC {{nic}} for the Instance {{instance}} as failed to find a NIC profile for the existing default Network.", + "vm.updatenic.default.update.failed": "Setting a default NIC failed, and we had no default nic, but we were unable to set it back to the original.", + "vm.updatenic.default.no.default": "Unable to update default NIC to {{nic}} for the Instance {{instance}} and now it has no default.", + "vm.updatenic.default.unknown.error": "Something strange happened, new default network {{newDefaultNetwork}} is not null, and is not equal to the network {{networkId}} of the chosen nic.", + "vm.updatenicip.nic.not.found": "There is no nic for the {{nicId}}.", + "vm.updatenicip.nic.not.user.vm": "The nic is not belongs to user vm.", + "vm.updatenicip.vm.not.found": "There is no vm with the nic.", + "vm.updatenicip.network.not.found": "There is no network with the nic.", + "vm.updatenicip.network.not.right.state": "Network is not in the right state to update vm nic ip. Correct states are: {{allowedStates}}.", + "vm.updatenicip.offering.not.found": "There is no network offering with the network.", + "vm.updatenicip.vm.running": "VM is not Stopped, unable to update the vm nic having the specified id.", + "vm.updatenicip.datacenter.not.found": "There is no dc with the NIC.", + "vm.updatenicip.allocation.failed.capacity": "Allocating IP to guest NIC {{nic}} failed, for insufficient address capacity.", + "vm.updatenicip.allocation.failed.choose.another": "Allocating IP to guest NIC {{nic}} failed, please choose another IP.", + "vm.updatenicip.pod.id.null": "Instance Pod ID is null in Basic zone; can't decide the range for IP allocation.", + "vm.updatenicip.allocation.failed.basic": "Allocating IP to guest NIC {{nicId}} failed, please choose another IP.", + "vm.updatenicip.not.supported.l2.network": "UpdateVmNicIpCmd is not supported in L2 network.", + "vm.upgrade.vm.uuid.not.found": "Unable to find VM's UUID.", + "vm.upgrade.external.hypervisor.not.supported": "Operation not supported for instance: {{instance}} as it is external hypervisor instance.", + "vm.upgrade.hypervisor.not.supported": "Scaling the VM dynamically is not supported for VMs running on Hypervisor {{hypervisorType}}.", + "vm.upgrade.dynamic.scaling.flag.mismatch": "Unable to Scale VM: since dynamic scaling enabled flag is not same for new service offering and old service offering.", + "vm.upgrade.disk.offering.strictness.mismatch": "Unable to Scale VM, since disk offering strictness flag is not same for new service offering and old service offering.", + "vm.upgrade.disk.offering.id.not.same": "Unable to Scale VM, since disk offering id associated with the old service offering is not same for new service offering.", + "vm.scale.vgpu.not.supported": "Dynamic scaling of vGPU type is not supported. VM has vGPU Type: {{vgpuType}}.", + "vm.scale.dynamic.scaling.disabled": "Dynamically scaling Instances is disabled for this zone, please contact your admin.", + "vm.scale.dynamic.scaling.not.supported": "Unable to scale {{instance}} as it does not have tools to support dynamic scaling.", + "vm.scale.insufficient.resources": "Unable to scale {{instance}} due to insufficient resources.", + "vm.scale.up.required": "While the VM is running, only scalling up it is supported. New service offering {{newOffering}} should have at least one value (ram, speed or cpu) greater than the current values {{currentOffering}}.", + "vm.scale.kvm.fixed.offering.not.supported": "Unable to live scale VM on KVM when current service offering is a Fixed Offering. KVM needs the tag maxMemory to live scale and it is only configured when VM is deployed with a custom service offering and Dynamic Scalable is enabled.", + "vm.scale.root.volume.change.failed": "Failed to change disk offering of the root volume.", + "vm.scale.hypervisor.simulator.root.resize.not.supported": "Hypervisor {{hypervisorType}} does not support volume resize.", + "vm.recover.vm.not.found": "Unable to find an Instance with id {{vmId}}.", + "vm.recover.sharedfs.not.supported": "Operation not supported on Shared FileSystem Instance.", + "vm.recover.permission.denied": "Recovering a vm can only be done by an Admin. Or when the allow.user.expunge.recover.vm key is set.", + "vm.recover.vm.removed": "Unable to find vm by id {{vmUuid}}.", + "vm.recover.vm.not.destroyed": "Vm with id {{vmUuid}} is not in the right state.", + "vm.recover.account.deleted": "Unable to recover Instance as the Account is deleted.", + "vm.recover.state.transition.failed": "Unable to recover the vm {{instance}} because it is not in the correct state. Current state: {{instanceState}}.", + "vm.resize.volume.root.not.found": "Root volume for Instance not found while preparing resize.", + "vm.resize.volume.current.diskoffering.not.found": "Could not find disk offering matching the current root offering ID.", + "vm.resize.volume.new.diskoffering.not.found": "Could not find disk offering for resizing the root volume.", + "vm.resize.volume.new.offering.smaller": "Failed to resize root volume. New Service Offering {{newOffering}} has a smaller disk size ({{newSize}} GB) than the current disk ({{currentSize}} GB).", + "vm.update.owner.not.found": "The owner of Instance {{instance}} does not exist.", + "vm.update.non.dynamic.cpu.memory.not.updatable": "CPU number, memory, and CPU speed cannot be updated for a non-dynamic service offering.", + "vm.update.sharedfs.not.supported": "Operation not supported on Shared FileSystem Instance.", + "vm.update.ova.details.cleanup.not.allowed": "OVA detail settings are read from OVA and cannot be cleaned up via API call.", + "vm.update.lease.params.in.details": "Lease parameters should not be included in the details map as a key.", + "vm.update.extraconfig.in.details": "'extraconfig' should not be included in the details map as a key.", + "vm.update.ova.details.change.not.allowed": "OVA detail settings are read from OVA and cannot be changed via API call.", + "vm.update.detail.restricted": "You are not allowed to add or edit the restricted setting: {{detailName}}.", + "vm.update.detail.readonly": "You are not allowed to add or edit the read-only setting: {{detailName}}.", + "vm.update.detail.nondisplayable": "You are not allowed to add or edit the non-displayable setting: {{detailName}}.", + "vm.update.extraconfig.disabled": "Cannot set extraconfig because enable.additional.vm.configuration is disabled.", + "vm.update.vm.not.found": "Unable to find virtual machine with specified ID.", + "vm.update.guestos.not.found": "Please specify a valid guest OS ID.", + "vm.update.instance.name.not.unique": "Instance name {{instanceName}} is not unique.", + "vm.update.vm.not.right.state": "Instance {{instance}} is not in the right state for this operation.", + "vm.update.ha.offering.disabled": "Cannot enable HA for the Instance as its Service Offering has HA disabled.", + "vm.update.dynamic.scaling.template.not.supported": "Dynamic Scaling cannot be enabled for the Instance since its Template does not support dynamic scaling.", + "vm.update.dynamic.scaling.offering.not.supported": "Dynamic Scaling cannot be enabled for the Instance since its Service Offering does not support dynamic scaling.", + "vm.update.dynamic.scaling.global.setting.disabled": "Dynamic Scaling cannot be enabled for the Instance as the corresponding global setting is disabled.", + "vm.update.securitygroup.vmware.not.supported": "Security group feature is not supported for VMware hypervisor.", + "vm.update.securitygroup.vm.not.stopped": "Instance {{instance}} must be stopped before updating security groups.", + "vm.update.userdata.failed": "Failed to reset userdata for the Instance.", + "vm.update.dns.router.send.failed": "Unable to send commands to virtual router to update DNS for the Instance.", + "vm.update.dns.hostname.update.failed": "Failed to update hostname for the Instance.", + "vm.update.dns.hostname.failed": "Failed to update hostname of Instance {{instance}} to {{hostname}}.", + "vm.update.userdata.network.element.not.found": "Cannot find network element for UserData provider needed for userdata update.", + "vm.reboot.vm.not.found": "Unable to find Instance with specified ID.", + "vm.reboot.vm.not.running": "The Instance {{instance}} is not running and cannot be rebooted.", + "vm.reboot.serviceoffering.not.found": "Unable to find Service Offering for the Instance.", + "vm.reboot.setup.menu.hypervisor.not.supported": "Booting into a hardware setup menu is not supported on hypervisor {{hypervisorType}}.", + "vm.expunge.permission.denied": "Account does not have permission for expunging the Instance.", + "vm.expunge.vm.not.found": "Unable to find Instance with specified ID.", + "vm.expunge.sharedfs.not.supported": "Operation not supported on Shared FileSystem Instance.", + "vm.expunge.admin.only": "Expunging an Instance can only be done by an Admin, or when allow.user.expunge.recover.vm is enabled.", + "vm.destroy.vm.not.found": "Unable to find Instance with specified ID.", + "vm.destroy.sharedfs.not.supported": "Operation not supported on Shared FileSystem Instance.", + "vm.destroy.delete.protection.enabled": "Instance {{instance}} has delete protection enabled and cannot be deleted.", + "vm.destroy.unbacked.snapshots": "There are unbacked up snapshots on the ROOT volume. Instance destroy is not permitted; please try again later.", + "vm.destroy.expunge.failed": "Failed to expunge Instance {{instance}}.", + "vm.destroy.volume.not.found": "Unable to find volume with specified ID.", + "vm.destroy.volumes.not.attached": "The supplied volumes are not DATADISK volumes attached to the Instance.", + "vm.destroy.volume.type.invalid": "Please specify a volume of type DATADISK or ROOT.", + "vm.destroy.volume.delete.protection": "Volume {{volume}} has delete protection enabled and cannot be deleted.", + "vm.destroy.failed": "Failed to destroy Instance with specified ID.", + "vm.group.create.name.exists": "Unable to create Instance group: a group named {{groupName}} already exists for Account {{account}}.", + "vm.group.delete.not.found": "Unable to find Instance group with specified ID.", + "vm.group.add.lock.failed": "Failed to acquire lock on Instance group {{group}}.", + "vm.deploy.basic.network.not.found": "Unable to find a default network to deploy the Instance.", + "vm.deploy.securitygroup.vmware.not.supported": "Security group feature is not supported for VMware hypervisor.", + "vm.deploy.sg.network.not.found": "No network with security group enabled is found in zone {{zone}}.", + "vm.deploy.sg.multiple.networks.not.supported": "Only one network per VM is supported when security group is enabled.", + "vm.deploy.network.not.found": "Unable to find network with specified ID.", + "vm.deploy.sg.network.not.sg.enabled": "Network {{network}} is not security group enabled and is not an L2 network.", + "vm.deploy.sg.advanced.network.type.invalid": "Only Shared or L2 Guest networks can be specified when deploying a VM in an Advanced Security Group enabled zone.", + "vm.deploy.advanced.vpc.template.hypervisor.not.supported": "Cannot create Instance from Template with hypervisor {{hypervisorType}} in VPC Network {{network}}.", + "vm.deploy.advanced.vpc.hypervisor.not.supported": "Cannot create Instance of hypervisor type {{hypervisorType}} in VPC Network.", + "vm.deploy.network.system.only": "Network {{network}} is system only and cannot be used for VM deployment.", + "vm.deploy.network.offering.required.not.found": "Unable to find a network offering with Required availability to automatically create the network as part of VM creation.", + "vm.deploy.network.none.found.for.account": "No virtual networks found for Account {{account}}.", + "vm.deploy.network.multiple.default.found": "More than one default Isolated network found for Account {{account}}; please specify networkIds.", + "vm.deploy.network.offering.required.not.enabled": "Required network offering {{offering}} is not in Enabled state.", + "vm.deploy.physical.network.not.found": "Unable to find physical network with ID {{physicalNetworkId}} and tag {{tag}}.", + "vm.deploy.dhcp.options.network.no.nic": "Instance does not have a NIC in network {{network}} specified in the extra DHCP options.", + "vm.deploy.hostname.invalid": "Invalid hostname. Must be 1-63 chars, letters/digits/hyphens, cannot start or end with a hyphen or start with a digit.", + "vm.deploy.owner.disabled": "The owner of the Instance to deploy is disabled: {{owner}}.", + "vm.deploy.hypervisor.missing.or.invalid": "Hypervisor parameter is required to deploy the VM, or the value provided is invalid.", + "vm.deploy.hypervisor.mismatch": "The specified hypervisor type differs from the hypervisor type of the Template.", + "vm.deploy.zone.disabled": "Cannot deploy Instance: zone {{zone}} is currently disabled.", + "vm.deploy.zone.domain.not.found": "Unable to find the domain for zone {{zone}}.", + "vm.deploy.iso.disk.offering.required": "Installing from ISO requires a disk offering to be specified for the root disk.", + "vm.deploy.root.encryption.hypervisor.not.supported": "Root volume encryption is not supported for hypervisor type {{hypervisorType}}.", + "vm.deploy.security.group.not.found": "Unable to find security group with specified ID.", + "vm.deploy.datadisk.template.invalid": "Invalid datadisk Template ID specified.", + "vm.deploy.datadisk.template.not.child": "Datadisk Template {{dataDiskTemplate}} does not belong to Template {{template}}.", + "vm.deploy.datadisk.template.offering.invalid": "Invalid disk offering {{diskOffering}} specified for datadisk Template {{dataDiskTemplate}}.", + "vm.deploy.datadisk.template.custom.offering.not.supported": "Custom disk offerings are not supported for datadisk Templates.", + "vm.deploy.datadisk.template.offering.too.small": "Disk offering {{diskOffering}} size is smaller than datadisk Template {{dataDiskTemplate}} size.", + "vm.deploy.affinity.group.not.found": "Unable to find affinity group with specified ID.", + "vm.deploy.affinity.group.type.not.supported": "Affinity group type {{groupType}} is not supported for group {{group}}.", + "vm.deploy.affinity.group.domain.mismatch": "Affinity Group {{group}} does not belong to the VM's domain.", + "vm.deploy.affinity.group.account.mismatch": "Affinity Group {{group}} does not belong to the VM's account.", + "vm.deploy.system.template.not.allowed": "System template {{template}} cannot be used to deploy a user VM.", + "vm.deploy.volume.zone.mismatch": "The volume's zone {{volumeZone}} does not match the provided zone {{zone}}.", + "vm.deploy.snapshot.zone.mismatch": "The snapshot does not exist in zone {{zone}}.", + "vm.deploy.template.not.available": "Template {{template}} is not available for use.", + "vm.deploy.iso.not.bootable": "Installing from ISO requires a bootable ISO. The provided ISO {{iso}} is not bootable.", + "vm.deploy.keypairs.not.found": "Not all specified SSH keypairs exist.", + "vm.deploy.network.zone.mismatch": "Network {{network}} does not belong to zone {{zone}}.", + "vm.deploy.network.not.stretched": "Network {{network}} cannot be stretched to zone {{zone}} for VM deployment.", + "vm.deploy.userdata.network.service.not.found": "Cannot deploy Instance with UserData: the default network {{network}} does not support the UserData service.", + "vm.deploy.sshkey.network.service.not.found": "Cannot deploy Instance with SSH keypair: the default network {{network}} does not support the UserData service.", + "vm.deploy.template.password.network.service.not.found": "Cannot deploy Instance from password-enabled template {{template}}: the default network {{network}} does not support the UserData service.", + "vm.deploy.securitygroup.service.not.enabled": "Cannot deploy Instance with security groups: SecurityGroup service is not enabled for the VM's network.", + "vm.deploy.default.network.missing": "At least one default network must be specified for the Instance.", + "vm.deploy.default.network.multiple": "Only one default network per Instance is supported.", + "vm.deploy.hostname.exists": "An Instance with hostname {{hostname}} already exists.", + "vm.deploy.displayname.exists": "An Instance with the supplied display name already exists.", + "vm.deploy.group.assign.failed": "Unable to assign Instance to group {{group}}.", + "vm.deploy.disk.offering.custom.size.required": "This disk offering requires a custom size to be specified.", + "vm.deploy.root.disk.size.not.positive": "Root disk size must be a positive number.", + "vm.deploy.root.disk.size.override.not.supported": "Hypervisor {{hypervisorType}} does not support root disk size override.", + "vm.deploy.hostname.network.domain.exists": "An Instance with hostname {{hostname}} already exists in the network domain.", + "vm.deploy.root.disk.size.smaller.than.template": "Root disk size override ({{rootDiskSize}} GB) is smaller than the template size.", + "vm.deploy.root.disk.controller.invalid": "Unsupported root disk controller {{diskController}} for resizing.", + "vm.deploy.userdata.both.inputs": "Both userdata and userdata ID inputs are not allowed; please provide only one.", + "vm.deploy.userdata.override.denied": "UserData input is not allowed since template {{template}} is configured to deny userdata override.", + "vm.deploy.userdata.template.linked.not.found": "UserData linked to the template {{template}} is not found.", + "vm.deploy.userdata.policy.not.supported": "UserData policy {{policy}} is not supported.", + "vm.deploy.template.not.vnf": "Cannot deploy VNF appliance from a non-VNF template.", + "vm.deploy.template.deploy.as.is.root.disk.size.not.allowed": "Cannot deploy VM: a service offering with root disk size cannot be used with a deploy-as-is template.", + "vm.deploy.template.deploy.as.is.override.disk.size.not.supported": "Overriding root disk size is not supported for VMs deployed from deploy-as-is templates.", + "vm.deploy.template.deploy.as.is.boot.not.supported": "Boot type and boot mode are not supported on VMware for deploy-as-is templates.", + "vm.deploy.snapshot.template.not.determinable": "Could not determine template from snapshot. The source volume no longer exists. Please specify a templateId.", + "vm.deploy.backup.userdata.not.supported": "User data is not supported for instances created from a backup.", + "vm.deploy.basic.zone.network.ids.not.allowed": "Network IDs cannot be specified when deploying in a Basic zone.", + "vm.deploy.securitygroup.zone.not.enabled": "Cannot create Instance with security groups: security group feature is not enabled for this zone.", + "vm.deploy.lease.duration.invalid": "Invalid lease duration. Must be a natural number >= 1 or -1; maximum value is 36500.", + "vm.deploy.lease.params.both.required": "Both leaseduration and leaseexpiryaction must be specified together.", + "vm.deploy.lease.no.active.lease": "Lease cannot be applied to Instance {{instance}}: it does not have an active lease associated from deployment.", + "vm.deploy.lease.not.pending": "Lease cannot be applied to Instance {{instance}}: the lease is not in PENDING state.", + "vm.deploy.lease.expired.redefinition": "Lease cannot be redefined on an expired leased instance.", + "vm.deploy.volume.storage.pool.zone.required": "VM deployment from a volume is supported only for Zone-wide storage pools.", + "vm.deploy.volume.already.attached": "Volume {{volume}} is already attached to another VM.", + "vm.deploy.volume.template.mismatch": "The volume's template does not match the provided template.", + "vm.deploy.volume.snapshot.no.template": "The provided volume or snapshot does not have a template for VM deployment.", + "vm.deploy.security.group.id.and.name.exclusive": "The securitygroupids and securitygroupnames parameters are mutually exclusive.", + "vm.deploy.security.group.name.not.found": "Unable to find security group with name {{groupName}}.", + "vm.deploy.detail.extraconfig.prefix.not.allowed": "Detail name should not start with 'extraconfig'.", + "vm.deploy.iops.both.or.neither": "Either both Min IOPS and Max IOPS must be specified, or neither.", + "vm.deploy.iops.min.not.integer": "Min IOPS must be a whole number.", + "vm.deploy.iops.max.not.integer": "Max IOPS must be a whole number.", + "vm.deploy.iops.min.greater.than.max": "Min IOPS must be less than or equal to Max IOPS.", + "vm.deploy.ovf.sg.network.not.found": "No network with security enabled found in zone {{zone}} for OVF network mapping.", + "vm.deploy.ovf.default.network.not.found": "Default network not found for zone {{zone}} and account {{account}} for OVF network mapping.", + "vm.stop.force.permission.denied": "Account does not have permission to force stop the Instance.", + "vm.stop.account.removed": "The caller account has been removed and cannot be used.", + "vm.stop.vm.not.found": "Unable to find Instance with specified ID.", + "vm.start.host.capacity.insufficient": "Cannot deploy VM to specified host {{host}}: insufficient CPU or RAM capacity.", + "vm.start.password.not.provided": "A valid password for the Instance was not provided.", + "vm.start.setup.menu.hypervisor.not.applicable": "Boot into setup mode is not applicable for hypervisor {{hypervisorType}}.", + "vm.start.planner.not.found": "Cannot find deployment planner '{{plannerName}}'.", + "vm.start.account.removed": "The caller account {{account}} has been removed.", + "vm.start.vm.not.found": "Unable to find Instance with specified ID.", + "vm.start.vm.already.running": "The Instance {{instance}} is already running.", + "vm.start.owner.not.found": "The owner of Instance {{instance}} does not exist.", + "vm.start.owner.disabled": "The owner of Instance {{instance}} is disabled.", + "vm.start.pod.root.admin.only": "Only root administrators can specify a pod ID for VM deployment.", + "vm.start.pod.not.found": "Unable to find pod with specified ID for VM deployment.", + "vm.start.cluster.root.admin.only": "Only root administrators can specify a cluster ID for VM deployment.", + "vm.start.cluster.not.found": "Unable to find cluster with specified ID for VM deployment.", + "vm.start.host.root.admin.only": "Only root administrators can specify a host ID for VM deployment.", + "vm.start.host.not.found": "Unable to find host with specified ID for VM deployment.", + "vm.start.host.not.right.state": "Cannot deploy Instance on host {{host}} as it is not in the correct state.", + "vm.migrate.storage.permission.denied": "No permission to migrate VM storage. Only root administrators can perform this operation.", + "vm.migrate.storage.vm.not.found": "Unable to find Instance with specified ID for storage migration.", + "vm.migrate.storage.nonuser.hypervisor.not.supported": "Unable to migrate storage of non-user VM for hypervisor {{hypervisorType}}.", + "vm.migrate.storage.data.disks.attached": "Data disks are attached to the Instance. Detach all data disks before migrating storage.", + "vm.migrate.storage.snapshots.exist": "Instance disk cannot be migrated. Remove all Instance Snapshots before proceeding.", + "vm.migrate.storage.nonuser.different.pods": "Storage migration of non-user VMs between storage pools in different pods is not supported.", + "vm.migrate.storage.suitability.failed": "Storage suitability check failed for volume {{volume}}: {{error}}.", + "vm.migrate.storage.different.clusters": "VM disk migration failed: destination storage pools belong to different clusters.", + "vm.migrate.storage.access.groups.mismatch": "Destination pool {{pool}} does not have matching storage access groups as host {{host}}.", + "vm.migrate.storage.hypervisor.mismatch": "Hypervisor mismatch for storage migration: destination has {{destHypervisor}}, VM requires {{vmHypervisor}}.", + "vm.migrate.permission.denied": "No permission to migrate VM. Only root administrators can perform this operation.", + "vm.migrate.vm.not.found": "Unable to find Instance with specified ID for migration.", + "vm.migrate.gpu.not.supported": "Live migration of GPU-enabled Instance is not supported.", + "vm.migrate.hypervisor.not.supported": "Unsupported hypervisor type for VM migration. Supported: XenServer, VMware, KVM, OVM, Hyper-V, OVM3.", + "vm.migrate.local.storage.not.supported": "VM uses local storage and cannot be live migrated.", + "vm.migrate.source.host.not.found": "Cannot migrate VM: source host not found.", + "vm.migrate.destination.not.found": "Unable to find a suitable destination to migrate Instance {{instance}}.", + "vm.migrate.affinity.conflict": "Unable to create migration deployment: affinity rules conflict.", + "vm.migrate.server.not.found": "Unable to find a server to migrate the Instance to.", + "vm.migrate.storage.access.groups.src.has.dest.none": "Source host has storage access groups but destination host has none.", + "vm.migrate.storage.access.groups.mismatch.hosts": "Storage access groups on the source and destination hosts do not match.", + "vm.migrate.host.tags.mismatch": "Cannot migrate Instance: destination host {{host}} does not match the host tags of the service offering.", + "vm.migrate.vm.already.on.host": "Cannot migrate Instance: the Instance is already on the destination host. Please specify a different host.", + "vm.migrate.destination.host.not.right.state": "Cannot migrate Instance: destination host {{host}} is not in the correct state.", + "vm.migrate.destination.different.pod": "Cannot migrate Instance: destination host is not in the same pod as the current host.", + "vm.migrate.dpdk.host.not.supported": "Cannot migrate DPDK-enabled Instance to a host that is not DPDK-enabled.", + "vm.migrate.unbacked.snapshots": "There are unbacked up snapshots on volumes attached to this Instance. Migration is not permitted; please try again later.", + "vm.migrate.host.maintenance.mode": "Operation {{operation}} on Instance {{instance}} is not allowed as the host is preparing for maintenance mode.", + "vm.migrate.storage.source.host.not.found": "Cannot migrate VM with storage: source host not found.", + "vm.migrate.storage.vm.already.on.host": "Cannot migrate VM with storage: Instance is already on the destination host. Please specify a different host.", + "vm.migrate.storage.hypervisor.version.mismatch": "Source and destination hosts must have the same hypervisor type and version for migration with storage.", + "vm.migrate.storage.source.hypervisor.not.supported": "Migration with storage is not supported for source host {{host}} on hypervisor {{hypervisorType}} version {{version}}.", + "vm.migrate.storage.destination.hypervisor.not.supported": "Migration with storage is not supported for destination host {{host}} on hypervisor {{hypervisorType}} version {{version}}.", + "vm.migrate.storage.destination.host.not.right.state": "Cannot migrate VM with storage: destination host {{host}} is not in the correct state.", + "vm.migrate.storage.volume.not.ready": "Volume {{volume}} of the Instance is not in Ready state. Cannot proceed with storage migration.", + "vm.migrate.storage.volume.not.found": "Volume with specified ID not found for storage migration.", + "vm.migrate.storage.pool.not.found": "Storage pool with specified ID not found for migration.", + "vm.migrate.storage.volume.pool.incompatible": "Cannot migrate volume {{volume}} to destination storage pool {{pool}}: incompatible hypervisor type.", + "vm.migrate.storage.volume.vm.mismatch": "Volume {{volume}} does not belong to Instance {{instance}} being migrated.", + "vm.migrate.storage.volume.pool.access.groups.mismatch": "Destination pool {{pool}} for volume {{volume}} does not have matching storage access groups as host {{host}}.", + "vm.migrate.storage.volume.pool.unsuitable": "Unable to migrate {{volume}} to destination storage pool {{pool}}: {{error}}.", + "vm.migrate.storage.volume.policy.noncompliant": "Storage pool {{pool}} is not compliant with the storage policy for volume {{volume}}.", + "vm.migrate.storage.volume.policy.verify.failed": "Failed to verify storage policy compliance for storage pool {{pool}}.", + "vm.migrate.storage.hypervisor.not.supported": "Unsupported hypervisor {{hypervisorType}} for VM migration with storage.", + "vm.migrate.storage.instance.snapshots.exist": "Instance cannot be migrated with storage because it has Instance Snapshots. Remove all Instance Snapshots first.", + "vm.migrate.storage.no.volume.migration": "Migration of Instance {{instance}} from host {{srcHost}} to {{destHost}} does not involve migrating any volumes.", + "vm.assign.permission.denied": "Only root or domain administrators are allowed to assign VMs. Caller {{caller}} is of type {{callerType}}.", + "vm.assign.domain.id.null": "Please provide a valid domain ID. Cannot assign VM to a project if domain ID is null.", + "vm.assign.vm.not.found": "Unable to find Instance with specified ID for assignment.", + "vm.assign.vm.not.right.state": "Cannot move Instance {{instance}} in {{instanceState}} state.", + "vm.assign.sharedfs.not.supported": "Assignment is not supported for Shared FileSystem Instances.", + "vm.assign.portforwarding.rules.exist": "Remove all Port Forwarding rules for Instance {{instance}} before assigning it to another user.", + "vm.assign.staticnat.rules.exist": "Remove all Static NAT rules for Instance {{instance}} before assigning it to another user.", + "vm.assign.loadbalancer.rules.exist": "Remove all Load Balancing rules for Instance {{instance}} before assigning it to another user.", + "vm.assign.onetoonat.rule.exists": "Remove the One-to-One NAT rule for Instance {{instance}} and IP {{ip}} before assigning it.", + "vm.assign.volume.snapshots.exist": "Snapshots exist for volume {{volume}}. Detach the volume or remove all snapshots before assigning the Instance.", + "vm.assign.template.not.found": "Template for Instance {{instance}} cannot be found.", + "vm.assign.template.access.denied": "New owner does not have access to the template of Instance {{instance}}.", + "vm.assign.securitygroup.zone.not.enabled": "Cannot move Instance with security groups: security group feature is not enabled in this zone.", + "vm.assign.network.offering.required.not.found": "Unable to find a Required network offering to automatically create the network during VM assignment.", + "vm.assign.network.offering.required.not.enabled": "Required network offering {{offering}} is not in Enabled state.", + "vm.assign.networks.update.failed": "Unable to update networks when assigning Instance {{instance}}.", + "vm.assign.old.account.invalid": "Invalid old account for VM in domain {{domain}}.", + "vm.assign.new.account.invalid": "Invalid new account {{account}} for VM in domain {{domain}}.", + "vm.assign.new.account.disabled": "The new account owner {{account}} is disabled.", + "vm.assign.same.account": "The new account {{account}} is the same as the old account.", + "vm.assign.basic.zone.network.ids.not.allowed": "Cannot move Instance with Network IDs; this is a basic zone Instance.", + "vm.assign.advanced.sg.no.network": "No network specified for moving the Instance. Please specify a network or add a network to the Instance via the NICs tab.", + "vm.assign.default.network.not.found": "Unable to find a default network to start the Instance.", + "vm.assign.securitygroup.vmware.not.supported": "Security group feature is not supported for VMware hypervisor.", + "vm.assign.applicable.network.not.found": "Could not find an applicable network to create virtual machine for account {{account}}.", + "vm.assign.multiple.default.networks": "More than one default isolated network found for account {{account}}. Please specify networkIDs.", + "vm.assign.network.system.only": "Network {{network}} is system only and cannot be used for VM deployment.", + "vm.assign.physical.network.not.found": "Unable to find physical network with ID {{physicalNetworkId}} and tag {{tag}}.", + "vm.assign.network.implement.failed": "Failed to implement network {{network}} elements and resources as part of network provision.", + "vm.restore.disk.offering.not.found": "Cannot find disk offering with the specified ID.", + "vm.restore.disk.offering.strict.mismatch": "The service offering has a strict disk offering requirement, and the specified disk offering does not match.", + "vm.restore.sharedfs.not.supported": "Operation not supported on Shared FileSystem Instance.", + "vm.restore.instance.not.supported": "Operation not supported for Instance {{instance}}.", + "vm.restore.template.not.found": "Cannot find template with the specified ID.", + "vm.restore.template.linked.not.found": "Cannot find the template linked with the Instance.", + "vm.restore.root.disk.size.smaller.than.template": "Root disk size {{rootDiskSize}} is smaller than the template size {{templateSize}}.", + "vm.restore.disk.offering.size.smaller.than.template": "Disk size {{diskSize}} for the selected offering is less than the template size {{templateSize}}.", + "vm.restore.external.hypervisor.type.not.allowed": "Restore operation is not allowed for External hypervisor type.", + "vm.restore.unbacked.snapshots": "There are unbacked up snapshots on the ROOT volume. Re-install VM is not permitted; please try again later.", + "vm.restore.iso.cannot.use.template": "This Instance was created from an ISO and cannot be re-installed with a template.", + "vm.restore.template.id.invalid": "Invalid template ID provided to restore the Instance.", + "vm.restore.iso.not.attached": "Cannot restore the Instance: no ISO is attached to the VM.", + "vm.restore.owner.not.found": "The owner of Instance {{instance}} does not exist.", + "vm.restore.owner.disabled": "The owner of Instance {{instance}} is disabled.", + "vm.restore.vm.not.right.state": "Instance {{instance}} is in {{instanceState}} state. Restore can only be performed when the Instance is Running or Stopped.", + "vm.restore.root.volume.not.found": "Cannot find root volume for Instance {{instance}}.", + "vm.restore.multiple.root.volumes": "There are {{count}} root volumes for Instance {{instance}}; expected at most one.", + "vm.restore.snapshots.exist": "Unable to restore Instance: please remove all Instance Snapshots first.", + "vm.restore.stop.failed": "Failed to stop the Instance before restore.", + "vm.restore.password.reset.failed": "VM restore is complete but failed to reset the password.", + "vm.restore.start.failed": "Unable to start Instance after restore.", + "vm.restore.failed": "Failed to restore Instance {{instance}}.", + "vm.restore.template.not.available.in.zone": "Cannot restore Instance: template {{template}} is not available in the zone.", + "vm.restore.template.bypassed.not.available": "Cannot restore Instance: bypassed template {{template}} is not available in the zone.", + "vm.restore.managed.storage.hypervisor.not.supported": "This hypervisor type is not supported on managed storage for this command.", + "vm.restore.managed.storage.reset.failed": "Unable to reset Instance {{instance}} during managed storage operation.", + "vm.extraconfig.vmware.key.not.allowed": "Extra config key '{{key}}' is not in the allowed list for VMware hypervisor.", + "vm.extraconfig.vmware.invalid.format": "The extra config string contains an invalid key/value pair pattern.", + "vm.extraconfig.xenserver.key.not.allowed": "Extra config key '{{key}}' is not in the allowed list for XenServer hypervisor.", + "vm.extraconfig.xenserver.invalid.format": "The extra config string contains an invalid key/value pair pattern.", + "vm.extraconfig.config.incorrect": "An incorrect extra configuration '{{config}}' was passed.", + "vm.extraconfig.account.not.enabled": "Additional VM configuration is not enabled for this account.", + "vm.extraconfig.kvm.key.not.allowed": "Extra config key '{{key}}' is not in the allowed list for KVM hypervisor.", + "vm.extraconfig.kvm.xml.parse.failed": "Failed to parse additional XML configuration.", + "vm.extraconfig.hypervisor.not.supported": "Hypervisor {{hypervisorType}} is not supported for additional VM configuration.", + "vm.extraconfig.url.decode.failed": "Failed to decode URL-encoded extra config string.", + "vm.password.encrypt.failed": "Failed to encrypt the password for the Instance.", + "vm.userdata.vm.not.found": "Unable to find Instance with specified ID.", + "vm.import.zone.invalid": "Unable to import virtual machine: invalid zone specified.", + "vm.import.host.invalid": "Unable to import virtual machine: invalid host specified.", + "vm.unmanage.vm.not.found": "Unable to find Instance with specified ID for unmanage operation.", + "vm.unmanage.vm.not.right.state": "Instance {{instance}} is not running or stopped and cannot be unmanaged.", + "vm.unmanage.failed": "Failed to unmanage Instance {{instance}}.", + "vm.unmanage.unbacked.snapshots": "There are unbacked up snapshots on the ROOT volume. VM unmanage is not permitted; please try again later.", + "vm.unmanage.volume.not.attached": "Volume {{volume}} of Instance {{instance}} is not attached to the Instance.", + "vm.unmanage.volume.type.invalid": "Volume {{volume}} has invalid type {{volumeType}}: expected ROOT or DATADISK.", + "vm.backup.root.disk.size.smaller.than.backup": "Instance root disk size {{instanceSize}} GiB cannot be less than the backed-up volume size {{backupSize}} GiB.", + "vm.backup.not.found": "Backup with specified ID does not exist.", + "vm.backup.create.instance.not.supported": "Create instance from backup is not supported for this backup provider.", + "vm.backup.zone.not.found": "Unable to find zone with specified ID.", + "vm.backup.cross.zone.not.supported": "Create Instance from Backup across zones is not supported by this backup provider or repository.", + "vm.backup.service.offering.not.found": "Unable to find service offering with specified ID.", + "vm.backup.service.offering.uuid.missing": "Backup does not contain a Service Offering UUID. Please specify a valid Service Offering when creating the Instance.", + "vm.backup.service.offering.uuid.not.found": "Unable to find Service Offering from the UUID stored in the Backup. Please specify a valid Service Offering.", + "vm.backup.template.not.found": "Unable to find template with specified ID.", + "vm.backup.template.uuid.missing": "Backup does not contain a Template UUID. Please specify a valid Template or ISO when creating the Instance.", + "vm.backup.template.uuid.not.found": "Unable to find Template from the UUID stored in the Backup. Please specify a valid Template or ISO.", + "vm.backup.disk.offering.iso.only": "The diskofferingid parameter is only supported for creating instances from backup when using ISO. For templates, use datadisksdetails.", + "vm.backup.disk.offering.not.found": "Unable to find disk offering with specified ID.", + "vm.backup.disk.offering.compute.only": "Disk offering {{diskOffering}} is directly mapped to a service offering. Please provide an individual disk offering.", + "vm.expunge.destroy.first": "Please destroy the Instance before expunging it.", + "vm.expunge.failed": "Failed to expunge Instance with specified ID.", + "vm.gethypervisortype.vm.not.found": "Unable to find Instance with specified ID.", + "vm.migrate.storage.vm.not.stopped": "Instance is not Stopped. Unable to perform storage migration.", + "vm.migrate.vm.not.running": "Instance is not Running. Unable to migrate the Instance.", + "vm.migrate.storage.vm.not.running": "Instance is not Running. Unable to migrate the Instance with storage.", + "vm.assign.network.not.found": "Unable to find network with specified ID.", + "vm.restore.vm.not.found": "Unable to find Instance with specified ID.", + "vm.restore.template.iso.not.found": "Unable to find template or ISO for the specified volume and Instance." } diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 5366c408626f..b2314bb400c2 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -108,6 +108,7 @@ import org.apache.cloudstack.backup.dao.BackupDao; import org.apache.cloudstack.backup.dao.BackupScheduleDao; import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.context.ResponseMessageResolver; import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity; import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMNetworkMapDao; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -126,6 +127,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; +import org.apache.cloudstack.error.Exceptions; import org.apache.cloudstack.extension.ExtensionHelper; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.config.ConfigKey; @@ -869,24 +871,38 @@ public UserVm resetVMPassword(ResetVMPasswordCmd cmd, String password) throws Re // Do parameters input validation if (userVm == null) { - throw new InvalidParameterValueException("unable to find an Instance with id " + cmd.getId()); + throw Exceptions.invalidParameterValueException("vm.resetpassword.vm.not.found"); } _vmDao.loadDetails(userVm); VMTemplateVO template = _templateDao.findByIdIncludingRemoved(userVm.getTemplateId()); - if (template == null || !template.isEnablePassword()) { - throw new InvalidParameterValueException("Fail to reset password for the Instance, the Template is not password enabled"); + if (template == null) { + throw Exceptions.invalidParameterValueException("vm.resetpassword.template.not.found", Map.of( + "instance", userVm + )); + } + if (!template.isEnablePassword()) { + throw Exceptions.invalidParameterValueException("vm.resetpassword.template.not.passwordenabled", Map.of( + "instance", userVm, + "template", template + )); } - if (userVm.getState() == State.Error || userVm.getState() == State.Expunging) { + if (State.Error.equals(userVm.getState()) || State.Expunging.equals(userVm.getState())) { logger.error("vm is not in the right state: {}", userVm); - throw new InvalidParameterValueException(String.format("Vm %s is not in the right state", userVm)); + throw Exceptions.invalidParameterValueException("vm.resetpassword.vm.not.right.state", Map.of( + "instance", userVm, + "instanceState", userVm.getState() + )); } - if (userVm.getState() != State.Stopped) { + if (!State.Stopped.equals(userVm.getState())) { logger.error("vm is not in the right state: {}", userVm); - throw new InvalidParameterValueException(String.format("Vm %s should be stopped to do password reset", userVm)); + throw Exceptions.invalidParameterValueException("vm.resetpassword.vm.not.stopped", Map.of( + "instance", userVm, + "instanceState", userVm.getState() + )); } _accountMgr.checkAccess(caller, null, true, userVm); @@ -896,7 +912,8 @@ public UserVm resetVMPassword(ResetVMPasswordCmd cmd, String password) throws Re if (result) { userVm.setPassword(password); } else { - throw new CloudRuntimeException("Failed to reset password for the Instance "); + throw Exceptions.cloudRuntimeException( + "vm.resetpassword.failed", Map.of("instance", userVm)); } return userVm; @@ -926,7 +943,12 @@ private boolean resetVMPasswordInternal(Long vmId, String password) throws Resou UserDataServiceProvider element = _networkMgr.getPasswordResetProvider(defaultNetwork); if (element == null) { - throw new CloudRuntimeException("Can't find network element for " + Service.UserData.getName() + " provider needed for password reset"); + throw Exceptions.cloudRuntimeException( + "vm.resetpassword.network.service.not.found", Map.of( + "instance", vmInstance, + "network", defaultNetwork, + "networkService", Service.UserData.getName()) + ); } boolean result = element.savePassword(defaultNetwork, defaultNicProfile, vmProfile); @@ -974,16 +996,19 @@ public UserVm resetVMUserData(ResetVMUserDataCmd cmd) throws ResourceUnavailable UserVmVO userVm = _vmDao.findById(cmd.getId()); if (userVm == null) { - throw new InvalidParameterValueException("unable to find an Instance by id" + cmd.getId()); + throw Exceptions.invalidParameterValueException("vm.resetuserdata.vm.not.found"); } if (UserVmManager.SHAREDFSVM.equals(userVm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); + throw Exceptions.invalidParameterValueException("vm.resetuserdata.vm.sharedfs.operation.not.supported", Map.of( + "instance", userVm + )); } if (Hypervisor.HypervisorType.External.equals(userVm.getHypervisorType())) { logger.error("Reset VM userdata not supported for {} as it is {} hypervisor instance", userVm, Hypervisor.HypervisorType.External.name()); - throw new InvalidParameterValueException(String.format("Operation not supported for instance: %s", - userVm.getName())); + throw Exceptions.invalidParameterValueException("vm.resetuserdata.vm.operation.not.supported", Map.of( + "instance", userVm + )); } _accountMgr.checkAccess(caller, null, true, userVm); @@ -993,7 +1018,10 @@ public UserVm resetVMUserData(ResetVMUserDataCmd cmd) throws ResourceUnavailable if (userVm.getState() != State.Stopped) { logger.error("vm ({}) should be stopped to do UserData reset. current state: {}", userVm, userVm.getState()); - throw new InvalidParameterValueException(String.format("VM %s should be stopped to do UserData reset", userVm)); + throw Exceptions.invalidParameterValueException("vm.resetuserdata.vm.no.stopped", Map.of( + "instance", userVm, + "instanceState", userVm.getState() + )); } String userData = cmd.getUserData(); @@ -1025,31 +1053,40 @@ public UserVm resetVMSSHKey(ResetVMSSHKeyCmd cmd) throws ResourceUnavailableExce UserVmVO userVm = _vmDao.findById(cmd.getId()); if (userVm == null) { - throw new InvalidParameterValueException("unable to find an Instance by id" + cmd.getId()); + throw Exceptions.invalidParameterValueException("vm.resetsshkey.vm.not.found"); } if (UserVmManager.SHAREDFSVM.equals(userVm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); + throw Exceptions.invalidParameterValueException("vm.resetsshkey.vm.sharedfs.operation.not.supported", Map.of( + "instance", userVm + )); } if (Hypervisor.HypervisorType.External.equals(userVm.getHypervisorType())) { logger.error("Reset VM SSH key not supported for {} as it is {} hypervisor instance", userVm, Hypervisor.HypervisorType.External.name()); - throw new InvalidParameterValueException(String.format("Operation not supported for instance: %s", - userVm.getName())); + throw Exceptions.invalidParameterValueException("vm.resetsshkey.vm.operation.not.supported", Map.of( + "instance", userVm + )); } // Do parameters input validation if (userVm.getState() == State.Error || userVm.getState() == State.Expunging) { logger.error("vm ({}) is not in the right state: {}", userVm, userVm.getState()); - throw new InvalidParameterValueException("Vm with specified id is not in the right state"); + throw Exceptions.invalidParameterValueException("vm.resetsshkey.vm.not.right.state", Map.of( + "instance", userVm, + "instanceState", userVm.getState() + )); } if (userVm.getState() != State.Stopped) { logger.error(String.format("vm (%s) is not in the stopped state. current state: %s", userVm, userVm.getState())); - throw new InvalidParameterValueException("Vm " + userVm + " should be stopped to do SSH Key reset"); + throw Exceptions.invalidParameterValueException("vm.resetsshkey.vm.no.stopped", Map.of( + "instance", userVm, + "instanceState", userVm.getState() + )); } List names = cmd.getNames(); if (CollectionUtils.isEmpty(names)) { - throw new InvalidParameterValueException("'keypair' or 'keypairs' must be specified"); + throw Exceptions.invalidParameterValueException("vm.resetsshkey.key.not.specified"); } userVm = resetVMSSHKeyInternal(userVm, owner, names); @@ -1065,7 +1102,7 @@ private UserVmVO resetVMSSHKeyInternal(UserVmVO userVm, Account owner, List p.getPublicKey()).collect(Collectors.joining("\n")); keypairnames = String.join(",", names); @@ -1077,7 +1114,8 @@ private UserVmVO resetVMSSHKeyInternal(UserVmVO userVm, Account owner, List params = null; + Map params = null; if (enterSetup) { params = new HashMap(); params.put(VirtualMachineProfile.Param.BootIntoSetup, Boolean.TRUE); @@ -1234,14 +1298,16 @@ private UserVm rebootVirtualMachine(long userId, long vmId, boolean enterSetup, private UserVm forceRebootVirtualMachine(UserVmVO vm, long hostId, boolean enterSetup) { try { if (stopVirtualMachine(vm.getId(), false) != null) { - Map params = new HashMap<>(); + Map params = new HashMap<>(); if (enterSetup) { params.put(VirtualMachineProfile.Param.BootIntoSetup, Boolean.TRUE); } return startVirtualMachine(vm.getId(), null, null, hostId, params, null, false).first(); } } catch (CloudException e) { - throw new CloudRuntimeException(String.format("Unable to reboot the VM: %s", vm), e); + throw Exceptions.cloudRuntimeException("vm.forcereboot.failed", Map.of( + "instance", vm + ), e); } return null; } @@ -1261,10 +1327,11 @@ public UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) throws ResourceAllocationE //UserVmVO vmInstance = _vmDao.findById(vmId); VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId); if (vmInstance == null) { - throw new InvalidParameterValueException("unable to find an Instance with id " + vmId); + throw Exceptions.invalidParameterValueException("unable to find an Instance with id " + vmId); } else if (!(vmInstance.getState().equals(State.Stopped))) { - throw new InvalidParameterValueException("Unable to upgrade Instance " + vmInstance + " " + " in state " + vmInstance.getState() - + "; make sure the Instance is stopped"); + throw Exceptions.invalidParameterValueException("vm.upgrade.vm.not.right.state", + Map.of("instance", vmInstance, + "instanceState", vmInstance.getState())); } _accountMgr.checkAccess(caller, null, true, vmInstance); @@ -1313,56 +1380,70 @@ protected void addCurrentDetailValueToInstanceDetailsMapIfNewValueWasNotSpecifie private void validateOfferingMaxResource(ServiceOfferingVO offering) { - Integer maxCPUCores = ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES.value() == 0 ? Integer.MAX_VALUE: ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES.value(); + Integer maxCPUCores = ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES.value() == 0 ? Integer.MAX_VALUE : ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES.value(); if (offering.getCpu() > maxCPUCores) { - throw new InvalidParameterValueException("Invalid cpu cores value, please choose another service offering with cpu cores between 1 and " + maxCPUCores); + throw Exceptions.invalidParameterValueException("vm.validate.serviceoffering.invalid.cpu.cores", + Map.of("serviceOffering", offering, "maxCPUCores", maxCPUCores)); } - Integer maxRAMSize = ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_RAM_SIZE.value() == 0 ? Integer.MAX_VALUE: ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_RAM_SIZE.value(); + Integer maxRAMSize = ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_RAM_SIZE.value() == 0 ? Integer.MAX_VALUE : ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_RAM_SIZE.value(); if (offering.getRamSize() > maxRAMSize) { - throw new InvalidParameterValueException("Invalid memory value, please choose another service offering with memory between 32 and " + maxRAMSize + " MB"); + throw Exceptions.invalidParameterValueException("vm.validate.serviceoffering.invalid.memory", + Map.of("serviceOffering", offering, "maxMemory", maxRAMSize)); } } @Override public void validateCustomParameters(ServiceOfferingVO serviceOffering, Map customParameters) { if (MapUtils.isEmpty(customParameters) && serviceOffering.isDynamic()) { - throw new InvalidParameterValueException("Need to specify custom parameter values cpu, cpu speed and memory when using custom offering"); + throw Exceptions.invalidParameterValueException("vm.validate.serviceoffering.custom.params.missing", + Map.of("serviceOffering", serviceOffering)); } Map offeringDetails = serviceOfferingDetailsDao.listDetailsKeyPairs(serviceOffering.getId()); if (serviceOffering.getCpu() == null) { int minCPU = NumbersUtil.parseInt(offeringDetails.get(ApiConstants.MIN_CPU_NUMBER), 1); int maxCPU = NumbersUtil.parseInt(offeringDetails.get(ApiConstants.MAX_CPU_NUMBER), Integer.MAX_VALUE); int cpuNumber = NumbersUtil.parseInt(customParameters.get(UsageEventVO.DynamicParameters.cpuNumber.name()), -1); - int maxCPUCores = ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES.value() == 0 ? Integer.MAX_VALUE: ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES.value(); + int maxCPUCores = ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES.value() == 0 ? Integer.MAX_VALUE : ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES.value(); if (cpuNumber < minCPU || cpuNumber > maxCPU || cpuNumber > maxCPUCores) { - throw new InvalidParameterValueException(String.format("Invalid CPU cores value, specify a value between %d and %d", minCPU, Math.min(maxCPUCores, maxCPU))); + throw Exceptions.invalidParameterValueException("vm.validate.serviceoffering.invalid.params.cpu.cores", + Map.of("serviceOffering", serviceOffering, + "minCPUCores", minCPU, + "maxCPUCores", Math.min(maxCPUCores, maxCPU))); } } else if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuNumber.name())) { - throw new InvalidParameterValueException("The CPU cores of this offering id:" + serviceOffering.getUuid() - + " is not customizable. This is predefined in the Template."); + throw Exceptions.invalidParameterValueException("vm.validate.serviceoffering.cpu.cores.not.dynamic", + Map.of("serviceOffering", serviceOffering, + "cpuCores", serviceOffering.getCpu())); } if (serviceOffering.getSpeed() == null) { String cpuSpeed = customParameters.get(UsageEventVO.DynamicParameters.cpuSpeed.name()); if ((cpuSpeed == null) || (NumbersUtil.parseInt(cpuSpeed, -1) <= 0)) { - throw new InvalidParameterValueException("Invalid CPU speed value, specify a value between 1 and " + Integer.MAX_VALUE); + throw Exceptions.invalidParameterValueException("vm.validate.serviceoffering.invalid.params.cpu.speed", + Map.of("serviceOffering", serviceOffering, + "maxCPUSpeed", Integer.MAX_VALUE)); } } else if (!serviceOffering.isCustomCpuSpeedSupported() && customParameters.containsKey(UsageEventVO.DynamicParameters.cpuSpeed.name())) { - throw new InvalidParameterValueException(String.format("The CPU speed of this offering id:%s" - + " is not customizable. This is predefined as %d MHz.", - serviceOffering.getUuid(), serviceOffering.getSpeed())); + throw Exceptions.invalidParameterValueException("vm.validate.serviceoffering.cpu.speed.not.dynamic", + Map.of("serviceOffering", serviceOffering, + "cpuSpeed", serviceOffering.getSpeed())); } if (serviceOffering.getRamSize() == null) { int minMemory = NumbersUtil.parseInt(offeringDetails.get(ApiConstants.MIN_MEMORY), 32); int maxMemory = NumbersUtil.parseInt(offeringDetails.get(ApiConstants.MAX_MEMORY), Integer.MAX_VALUE); int memory = NumbersUtil.parseInt(customParameters.get(UsageEventVO.DynamicParameters.memory.name()), -1); - int maxRAMSize = ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_RAM_SIZE.value() == 0 ? Integer.MAX_VALUE: ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_RAM_SIZE.value(); + int maxRAMSize = ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_RAM_SIZE.value() == 0 ? Integer.MAX_VALUE : ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_RAM_SIZE.value(); if (memory < minMemory || memory > maxMemory || memory > maxRAMSize) { - throw new InvalidParameterValueException(String.format("Invalid memory value, specify a value between %d and %d", minMemory, Math.min(maxRAMSize, maxMemory))); + throw Exceptions.invalidParameterValueException("vm.validate.serviceoffering.invalid.params.memory", + Map.of("serviceOffering", serviceOffering, + "minMemory", minMemory, + "maxMemory", Math.min(maxRAMSize, maxMemory))); } } else if (customParameters.containsKey(UsageEventVO.DynamicParameters.memory.name())) { - throw new InvalidParameterValueException("The memory of this offering id:" + serviceOffering.getUuid() + " is not customizable. This is predefined in the Template."); + throw Exceptions.invalidParameterValueException("vm.validate.serviceoffering.memory.not.dynamic", + Map.of("serviceOffering", serviceOffering, + "memory", serviceOffering.getRamSize())); } } @@ -1372,7 +1453,9 @@ private UserVm upgradeStoppedVirtualMachine(Long vmId, Long svcOffId, Map 0l && newNewOfferingRootSizeInBytes < currentRootDiskOffering.getDiskSize()) { - throw new InvalidParameterValueException(String.format( - "Failed to resize Root volume. The new Service Offering [%s] has a smaller disk size [%d GB] than the current disk [%d GB].", - newRootDiskOffering, newNewOfferingRootSizeInGiB, currentRootDiskOfferingGiB)); + throw Exceptions.invalidParameterValueException("vm.resize.volume.new.offering.smaller", Map.of("newOffering", newRootDiskOffering, "newSize", newNewOfferingRootSizeInGiB, "currentSize", currentRootDiskOfferingGiB)); } return resizeVolumeCmd; } @@ -1470,24 +1551,27 @@ public UserVm addNicToVirtualMachine(AddNicToVMCmd cmd) throws InvalidParameterV UserVmVO vmInstance = _vmDao.findById(vmId); if (vmInstance == null) { - throw new InvalidParameterValueException("Unable to find an Instance with ID " + vmId); + throw Exceptions.invalidParameterValueException("vm.addnic.vm.not.found"); } // Check that Vm does not have VM Snapshots - if (_vmSnapshotDao.findByVm(vmId).size() > 0) { - throw new InvalidParameterValueException("NIC cannot be added to Instance with Instance Snapshots"); + if (!_vmSnapshotDao.findByVm(vmId).isEmpty()) { + throw Exceptions.invalidParameterValueException("vm.addnic.vm.having.snapshots", + Map.of("instance", vmInstance)); } NetworkVO network = _networkDao.findById(networkId); if (network == null) { - throw new InvalidParameterValueException("Unable to find a Network with ID " + networkId); + throw Exceptions.invalidParameterValueException("vm.addnic.network.not.found", + Map.of("instance", vmInstance)); } - if (UserVmManager.SHAREDFSVM.equals(vmInstance.getUserVmType()) && network.getGuestType() == Network.GuestType.Shared) { + if (UserVmManager.SHAREDFSVM.equals(vmInstance.getUserVmType()) && network.getGuestType() == Network.GuestType.Shared) { if ((network.getAclType() != ControlledEntity.ACLType.Account) || (network.getDomainId() != vmInstance.getDomainId()) || (network.getAccountId() != vmInstance.getAccountId())) { - throw new InvalidParameterValueException("Shared network which is not Account scoped and not belonging to the same account can not be added to a Shared FileSystem Instance"); + throw Exceptions.invalidParameterValueException("vm.addnic.network.sharedfs.account.scope", + Map.of("instance", vmInstance, "network", network)); } } @@ -1499,13 +1583,15 @@ public UserVm addNicToVirtualMachine(AddNicToVMCmd cmd) throws InvalidParameterV macAddress = validateOrReplaceMacAddress(macAddress, network); if (_nicDao.findByNetworkIdAndMacAddress(networkId, macAddress) != null) { - throw new CloudRuntimeException("A NIC with this MAC address exists for network: " + network.getUuid()); + throw Exceptions.cloudRuntimeException("vm.addnic.network.nic.mac.exists", + Map.of("instance", vmInstance, "network", network, "macAddress", macAddress)); } NicProfile profile = new NicProfile(ipAddress, null, macAddress); if (ipAddress != null) { if (!(NetUtils.isValidIp4(ipAddress) || NetUtils.isValidIp6(ipAddress))) { - throw new InvalidParameterValueException("Invalid format for IP address parameter: " + ipAddress); + throw Exceptions.cloudRuntimeException("vm.addnic.ip.invalid", + Map.of("instance", vmInstance, "network", network, "ipAddress", ipAddress)); } } @@ -1515,23 +1601,22 @@ public UserVm addNicToVirtualMachine(AddNicToVMCmd cmd) throws InvalidParameterV // Verify that zone is not Basic DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterId()); if (dc.getNetworkType() == DataCenter.NetworkType.Basic) { - throw new CloudRuntimeException(String.format("Zone %s, has a NetworkType of Basic. Can't add a new NIC to a Instance on a Basic Network", dc)); + throw Exceptions.cloudRuntimeException("vm.addnic.zone.basic.not.allowed", Map.of("zone", dc)); } //ensure network belongs in zone if (network.getDataCenterId() != vmInstance.getDataCenterId()) { - throw new CloudRuntimeException(String.format("%s is in zone: %s but %s is in zone: %s", - vmInstance, dc, network, dataCenterDao.findById(network.getDataCenterId()))); + throw Exceptions.cloudRuntimeException("vm.addnic.zone.mismatch", Map.of("instance", vmInstance, "instanceZone", dc, "network", network, "networkZone", dataCenterDao.findById(network.getDataCenterId()))); } - if (_networkModel.getNicInNetwork(vmInstance.getId(),network.getId()) != null) { + if (_networkModel.getNicInNetwork(vmInstance.getId(), network.getId()) != null) { logger.debug("Instance {} already in network {} going to add another NIC", vmInstance, network); } else { //* get all vms hostNames in the network List hostNames = _vmInstanceDao.listDistinctHostNames(network.getId()); //* verify that there are no duplicates if (hostNames.contains(vmInstance.getHostName())) { - throw new CloudRuntimeException("Network " + network.getName() + " already has an Instance with host name: " + vmInstance.getHostName()); + throw Exceptions.cloudRuntimeException("vm.addnic.hostname.duplicate", Map.of("network", network, "hostname", vmInstance.getHostName())); } } @@ -1546,17 +1631,17 @@ public UserVm addNicToVirtualMachine(AddNicToVMCmd cmd) throws InvalidParameterV _networkMgr.configureExtraDhcpOptions(network, guestNic.getId(), cmd.getDhcpOptionsMap()); cleanUp = false; } catch (ResourceUnavailableException e) { - throw new CloudRuntimeException("Unable to add NIC to " + vmInstance + ": " + e); + throw Exceptions.cloudRuntimeException("vm.addnic.resource.unavailable", Map.of("instance", vmInstance, "error", e.getMessage())); } catch (InsufficientCapacityException e) { - throw new CloudRuntimeException("Insufficient capacity when adding NIC to " + vmInstance + ": " + e); + throw Exceptions.cloudRuntimeException("vm.addnic.insufficient.capacity", Map.of("instance", vmInstance, "error", e.getMessage())); } catch (ConcurrentOperationException e) { - throw new CloudRuntimeException("Concurrent operations on adding NIC to " + vmInstance + ": " + e); + throw Exceptions.cloudRuntimeException("vm.addnic.concurrent.operation", Map.of("instance", vmInstance, "error", e.getMessage())); } finally { if (cleanUp) { try { _itMgr.removeVmFromNetwork(vmInstance, network, null); } catch (ResourceUnavailableException e) { - throw new CloudRuntimeException("Error while cleaning up NIC " + e); + throw Exceptions.cloudRuntimeException("vm.addnic.cleanup.failed", Map.of("error", e.getMessage())); } } } @@ -1584,7 +1669,7 @@ private void checkIfNetExistsForVM(VirtualMachine virtualMachine, Network networ List allNics = _nicDao.listByVmId(virtualMachine.getId()); for (NicVO nic : allNics) { if (nic.getNetworkId() == network.getId()) { - throw new CloudRuntimeException("A NIC already exists for VM:" + virtualMachine.getInstanceName() + " in network: " + network.getUuid()); + throw Exceptions.cloudRuntimeException("vm.addnic.already.exists", Map.of("instance", virtualMachine, "network", network)); } } } @@ -1597,7 +1682,7 @@ protected String validateOrReplaceMacAddress(String macAddress, NetworkVO networ try { macAddress = _networkModel.getNextAvailableMacAddressInNetwork(network.getId()); } catch (InsufficientAddressCapacityException e) { - throw new CloudRuntimeException(String.format("A MAC address cannot be generated for this NIC in the network [%s] ", network)); + throw Exceptions.cloudRuntimeException("vm.addnic.mac.generation.failed", Map.of("network", network)); } } return macAddress; @@ -1622,22 +1707,25 @@ public UserVm removeNicFromVirtualMachine(RemoveNicFromVMCmd cmd) throws Invalid UserVmVO vmInstance = _vmDao.findById(vmId); if (vmInstance == null) { - throw new InvalidParameterValueException("Unable to find an Instance with ID " + vmId); + throw Exceptions.invalidParameterValueException("vm.removenic.vm.not.found"); } // Check that Vm does not have VM Snapshots - if (_vmSnapshotDao.findByVm(vmId).size() > 0) { - throw new InvalidParameterValueException("NIC cannot be removed from Instance with Instance Snapshots"); + if (!_vmSnapshotDao.findByVm(vmId).isEmpty()) { + throw Exceptions.invalidParameterValueException("vm.removenic.vm.having.snapshots", + Map.of("instance", vmInstance)); } NicVO nic = _nicDao.findById(nicId); if (nic == null) { - throw new InvalidParameterValueException("Unable to find a NIC with ID " + nicId); + throw Exceptions.invalidParameterValueException("vm.removenic.nic.not.found", + Map.of("instance", vmInstance)); } NetworkVO network = _networkDao.findById(nic.getNetworkId()); if (network == null) { - throw new InvalidParameterValueException("Unable to find a Network with ID " + nic.getNetworkId()); + throw Exceptions.invalidParameterValueException("vm.removenic.network.not.found", + Map.of("nic", nic, "instance", vmInstance)); } // Perform permission check on VM @@ -1646,36 +1734,43 @@ public UserVm removeNicFromVirtualMachine(RemoveNicFromVMCmd cmd) throws Invalid // Verify that zone is not Basic DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterId()); if (dc.getNetworkType() == DataCenter.NetworkType.Basic) { - throw new InvalidParameterValueException(String.format("Zone %s, has a NetworkType of Basic. Can't remove a NIC from a VM on a Basic Network", dc)); + throw Exceptions.invalidParameterValueException("vm.removenic.zone.basic.not.allowed", + Map.of("zone", dc)); } // check to see if nic is attached to VM if (nic.getInstanceId() != vmId) { - throw new InvalidParameterValueException(nic + " is not a NIC on " + vmInstance); + throw Exceptions.invalidParameterValueException("vm.removenic.nic.not.attached", + Map.of("nic", nic, "instance", vmInstance)); } // don't delete default NIC on a user VM if (nic.isDefaultNic() && vmInstance.getType() == VirtualMachine.Type.User) { - throw new InvalidParameterValueException("Unable to remove NIC from " + vmInstance + " in " + network + ", NIC is default."); + throw Exceptions.invalidParameterValueException("vm.removenic.default.nic", + Map.of("nic", nic, "instance", vmInstance, "network", network)); } // if specified nic is associated with PF/LB/Static NAT - if (_rulesMgr.listAssociatedRulesForGuestNic(nic).size() > 0) { - throw new InvalidParameterValueException("Unable to remove NIC from " + vmInstance + " in " + network + ", NIC has associated Port forwarding or Load balancer or Static NAT rules."); + if (!_rulesMgr.listAssociatedRulesForGuestNic(nic).isEmpty()) { + throw Exceptions.invalidParameterValueException("vm.removenic.nic.with.rules", + Map.of("nic", nic, "instance", vmInstance, "network", network)); } boolean nicremoved = false; try { nicremoved = _itMgr.removeNicFromVm(vmInstance, nic); } catch (ResourceUnavailableException e) { - throw new CloudRuntimeException("Unable to remove " + network + " from " + vmInstance + ": " + e); + throw Exceptions.cloudRuntimeException("vm.removenic.resource.unavailable", + Map.of("nic", nic, "network", network, "instance", vmInstance, "error", e.getMessage())); } catch (ConcurrentOperationException e) { - throw new CloudRuntimeException("Concurrent operations on removing " + network + " from " + vmInstance + ": " + e); + throw Exceptions.cloudRuntimeException("vm.removenic.concurrent.operation", + Map.of("nic", nic, "network", network, "instance", vmInstance, "error", e.getMessage())); } if (!nicremoved) { - throw new CloudRuntimeException("Unable to remove " + network + " from " + vmInstance); + throw Exceptions.cloudRuntimeException("vm.removenic.failed", + Map.of("nic", nic, "network", network, "instance", vmInstance)); } logger.debug("Successful removal of " + network + " from " + vmInstance); @@ -1691,21 +1786,24 @@ public UserVm updateDefaultNicForVirtualMachine(UpdateDefaultNicForVMCmd cmd) th UserVmVO vmInstance = _vmDao.findById(vmId); if (vmInstance == null) { - throw new InvalidParameterValueException("Unable to find an Instance with ID " + vmId); + throw Exceptions.invalidParameterValueException("vm.updatenic.vm.not.found"); } // Check that Vm does not have VM Snapshots - if (_vmSnapshotDao.findByVm(vmId).size() > 0) { - throw new InvalidParameterValueException("NIC cannot be updated for Instance with Instance Snapshots"); + if (!_vmSnapshotDao.findByVm(vmId).isEmpty()) { + throw Exceptions.invalidParameterValueException("vm.updatenic.vm.having.snapshots", + Map.of("instance", vmInstance)); } NicVO nic = _nicDao.findById(nicId); if (nic == null) { - throw new InvalidParameterValueException("Unable to find a NIC with ID " + nicId); + throw Exceptions.invalidParameterValueException("vm.updatenic.nic.not.found", + Map.of("instance", vmInstance)); } NetworkVO network = _networkDao.findById(nic.getNetworkId()); if (network == null) { - throw new InvalidParameterValueException("Unable to find a Network with ID " + nic.getNetworkId()); + throw Exceptions.invalidParameterValueException("vm.updatenic.nic.network.not.found", + Map.of("nic", nic, "instance", vmInstance)); } // Perform permission check on VM @@ -1714,7 +1812,8 @@ public UserVm updateDefaultNicForVirtualMachine(UpdateDefaultNicForVMCmd cmd) th // Verify that zone is not Basic DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterId()); if (dc.getNetworkType() == DataCenter.NetworkType.Basic) { - throw new CloudRuntimeException(String.format("Zone %s, has a NetworkType of Basic. Can't change default NIC on a Basic Network", dc)); + throw Exceptions.cloudRuntimeException("vm.updatenic.zone.basic.not.allowed", + Map.of("zone", dc)); } // no need to check permissions for network, we'll enumerate the ones they already have access to @@ -1722,16 +1821,18 @@ public UserVm updateDefaultNicForVirtualMachine(UpdateDefaultNicForVMCmd cmd) th //check to see if nic is attached to VM if (nic.getInstanceId() != vmId) { - throw new InvalidParameterValueException(nic + " is not a NIC on " + vmInstance); + throw Exceptions.invalidParameterValueException("vm.updatenic.nic.not.attached", + Map.of("nic", nic, "instance", vmInstance)); } // if current default equals chosen new default, Throw an exception if (nic.isDefaultNic()) { - throw new CloudRuntimeException("refusing to set default NIC because chosen NIC is already the default"); + throw Exceptions.cloudRuntimeException("vm.updatenic.nic.already.default"); } //make sure the VM is Running or Stopped - if ((vmInstance.getState() != State.Running) && (vmInstance.getState() != State.Stopped)) { - throw new CloudRuntimeException("refusing to set default " + vmInstance + " is not Running or Stopped"); + if (!State.Running.equals(vmInstance.getState()) && !State.Stopped.equals(vmInstance.getState())) { + throw Exceptions.cloudRuntimeException("vm.updatenic.vm.not.running.or.stopped", + Map.of("nic", nic, "instance", vmInstance)); } NicProfile existing = null; @@ -1744,7 +1845,7 @@ public UserVm updateDefaultNicForVirtualMachine(UpdateDefaultNicForVMCmd cmd) th if (existing == null) { logger.warn("Failed to update default NIC, no NIC profile found for existing default Network"); - throw new CloudRuntimeException("Failed to find a NIC profile for the existing default Network. This is bad and probably means some sort of configuration corruption"); + throw Exceptions.cloudRuntimeException("vm.updatenic.nic.profile.not.found"); } Network oldDefaultNetwork = null; @@ -1775,9 +1876,9 @@ public UserVm updateDefaultNicForVirtualMachine(UpdateDefaultNicForVMCmd cmd) th newdefault = _networkModel.getDefaultNetworkForVm(vmId); if (newdefault.getId() == existingdefaultnet.getId()) { - throw new CloudRuntimeException("Setting a default nic failed, and we had no default nic, but we were able to set it back to the original"); + throw Exceptions.cloudRuntimeException("vm.updatenic.default.update.failed", Collections.emptyMap()); } - throw new CloudRuntimeException("Failed to change default nic to " + nic + " and now we have no default"); + throw Exceptions.cloudRuntimeException("vm.updatenic.default.no.default", Map.of("nic", nic)); } else if (newdefault.getId() == nic.getNetworkId()) { logger.debug("successfully set default network to " + network + " for " + vmInstance); String nicIdString = Long.toString(nic.getId()); @@ -1806,7 +1907,8 @@ public UserVm updateDefaultNicForVirtualMachine(UpdateDefaultNicForVMCmd cmd) th return _vmDao.findById(vmInstance.getId()); } - throw new CloudRuntimeException(String.format("something strange happened, new default network(%s) is not null, and is not equal to the network(%d) of the chosen nic", newdefault, nic.getNetworkId())); + throw Exceptions.cloudRuntimeException("vm.updatenic.default.unknown.error", + Map.of("newDefaultNetwork", newdefault, "networkId", nic.getNetworkId())); } @Override @@ -1818,35 +1920,35 @@ public UserVm updateNicIpForVirtualMachine(UpdateVmNicIpCmd cmd) { //check whether the nic belongs to user vm. NicVO nicVO = _nicDao.findById(nicId); if (nicVO == null) { - throw new InvalidParameterValueException("There is no nic for the " + nicId); + throw Exceptions.invalidParameterValueException("vm.updatenicip.nic.not.found"); } if (nicVO.getVmType() != VirtualMachine.Type.User) { - throw new InvalidParameterValueException("The nic is not belongs to user vm"); + throw Exceptions.invalidParameterValueException("vm.updatenicip.nic.not.user.vm", + Map.of("nic", nicVO)); } UserVm vm = _vmDao.findById(nicVO.getInstanceId()); if (vm == null) { - throw new InvalidParameterValueException("There is no vm with the nic"); + throw Exceptions.invalidParameterValueException("vm.updatenicip.vm.not.found"); } Network network = _networkDao.findById(nicVO.getNetworkId()); if (network == null) { - throw new InvalidParameterValueException("There is no network with the nic"); + throw Exceptions.invalidParameterValueException("vm.updatenicip.network.not.found"); } // Don't allow to update vm nic ip if network is not in Implemented/Setup/Allocated state if (!(network.getState() == Network.State.Allocated || network.getState() == Network.State.Implemented || network.getState() == Network.State.Setup)) { - throw new InvalidParameterValueException("Network is not in the right state to update vm nic ip. Correct states are: " + Network.State.Allocated + ", " + Network.State.Implemented + ", " - + Network.State.Setup); + throw Exceptions.invalidParameterValueException("vm.updatenicip.network.not.right.state", Map.of("allowedStates", Network.State.Allocated + ", " + Network.State.Implemented + ", " + Network.State.Setup)); } NetworkOfferingVO offering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId()); if (offering == null) { - throw new InvalidParameterValueException("There is no network offering with the network"); + throw Exceptions.invalidParameterValueException("vm.updatenicip.offering.not.found"); } if (!_networkModel.listNetworkOfferingServices(offering.getId()).isEmpty() && vm.getState() != State.Stopped) { - InvalidParameterValueException ex = new InvalidParameterValueException( - "VM is not Stopped, unable to update the vm nic having the specified id"); + InvalidParameterValueException ex = Exceptions.invalidParameterValueException( + "vm.updatenicip.vm.running"); ex.addProxyObject(vm.getUuid(), "vmId"); throw ex; } @@ -1859,16 +1961,16 @@ public UserVm updateNicIpForVirtualMachine(UpdateVmNicIpCmd cmd) { logger.debug("Calling the IP allocation ..."); DataCenter dc = _dcDao.findById(network.getDataCenterId()); if (dc == null) { - throw new InvalidParameterValueException("There is no dc with the NIC"); + throw Exceptions.invalidParameterValueException("vm.updatenicip.datacenter.not.found"); } if (dc.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Isolated) { try { ipaddr = _ipAddrMgr.allocateGuestIP(network, ipaddr); } catch (InsufficientAddressCapacityException e) { - throw new InvalidParameterValueException(String.format("Allocating IP to guest NIC %s failed, for insufficient address capacity", nicVO)); + throw Exceptions.invalidParameterValueException("vm.updatenicip.allocation.failed.capacity", Map.of("nic", nicVO)); } if (ipaddr == null) { - throw new InvalidParameterValueException(String.format("Allocating IP to guest NIC %s failed, please choose another IP", nicVO)); + throw Exceptions.invalidParameterValueException("vm.updatenicip.allocation.failed.choose.another", Map.of("nic", nicVO)); } if (nicVO.getIPv4Address() != null) { @@ -1877,21 +1979,21 @@ public UserVm updateNicIpForVirtualMachine(UpdateVmNicIpCmd cmd) { updatePortForwardingRulesVmIp(vm.getId(), network.getId(), nicVO.getIPv4Address(), ipaddr); } - } else if (dc.getNetworkType() == NetworkType.Basic || network.getGuestType() == Network.GuestType.Shared) { + } else if (dc.getNetworkType() == NetworkType.Basic || network.getGuestType() == Network.GuestType.Shared) { //handle the basic networks here //for basic zone, need to provide the podId to ensure proper ip alloation Long podId = null; if (dc.getNetworkType() == NetworkType.Basic) { podId = vm.getPodIdToDeployIn(); if (podId == null) { - throw new InvalidParameterValueException("Instance Pod ID is null in Basic zone; can't decide the range for IP allocation"); + throw Exceptions.invalidParameterValueException("vm.updatenicip.pod.id.null"); } } try { ipaddr = _ipAddrMgr.allocatePublicIpForGuestNic(network, podId, ipOwner, ipaddr); if (ipaddr == null) { - throw new InvalidParameterValueException("Allocating IP to guest NIC " + nicVO.getUuid() + " failed, please choose another IP"); + throw Exceptions.invalidParameterValueException("vm.updatenicip.allocation.failed.basic", Map.of("nicId", nicVO.getUuid())); } final IPAddressVO newIp = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), ipaddr); @@ -1914,7 +2016,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { return null; } } else { - throw new InvalidParameterValueException("UpdateVmNicIpCmd is not supported in L2 network"); + throw Exceptions.invalidParameterValueException("vm.updatenicip.not.supported.l2.network"); } logger.debug("Updating IPv4 address of NIC " + nicVO + " to " + ipaddr + "/" + nicVO.getIPv4Netmask() + " with gateway " + nicVO.getIPv4Gateway()); @@ -1969,19 +2071,18 @@ private void updatePortForwardingRulesVmIp(long vmId, long networkId, String old @Override @ActionEvent(eventType = EventTypes.EVENT_VM_UPGRADE, eventDescription = "Upgrading VM", async = true) public UserVm upgradeVirtualMachine(ScaleVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, - VirtualMachineMigrationException { + VirtualMachineMigrationException { Long vmId = cmd.getId(); Long newServiceOfferingId = cmd.getServiceOfferingId(); VirtualMachine vm = (VirtualMachine) this._entityMgr.findById(VirtualMachine.class, vmId); if (vm == null) { - throw new InvalidParameterValueException("Unable to find VM's UUID"); + throw Exceptions.invalidParameterValueException("vm.upgrade.vm.uuid.not.found"); } if (Hypervisor.HypervisorType.External.equals(vm.getHypervisorType())) { logger.error("Scale VM not supported for {} as it is {} hypervisor instance", vm, Hypervisor.HypervisorType.External.name()); - throw new InvalidParameterValueException(String.format("Operation not supported for instance: %s", - vm.getName())); + throw Exceptions.invalidParameterValueException("vm.upgrade.external.hypervisor.not.supported", Map.of("instance", vm)); } CallContext.current().setEventDetails("Vm Id: " + vm.getUuid()); @@ -1998,13 +2099,13 @@ public UserVm upgradeVirtualMachine(ScaleVMCmd cmd) throws ResourceUnavailableEx } return vmInstance; } else { - throw new CloudRuntimeException("Failed to scale the VM"); + throw Exceptions.cloudRuntimeException("vm.upgrade.failed"); } } @Override public boolean upgradeVirtualMachine(Long vmId, Long newServiceOfferingId, Map customParameters) throws ResourceUnavailableException, - ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException { + ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException { VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId); @@ -2038,7 +2139,7 @@ public boolean upgradeVirtualMachine(Long vmId, Long newServiceOfferingId, Map customParameters) throws ResourceUnavailableException, - ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException { + ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException { Account caller = CallContext.current().getCallingAccount(); VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId); @@ -2055,7 +2156,7 @@ private boolean upgradeRunningVirtualMachine(Long vmId, Long newServiceOfferingI if (!supportedHypervisorTypes.contains(vmHypervisorType)) { String message = String.format("Scaling the VM dynamically is not supported for VMs running on Hypervisor [%s].", vmInstance.getHypervisorType()); logger.info(message); - throw new InvalidParameterValueException(message); + throw Exceptions.invalidParameterValueException("vm.upgrade.hypervisor.not.supported", Map.of("hypervisorType", vmInstance.getHypervisorType())); } _accountMgr.checkAccess(caller, null, true, vmInstance); @@ -2073,7 +2174,7 @@ private boolean upgradeRunningVirtualMachine(Long vmId, Long newServiceOfferingI ServiceOfferingVO currentServiceOffering = serviceOfferingDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId()); if (newServiceOffering.isDynamicScalingEnabled() != currentServiceOffering.isDynamicScalingEnabled()) { - throw new InvalidParameterValueException("Unable to Scale VM: since dynamic scaling enabled flag is not same for new service offering and old service offering"); + throw Exceptions.invalidParameterValueException("vm.upgrade.dynamic.scaling.flag.mismatch"); } validateDiskOfferingChecks(currentServiceOffering, newServiceOffering); @@ -2090,16 +2191,15 @@ private boolean upgradeRunningVirtualMachine(Long vmId, Long newServiceOfferingI // Don't allow to scale when (Any of the new values less than current values) OR (All current and new values are same) if ((newSpeed < currentSpeed || newMemory < currentMemory || newCpu < currentCpu) || (newSpeed == currentSpeed && newMemory == currentMemory && newCpu == currentCpu)) { String message = String.format("While the VM is running, only scalling up it is supported. New service offering {\"memory\": %s, \"speed\": %s, \"cpu\": %s} should" - + " have at least one value (ram, speed or cpu) greater than the current values {\"memory\": %s, \"speed\": %s, \"cpu\": %s}.", newMemory, newSpeed, newCpu, - currentMemory, currentSpeed, currentCpu); - - throw new InvalidParameterValueException(message); + + " have at least one value (ram, speed or cpu) greater than the current values {\"memory\": %s, \"speed\": %s, \"cpu\": %s}.", newMemory, newSpeed, newCpu, + currentMemory, currentSpeed, currentCpu); + throw Exceptions.invalidParameterValueException("vm.scale.up.required", Map.of("newOffering", newServiceOffering, "currentOffering", currentServiceOffering)); } if (vmHypervisorType.equals(HypervisorType.KVM) && !currentServiceOffering.isDynamic()) { String message = String.format("Unable to live scale VM on KVM when current service offering is a \"Fixed Offering\". KVM needs the tag \"maxMemory\" to live scale and it is only configured when VM is deployed with a custom service offering and \"Dynamic Scalable\" is enabled."); logger.info(message); - throw new InvalidParameterValueException(message); + throw Exceptions.invalidParameterValueException("vm.scale.kvm.fixed.offering.not.supported"); } serviceOfferingDao.loadDetails(currentServiceOffering); @@ -2111,7 +2211,7 @@ private boolean upgradeRunningVirtualMachine(Long vmId, Long newServiceOfferingI String newVgpuType = newDetails.get("vgpuType"); if (currentVgpuType != null && (newVgpuType == null || !newVgpuType.equalsIgnoreCase(currentVgpuType))) { - throw new InvalidParameterValueException(String.format("Dynamic scaling of vGPU type is not supported. VM has vGPU Type: [%s].", currentVgpuType)); + throw Exceptions.invalidParameterValueException("vm.scale.vgpu.not.supported", Map.of("vgpuType", currentVgpuType)); } VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId()); @@ -2131,19 +2231,19 @@ private boolean upgradeRunningVirtualMachine(Long vmId, Long newServiceOfferingI // Check zone wide flag boolean enableDynamicallyScaleVm = EnableDynamicallyScaleVm.valueIn(vmInstance.getDataCenterId()); if (!enableDynamicallyScaleVm) { - throw new PermissionDeniedException("Dynamically scaling Instances is disabled for this zone, please contact your admin."); + throw Exceptions.permissionDeniedException("vm.scale.dynamic.scaling.disabled"); } // Check vm flag if (!vmInstance.isDynamicallyScalable()) { - throw new CloudRuntimeException(String.format("Unable to scale %s as it does not have tools to support dynamic scaling.", vmInstance)); + throw Exceptions.cloudRuntimeException("vm.scale.dynamic.scaling.not.supported", Map.of("instance", vmInstance)); } // Check disable threshold for cluster is not crossed HostVO host = _hostDao.findById(vmInstance.getHostId()); _hostDao.loadDetails(host); if (_capacityMgr.checkIfClusterCrossesThreshold(host.getClusterId(), cpuDiff, memoryDiff)) { - throw new CloudRuntimeException(String.format("Unable to scale %s due to insufficient resources.", vmInstance)); + throw Exceptions.cloudRuntimeException("vm.scale.insufficient.resources", Map.of("instance", vmInstance)); } while (retry-- != 0) { // It's != so that it can match -1. @@ -2200,11 +2300,11 @@ private boolean upgradeRunningVirtualMachine(Long vmId, Long newServiceOfferingI protected void validateDiskOfferingChecks(ServiceOfferingVO currentServiceOffering, ServiceOfferingVO newServiceOffering) { if (currentServiceOffering.getDiskOfferingStrictness() != newServiceOffering.getDiskOfferingStrictness()) { - throw new InvalidParameterValueException("Unable to Scale VM, since disk offering strictness flag is not same for new service offering and old service offering"); + throw Exceptions.invalidParameterValueException("vm.upgrade.disk.offering.strictness.mismatch"); } if (currentServiceOffering.getDiskOfferingStrictness() && !currentServiceOffering.getDiskOfferingId().equals(newServiceOffering.getDiskOfferingId())) { - throw new InvalidParameterValueException("Unable to Scale VM, since disk offering id associated with the old service offering is not same for new service offering"); + throw Exceptions.invalidParameterValueException("vm.upgrade.disk.offering.id.not.same"); } _volService.validateChangeDiskOfferingEncryptionType(currentServiceOffering.getDiskOfferingId(), newServiceOffering.getDiskOfferingId()); @@ -2223,7 +2323,7 @@ private void changeDiskOfferingForRootVolume(Long vmId, DiskOfferingVO newDiskOf for (final VolumeVO rootVolumeOfVm : vols) { DiskOfferingVO currentRootDiskOffering = _diskOfferingDao.findById(rootVolumeOfVm.getDiskOfferingId()); - Long rootDiskSize= null; + Long rootDiskSize = null; Long rootDiskSizeBytes = null; if (customParameters.containsKey(ApiConstants.ROOT_DISK_SIZE)) { rootDiskSize = Long.parseLong(customParameters.get(ApiConstants.ROOT_DISK_SIZE)); @@ -2263,16 +2363,16 @@ private void changeDiskOfferingForRootVolume(Long vmId, DiskOfferingVO newDiskOf } Volume result = _volumeService.changeDiskOfferingForVolume(changeOfferingForVolumeCmd); if (result == null) { - throw new CloudRuntimeException("Failed to change disk offering of the root volume"); + throw Exceptions.cloudRuntimeException("vm.scale.root.volume.change.failed"); } } else if (newDiskOffering.getDiskSize() > 0 && currentRootDiskOffering.getDiskSize() != newDiskOffering.getDiskSize()) { - throw new InvalidParameterValueException("Hypervisor " + hypervisorType + " does not support volume resize"); + throw Exceptions.invalidParameterValueException("vm.scale.hypervisor.simulator.root.resize.not.supported", Map.of("hypervisorType", hypervisorType)); } } } @Override - public HashMap getVolumeStatistics(long clusterId, String poolUuid, StoragePoolType poolType, int timeout) { + public HashMap getVolumeStatistics(long clusterId, String poolUuid, StoragePoolType poolType, int timeout) { List neighbors = _resourceMgr.listHostsInClusterByStatus(clusterId, Status.Up); StoragePoolVO storagePool = _storagePoolDao.findPoolByUUID(poolUuid); HashMap volumeStatsByUuid = new HashMap<>(); @@ -2300,14 +2400,14 @@ public HashMap getVolumeStatistics(long clusterId, Str answer = storageManager.getVolumeStats(storagePool, cmd); } else { if (timeout > 0) { - cmd.setWait(timeout/1000); + cmd.setWait(timeout / 1000); } answer = _agentMgr.easySend(neighbor.getId(), cmd); } if (answer != null && answer instanceof GetVolumeStatsAnswer) { - GetVolumeStatsAnswer volstats = (GetVolumeStatsAnswer)answer; + GetVolumeStatsAnswer volstats = (GetVolumeStatsAnswer) answer; if (volstats.getVolumeStats() != null) { volumeStatsByUuid.putAll(volstats.getVolumeStats()); } @@ -2338,29 +2438,29 @@ public UserVm recoverVirtualMachine(RecoverVMCmd cmd) throws ResourceAllocationE final UserVmVO vm = _vmDao.findById(vmId); if (vm == null) { - throw new InvalidParameterValueException("Unable to find an Instance with id " + vmId); + throw Exceptions.invalidParameterValueException("vm.recover.vm.not.found", Map.of("vmId", vmId)); } if (UserVmManager.SHAREDFSVM.equals(vm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); + throw Exceptions.invalidParameterValueException("vm.recover.sharedfs.not.supported"); } // When trying to expunge, permission is denied when the caller is not an admin and the AllowUserExpungeRecoverVm is false for the caller. if (!_accountMgr.isAdmin(userId) && !AllowUserExpungeRecoverVm.valueIn(userId)) { - throw new PermissionDeniedException("Recovering a vm can only be done by an Admin. Or when the allow.user.expunge.recover.vm key is set."); + throw Exceptions.permissionDeniedException("vm.recover.permission.denied"); } if (vm.getRemoved() != null) { if (logger.isDebugEnabled()) { logger.debug("Unable to find vm. vm is removed: {}", vm); } - throw new InvalidParameterValueException("Unable to find vm by id " + vm.getUuid()); + throw Exceptions.invalidParameterValueException("vm.recover.vm.removed", Map.of("vmUuid", vm.getUuid())); } if (vm.getState() != State.Destroyed) { if (logger.isDebugEnabled()) { logger.debug("vm {} is not in the Destroyed state. current sate: {}", vm, vm.getState()); } - throw new InvalidParameterValueException("Vm with id " + vm.getUuid() + " is not in the right state"); + throw Exceptions.invalidParameterValueException("vm.recover.vm.not.destroyed", Map.of("vmUuid", vm.getUuid())); } if (logger.isDebugEnabled()) { @@ -2368,13 +2468,14 @@ public UserVm recoverVirtualMachine(RecoverVMCmd cmd) throws ResourceAllocationE } Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { - @Override public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException { Account account = _accountDao.lockRow(vm.getAccountId(), true); // if the account is deleted, throw error if (account.getRemoved() != null) { - throw new CloudRuntimeException("Unable to recover Instance as the Account is deleted"); + throw Exceptions.cloudRuntimeException("vm.recover.account.deleted"); } // Get serviceOffering for Virtual Machine @@ -2394,10 +2495,10 @@ public UserVm recoverVirtualMachine(RecoverVMCmd cmd) throws ResourceAllocationE try { if (!_itMgr.stateTransitTo(vm, VirtualMachine.Event.RecoveryRequested, null)) { logger.debug("Unable to recover the vm {} because it is not in the correct state. current state: {}", vm, vm.getState()); - throw new InvalidParameterValueException(String.format("Unable to recover the vm %s because it is not in the correct state. current state: %s", vm, vm.getState())); + throw Exceptions.invalidParameterValueException("vm.recover.state.transition.failed", Map.of("instance", vm, "instanceState", vm.getState())); } } catch (NoTransitionException e) { - throw new InvalidParameterValueException(String.format("Unable to recover the vm %s because it is not in the correct state. current state: %s", vm, vm.getState())); + throw Exceptions.invalidParameterValueException("vm.recover.state.transition.failed", Map.of("instance", vm, "instanceState", vm.getState())); } // Recover the VM's disks @@ -2461,10 +2562,10 @@ public boolean configure(String name, Map params) throws Configu String vmIpWorkers = configs.get(VmIpFetchTaskWorkers.value()); int vmipwrks = NumbersUtil.parseInt(vmIpWorkers, 10); - _vmIpFetchExecutor = Executors.newScheduledThreadPool(vmipwrks, new NamedThreadFactory("UserVm-ipfetch")); + _vmIpFetchExecutor = Executors.newScheduledThreadPool(vmipwrks, new NamedThreadFactory("UserVm-ipfetch")); String aggregationRange = configs.get("usage.stats.job.aggregation.range"); - int _usageAggregationRange = NumbersUtil.parseInt(aggregationRange, 1440); + int _usageAggregationRange = NumbersUtil.parseInt(aggregationRange, 1440); int HOURLY_TIME = 60; final int DAILY_TIME = 60 * 24; if (_usageAggregationRange == DAILY_TIME) { @@ -2509,7 +2610,7 @@ private void loadVmDetailsInMapForExternalDhcpIp() { List networks = _networkDao.listByGuestType(Network.GuestType.Shared); networks.addAll(_networkDao.listByGuestType(Network.GuestType.L2)); - for (NetworkVO network: networks) { + for (NetworkVO network : networks) { if (GuestType.L2.equals(network.getGuestType()) || _networkModel.isSharedNetworkWithoutServices(network.getId())) { List nics = _nicDao.listByNetworkId(network.getId()); @@ -2826,7 +2927,7 @@ protected void runInContext() { protected void verifyVmLimits(UserVmVO vmInstance, Map details) { Account owner = _accountDao.findById(vmInstance.getAccountId()); if (owner == null) { - throw new InvalidParameterValueException("The owner of " + vmInstance + " does not exist: " + vmInstance.getAccountId()); + throw Exceptions.invalidParameterValueException("vm.update.owner.not.found", Map.of("instance", vmInstance)); } long newCpu = NumberUtils.toLong(details.get(VmDetailConstants.CPU_NUMBER)); @@ -2845,8 +2946,7 @@ protected void verifyVmLimits(UserVmVO vmInstance, Map details) } else { if (details.containsKey(VmDetailConstants.CPU_NUMBER) || details.containsKey(VmDetailConstants.MEMORY) || details.containsKey(VmDetailConstants.CPU_SPEED)) { - throw new InvalidParameterValueException("CPU number, Memory and CPU speed cannot be updated for a " + - "non-dynamic offering"); + throw Exceptions.invalidParameterValueException("vm.update.non.dynamic.cpu.memory.not.updatable"); } } if (VirtualMachineManager.ResourceCountRunningVMsonly.value()) { @@ -2900,7 +3000,7 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx UserVmVO userVm = _vmDao.findById(cmd.getId()); if (userVm != null && UserVmManager.SHAREDFSVM.equals(userVm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); + throw Exceptions.invalidParameterValueException("vm.update.sharedfs.not.supported"); } String userData = cmd.getUserData(); @@ -2933,7 +3033,7 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx List existingDetails = vmInstanceDetailsDao.listDetails(id); if (cleanupDetails) { if (template != null && template.isDeployAsIs()) { - throw new InvalidParameterValueException("Detail settings are read from OVA, it cannot be cleaned up by API call."); + throw Exceptions.invalidParameterValueException("vm.update.ova.details.cleanup.not.allowed"); } if (caller != null && caller.getType() == Account.Type.ADMIN) { for (final VMInstanceDetailVO detail : existingDetails) { @@ -2956,11 +3056,11 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx if (details.containsKey(VmDetailConstants.INSTANCE_LEASE_EXECUTION) || details.containsKey(VmDetailConstants.INSTANCE_LEASE_EXPIRY_DATE) || details.containsKey(VmDetailConstants.INSTANCE_LEASE_EXPIRY_ACTION)) { - throw new InvalidParameterValueException("lease parameters should not be included in details as key"); + throw Exceptions.invalidParameterValueException("vm.update.lease.params.in.details"); } if (details.containsKey("extraconfig")) { - throw new InvalidParameterValueException("'extraconfig' should not be included in details as key"); + throw Exceptions.invalidParameterValueException("vm.update.extraconfig.in.details"); } if (template != null && template.isDeployAsIs()) { @@ -2976,7 +3076,7 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx if (detailVO != null && ObjectUtils.allNotNull(detailVO.getValue(), details.get(detailKey)) && detailVO.getValue().equals(details.get(detailKey))) { continue; } - throw new InvalidParameterValueException("Detail settings are read from OVA, it cannot be changed by API call."); + throw Exceptions.invalidParameterValueException("vm.update.ova.details.change.not.allowed"); } } @@ -2986,13 +3086,13 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx // Ensure denied or read-only detail is not passed by non-root-admin user for (final String detailName : details.keySet()) { if (userDenyListedSettings.contains(detailName)) { - throw new InvalidParameterValueException("You're not allowed to add or edit the restricted setting: " + detailName); + throw Exceptions.invalidParameterValueException("vm.update.detail.restricted", Map.of("detailName", detailName)); } if (userReadOnlySettings.contains(detailName)) { - throw new InvalidParameterValueException("You're not allowed to add or edit the read-only setting: " + detailName); + throw Exceptions.invalidParameterValueException("vm.update.detail.readonly", Map.of("detailName", detailName)); } if (existingDetails.stream().anyMatch(d -> Objects.equals(d.getName(), detailName) && !d.isDisplay())) { - throw new InvalidParameterValueException("You're not allowed to add or edit the non-displayable setting: " + detailName); + throw Exceptions.invalidParameterValueException("vm.update.detail.nondisplayable", Map.of("detailName", detailName)); } } // Add any existing user denied or read-only details. We do it here because admins would already provide these (or can delete them). @@ -3019,7 +3119,7 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx logger.info("Adding extra configuration to user vm: " + vmInstance.getUuid()); addExtraConfig(vmInstance, extraConfig); } else { - throw new InvalidParameterValueException("attempted setting extraconfig but enable.additional.vm.configuration is disabled"); + throw Exceptions.invalidParameterValueException("vm.update.extraconfig.disabled"); } } } @@ -3070,7 +3170,7 @@ protected void updateDisplayVmFlag(Boolean isDisplayVm, Long id, UserVmVO vmInst protected void validateInputsAndPermissionForUpdateVirtualMachineCommand(UpdateVMCmd cmd) { UserVmVO vmInstance = _vmDao.findById(cmd.getId()); if (vmInstance == null) { - throw new InvalidParameterValueException("unable to find virtual machine with id: " + cmd.getId()); + throw Exceptions.invalidParameterValueException("vm.update.vm.not.found"); } validateGuestOsIdForUpdateVirtualMachineCommand(cmd); Account caller = CallContext.current().getCallingAccount(); @@ -3082,7 +3182,7 @@ protected void validateGuestOsIdForUpdateVirtualMachineCommand(UpdateVMCmd cmd) if (osTypeId != null) { GuestOSVO guestOS = _guestOSDao.findById(osTypeId); if (guestOS == null) { - throw new InvalidParameterValueException("Please specify a valid guest OS ID."); + throw Exceptions.invalidParameterValueException("vm.update.guestos.not.found"); } } } @@ -3141,19 +3241,19 @@ public UserVm updateVirtualMachine(long id, String displayName, String group, Bo ) throws ResourceUnavailableException, InsufficientCapacityException { UserVmVO vm = _vmDao.findById(id); if (vm == null) { - throw new CloudRuntimeException("Unable to find virtual machine with id " + id); + throw Exceptions.cloudRuntimeException("vm.update.vm.not.found"); } if (instanceName != null) { VMInstanceVO vmInstance = _vmInstanceDao.findVMByInstanceName(instanceName); if (vmInstance != null && vmInstance.getId() != id) { - throw new CloudRuntimeException("Instance name : " + instanceName + " is not unique"); + throw Exceptions.cloudRuntimeException("vm.update.instance.name.not.unique", Map.of("instanceName", instanceName)); } } if (vm.getState() == State.Error || vm.getState() == State.Expunging) { logger.error("vm {} is not in the correct state. current state: {}", vm, vm.getState()); - throw new InvalidParameterValueException(String.format("Vm %s is not in the right state", vm)); + throw Exceptions.invalidParameterValueException("vm.update.vm.not.right.state", Map.of("instance", vm)); } if (displayName == null) { @@ -3166,7 +3266,7 @@ public UserVm updateVirtualMachine(long id, String displayName, String group, Bo ServiceOffering offering = serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId()); if (!offering.isOfferHA() && ha) { - throw new InvalidParameterValueException("Can't enable ha for the vm as it's created from the Service offering having HA disabled"); + throw Exceptions.invalidParameterValueException("vm.update.ha.offering.disabled"); } if (isDisplayVmEnabled == null) { @@ -3210,14 +3310,14 @@ public UserVm updateVirtualMachine(long id, String displayName, String group, Bo if (isDynamicallyScalable == true) { VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId()); if (!template.isDynamicallyScalable()) { - throw new InvalidParameterValueException("Dynamic Scaling cannot be enabled for the Instance since its Template does not have dynamic scaling enabled"); + throw Exceptions.invalidParameterValueException("vm.update.dynamic.scaling.template.not.supported"); } if (!offering.isDynamicScalingEnabled()) { - throw new InvalidParameterValueException("Dynamic Scaling cannot be enabled for the Instance since its service offering does not have dynamic scaling enabled"); + throw Exceptions.invalidParameterValueException("vm.update.dynamic.scaling.offering.not.supported"); } if (!UserVmManager.EnableDynamicallyScaleVm.valueIn(vm.getDataCenterId())) { logger.debug("Dynamic Scaling cannot be enabled for the VM {} since the global setting enable.dynamic.scale.vm is set to false", vm); - throw new InvalidParameterValueException("Dynamic Scaling cannot be enabled for the VM since corresponding global setting is set to false"); + throw Exceptions.invalidParameterValueException("vm.update.dynamic.scaling.global.setting.disabled"); } } } @@ -3275,7 +3375,7 @@ private void checkAndUpdateSecurityGroupForVM(List securityGroupIdList, Us boolean isVMware = (vm.getHypervisorType() == HypervisorType.VMware); if (securityGroupIdList != null && isVMware) { - throw new InvalidParameterValueException("Security group feature is not supported for VMware hypervisor"); + throw Exceptions.invalidParameterValueException("vm.update.securitygroup.vmware.not.supported"); } else if (securityGroupIdList != null) { DataCenterVO zone = _dcDao.findById(vm.getDataCenterId()); List networkIds = new ArrayList<>(); @@ -3309,7 +3409,7 @@ private void updateSecurityGroup(UserVmVO vm, List securityGroupIdList) { // Add instance in provided groups _securityGroupMgr.addInstanceToGroups(vm, securityGroupIdList); } else { - throw new InvalidParameterValueException(String.format("VM %s must be stopped prior to update security groups", vm.getUuid())); + throw Exceptions.invalidParameterValueException("vm.update.securitygroup.vm.not.stopped", Map.of("instance", vm)); } } @@ -3318,7 +3418,7 @@ protected void updateUserData(UserVm vm) throws ResourceUnavailableException, In if (result) { logger.debug("User data successfully updated for vm id: {}", vm); } else { - throw new CloudRuntimeException("Failed to reset userdata for the virtual machine "); + throw Exceptions.cloudRuntimeException("vm.update.userdata.failed"); } } @@ -3337,17 +3437,17 @@ private void updateDns(UserVmVO vm, String hostName) throws ResourceUnavailableE Commands commands = new Commands(Command.OnError.Stop); commandSetupHelper.createDhcpEntryCommand(router, vm, nic, false, commands); if (!nwHelper.sendCommandsToRouter(router, commands)) { - throw new CloudRuntimeException(String.format("Unable to send commands to virtual router: %s", router.getHostId())); + throw Exceptions.cloudRuntimeException("vm.update.dns.router.send.failed", Map.of("router", router.getHostId())); } Answer answer = commands.getAnswer("dhcp"); if (answer == null || !answer.getResult()) { - throw new CloudRuntimeException("Failed to update hostname"); + throw Exceptions.cloudRuntimeException("vm.update.dns.hostname.update.failed"); } updateUserData(vm); } } } catch (CloudRuntimeException e) { - throw new CloudRuntimeException(String.format("Failed to update hostname of VM %s to %s", vm.getInstanceName(), vm.getHostName())); + throw Exceptions.cloudRuntimeException("vm.update.dns.hostname.failed", Map.of("instance", vm.getInstanceName(), "hostname", vm.getHostName())); } } } @@ -3377,7 +3477,7 @@ protected boolean applyUserData(HypervisorType hyperVisorType, UserVm vm, Nic ni if (_networkModel.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Service.UserData)) { UserDataServiceProvider element = _networkModel.getUserDataUpdateProvider(network); if (element == null) { - throw new CloudRuntimeException("Can't find network element for " + Service.UserData.getName() + " provider needed for UserData update"); + throw Exceptions.cloudRuntimeException("vm.update.userdata.network.element.not.found"); } boolean result = element.saveUserData(network, nicProfile, vmProfile); if (!result) { @@ -3435,12 +3535,11 @@ public UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityE // Verify input parameters UserVmVO vmInstance = _vmDao.findById(vmId); if (vmInstance == null) { - throw new InvalidParameterValueException("Unable to find a Instance with ID " + vmId); + throw Exceptions.invalidParameterValueException("vm.reboot.vm.not.found"); } if (vmInstance.getState() != State.Running) { - throw new InvalidParameterValueException(String.format("The Instance %s (%s) is not running, unable to reboot it", - vmInstance.getUuid(), vmInstance.getDisplayNameOrHostName())); + throw Exceptions.invalidParameterValueException("vm.reboot.vm.not.running", Map.of("instance", vmInstance)); } _accountMgr.checkAccess(caller, null, true, vmInstance); @@ -3455,12 +3554,12 @@ public UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityE return restoreVMInternal(caller, vmInstance); } } else { - throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId + " corresponding to the Instance"); + throw Exceptions.invalidParameterValueException("vm.reboot.serviceoffering.not.found"); } Boolean enterSetup = cmd.getBootIntoSetup(); if (enterSetup != null && enterSetup && !HypervisorType.VMware.equals(vmInstance.getHypervisorType())) { - throw new InvalidParameterValueException("Booting into a hardware setup menu is not implemented on " + vmInstance.getHypervisorType()); + throw Exceptions.invalidParameterValueException("vm.reboot.setup.menu.hypervisor.not.supported", Map.of("hypervisorType", vmInstance.getHypervisorType())); } UserVm userVm = rebootVirtualMachine(CallContext.current().getCallingUserId(), vmId, enterSetup == null ? false : cmd.getBootIntoSetup(), cmd.isForced()); @@ -3491,13 +3590,13 @@ protected void checkExpungeVmPermission (Account callingAccount) { logger.debug(String.format("Checking if [%s] has permission for expunging VMs.", callingAccount)); if (!_accountMgr.isAdmin(callingAccount.getId()) && !getConfigAllowUserExpungeRecoverVm(callingAccount.getId())) { logger.error(String.format("Parameter [%s] can only be passed by Admin accounts or when the allow.user.expunge.recover.vm key is true.", ApiConstants.EXPUNGE)); - throw new PermissionDeniedException("Account does not have permission for expunging."); + throw Exceptions.permissionDeniedException("vm.expunge.permission.denied"); } try { _accountMgr.checkApiAccess(callingAccount, BaseCmd.getCommandNameByClass(ExpungeVMCmd.class)); } catch (PermissionDeniedException ex) { logger.error(String.format("Role [%s] of [%s] does not have permission for expunging VMs.", callingAccount.getRoleId(), callingAccount)); - throw new PermissionDeniedException("Account does not have permission for expunging."); + throw Exceptions.permissionDeniedException("vm.expunge.permission.denied"); } } @@ -3526,10 +3625,10 @@ public UserVm destroyVm(DestroyVMCmd cmd) throws ResourceUnavailableException, C UserVmVO vm = _vmDao.findById(vmId); if (vm == null || vm.getRemoved() != null) { - throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId); + throw Exceptions.invalidParameterValueException("vm.destroy.vm.not.found"); } if (UserVmManager.SHAREDFSVM.equals(vm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); + throw Exceptions.invalidParameterValueException("vm.destroy.sharedfs.not.supported"); } if (Arrays.asList(State.Destroyed, State.Expunging).contains(vm.getState()) && !expunge) { @@ -3538,9 +3637,7 @@ public UserVm destroyVm(DestroyVMCmd cmd) throws ResourceUnavailableException, C } if (vm.isDeleteProtection()) { - throw new InvalidParameterValueException(String.format( - "Instance [id = %s, name = %s] has delete protection enabled and cannot be deleted.", - vm.getUuid(), vm.getName())); + throw Exceptions.invalidParameterValueException("vm.destroy.delete.protection.enabled", Map.of("instance", vm)); } // check if vm belongs to AutoScale vm group in Disabled state @@ -3552,7 +3649,7 @@ public UserVm destroyVm(DestroyVMCmd cmd) throws ResourceUnavailableException, C // check if there are active volume snapshots tasks logger.debug("Checking if there are any ongoing Snapshots on the ROOT volumes associated with Instance {}", vm); if (checkStatusOfVolumeSnapshots(vm, Volume.Type.ROOT)) { - throw new CloudRuntimeException("There is/are unbacked up Snapshot(s) on ROOT volume, Instance destroy is not permitted, please try again later."); + throw Exceptions.cloudRuntimeException("vm.destroy.unbacked.snapshots"); } logger.debug("Found no ongoing Snapshots on volume of type ROOT, for the Instance {}", vm); @@ -3586,7 +3683,7 @@ public UserVm destroyVm(DestroyVMCmd cmd) throws ResourceUnavailableException, C } if (!expunged) { transitionExpungingToError(vm.getId()); - throw new CloudRuntimeException("Failed to expunge VM " + vm.getUuid() + (StringUtils.isNotBlank(errorMsg) ? " due to: " + errorMsg : "")); + throw Exceptions.cloudRuntimeException("vm.destroy.expunge.failed", Map.of("instance", vm)); } } @@ -3613,7 +3710,7 @@ private List getVolumesFromIds(DestroyVMCmd cmd) { VolumeVO vol = _volsDao.findById(volId); if (vol == null) { - throw new InvalidParameterValueException("Unable to find volume with ID: " + volId); + throw Exceptions.invalidParameterValueException("vm.destroy.volume.not.found"); } volumes.add(vol); } @@ -3637,7 +3734,7 @@ public InstanceGroupVO createVmGroup(CreateVMGroupCmd cmd) { boolean isNameInUse = _vmGroupDao.isNameInUse(accountId, groupName); if (isNameInUse) { - throw new InvalidParameterValueException(String.format("Unable to create Instance group, a group with name %s already exists for Account %s", groupName, owner)); + throw Exceptions.invalidParameterValueException("vm.group.create.name.exists", Map.of("groupName", groupName, "account", owner)); } return createVmGroup(groupName, accountId); @@ -3678,7 +3775,7 @@ public boolean deleteVmGroup(DeleteVMGroupCmd cmd) { // Verify input parameters InstanceGroupVO group = _vmGroupDao.findById(groupId); if ((group == null) || (group.getRemoved() != null)) { - throw new InvalidParameterValueException("unable to find a vm group with id " + groupId); + throw Exceptions.invalidParameterValueException("vm.group.delete.not.found"); } _accountMgr.checkAccess(caller, null, true, group); @@ -3731,7 +3828,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { InstanceGroupVO ngrpLock = _vmGroupDao.lockRow(groupFinal.getId(), false); if (ngrpLock == null) { logger.warn("Failed to acquire lock on Instance group {}", groupFinal); - throw new CloudRuntimeException(String.format("Failed to acquire lock on Instance group %s", groupFinal)); + throw Exceptions.cloudRuntimeException("vm.group.add.lock.failed", Map.of("group", groupFinal)); } // Currently don't allow to assign a vm to more than one group @@ -3828,7 +3925,7 @@ public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOff Network defaultNetwork = _networkModel.getExclusiveGuestNetwork(zone.getId()); if (defaultNetwork == null) { - throw new InvalidParameterValueException("Unable to find a default network to start a vm"); + throw Exceptions.invalidParameterValueException("vm.deploy.basic.network.not.found"); } else { networkList.add(_networkDao.findById(defaultNetwork.getId())); } @@ -3836,7 +3933,7 @@ public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOff boolean isVmWare = (template.getHypervisorType() == HypervisorType.VMware || (hypervisor != null && hypervisor == HypervisorType.VMware)); if (securityGroupIdList != null && isVmWare) { - throw new InvalidParameterValueException("Security group feature is not supported for VMware hypervisor"); + throw Exceptions.invalidParameterValueException("vm.deploy.securitygroup.vmware.not.supported"); } else if (!isVmWare && _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork) && _networkModel.canAddDefaultSecurityGroup()) { //add the default securityGroup only if no security group is specified if (securityGroupIdList == null || securityGroupIdList.isEmpty()) { @@ -3888,7 +3985,7 @@ public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, Service if (networkIdList == null || networkIdList.isEmpty()) { Network networkWithSecurityGroup = _networkModel.getNetworkWithSGWithFreeIPs(owner, zone.getId()); if (networkWithSecurityGroup == null) { - throw new InvalidParameterValueException("No network with security enabled is found in zone id=" + zone.getUuid()); + throw Exceptions.invalidParameterValueException("vm.deploy.sg.network.not.found", Map.of("zone", zone)); } networkList.add(_networkDao.findById(networkWithSecurityGroup.getId())); @@ -3896,11 +3993,11 @@ public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, Service } else if (securityGroupIdList != null && !securityGroupIdList.isEmpty()) { if (isVmWare) { - throw new InvalidParameterValueException("Security group feature is not supported for VMware hypervisor"); + throw Exceptions.invalidParameterValueException("vm.deploy.securitygroup.vmware.not.supported"); } // Only one network can be specified, and it should be security group enabled if (networkIdList.size() > 1 && template.getHypervisorType() != HypervisorType.KVM && hypervisor != HypervisorType.KVM) { - throw new InvalidParameterValueException("Only support one network per VM if security group enabled"); + throw Exceptions.invalidParameterValueException("vm.deploy.sg.multiple.networks.not.supported"); } for (Long networkId : networkIdList) { @@ -3908,11 +4005,11 @@ public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, Service NetworkOffering ntwkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId()); if (network == null) { - throw new InvalidParameterValueException("Unable to find network by id " + networkId); + throw Exceptions.invalidParameterValueException("vm.deploy.network.not.found"); } if (!_networkModel.isSecurityGroupSupportedInNetwork(network) && (ntwkOffering.getGuestType() != GuestType.L2)) { - throw new InvalidParameterValueException(String.format("Network is not security group enabled or not L2 network: %s", network)); + throw Exceptions.invalidParameterValueException("vm.deploy.sg.network.not.sg.enabled", Map.of("network", network)); } _accountMgr.checkAccess(owner, AccessType.UseEntry, false, network); @@ -3927,7 +4024,7 @@ public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, Service NetworkVO network = _networkDao.findById(networkId); if (network == null) { - throw new InvalidParameterValueException("Unable to find network by id " + networkIdList.get(0).longValue()); + throw Exceptions.invalidParameterValueException("vm.deploy.network.not.found"); } boolean isSecurityGroupEnabled = _networkModel.isSecurityGroupSupportedInNetwork(network); @@ -3936,7 +4033,7 @@ public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, Service } if (network.getTrafficType() != TrafficType.Guest || !Arrays.asList(GuestType.Shared, GuestType.L2).contains(network.getGuestType())) { - throw new InvalidParameterValueException("Can specify only Shared or L2 Guest networks when deploy vm in Advance Security Group enabled zone"); + throw Exceptions.invalidParameterValueException("vm.deploy.sg.advanced.network.type.invalid"); } _accountMgr.checkAccess(owner, AccessType.UseEntry, false, network); @@ -4007,17 +4104,17 @@ public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serv for (Long networkId : networkIdList) { NetworkVO network = _networkDao.findById(networkId); if (network == null) { - throw new InvalidParameterValueException("Unable to find network by id " + networkIdList.get(0).longValue()); + throw Exceptions.invalidParameterValueException("vm.deploy.network.not.found"); } if (network.getVpcId() != null) { // Only ISOs, XenServer, KVM, and VmWare template types are // supported for vpc networks if (template.getFormat() != ImageFormat.ISO && !vpcSupportedHTypes.contains(template.getHypervisorType())) { - throw new InvalidParameterValueException("Can't create Instance from Template with hypervisor " + template.getHypervisorType() + " in VPC Network " + network); + throw Exceptions.invalidParameterValueException("vm.deploy.advanced.vpc.template.hypervisor.not.supported", Map.of("hypervisorType", template.getHypervisorType(), "network", network)); } else if (template.getFormat() == ImageFormat.ISO && !vpcSupportedHTypes.contains(hypervisor)) { // Only XenServer, KVM, and VMware hypervisors are supported // for vpc networks - throw new InvalidParameterValueException("Can't create Instance of hypervisor type " + hypervisor + " in VPC Network"); + throw Exceptions.invalidParameterValueException("vm.deploy.advanced.vpc.hypervisor.not.supported", Map.of("hypervisorType", hypervisor)); } } @@ -4027,7 +4124,7 @@ public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serv // don't allow to use system networks NetworkOffering networkOffering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId()); if (networkOffering.isSystemOnly()) { - throw new InvalidParameterValueException(String.format("Network id=%s is system only and can't be used for vm deployment", network.getUuid())); + throw Exceptions.invalidParameterValueException("vm.deploy.network.system.only", Map.of("network", network)); } networkList.add(network); } @@ -4061,11 +4158,11 @@ private NetworkVO getNetworkToAddToNetworkList(VirtualMachineTemplate template, // Only ISOs, XenServer, KVM, and VmWare template types are // supported for vpc networks if (template.getFormat() != ImageFormat.ISO && !vpcSupportedHTypes.contains(template.getHypervisorType())) { - throw new InvalidParameterValueException("Can't create Instance from Template with hypervisor " + template.getHypervisorType() + " in VPC Network " + network); + throw Exceptions.invalidParameterValueException("vm.deploy.advanced.vpc.template.hypervisor.not.supported", Map.of("hypervisorType", template.getHypervisorType(), "network", network)); } else if (template.getFormat() == ImageFormat.ISO && !vpcSupportedHTypes.contains(hypervisor)) { // Only XenServer, KVM, and VMware hypervisors are supported // for vpc networks - throw new InvalidParameterValueException("Can't create Instance of hypervisor type " + hypervisor + " in VPC Network"); + throw Exceptions.invalidParameterValueException("vm.deploy.advanced.vpc.hypervisor.not.supported", Map.of("hypervisorType", hypervisor)); } } @@ -4074,7 +4171,7 @@ private NetworkVO getNetworkToAddToNetworkList(VirtualMachineTemplate template, // don't allow to use system networks NetworkOffering networkOffering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId()); if (networkOffering.isSystemOnly()) { - throw new InvalidParameterValueException(String.format("Network id=%s is system only and can't be used for vm deployment", network.getUuid())); + throw Exceptions.invalidParameterValueException("vm.deploy.network.system.only", Map.of("network", network)); } return network; } @@ -4100,17 +4197,17 @@ private NetworkVO getDefaultNetwork(DataCenter zone, Account owner, boolean sele // get Virtual networks List virtualNetworks = _networkModel.listNetworksForAccount(owner.getId(), zone.getId(), Network.GuestType.Isolated); if (virtualNetworks == null) { - throw new InvalidParameterValueException("No (virtual) networks are found for Account " + owner); + throw Exceptions.invalidParameterValueException("vm.deploy.network.none.found.for.account", Map.of("account", owner)); } if (virtualNetworks.isEmpty()) { defaultNetwork = createDefaultNetworkForAccount(zone, owner, requiredOfferings); } else if (virtualNetworks.size() > 1 && !selectAny) { - throw new InvalidParameterValueException("More than 1 default Isolated networks are found for Account " + owner + "; please specify networkIds"); + throw Exceptions.invalidParameterValueException("vm.deploy.network.multiple.default.found", Map.of("account", owner)); } else { defaultNetwork = _networkDao.findById(virtualNetworks.get(0).getId()); } } else { - throw new InvalidParameterValueException(String.format("Required network offering %s is not in %s", requiredOfferings.get(0), NetworkOffering.State.Enabled)); + throw Exceptions.invalidParameterValueException("vm.deploy.network.offering.required.not.enabled", Map.of("offering", requiredOfferings.get(0))); } return defaultNetwork; @@ -4148,7 +4245,7 @@ private void verifyExtraDhcpOptionsNetwork(Map> dhc } if (!networkFound) { - throw new InvalidParameterValueException("VM does not has a nic in the Network (" + networkUuid + ") that is specified in the extra dhcp options."); + throw Exceptions.invalidParameterValueException("vm.deploy.dhcp.options.network.no.nic", Map.of("network", networkUuid)); } } } @@ -4173,7 +4270,7 @@ private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffe _accountMgr.checkAccess(caller, null, true, owner); if (owner.getState() == Account.State.DISABLED) { - throw new PermissionDeniedException("The owner of vm to deploy is disabled: " + owner); + throw Exceptions.permissionDeniedException("vm.deploy.owner.disabled", Map.of("owner", owner)); } VMTemplateVO template = _templateDao.findByIdIncludingRemoved(tmplt.getId()); if (template != null) { @@ -4183,12 +4280,12 @@ private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffe HypervisorType hypervisorType = null; if (template.getHypervisorType() == null || template.getHypervisorType() == HypervisorType.None) { if (hypervisor == null || hypervisor == HypervisorType.None) { - throw new InvalidParameterValueException("Hypervisor parameter is needed to deploy VM or the hypervisor parameter value passed is invalid"); + throw Exceptions.invalidParameterValueException("vm.deploy.hypervisor.missing.or.invalid"); } hypervisorType = hypervisor; } else { if (hypervisor != null && hypervisor != HypervisorType.None && hypervisor != template.getHypervisorType()) { - throw new InvalidParameterValueException("Hypervisor passed to the deployVm call, is different from the hypervisor type of the Template"); + throw Exceptions.invalidParameterValueException("vm.deploy.hypervisor.mismatch"); } hypervisorType = template.getHypervisorType(); } @@ -4199,8 +4296,7 @@ private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffe if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) { - throw new PermissionDeniedException( - String.format("Cannot perform this operation, Zone is currently disabled: %s", zone)); + throw Exceptions.permissionDeniedException("vm.deploy.zone.disabled", Map.of("zone", zone)); } // check if zone is dedicated @@ -4208,7 +4304,7 @@ private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffe if (dedicatedZone != null) { DomainVO domain = _domainDao.findById(dedicatedZone.getDomainId()); if (domain == null) { - throw new CloudRuntimeException("Unable to find the domain " + zone.getDomainId() + " for the zone: " + zone); + throw Exceptions.cloudRuntimeException("vm.deploy.zone.domain.not.found", Map.of("zone", zone)); } // check that caller can operate with domain _configMgr.checkZoneAccess(caller, zone); @@ -4233,7 +4329,7 @@ private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffe if (diskOfferingId == null) { DiskOfferingVO diskOffering = _diskOfferingDao.findById(rootDiskOfferingId); if (diskOffering.isComputeOnly()) { - throw new InvalidParameterValueException("Installing from ISO requires a disk offering to be specified for the root disk."); + throw Exceptions.invalidParameterValueException("vm.deploy.iso.disk.offering.required"); } } else { rootDiskOfferingId = diskOfferingId; @@ -4251,7 +4347,7 @@ private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffe long volumesSize = configureCustomRootDiskSize(customParameters, template, hypervisorType, rootDiskOffering); if (rootDiskOffering.getEncrypt() && hypervisorType != HypervisorType.KVM) { - throw new InvalidParameterValueException("Root volume encryption is not supported for hypervisor type " + hypervisorType); + throw Exceptions.invalidParameterValueException("vm.deploy.root.encryption.hypervisor.not.supported", Map.of("hypervisorType", hypervisorType)); } UserVm vm = getCheckedUserVmResource(zone, hostName, displayName, owner, diskOfferingId, diskSize, dataDiskInfoList, networkList, securityGroupIdList, group, httpmethod, userData, userDataId, userDataDetails, sshKeyPairs, caller, requestedIps, defaultIps, isDisplayVm, keyboard, affinityGroupIdList, customParameters, customId, dhcpOptionMap, datadiskTemplateToDiskOfferringMap, userVmOVFPropertiesMap, dynamicScalingEnabled, vmType, template, hypervisorType, accountId, offering, isIso, rootDiskOfferingId, volumesSize, volume, snapshot); @@ -4351,7 +4447,7 @@ private UserVm getUncheckedUserVmResource(DataCenter zone, String hostName, Stri for (Long securityGroupId : securityGroupIdList) { SecurityGroup sg = _securityGroupDao.findById(securityGroupId); if (sg == null) { - throw new InvalidParameterValueException("Unable to find security group by id " + securityGroupId); + throw Exceptions.invalidParameterValueException("vm.deploy.security.group.not.found"); } else { // verify permissions _accountMgr.checkAccess(caller, null, true, owner, sg); @@ -4366,20 +4462,20 @@ private UserVm getUncheckedUserVmResource(DataCenter zone, String hostName, Stri if (dataDiskTemplate == null || (!dataDiskTemplate.getTemplateType().equals(TemplateType.DATADISK)) && (dataDiskTemplate.getState().equals(VirtualMachineTemplate.State.Active))) { - throw new InvalidParameterValueException("Invalid Template ID specified for Datadisk Template" + datadiskTemplateToDiskOffering.getKey()); + throw Exceptions.invalidParameterValueException("vm.deploy.datadisk.template.invalid"); } long dataDiskTemplateId = datadiskTemplateToDiskOffering.getKey(); if (!dataDiskTemplate.getParentTemplateId().equals(template.getId())) { - throw new InvalidParameterValueException(String.format("Invalid Datadisk Template. Specified Datadisk Template %s doesn't belong to Template %s", dataDiskTemplate, template)); + throw Exceptions.invalidParameterValueException("vm.deploy.datadisk.template.not.child", Map.of("dataDiskTemplate", dataDiskTemplate, "template", template)); } if (dataDiskOffering == null) { - throw new InvalidParameterValueException(String.format("Invalid disk offering %s specified for datadisk Template %s", datadiskTemplateToDiskOffering.getValue(), dataDiskTemplate)); + throw Exceptions.invalidParameterValueException("vm.deploy.datadisk.template.offering.invalid", Map.of("diskOffering", datadiskTemplateToDiskOffering.getValue(), "dataDiskTemplate", dataDiskTemplate)); } if (dataDiskOffering.isCustomized()) { - throw new InvalidParameterValueException(String.format("Invalid disk offering %s specified for datadisk Template %s. Custom Disk offerings are not supported for Datadisk Templates", dataDiskOffering, dataDiskTemplate)); + throw Exceptions.invalidParameterValueException("vm.deploy.datadisk.template.custom.offering.not.supported", Map.of("diskOffering", dataDiskOffering, "dataDiskTemplate", dataDiskTemplate)); } if (dataDiskOffering.getDiskSize() < dataDiskTemplate.getSize()) { - throw new InvalidParameterValueException(String.format("Invalid disk offering %s specified for datadisk Template %s. Disk offering size should be greater than or equal to the Template size", dataDiskOffering, dataDiskTemplate)); + throw Exceptions.invalidParameterValueException("vm.deploy.datadisk.template.offering.too.small", Map.of("diskOffering", dataDiskOffering, "dataDiskTemplate", dataDiskTemplate)); } _templateDao.loadDetails(dataDiskTemplate); } @@ -4390,10 +4486,9 @@ private UserVm getUncheckedUserVmResource(DataCenter zone, String hostName, Stri for (Long affinityGroupId : affinityGroupIdList) { AffinityGroupVO ag = _affinityGroupDao.findById(affinityGroupId); if (ag == null) { - throw new InvalidParameterValueException("Unable to find affinity group " + ag); + throw Exceptions.invalidParameterValueException("vm.deploy.affinity.group.not.found"); } else if (!_affinityGroupService.isAffinityGroupProcessorAvailable(ag.getType())) { - throw new InvalidParameterValueException("Affinity group type is not supported for group: " + ag + " ,type: " + ag.getType() - + " , Please try again after removing the affinity group"); + throw Exceptions.invalidParameterValueException("vm.deploy.affinity.group.type.not.supported", Map.of("group", ag, "groupType", ag.getType())); } else { // verify permissions if (ag.getAclType() == ACLType.Domain) { @@ -4403,7 +4498,7 @@ private UserVm getUncheckedUserVmResource(DataCenter zone, String hostName, Stri // make sure the owner of these entities is same if (caller.getId() == Account.ACCOUNT_ID_SYSTEM || _accountMgr.isRootAdmin(caller.getId())) { if (!_affinityGroupService.isAffinityGroupAvailableInDomain(ag.getId(), owner.getDomainId())) { - throw new PermissionDeniedException("Affinity Group " + ag + " does not belong to the VM's domain"); + throw Exceptions.permissionDeniedException("vm.deploy.affinity.group.domain.mismatch", Map.of("group", ag)); } } } else { @@ -4413,7 +4508,7 @@ private UserVm getUncheckedUserVmResource(DataCenter zone, String hostName, Stri // make sure the owner of these entities is same if (caller.getId() == Account.ACCOUNT_ID_SYSTEM || _accountMgr.isRootAdmin(caller.getId())) { if (ag.getAccountId() != owner.getAccountId()) { - throw new PermissionDeniedException("Affinity Group " + ag + " does not belong to the VM's account"); + throw Exceptions.permissionDeniedException("vm.deploy.affinity.group.account.mismatch", Map.of("group", ag)); } } } @@ -4430,27 +4525,27 @@ private UserVm getUncheckedUserVmResource(DataCenter zone, String hostName, Stri } if (TemplateType.SYSTEM.equals(template.getTemplateType()) && !CKS_NODE.equals(vmType) && !SHAREDFSVM.equals(vmType)) { - throw new InvalidParameterValueException(String.format("Unable to use system template %s to deploy a user vm", template)); + throw Exceptions.invalidParameterValueException("vm.deploy.system.template.not.allowed", Map.of("template", template)); } if (volume != null) { if (zone.getId() != volume.getDataCenterId()) { - throw new InvalidParameterValueException(String.format("The volume's zone [%s] is not the same as the provided zone [%s]", volume.getDataCenterId(), zone.getId())); + throw Exceptions.invalidParameterValueException("vm.deploy.volume.zone.mismatch", Map.of("volumeZone", volume.getDataCenterId(), "zone", zone.getId())); } } else if (snapshot != null) { List snapshotsOnZone = snapshotDataFactory.getSnapshots(snapshot.getId(), zone.getId()); if (CollectionUtils.isEmpty(snapshotsOnZone)) { - throw new InvalidParameterValueException("The snapshot does not exist on zone " + zone.getId()); + throw Exceptions.invalidParameterValueException("vm.deploy.snapshot.zone.mismatch", Map.of("zone", zone)); } } else { List listZoneTemplate = _templateZoneDao.listByZoneTemplate(zone.getId(), template.getId()); if (listZoneTemplate == null || listZoneTemplate.isEmpty()) { - throw new InvalidParameterValueException("The template " + template.getId() + " is not available for use"); + throw Exceptions.invalidParameterValueException("vm.deploy.template.not.available", Map.of("template", template)); } } if (isIso && !template.isBootable()) { - throw new InvalidParameterValueException(String.format("Installing from ISO requires an ISO that is bootable: %s", template)); + throw Exceptions.invalidParameterValueException("vm.deploy.iso.not.bootable", Map.of("iso", template)); } // Check templates permissions @@ -4466,7 +4561,7 @@ private UserVm getUncheckedUserVmResource(DataCenter zone, String hostName, Stri if (!sshKeyPairs.isEmpty()) { List pairs = _sshKeyPairDao.findByNames(owner.getAccountId(), owner.getDomainId(), sshKeyPairs); if (pairs == null || pairs.size() != sshKeyPairs.size()) { - throw new InvalidParameterValueException("Not all specified keypairs exist"); + throw Exceptions.invalidParameterValueException("vm.deploy.keypairs.not.found"); } sshPublicKeys = pairs.stream().map(p -> p.getPublicKey()).collect(Collectors.joining("\n")); @@ -4481,7 +4576,7 @@ private UserVm getUncheckedUserVmResource(DataCenter zone, String hostName, Stri for (NetworkVO network : networkList) { if ((network.getDataCenterId() != zone.getId())) { if (!network.isStrechedL2Network()) { - throw new InvalidParameterValueException(String.format("Network %s doesn't belong to zone %s", network, zone)); + throw Exceptions.invalidParameterValueException("vm.deploy.network.zone.mismatch", Map.of("network", network, "zone", zone)); } NetworkOffering ntwkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId()); @@ -4522,15 +4617,15 @@ private UserVm getUncheckedUserVmResource(DataCenter zone, String hostName, Stri profile.setDefaultNic(true); if (!_networkModel.areServicesSupportedInNetwork(network.getId(), new Service[]{Service.UserData})) { if ((userData != null) && (!userData.isEmpty())) { - throw new InvalidParameterValueException(String.format("Unable to deploy VM as UserData is provided while deploying the VM, but there is no support for %s service in the default network %s/%s.", Service.UserData.getName(), network.getName(), network.getUuid())); + throw Exceptions.invalidParameterValueException("vm.deploy.userdata.network.service.not.found", Map.of("network", network)); } if ((sshPublicKeys != null) && (!sshPublicKeys.isEmpty())) { - throw new InvalidParameterValueException(String.format("Unable to deploy VM as SSH keypair is provided while deploying the VM, but there is no support for %s service in the default network %s/%s", Service.UserData.getName(), network.getName(), network.getUuid())); + throw Exceptions.invalidParameterValueException("vm.deploy.sshkey.network.service.not.found", Map.of("network", network)); } if (template.isEnablePassword()) { - throw new InvalidParameterValueException(String.format("Unable to deploy VM as template %s is password enabled, but there is no support for %s service in the default network %s/%s", template, Service.UserData.getName(), network.getName(), network.getUuid())); + throw Exceptions.invalidParameterValueException("vm.deploy.template.password.network.service.not.found", Map.of("template", template, "network", network)); } } } @@ -4548,7 +4643,7 @@ private UserVm getUncheckedUserVmResource(DataCenter zone, String hostName, Stri } if (securityGroupIdList != null && !securityGroupIdList.isEmpty() && !securityGroupEnabled) { - throw new InvalidParameterValueException("Unable to deploy vm with security groups as SecurityGroup service is not enabled for the vm's network"); + throw Exceptions.invalidParameterValueException("vm.deploy.securitygroup.service.not.enabled"); } // Verify network information - network default network has to be set; @@ -4557,9 +4652,9 @@ private UserVm getUncheckedUserVmResource(DataCenter zone, String hostName, Stri // by Agent Manager in order to configure default // gateway for the vm if (defaultNetworkNumber == 0) { - throw new InvalidParameterValueException("At least 1 default network has to be specified for the vm"); + throw Exceptions.invalidParameterValueException("vm.deploy.default.network.missing"); } else if (defaultNetworkNumber > 1) { - throw new InvalidParameterValueException("Only 1 default network per vm is supported"); + throw Exceptions.invalidParameterValueException("vm.deploy.default.network.multiple"); } long id = _vmDao.getNextInSequence(Long.class, "id"); @@ -4587,7 +4682,7 @@ private UserVm getUncheckedUserVmResource(DataCenter zone, String hostName, Stri // In case of VMware since VM name must be unique within a DC, check if VM with the same hostname already exists in the zone. VMInstanceVO vmByHostName = _vmInstanceDao.findVMByHostNameInZone(hostName, zone.getId()); if (vmByHostName != null && vmByHostName.getState() != State.Expunging) { - throw new InvalidParameterValueException("There already exists a VM by the name: " + hostName + "."); + throw Exceptions.invalidParameterValueException("vm.deploy.hostname.exists", Map.of("hostname", hostName)); } } else { if (hostName == null) { @@ -4608,7 +4703,7 @@ private UserVm getUncheckedUserVmResource(DataCenter zone, String hostName, Stri // Check if VM with instanceName already exists. VMInstanceVO vmObj = _vmInstanceDao.findVMByInstanceName(instanceName); if (vmObj != null && vmObj.getState() != State.Expunging) { - throw new InvalidParameterValueException("There already exists a VM by the display name supplied"); + throw Exceptions.invalidParameterValueException("vm.deploy.displayname.exists"); } checkIfHostNameUniqueInNtwkDomain(hostName, networkList); @@ -4645,7 +4740,7 @@ private void assignInstanceToGroup(String group, long id) { if (group != null) { boolean addToGroup = addInstanceToGroup(Long.valueOf(id), group); if (!addToGroup) { - throw new CloudRuntimeException("Unable to assign Vm to the group " + group); + throw Exceptions.cloudRuntimeException("vm.deploy.group.assign.failed", Map.of("group", group)); } } } catch (Exception ex) { @@ -4656,11 +4751,11 @@ private void assignInstanceToGroup(String group, long id) { private long verifyAndGetDiskSize(DiskOffering diskOffering, Long diskSize) { long size = 0l; if (diskOffering == null) { - throw new InvalidParameterValueException("Specified disk offering cannot be found"); + throw Exceptions.invalidParameterValueException("vm.deploy.diskoffering.not.found"); } if (diskOffering.isCustomized() && !diskOffering.isComputeOnly()) { if (diskSize == null) { - throw new InvalidParameterValueException("This disk offering requires a custom size specified"); + throw Exceptions.invalidParameterValueException("vm.deploy.disk.offering.custom.size.required"); } _volumeService.validateCustomDiskOfferingSizeRange(diskSize); size = diskSize * GiB_TO_BYTES; @@ -4691,7 +4786,7 @@ protected long configureCustomRootDiskSize(Map customParameters, if (customParameters.containsKey(VmDetailConstants.ROOT_DISK_SIZE)) { rootDiskSizeCustomParam = NumbersUtil.parseLong(customParameters.get(VmDetailConstants.ROOT_DISK_SIZE), -1); if (rootDiskSizeCustomParam <= 0) { - throw new InvalidParameterValueException("Root disk size should be a positive number."); + throw Exceptions.invalidParameterValueException("vm.deploy.root.disk.size.not.positive"); } } long rootDiskSizeInBytes = verifyAndGetDiskSize(rootDiskOffering, rootDiskSizeCustomParam); @@ -4705,7 +4800,7 @@ protected long configureCustomRootDiskSize(Map customParameters, if (customParameters.containsKey(VmDetailConstants.ROOT_DISK_SIZE)) { long rootDiskSize = NumbersUtil.parseLong(customParameters.get(VmDetailConstants.ROOT_DISK_SIZE), -1); if (rootDiskSize <= 0) { - throw new InvalidParameterValueException("Root disk size should be a positive number."); + throw Exceptions.invalidParameterValueException("vm.deploy.root.disk.size.not.positive"); } rootDiskSize = rootDiskSizeCustomParam * GiB_TO_BYTES; _volumeService.validateVolumeSizeInBytes(rootDiskSize); @@ -4726,7 +4821,7 @@ protected long configureCustomRootDiskSize(Map customParameters, */ protected void verifyIfHypervisorSupportsRootdiskSizeOverride(HypervisorType hypervisorType) { if (!hypervisorType.isFunctionalitySupported(Functionality.RootDiskSizeOverride)) { - throw new InvalidParameterValueException("Hypervisor " + hypervisorType + " does not support rootdisksize override"); + throw Exceptions.invalidParameterValueException("vm.deploy.root.disk.size.override.not.supported", Map.of("hypervisorType", hypervisorType)); } } @@ -4804,8 +4899,7 @@ private void checkIfHostNameUniqueInNtwkDomain(String hostName, List List hostNames = _vmInstanceDao.listDistinctHostNames(ntwkId); // * verify that there are no duplicates if (hostNames.contains(hostName)) { - throw new InvalidParameterValueException("The vm with hostName " + hostName + " already exists in the network domain: " + ntwkDomain.getKey() + "; network=" - + ((_networkModel.getNetwork(ntwkId) != null) ? _networkModel.getNetwork(ntwkId).getName() : "")); + throw Exceptions.invalidParameterValueException("vm.deploy.hostname.network.domain.exists", Map.of("hostname", hostName)); } } } @@ -5120,14 +5214,14 @@ public void validateRootDiskResize(final HypervisorType hypervisorType, Long roo if ((rootDiskSize << 30) < templateVO.getSize()) { String error = String.format("Unsupported: rootdisksize override (%s GB) is smaller than template size %s", rootDiskSize, toHumanReadableSize(templateVO.getSize())); logger.error(error); - throw new InvalidParameterValueException(error); + throw Exceptions.invalidParameterValueException("vm.deploy.root.disk.size.smaller.than.template", Map.of("rootDiskSize", rootDiskSize)); } else if ((rootDiskSize << 30) > templateVO.getSize()) { if (hypervisorType == HypervisorType.VMware && (vm.getDetails() == null || vm.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER) == null)) { logger.warn("If Root disk controller parameter is not overridden, then Root disk resize may fail because current Root disk controller value is NULL."); } else if (hypervisorType == HypervisorType.VMware && vm.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER).toLowerCase().contains("ide") && !isIso) { String error = String.format("Found unsupported root disk controller [%s].", vm.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER)); logger.error(error); - throw new InvalidParameterValueException(error); + throw Exceptions.invalidParameterValueException("vm.deploy.root.disk.controller.invalid", Map.of("diskController", vm.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER))); } else { logger.debug("Rootdisksize override validation successful. Template root disk size " + toHumanReadableSize(templateVO.getSize()) + " Root disk size specified " + rootDiskSize + " GB"); } @@ -5632,7 +5726,7 @@ public void finalizeExpunge(VirtualMachine vm) { private void checkForceStopVmPermission(Account callingAccount) { if (!AllowUserForceStopVm.valueIn(callingAccount.getId())) { logger.error("Parameter [{}] can only be passed by Admin accounts or when the allow.user.force.stop.vm config is true for the account.", ApiConstants.FORCED); - throw new PermissionDeniedException("Account does not have the permission to force stop the vm."); + throw Exceptions.permissionDeniedException("vm.stop.force.permission.denied"); } } @@ -5645,12 +5739,12 @@ public UserVm stopVirtualMachine(long vmId, boolean forced) throws ConcurrentOpe // if account is removed, return error if (caller != null && caller.getRemoved() != null) { - throw new PermissionDeniedException("The account " + caller.getUuid() + " is removed"); + throw Exceptions.permissionDeniedException("vm.stop.account.removed"); } UserVmVO vm = _vmDao.findById(vmId); if (vm == null) { - throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId); + throw Exceptions.invalidParameterValueException("vm.stop.vm.not.found"); } if (forced) { @@ -5675,9 +5769,9 @@ public UserVm stopVirtualMachine(long vmId, boolean forced) throws ConcurrentOpe return null; } } catch (ResourceUnavailableException e) { - throw new CloudRuntimeException("Unable to contact the agent to stop the virtual machine " + vm, e); + throw Exceptions.cloudRuntimeException("vm.stop.agent.no.contact", Map.of("instance", vm), e); } catch (CloudException e) { - throw new CloudRuntimeException("Unable to contact the agent to stop the virtual machine " + vm, e); + throw Exceptions.cloudRuntimeException("vm.stop.agent.no.contact", Map.of("instance", vm), e); } } @@ -5768,7 +5862,7 @@ private Pair> startVirtualMac } logger.info(errorMsg); if (!AllowDeployVmIfGivenHostFails.value()) { - throw new InvalidParameterValueException(errorMsg); + throw Exceptions.invalidParameterValueException("vm.start.host.capacity.insufficient", Map.of("host", destinationHost)); } } else { plan = new DataCenterDeployment(vm.getDataCenterId(), destinationHost.getPodId(), destinationHost.getClusterId(), destinationHost.getId(), null, null); @@ -5796,7 +5890,7 @@ private Pair> startVirtualMac _vmDao.loadDetails(vm); String password = getCurrentVmPasswordOrDefineNewPassword(String.valueOf(additionalParams.getOrDefault(VirtualMachineProfile.Param.VmPassword, "")), vm, template); if (!validPassword(password)) { - throw new InvalidParameterValueException("A valid password for this virtual machine was not provided."); + throw Exceptions.invalidParameterValueException("vm.start.password.not.provided"); } // Check if an SSH key pair was selected for the instance and if so // use it to encrypt & save the vm password @@ -5806,7 +5900,7 @@ private Pair> startVirtualMac if (additionalParams.containsKey(VirtualMachineProfile.Param.BootIntoSetup)) { if (!HypervisorType.VMware.equals(vm.getHypervisorType())) { - throw new InvalidParameterValueException(ApiConstants.BOOT_INTO_SETUP + " makes no sense for " + vm.getHypervisorType()); + throw Exceptions.invalidParameterValueException("vm.start.setup.menu.hypervisor.not.applicable", Map.of("hypervisorType", vm.getHypervisorType())); } Object paramValue = additionalParams.get(VirtualMachineProfile.Param.BootIntoSetup); if (logger.isTraceEnabled()) { @@ -5823,7 +5917,7 @@ private Pair> startVirtualMac // the service offering planner = _planningMgr.getDeploymentPlannerByName(deploymentPlannerToUse); if (planner == null) { - throw new InvalidParameterValueException("Can't find a planner by name " + deploymentPlannerToUse); + throw Exceptions.invalidParameterValueException("vm.start.planner.not.found", Map.of("plannerName", deploymentPlannerToUse)); } } vmEntity.setParamsToEntity(additionalParams); @@ -5856,17 +5950,16 @@ public Pair> startVirtualMach // if account is removed, return error if (callerAccount == null || callerAccount.getRemoved() != null) { - throw new InvalidParameterValueException(String.format("The account %s is removed", callerAccount)); + throw Exceptions.invalidParameterValueException("vm.start.account.removed", Map.of("account", callerAccount)); } UserVmVO vm = _vmDao.findById(vmId); if (vm == null) { - throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId); + throw Exceptions.invalidParameterValueException("vm.start.vm.not.found"); } if (vm.getState() == State.Running) { - throw new InvalidParameterValueException(String.format("The virtual machine %s (%s) is already running", - vm.getUuid(), vm.getDisplayNameOrHostName())); + throw Exceptions.invalidParameterValueException("vm.start.vm.already.running", Map.of("instance", vm)); } _accountMgr.checkAccess(callerAccount, null, true, vm); @@ -5874,11 +5967,11 @@ public Pair> startVirtualMach Account owner = _accountDao.findById(vm.getAccountId()); if (owner == null) { - throw new InvalidParameterValueException("The owner of " + vm + " does not exist: " + vm.getAccountId()); + throw Exceptions.invalidParameterValueException("vm.start.owner.not.found", Map.of("instance", vm)); } if (owner.getState() == Account.State.DISABLED) { - throw new PermissionDeniedException(String.format("The owner of %s is disabled: %s", vm, owner)); + throw Exceptions.permissionDeniedException("vm.start.owner.disabled", Map.of("instance", vm)); } boolean isRootAdmin = _accountService.isRootAdmin(callerAccount.getId()); @@ -5952,12 +6045,11 @@ private Pod getDestinationPod(Long podId, boolean isRootAdmin) { Pod destinationPod = null; if (podId != null) { if (!isRootAdmin) { - throw new PermissionDeniedException( - "Parameter " + ApiConstants.POD_ID + " can only be specified by a Root Admin, permission denied"); + throw Exceptions.permissionDeniedException("vm.start.pod.root.admin.only"); } destinationPod = _podDao.findById(podId); if (destinationPod == null) { - throw new InvalidParameterValueException("Unable to find the pod to deploy the VM, pod id=" + podId); + throw Exceptions.invalidParameterValueException("vm.start.pod.not.found"); } } return destinationPod; @@ -5967,12 +6059,11 @@ private Cluster getDestinationCluster(Long clusterId, boolean isRootAdmin) { Cluster destinationCluster = null; if (clusterId != null) { if (!isRootAdmin) { - throw new PermissionDeniedException( - "Parameter " + ApiConstants.CLUSTER_ID + " can only be specified by a Root Admin, permission denied"); + throw Exceptions.permissionDeniedException("vm.start.cluster.root.admin.only"); } destinationCluster = _clusterDao.findById(clusterId); if (destinationCluster == null) { - throw new InvalidParameterValueException("Unable to find the cluster to deploy the VM, cluster id=" + clusterId); + throw Exceptions.invalidParameterValueException("vm.start.cluster.not.found"); } } return destinationCluster; @@ -5982,14 +6073,13 @@ private HostVO getDestinationHost(Long hostId, boolean isRootAdmin, boolean isEx HostVO destinationHost = null; if (hostId != null) { if (isExplicitHost && !isRootAdmin) { - throw new PermissionDeniedException( - "Parameter " + ApiConstants.HOST_ID + " can only be specified by a Root Admin, permission denied"); + throw Exceptions.permissionDeniedException("vm.start.host.root.admin.only"); } destinationHost = _hostDao.findById(hostId); if (destinationHost == null) { - throw new InvalidParameterValueException("Unable to find the host to deploy the VM, host id=" + hostId); + throw Exceptions.invalidParameterValueException("vm.start.host.not.found"); } else if (destinationHost.getResourceState() != ResourceState.Enabled || destinationHost.getStatus() != Status.Up ) { - throw new InvalidParameterValueException("Unable to deploy the VM as the host: " + destinationHost.getName() + " is not in the right state"); + throw Exceptions.invalidParameterValueException("vm.start.host.not.right.state", Map.of("host", destinationHost)); } } return destinationHost; @@ -6000,8 +6090,7 @@ public UserVm destroyVm(long vmId, boolean expunge) throws ResourceUnavailableEx // Verify input parameters UserVmVO vm = _vmDao.findById(vmId); if (vm == null || vm.getRemoved() != null) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a virtual machine with specified vmId"); - throw ex; + throw Exceptions.invalidParameterValueException("vm.destroy.vm.not.found"); } if (vm.getState() == State.Destroyed || vm.getState() == State.Expunging) { @@ -6028,9 +6117,7 @@ public UserVm destroyVm(long vmId, boolean expunge) throws ResourceUnavailableEx VirtualMachineEntity vmEntity = _orchSrvc.getVirtualMachine(vm.getUuid()); status = vmEntity.destroy(expunge); } catch (CloudException e) { - CloudRuntimeException ex = new CloudRuntimeException("Unable to destroy with specified vmId", e); - ex.addProxyObject(vm.getUuid(), "vmId"); - throw ex; + throw Exceptions.cloudRuntimeException("vm.destroy.failed", Map.of(), e); } if (status) { @@ -6051,12 +6138,10 @@ public UserVm destroyVm(long vmId, boolean expunge) throws ResourceUnavailableEx } return _vmDao.findById(vmId); } else { - CloudRuntimeException ex = new CloudRuntimeException("Failed to destroy vm with specified vmId"); - ex.addProxyObject(vm.getUuid(), "vmId"); - throw ex; + throw Exceptions.cloudRuntimeException("vm.destroy.failed"); } } catch (Exception e) { - throw new CloudRuntimeException("Failed to destroy vm with specified vmId", e); + throw Exceptions.cloudRuntimeException("vm.destroy.failed", Map.of(), e); } } @@ -6209,12 +6294,10 @@ public UserVm expungeVm(long vmId) throws ResourceUnavailableException, Concurre // Verify input parameters UserVmVO vm = _vmDao.findById(vmId); if (vm == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a virtual machine with specified vmId"); - ex.addProxyObject(String.valueOf(vmId), "vmId"); - throw ex; + throw Exceptions.invalidParameterValueException("vm.expunge.vm.not.found"); } if (UserVmManager.SHAREDFSVM.equals(vm.getUserVmType())) { - throw new InvalidParameterValueException("Operation not supported on Shared FileSystem Instance"); + throw Exceptions.invalidParameterValueException("vm.expunge.sharedfs.not.supported"); } if (vm.getRemoved() != null) { @@ -6223,14 +6306,12 @@ public UserVm expungeVm(long vmId) throws ResourceUnavailableException, Concurre } if (!(vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getState() == State.Error)) { - CloudRuntimeException ex = new CloudRuntimeException("Please destroy vm with specified vmId before expunge"); - ex.addProxyObject(String.valueOf(vmId), "vmId"); - throw ex; + throw Exceptions.cloudRuntimeException("vm.expunge.destroy.first"); } // When trying to expunge, permission is denied when the caller is not an admin and the AllowUserExpungeRecoverVm is false for the caller. if (!_accountMgr.isAdmin(callerId) && !AllowUserExpungeRecoverVm.valueIn(callerId)) { - throw new PermissionDeniedException("Expunging a vm can only be done by an Admin. Or when the allow.user.expunge.recover.vm key is set."); + throw Exceptions.permissionDeniedException("vm.expunge.admin.only"); } // check if vm belongs to AutoScale vm group in Disabled state @@ -6244,9 +6325,7 @@ public UserVm expungeVm(long vmId) throws ResourceUnavailableException, Concurre if (status) { return _vmDao.findByIdIncludingRemoved(vmId); } else { - CloudRuntimeException ex = new CloudRuntimeException("Failed to expunge vm with specified vmId"); - ex.addProxyObject(String.valueOf(vmId), "vmId"); - throw ex; + throw Exceptions.cloudRuntimeException("vm.expunge.failed"); } } @@ -6255,9 +6334,7 @@ public UserVm expungeVm(long vmId) throws ResourceUnavailableException, Concurre public HypervisorType getHypervisorTypeOfUserVM(long vmId) { UserVmVO userVm = _vmDao.findById(vmId); if (userVm == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a virtual machine with specified id"); - ex.addProxyObject(String.valueOf(vmId), "vmId"); - throw ex; + throw Exceptions.invalidParameterValueException("vm.gethypervisortype.vm.not.found"); } return userVm.getHypervisorType(); @@ -6270,14 +6347,14 @@ public String finalizeUserData(String userData, Long userDataId, VirtualMachineT } if (userDataId != null && StringUtils.isNotEmpty(userData)) { - throw new InvalidParameterValueException("Both userdata and userdata ID inputs are not allowed, please provide only one"); + throw Exceptions.invalidParameterValueException("vm.deploy.userdata.both.inputs"); } if (template != null && template.getUserDataId() != null) { switch (template.getUserDataOverridePolicy()) { case DENYOVERRIDE: if (StringUtils.isNotEmpty(userData) || userDataId != null) { String msg = String.format("UserData input is not allowed here since template %s is configured to deny any userdata", template.getName()); - throw new CloudRuntimeException(msg); + throw Exceptions.cloudRuntimeException("vm.deploy.userdata.override.denied", Map.of("template", template)); } case ALLOWOVERRIDE: if (userDataId != null) { @@ -6289,7 +6366,7 @@ public String finalizeUserData(String userData, Long userDataId, VirtualMachineT UserData templateUserDataVO = userDataDao.findById(template.getUserDataId()); if (templateUserDataVO == null) { String msg = String.format("UserData linked to the template %s is not found", template.getName()); - throw new CloudRuntimeException(msg); + throw Exceptions.cloudRuntimeException("vm.deploy.userdata.template.linked.not.found", Map.of("template", template)); } return templateUserDataVO.getUserData(); } @@ -6297,7 +6374,7 @@ public String finalizeUserData(String userData, Long userDataId, VirtualMachineT UserData templateUserDataVO = userDataDao.findById(template.getUserDataId()); if (templateUserDataVO == null) { String msg = String.format("UserData linked to the template %s is not found", template.getName()); - throw new CloudRuntimeException(msg); + throw Exceptions.cloudRuntimeException("vm.deploy.userdata.template.linked.not.found", Map.of("template", template)); } if (userDataId != null) { UserData apiUserDataVO = userDataDao.findById(userDataId); @@ -6309,7 +6386,7 @@ public String finalizeUserData(String userData, Long userDataId, VirtualMachineT } default: String msg = String.format("This userdataPolicy %s is not supported for use with this feature", template.getUserDataOverridePolicy().toString()); - throw new CloudRuntimeException(msg); } + throw Exceptions.cloudRuntimeException("vm.deploy.userdata.policy.not.supported", Map.of("policy", template.getUserDataOverridePolicy())); } } else { if (userDataId != null) { UserData apiUserDataVO = userDataDao.findById(userDataId); @@ -6324,23 +6401,18 @@ public String finalizeUserData(String userData, Long userDataId, VirtualMachineT private void verifyServiceOffering(BaseDeployVMCmd cmd, ServiceOffering serviceOffering) { CallContext.current().putErrorContextParameter("serviceOffering", serviceOffering); if (ServiceOffering.State.Inactive.equals(serviceOffering.getState())) { - throw new InvalidParameterValueException("vm.deploy.serviceoffering.inactive", - Collections.emptyMap()); + throw Exceptions.invalidParameterValueException("vm.deploy.serviceoffering.inactive", Collections.emptyMap()); } Long overrideDiskOfferingId = cmd.getOverrideDiskOfferingId(); if (serviceOffering.getDiskOfferingStrictness() && overrideDiskOfferingId != null) { - throw new InvalidParameterValueException("vm.deploy.serviceoffering.override.not.allowed", - Collections.emptyMap()); + throw Exceptions.invalidParameterValueException("vm.deploy.serviceoffering.override.not.allowed", Collections.emptyMap()); } if (!serviceOffering.isDynamic()) { for (String detail: cmd.getDetails().keySet()) { if (detail.equalsIgnoreCase(VmDetailConstants.CPU_NUMBER) || detail.equalsIgnoreCase(VmDetailConstants.CPU_SPEED) || detail.equalsIgnoreCase(VmDetailConstants.MEMORY)) { - throw new InvalidParameterValueException("vm.deploy.serviceoffering.fixed.parameters.not.allowed", - Map.of("cpuNumberKey", VmDetailConstants.CPU_NUMBER, - "cpuSpeedKey", VmDetailConstants.CPU_NUMBER, - "memoryKey", VmDetailConstants.CPU_NUMBER)); + throw Exceptions.invalidParameterValueException("vm.deploy.serviceoffering.fixed.parameters.not.allowed", Map.of("cpuNumberKey", VmDetailConstants.CPU_NUMBER, "cpuSpeedKey", VmDetailConstants.CPU_NUMBER, "memoryKey", VmDetailConstants.CPU_NUMBER)); } } } @@ -6350,23 +6422,23 @@ private void verifyTemplate(BaseDeployVMCmd cmd, VirtualMachineTemplate template if (TemplateType.VNF.equals(template.getTemplateType())) { vnfTemplateManager.validateVnfApplianceNics(template, cmd.getNetworkIds(), cmd.getVmNetworkMap()); } else if (cmd instanceof DeployVnfApplianceCmd) { - throw new InvalidParameterValueException("Can't deploy VNF appliance from a non-VNF template"); + throw Exceptions.invalidParameterValueException("vm.deploy.template.not.vnf"); } ServiceOfferingJoinVO svcOffering = serviceOfferingJoinDao.findById(serviceOfferingId); if (template.isDeployAsIs()) { if (svcOffering != null && svcOffering.getRootDiskSize() != null && svcOffering.getRootDiskSize() > 0) { - throw new InvalidParameterValueException("Failed to deploy Virtual Machine as a service offering with root disk size specified cannot be used with a deploy as-is template"); + throw Exceptions.invalidParameterValueException("vm.deploy.template.deploy.as.is.root.disk.size.not.allowed"); } if (cmd.getDetails().get("rootdisksize") != null) { - throw new InvalidParameterValueException("Overriding root disk size isn't supported for VMs deployed from deploy as-is Templates"); + throw Exceptions.invalidParameterValueException("vm.deploy.template.deploy.as.is.override.disk.size.not.supported"); } // Bootmode and boottype are not supported on VMWare dpeloy-as-is templates (since 4.15) if ((cmd.getBootMode() != null || cmd.getBootType() != null)) { - throw new InvalidParameterValueException("Boot type and boot mode are not supported on VMware for Templates registered as deploy-as-is, as we honour what is defined in the template."); + throw Exceptions.invalidParameterValueException("vm.deploy.template.deploy.as.is.boot.not.supported"); } } } @@ -6422,9 +6494,7 @@ public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityE if (volumeOfSnapshot != null) { templateId = volumeOfSnapshot.getTemplateId(); } else if (templateId == null) { - throw new InvalidParameterValueException( - "Could not determine template from snapshot id=" + cmd.getSnapshotId() + - "; the source volume no longer exists. Please specify a templateId."); + throw Exceptions.invalidParameterValueException("vm.deploy.snapshot.template.not.determinable"); } } @@ -6454,26 +6524,22 @@ public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityE throw new InvalidParameterValueException("vm.deploy.diskoffering.not.found", Collections.emptyMap()); } if (diskOffering.isComputeOnly()) { - throw new InvalidParameterValueException("vm.deploy.diskoffering.compute.only", - Map.of("diskOffering", diskOffering)); + throw Exceptions.invalidParameterValueException("vm.deploy.diskoffering.compute.only", Map.of("diskOffering", diskOffering)); } } List dataDiskInfoList = cmd.getDataDiskInfoList(); if (dataDiskInfoList != null && diskOfferingId != null) { - throw new InvalidParameterValueException("vm.deploy.diskoffering.with.diskoffering.details", - Collections.emptyMap()); + throw Exceptions.invalidParameterValueException("vm.deploy.diskoffering.with.diskoffering.details", Collections.emptyMap()); } if (!zone.isLocalStorageEnabled()) { DiskOffering diskOfferingMappedInServiceOffering = _entityMgr.findById(DiskOffering.class, serviceOffering.getDiskOfferingId()); if (diskOfferingMappedInServiceOffering.isUseLocalStorage()) { - throw new InvalidParameterValueException("vm.deploy.serviceoffering.local.storage.zone.unsupported", - Map.of("serviceOffering", serviceOffering)); + throw Exceptions.invalidParameterValueException("vm.deploy.serviceoffering.local.storage.zone.unsupported", Map.of("serviceOffering", serviceOffering)); } if (diskOffering != null && diskOffering.isUseLocalStorage()) { - throw new InvalidParameterValueException("vm.deploy.diskoffering.local.storage.zone.unsupported", - Map.of("diskOffering", diskOffering)); + throw Exceptions.invalidParameterValueException("vm.deploy.diskoffering.local.storage.zone.unsupported", Map.of("diskOffering", diskOffering)); } } @@ -6502,7 +6568,7 @@ private UserVm createVirtualMachine(BaseDeployVMCmd cmd, DataCenter zone, Accoun List sshKeyPairNames = new ArrayList(); if (cmd instanceof CreateVMFromBackupCmd) { if (cmd.getUserData() != null) { - throw new InvalidParameterValueException("User data not supported for instance created from backup"); + throw Exceptions.invalidParameterValueException("vm.deploy.backup.userdata.not.supported"); } } else { userData = cmd.getUserData(); @@ -6540,7 +6606,7 @@ private UserVm createVirtualMachine(BaseDeployVMCmd cmd, DataCenter zone, Accoun Map userVmOVFProperties = cmd.getVmProperties(); if (zone.getNetworkType() == NetworkType.Basic) { if (networkIds != null) { - throw new InvalidParameterValueException("Can't specify network Ids in Basic zone"); + throw Exceptions.invalidParameterValueException("vm.deploy.basic.zone.network.ids.not.allowed"); } else { vm = createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(cmd, zone, template, owner), owner, name, displayName, diskOfferingId, size , dataDiskInfoList, group , hypervisor, cmd.getHttpMethod(), userData, userDataId, userDataDetails, sshKeyPairNames, ipToNetworkMap, addrs, displayVm , keyboard , cmd.getAffinityGroupIdList(), @@ -6557,7 +6623,7 @@ private UserVm createVirtualMachine(BaseDeployVMCmd cmd, DataCenter zone, Accoun } else { if (cmd.getSecurityGroupIdList() != null && !cmd.getSecurityGroupIdList().isEmpty()) { - throw new InvalidParameterValueException("Can't create vm with security groups; security group feature is not enabled per zone"); + throw Exceptions.invalidParameterValueException("vm.deploy.securitygroup.zone.not.enabled"); } vm = createAdvancedVirtualMachine(zone, serviceOffering, template, networkIds, owner, name, displayName, diskOfferingId, size, dataDiskInfoList, group, hypervisor, cmd.getHttpMethod(), userData, userDataId, userDataDetails, sshKeyPairNames, ipToNetworkMap, addrs, displayVm, keyboard, cmd.getAffinityGroupIdList(), cmd.getDetails(), @@ -6584,7 +6650,7 @@ private UserVm createVirtualMachine(BaseDeployVMCmd cmd, DataCenter zone, Accoun logger.info("Adding extra configuration to user vm: {}", vm); addExtraConfig(vm, extraConfig); } else { - throw new InvalidParameterValueException("attempted setting extraconfig but enable.additional.vm.configuration is disabled"); + throw Exceptions.invalidParameterValueException("vm.update.extraconfig.disabled"); } } @@ -6614,11 +6680,11 @@ protected void validateLeaseProperties(Integer leaseDuration, VMLeaseManager.Exp // any one of them have value // validate leaseduration if (leaseDuration == null || leaseDuration < 1 || leaseDuration > VMLeaseManager.MAX_LEASE_DURATION_DAYS) { - throw new InvalidParameterValueException("Invalid leaseduration: must be a natural number (>=1) or -1, max supported value is 36500"); + throw Exceptions.invalidParameterValueException("vm.deploy.lease.duration.invalid"); } if (leaseExpiryAction == null) { - throw new InvalidParameterValueException("Provide values for both: leaseduration and leaseexpiryaction"); + throw Exceptions.invalidParameterValueException("vm.deploy.lease.params.both.required"); } } @@ -6659,13 +6725,13 @@ protected void applyLeaseOnUpdateInstance(UserVm instance, Integer leaseDuration if (StringUtils.isEmpty(leaseExpiryDate)) { String errorMsg = "Lease can't be applied on instance with id: " + instanceUuid + ", it doesn't have lease associated during deployment"; logger.debug(errorMsg); - throw new CloudRuntimeException(errorMsg); + throw Exceptions.cloudRuntimeException("vm.deploy.lease.no.active.lease", Map.of("instance", instanceUuid)); } if (!VMLeaseManager.LeaseActionExecution.PENDING.name().equals(leaseExecution)) { String errorMsg = "Lease can't be applied on instance with id: " + instanceUuid + ", it doesn't have active lease"; logger.debug(errorMsg); - throw new CloudRuntimeException(errorMsg); + throw Exceptions.cloudRuntimeException("vm.deploy.lease.not.pending", Map.of("instance", instanceUuid)); } // proceed if lease is yet to expire @@ -6680,7 +6746,7 @@ protected void applyLeaseOnUpdateInstance(UserVm instance, Integer leaseDuration } if (leaseExpiryTimeDiff < 0) { logger.debug("Lease has expired for instance with id: {}, can't modify lease information", instanceUuid); - throw new CloudRuntimeException("Lease is not allowed to be redefined on expired leased instance"); + throw Exceptions.cloudRuntimeException("vm.deploy.lease.expired.redefinition"); } if (leaseDuration < 1) { @@ -6716,11 +6782,11 @@ private VolumeInfo getVolume(long id, Long templateId, boolean isSnapshot) { if (!isSnapshot && (volume.getDataStore() == null || !ScopeType.ZONE.equals(volume.getDataStore().getScope().getScopeType()))) { - throw new InvalidParameterValueException("Deployment of virtual machine is supported only for Zone-wide storage pools"); + throw Exceptions.invalidParameterValueException("vm.deploy.volume.storage.pool.zone.required"); } checkIfVolumeTemplateIsTheSameAsTheProvided(volume, templateId); if (volume.getInstanceId() != null && !isSnapshot) { - throw new InvalidParameterValueException(String.format("The volume %s is already attached to a VM %s", volume, volume.getInstanceId())); + throw Exceptions.invalidParameterValueException("vm.deploy.volume.already.attached", Map.of("volume", volume)); } } return volume; @@ -6729,10 +6795,10 @@ private VolumeInfo getVolume(long id, Long templateId, boolean isSnapshot) { private void checkIfVolumeTemplateIsTheSameAsTheProvided(VolumeInfo volume, Long templateId) { if (volume.getTemplateId() != null) { if (templateId != null && !volume.getTemplateId().equals(templateId)) { - throw new InvalidParameterValueException(String.format("The volume's template %s is not the same as the provided one %s", volume.getTemplateId(), templateId)); + throw Exceptions.invalidParameterValueException("vm.deploy.volume.template.mismatch"); } } else { - throw new InvalidParameterValueException("The provided volume/snapshot doesn't have a template to deploy a VM"); + throw Exceptions.invalidParameterValueException("vm.deploy.volume.snapshot.no.template"); } } @@ -6752,11 +6818,11 @@ protected void persistExtraConfigVmware(String decodedUrl, UserVm vm) { if (validXenOrVmwareConfiguration && paramArray.length == 2) { vmInstanceDetailsDao.addDetail(vm.getId(), paramArray[0].trim(), paramArray[1].trim(), true); } else { - throw new CloudRuntimeException("Extra config " + cfg + " is not on the list of allowed keys for VMware hypervisor hosts."); + throw Exceptions.cloudRuntimeException("vm.extraconfig.vmware.key.not.allowed", Map.of("key", cfg)); } } } else { - throw new CloudRuntimeException("The passed extra config string " + decodedUrl + "contains an invalid key/value pair pattern"); + throw Exceptions.cloudRuntimeException("vm.extraconfig.vmware.invalid.format"); } } @@ -6782,12 +6848,12 @@ protected void persistExtraConfigXenServer(String decodedUrl, UserVm vm) { vmInstanceDetailsDao.addDetail(vm.getId(), extraConfigKey + String.valueOf(i), cfg, true); i++; } else { - throw new CloudRuntimeException("Extra config " + cfg + " is not on the list of allowed keys for XenServer hypervisor hosts."); + throw Exceptions.cloudRuntimeException("vm.extraconfig.xenserver.key.not.allowed", Map.of("key", cfg)); } } } else { String msg = String.format("The passed extra config string '%s' contains an invalid key/value pair pattern", decodedUrl); - throw new CloudRuntimeException(msg); + throw Exceptions.cloudRuntimeException("vm.extraconfig.xenserver.invalid.format"); } } @@ -6835,7 +6901,7 @@ protected boolean isValidXenOrVmwareConfiguration(String cfg, String[] allowedKe } } else { String msg = String.format("An incorrect configuration %s has been passed", cfg); - throw new CloudRuntimeException(msg); + throw Exceptions.cloudRuntimeException("vm.extraconfig.config.incorrect", Map.of("config", cfg)); } return false; } @@ -6873,7 +6939,7 @@ protected void persistExtraConfigKvm(String decodedUrl, UserVm vm) { @Override public void validateExtraConfig(long accountId, HypervisorType hypervisorType, String extraConfig) { if (!EnableAdditionalVmConfig.valueIn(accountId)) { - throw new CloudRuntimeException("Additional VM configuration is not enabled for this account"); + throw Exceptions.cloudRuntimeException("vm.extraconfig.account.not.enabled"); } if (HypervisorType.KVM.equals(hypervisorType)) { validateKvmExtraConfig(extraConfig, accountId); @@ -6907,11 +6973,11 @@ protected void validateKvmExtraConfig(String decodedUrl, long accountId) { } } if (!isValidConfig) { - throw new CloudRuntimeException(String.format("Extra config '%s' is not on the list of allowed keys for KVM hypervisor hosts", currentConfig)); + throw Exceptions.cloudRuntimeException("vm.extraconfig.kvm.key.not.allowed", Map.of("key", currentConfig)); } } } catch (ParserConfigurationException | IOException | SAXException e) { - throw new CloudRuntimeException("Failed to parse additional XML configuration: " + e.getMessage()); + throw Exceptions.cloudRuntimeException("vm.extraconfig.kvm.xml.parse.failed"); } } } @@ -6932,7 +6998,7 @@ protected void addExtraConfig(UserVm vm, String extraConfig) { persistExtraConfigVmware(decodedUrl, vm); } else { String msg = String.format("This hypervisor %s is not supported for use with this feature", hypervisorType); - throw new CloudRuntimeException(msg); + throw Exceptions.cloudRuntimeException("vm.extraconfig.hypervisor.not.supported", Map.of("hypervisorType", hypervisorType)); } } @@ -6946,14 +7012,14 @@ protected String decodeExtraConfig(String encodeString) { try { decodedUrl = URLDecoder.decode(encodeString, "UTF-8"); } catch (UnsupportedEncodingException e) { - throw new CloudRuntimeException("Failed to provided decode URL string: " + e.getMessage()); + throw Exceptions.cloudRuntimeException("vm.extraconfig.url.decode.failed"); } return decodedUrl; } protected List getSecurityGroupIdList(SecurityGroupAction cmd) { if (cmd.getSecurityGroupNameList() != null && cmd.getSecurityGroupIdList() != null) { - throw new InvalidParameterValueException("securitygroupids parameter is mutually exclusive with securitygroupnames parameter"); + throw Exceptions.invalidParameterValueException("vm.deploy.security.group.id.and.name.exclusive"); } //transform group names to ids here @@ -6962,7 +7028,7 @@ protected List getSecurityGroupIdList(SecurityGroupAction cmd) { for (String groupName : cmd.getSecurityGroupNameList()) { SecurityGroup sg = _securityGroupMgr.getSecurityGroup(groupName, cmd.getEntityOwnerId()); if (sg == null) { - throw new InvalidParameterValueException("Unable to find group by name " + groupName); + throw Exceptions.invalidParameterValueException("vm.deploy.security.group.name.not.found", Map.of("groupName", groupName)); } else { securityGroupIds.add(sg.getId()); } @@ -7003,12 +7069,12 @@ private void verifyDetails(Map details) { verifyMinAndMaxIops(minIops, maxIops); if (details.containsKey("extraconfig")) { - throw new InvalidParameterValueException("'extraconfig' should not be included in details as key"); + throw Exceptions.invalidParameterValueException("vm.update.extraconfig.in.details"); } for (String detailName : details.keySet()) { if (isExtraConfig(detailName)) { - throw new InvalidParameterValueException("detail name should not start with extraconfig"); + throw Exceptions.invalidParameterValueException("vm.deploy.detail.extraconfig.prefix.not.allowed"); } } } @@ -7016,7 +7082,7 @@ private void verifyDetails(Map details) { private void verifyMinAndMaxIops(String minIops, String maxIops) { if ((minIops != null && maxIops == null) || (minIops == null && maxIops != null)) { - throw new InvalidParameterValueException("Either 'Min IOPS' and 'Max IOPS' must both be specified or neither be specified."); + throw Exceptions.invalidParameterValueException("vm.deploy.iops.both.or.neither"); } long lMinIops; @@ -7030,7 +7096,7 @@ private void verifyMinAndMaxIops(String minIops, String maxIops) { } } catch (NumberFormatException ex) { - throw new InvalidParameterValueException("'Min IOPS' must be a whole number."); + throw Exceptions.invalidParameterValueException("vm.deploy.iops.min.not.integer"); } long lMaxIops; @@ -7044,11 +7110,11 @@ private void verifyMinAndMaxIops(String minIops, String maxIops) { } } catch (NumberFormatException ex) { - throw new InvalidParameterValueException("'Max IOPS' must be a whole number."); + throw Exceptions.invalidParameterValueException("vm.deploy.iops.max.not.integer"); } if (lMinIops > lMaxIops) { - throw new InvalidParameterValueException("'Min IOPS' must be less than or equal to 'Max IOPS'."); + throw Exceptions.invalidParameterValueException("vm.deploy.iops.min.greater.than.max"); } } @@ -7069,38 +7135,34 @@ private VMInstanceVO preVmStorageMigrationCheck(Long vmId) { if (logger.isDebugEnabled()) { logger.debug("Caller is not a root admin, permission denied to migrate the VM"); } - throw new PermissionDeniedException("No permission to migrate VM, Only Root Admin can migrate a VM!"); + throw Exceptions.permissionDeniedException("vm.migrate.storage.permission.denied"); } VMInstanceVO vm = _vmInstanceDao.findById(vmId); if (vm == null) { - throw new InvalidParameterValueException("Unable to find the VM by id=" + vmId); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.vm.not.found"); } if (vm.getState() != State.Stopped) { - InvalidParameterValueException ex = new InvalidParameterValueException("VM is not Stopped, unable to migrate the vm having the specified id"); - ex.addProxyObject(vm.getUuid(), "vmId"); - throw ex; + throw Exceptions.invalidParameterValueException("vm.migrate.storage.vm.not.stopped"); } HypervisorType hypervisorType = vm.getHypervisorType(); List supportedHypervisorsForNonUserVMStorageMigration = HypervisorType.getListOfHypervisorsSupportingFunctionality(Functionality.VmStorageMigration) .stream().filter(hypervisor -> !hypervisor.equals(HypervisorType.XenServer)).collect(Collectors.toList()); if (vm.getType() != VirtualMachine.Type.User && !supportedHypervisorsForNonUserVMStorageMigration.contains(hypervisorType)) { - throw new InvalidParameterValueException(String.format( - "Unable to migrate storage of non-user VMs for hypervisor [%s]. Operation only supported for the following hypervisors: [%s].", - hypervisorType, supportedHypervisorsForNonUserVMStorageMigration)); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.nonuser.hypervisor.not.supported", Map.of("hypervisorType", hypervisorType, "supportedHypervisors", supportedHypervisorsForNonUserVMStorageMigration)); } List vols = _volsDao.findByInstance(vm.getId()); if (vols.size() > 1 && !(HypervisorType.VMware.equals(hypervisorType) || HypervisorType.KVM.equals(hypervisorType))) { - throw new InvalidParameterValueException("Data disks attached to the vm, can not migrate. Need to detach data disks first"); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.data.disks.attached"); } // Check that Vm does not have VM Snapshots if (_vmSnapshotDao.findByVm(vmId).size() > 0) { - throw new InvalidParameterValueException("Instance's disk cannot be migrated, please remove all the Instance Snapshots for this Instance"); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.snapshots.exist"); } return vm; @@ -7131,12 +7193,12 @@ public VirtualMachine vmStorageMigration(Long vmId, StoragePool destPool) { if (destPoolPodId != null && (ScopeType.CLUSTER.equals(pool.getScope()) || ScopeType.HOST.equals(pool.getScope())) && !destPoolPodId.equals(pool.getPodId())) { - throw new InvalidParameterValueException("Storage migration of non-user VMs cannot be done between storage pools of different pods"); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.nonuser.different.pods"); } } Pair checkResult = storageManager.checkIfReadyVolumeFitsInStoragePoolWithStorageAccessGroups(destPool, volume); if (!checkResult.first()) { - throw new CloudRuntimeException(String.format("Storage suitability check failed for volume %s with error, %s", volume, checkResult.second())); + throw Exceptions.cloudRuntimeException("vm.migrate.storage.suitability.failed", Map.of("volume", volume, "error", checkResult.second())); } volumeToPoolIds.put(volume.getId(), destPool.getId()); } @@ -7156,7 +7218,7 @@ public VirtualMachine vmStorageMigration(Long vmId, Map volumeTo if (poolClusterId != null && (ScopeType.CLUSTER.equals(pool.getScope()) || ScopeType.HOST.equals(pool.getScope())) && !poolClusterId.equals(pool.getClusterId())) { - throw new InvalidParameterValueException("VM's disk cannot be migrated, input destination storage pools belong to different clusters"); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.different.clusters"); } if (pool.getClusterId() != null) { poolClusterId = pool.getClusterId(); @@ -7164,7 +7226,7 @@ public VirtualMachine vmStorageMigration(Long vmId, Map volumeTo checkDestinationHypervisorType(pool, vm); Pair checkResult = storageManager.checkIfReadyVolumeFitsInStoragePoolWithStorageAccessGroups(pool, volume); if (!checkResult.first()) { - throw new CloudRuntimeException(String.format("Storage suitability check failed for volume %s with error %s", volume, checkResult.second())); + throw Exceptions.cloudRuntimeException("vm.migrate.storage.suitability.failed", Map.of("volume", volume, "error", checkResult.second())); } volumeToPoolIds.put(volume.getId(), pool.getId()); @@ -7178,7 +7240,7 @@ private void checkIfDestinationPoolHasSameStorageAccessGroups(StoragePool destPo if (hostId != null) { Host host = _hostDao.findById(hostId); if (!storageManager.checkIfHostAndStoragePoolHasCommonStorageAccessGroups(host, destPool)) { - throw new InvalidParameterValueException(String.format("Destination pool %s does not have matching storage access groups as host %s", destPool.getName(), host.getName())); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.access.groups.mismatch", Map.of("pool", destPool, "host", host)); } } } @@ -7191,7 +7253,7 @@ private void checkDestinationHypervisorType(StoragePool destPool, VMInstanceVO v } if (vm.getHypervisorType() != destHypervisorType && destHypervisorType != HypervisorType.Any) { - throw new InvalidParameterValueException("hypervisor is not compatible: dest: " + destHypervisorType.toString() + ", vm: " + vm.getHypervisorType().toString()); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.hypervisor.mismatch", Map.of("destHypervisor", destHypervisorType, "vmHypervisor", vm.getHypervisorType())); } } @@ -7211,48 +7273,46 @@ public VirtualMachine migrateVirtualMachine(Long vmId, Host destinationHost) thr if (logger.isDebugEnabled()) { logger.debug("Caller is not a root admin, permission denied to migrate the VM"); } - throw new PermissionDeniedException("No permission to migrate VM, Only Root Admin can migrate a VM!"); + throw Exceptions.permissionDeniedException("vm.migrate.permission.denied"); } VMInstanceVO vm = _vmInstanceDao.findById(vmId); if (vm == null) { - throw new InvalidParameterValueException("Unable to find the VM by id=" + vmId); + throw Exceptions.invalidParameterValueException("vm.migrate.vm.not.found"); } // business logic if (vm.getState() != State.Running) { if (logger.isDebugEnabled()) { logger.debug("VM is not Running, unable to migrate the vm " + vm); } - InvalidParameterValueException ex = new InvalidParameterValueException("VM is not Running, unable to migrate the vm with specified id"); - ex.addProxyObject(vm.getUuid(), "vmId"); - throw ex; + throw Exceptions.invalidParameterValueException("vm.migrate.vm.not.running"); } checkIfHostOfVMIsInPrepareForMaintenanceState(vm, "Migrate"); if (serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) { - throw new InvalidParameterValueException("Live Migration of GPU enabled VM is not supported"); + throw Exceptions.invalidParameterValueException("vm.migrate.gpu.not.supported"); } if (!isOnSupportedHypevisorForMigration(vm)) { logger.error(vm + " is not XenServer/VMware/KVM/Ovm/Hyperv, cannot migrate this VM from hypervisor type " + vm.getHypervisorType()); - throw new InvalidParameterValueException("Unsupported Hypervisor Type for VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only"); + throw Exceptions.invalidParameterValueException("vm.migrate.hypervisor.not.supported"); } if (vm.getType().equals(VirtualMachine.Type.User) && vm.getHypervisorType().equals(HypervisorType.LXC)) { - throw new InvalidParameterValueException("Unsupported Hypervisor Type for User VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only"); + throw Exceptions.invalidParameterValueException("vm.migrate.hypervisor.not.supported"); } if (isVMUsingLocalStorage(vm)) { logger.error(vm + " is using Local Storage, cannot migrate this VM."); - throw new InvalidParameterValueException("Unsupported operation, VM uses Local storage, cannot migrate"); + throw Exceptions.invalidParameterValueException("vm.migrate.local.storage.not.supported"); } // check if migrating to same host long srcHostId = vm.getHostId(); Host srcHost = _resourceMgr.getHost(srcHostId); if (srcHost == null) { - throw new InvalidParameterValueException("Cannot migrate VM, host with id: " + srcHostId + " for VM not found"); + throw Exceptions.invalidParameterValueException("vm.migrate.source.host.not.found"); } DeployDestination dest = null; @@ -7264,7 +7324,7 @@ public VirtualMachine migrateVirtualMachine(Long vmId, Host destinationHost) thr // If no suitable destination found then throw exception if (dest == null) { - throw new CloudRuntimeException("Unable to find suitable destination to migrate VM " + vm.getInstanceName()); + throw Exceptions.cloudRuntimeException("vm.migrate.destination.not.found", Map.of("instance", vm)); } logger.info("Starting migration of VM {} from host {} to host {} ", vm.getInstanceName(), srcHostId, dest.getHost().getId()); @@ -7286,9 +7346,9 @@ private DeployDestination chooseVmMigrationDestination(VMInstanceVO vm, Host src return _planningMgr.planDeployment(profile, plan, excludes, null); } catch (final AffinityConflictException e2) { logger.warn("Unable to create deployment, affinity rules associated to the VM conflict", e2); - throw new CloudRuntimeException("Unable to create deployment, affinity rules associated to the VM conflict"); + throw Exceptions.cloudRuntimeException("vm.migrate.affinity.conflict"); } catch (final InsufficientServerCapacityException e3) { - throw new CloudRuntimeException("Unable to find a server to migrate the vm to"); + throw Exceptions.cloudRuntimeException("vm.migrate.server.not.found"); } } @@ -7315,11 +7375,11 @@ protected void validateStorageAccessGroupsOnHosts(Host srcHost, Host destination } if (CollectionUtils.isEmpty(destHostStorageAccessGroupsList)) { - throw new CloudRuntimeException("Source host has storage access groups, but destination host has none."); + throw Exceptions.cloudRuntimeException("vm.migrate.storage.access.groups.src.has.dest.none"); } if (!destHostStorageAccessGroupsList.containsAll(srcHostStorageAccessGroupsList)) { - throw new CloudRuntimeException("Storage access groups on the source and destination hosts did not match."); + throw Exceptions.cloudRuntimeException("vm.migrate.storage.access.groups.mismatch.hosts"); } } @@ -7332,8 +7392,7 @@ protected void validateStrictHostTagCheck(VMInstanceVO vm, HostVO host) { logger.error("Cannot deploy VM: {} to host : {} due to tag mismatch. host tags: {}, " + "strict host tags: {} serviceOffering tags: {}, template tags: {}, missing tags: {}", vm, host, host.getHostTags(), UserVmManager.getStrictHostTags(), serviceOffering.getHostTag(), template.getTemplateTag(), missingTags); - throw new InvalidParameterValueException(String.format("Cannot deploy VM, destination host: %s " + - "is not compatible for the VM", host.getName())); + throw Exceptions.invalidParameterValueException("vm.migrate.host.tags.mismatch", Map.of("host", host)); } } @@ -7343,24 +7402,23 @@ private DeployDestination checkVmMigrationDestination(VMInstanceVO vm, Host srcH return null; } if (destinationHost.getId() == srcHost.getId()) { - throw new InvalidParameterValueException("Cannot migrate VM, VM is already present on this host, please specify valid destination host to migrate the VM"); + throw Exceptions.invalidParameterValueException("vm.migrate.vm.already.on.host"); } // check if host is UP if (destinationHost.getState() != com.cloud.host.Status.Up || destinationHost.getResourceState() != ResourceState.Enabled) { - throw new InvalidParameterValueException("Cannot migrate VM, destination host is not in correct state, has status: " + destinationHost.getState() + ", state: " - + destinationHost.getResourceState()); + throw Exceptions.invalidParameterValueException("vm.migrate.destination.host.not.right.state", Map.of("host", destinationHost)); } if (vm.getType() != VirtualMachine.Type.User) { // for System VMs check that the destination host is within the same pod if (srcHost.getPodId() != null && !srcHost.getPodId().equals(destinationHost.getPodId())) { - throw new InvalidParameterValueException("Cannot migrate the VM, destination host is not in the same pod as current host of the VM"); + throw Exceptions.invalidParameterValueException("vm.migrate.destination.different.pod"); } } if (dpdkHelper.isVMDpdkEnabled(vm.getId()) && !dpdkHelper.isHostDpdkEnabled(destinationHost.getId())) { - throw new CloudRuntimeException("Cannot migrate VM, VM is DPDK enabled VM but destination host is not DPDK enabled"); + throw Exceptions.cloudRuntimeException("vm.migrate.dpdk.host.not.supported"); } HostVO destinationHostVO = _hostDao.findById(destinationHost.getId()); @@ -7387,7 +7445,7 @@ private DeployDestination checkVmMigrationDestination(VMInstanceVO vm, Host srcH Long vmId = vm.getId(); logger.debug("Checking if there are any ongoing snapshots volumes associated with VM {}", vm); if (checkStatusOfVolumeSnapshots(vm, null)) { - throw new CloudRuntimeException("There is/are unbacked up snapshot(s) on volume(s) attached to this VM, VM Migration is not permitted, please try again later."); + throw Exceptions.cloudRuntimeException("vm.migrate.unbacked.snapshots"); } logger.debug("Found no ongoing snapshots on volumes associated with the vm {}", vm); @@ -7425,7 +7483,7 @@ private void checkIfHostOfVMIsInPrepareForMaintenanceState(VirtualMachine vm, St } logger.debug("Host is in PrepareForMaintenance state - {} VM operation on the VM: {} is not allowed", operation, vm); - throw new InvalidParameterValueException(String.format("%s VM operation on the VM: %s is not allowed as host is preparing for maintenance mode", operation, vm)); + throw Exceptions.invalidParameterValueException("vm.migrate.host.maintenance.mode", Map.of("operation", operation, "instance", vm)); } private Long accountOfDedicatedHost(HostVO host) { @@ -7665,7 +7723,7 @@ private Pair getHostsForMigrateVmWithStorage(VMInstanceVO vm, Host d Host srcHost = _resourceMgr.getHost(srcHostId); if (srcHost == null) { - throw new InvalidParameterValueException("Cannot migrate VM, host with ID: " + srcHostId + " for VM not found"); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.source.host.not.found"); } if (destinationHost == null) { @@ -7674,8 +7732,7 @@ private Pair getHostsForMigrateVmWithStorage(VMInstanceVO vm, Host d // Check if source and destination hosts are valid and migrating to same host if (destinationHost.getId() == srcHostId) { - throw new InvalidParameterValueException(String.format("Cannot migrate VM as it is already present on host %s (ID: %s), please specify valid destination host to migrate the VM", - destinationHost.getName(), destinationHost.getUuid())); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.vm.already.on.host"); } String srcHostVersion = srcHost.getHypervisorVersion(); @@ -7683,15 +7740,13 @@ private Pair getHostsForMigrateVmWithStorage(VMInstanceVO vm, Host d // Check if the source and destination hosts are of the same type and support storage motion. if (!srcHost.getHypervisorType().equals(destinationHost.getHypervisorType())) { - throw new CloudRuntimeException("The source and destination hosts are not of the same type and version. Source hypervisor type and version: " + - srcHost.getHypervisorType().toString() + " " + srcHostVersion + ", Destination hypervisor type and version: " + - destinationHost.getHypervisorType().toString() + " " + destHostVersion); + throw Exceptions.cloudRuntimeException("vm.migrate.storage.hypervisor.version.mismatch"); } if (!VirtualMachine.Type.User.equals(vm.getType())) { // for System VMs check that the destination host is within the same pod if (srcHost.getPodId() != null && !srcHost.getPodId().equals(destinationHost.getPodId())) { - throw new InvalidParameterValueException("Cannot migrate the VM, destination host is not in the same pod as current host of the VM"); + throw Exceptions.invalidParameterValueException("vm.migrate.destination.different.pod"); } } @@ -7706,19 +7761,18 @@ private Pair getHostsForMigrateVmWithStorage(VMInstanceVO vm, Host d } if (!_hypervisorCapabilitiesDao.isStorageMotionSupported(srcHost.getHypervisorType(), srcHostVersion)) { - throw new CloudRuntimeException(String.format("Migration with storage isn't supported for source host %s (ID: %s) on hypervisor %s with version %s", srcHost.getName(), srcHost.getUuid(), srcHost.getHypervisorType(), srcHost.getHypervisorVersion())); + throw Exceptions.cloudRuntimeException("vm.migrate.storage.source.hypervisor.not.supported", Map.of("host", srcHost, "hypervisorType", srcHost.getHypervisorType(), "version", srcHost.getHypervisorVersion())); } if (srcHostVersion == null || !srcHostVersion.equals(destHostVersion)) { if (!_hypervisorCapabilitiesDao.isStorageMotionSupported(destinationHost.getHypervisorType(), destHostVersion)) { - throw new CloudRuntimeException(String.format("Migration with storage isn't supported for target host %s (ID: %s) on hypervisor %s with version %s", destinationHost.getName(), destinationHost.getUuid(), destinationHost.getHypervisorType(), destinationHost.getHypervisorVersion())); + throw Exceptions.cloudRuntimeException("vm.migrate.storage.destination.hypervisor.not.supported", Map.of("host", destinationHost, "hypervisorType", destinationHost.getHypervisorType(), "version", destinationHost.getHypervisorVersion())); } } // Check if destination host is up. if (destinationHost.getState() != com.cloud.host.Status.Up || destinationHost.getResourceState() != ResourceState.Enabled) { - throw new CloudRuntimeException(String.format("Cannot migrate VM, destination host %s (ID: %s) is not in correct state, has status: %s, state: %s", - destinationHost.getName(), destinationHost.getUuid(), destinationHost.getState(), destinationHost.getResourceState())); + throw Exceptions.cloudRuntimeException("vm.migrate.storage.destination.host.not.right.state", Map.of("host", destinationHost)); } // Check max guest vm limit for the destinationHost. @@ -7736,7 +7790,7 @@ private List getVmVolumesForMigrateVmWithStorage(VMInstanceVO vm) { List vmVolumes = _volsDao.findUsableVolumesForInstance(vm.getId()); for (VolumeVO volume : vmVolumes) { if (volume.getState() != Volume.State.Ready) { - throw new CloudRuntimeException(String.format("Volume %s (ID: %s) of the VM is not in Ready state. Cannot migrate the VM %s (ID: %s) with its volumes", volume.getName(), volume.getUuid(), vm.getInstanceName(), vm.getUuid())); + throw Exceptions.cloudRuntimeException("vm.migrate.storage.volume.not.ready", Map.of("volume", volume)); } } return vmVolumes; @@ -7753,30 +7807,28 @@ private Map getVolumePoolMappingForMigrateVmWithStorage(VMInstanceVO VolumeVO volume = _volsDao.findByUuid(entry.getKey()); StoragePoolVO pool = _storagePoolDao.findByUuid(entry.getValue()); if (volume == null) { - throw new InvalidParameterValueException("There is no volume present with the given id " + entry.getKey()); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.volume.not.found"); } else if (pool == null) { - throw new InvalidParameterValueException("There is no storage pool present with the given id " + entry.getValue()); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.pool.not.found"); } else if (pool.isInMaintenance()) { - throw new InvalidParameterValueException("Cannot migrate volume " + volume + "to the destination storage pool " + pool.getName() + - " as the storage pool is in maintenance mode."); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.volume.pool.incompatible", Map.of("volume", volume, "pool", pool)); } else { // Verify the volume given belongs to the vm. if (!vmVolumes.contains(volume)) { - throw new InvalidParameterValueException(String.format("Volume " + volume + " doesn't belong to the VM %s (ID: %s) that has to be migrated", vm.getInstanceName(), vm.getUuid())); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.volume.vm.mismatch", Map.of("volume", volume, "instance", vm)); } volToPoolObjectMap.put(volume.getId(), pool.getId()); } HostVO host = _hostDao.findById(vm.getHostId()); if (!storageManager.checkIfHostAndStoragePoolHasCommonStorageAccessGroups(host, pool)) { - throw new InvalidParameterValueException(String.format("Destination pool %s for the volume %s does not have matching storage access groups as host %s", pool.getName(), volume.getName(), host.getName())); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.volume.pool.access.groups.mismatch", Map.of("pool", pool, "volume", volume, "host", host)); } HypervisorType hypervisorType = _volsDao.getHypervisorType(volume.getId()); try { snapshotHelper.checkKvmVolumeSnapshotsOnlyInPrimaryStorage(volume, hypervisorType); } catch (CloudRuntimeException ex) { - throw new CloudRuntimeException(String.format("Unable to migrate %s to the destination storage pool [%s] due to [%s]", volume, - new ToStringBuilder(pool, ToStringStyle.JSON_STYLE).append("uuid", pool.getUuid()).append("name", pool.getName()).toString(), ex.getMessage()), ex); + throw Exceptions.cloudRuntimeException("vm.migrate.storage.volume.pool.unsuitable", Map.of("volume", volume, "pool", pool, "error", ex.getMessage()), ex); } if (hypervisorType.equals(HypervisorType.VMware)) { @@ -7786,10 +7838,10 @@ private Map getVolumePoolMappingForMigrateVmWithStorage(VMInstanceVO Pair volumeDiskProfilePair = new Pair<>(volume, diskProfile); boolean isStoragePoolStoragepolicyCompliance = storageManager.isStoragePoolCompliantWithStoragePolicy(Arrays.asList(volumeDiskProfilePair), pool); if (!isStoragePoolStoragepolicyCompliance) { - throw new CloudRuntimeException(String.format("Storage pool %s is not storage policy compliance with the volume %s", pool.getUuid(), volume.getUuid())); + throw Exceptions.cloudRuntimeException("vm.migrate.storage.volume.policy.noncompliant", Map.of("pool", pool, "volume", volume)); } } catch (StorageUnavailableException e) { - throw new CloudRuntimeException(String.format("Could not verify storage policy compliance against storage pool %s due to exception %s", pool.getUuid(), e.getMessage())); + throw Exceptions.cloudRuntimeException("vm.migrate.storage.volume.policy.verify.failed", Map.of("pool", pool, "error", e.getMessage())); } } } @@ -7811,7 +7863,7 @@ protected Host chooseVmMigrationDestinationUsingVolumePoolMap(VMInstanceVO vm, H } DeployDestination deployDestination = chooseVmMigrationDestination(vm, srcHost, poolId); if (deployDestination == null || deployDestination.getHost() == null) { - throw new CloudRuntimeException("Unable to find suitable destination to migrate VM " + vm.getInstanceName()); + throw Exceptions.cloudRuntimeException("vm.migrate.destination.not.found", Map.of("instance", vm)); } return deployDestination.getHost(); } @@ -7826,12 +7878,12 @@ public VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host destinatio if (logger.isDebugEnabled()) { logger.debug("Caller is not a root admin, permission denied to migrate the VM"); } - throw new PermissionDeniedException("No permission to migrate VM, Only Root Admin can migrate a VM!"); + throw Exceptions.permissionDeniedException("vm.migrate.permission.denied"); } VMInstanceVO vm = _vmInstanceDao.findById(vmId); if (vm == null) { - throw new InvalidParameterValueException("Unable to find the VM by ID " + vmId); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.vm.not.found"); } // OfflineVmwareMigration: this would be it ;) if multiple paths exist: unify @@ -7840,25 +7892,20 @@ public VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host destinatio if (logger.isDebugEnabled()) { logger.debug("VM is not Running, unable to migrate the vm " + vm); } - CloudRuntimeException ex = new CloudRuntimeException(String.format("Unable to migrate the VM %s (ID: %s) as it is not in Running state", vm.getInstanceName(), vm.getUuid())); - ex.addProxyObject(vm.getUuid(), "vmId"); - throw ex; + throw Exceptions.cloudRuntimeException("vm.migrate.storage.vm.not.running"); } if (serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) { - throw new InvalidParameterValueException("Live Migration of GPU enabled VM is not supported"); + throw Exceptions.invalidParameterValueException("vm.migrate.gpu.not.supported"); } if (!vm.getHypervisorType().isFunctionalitySupported(Functionality.VmStorageMigration)) { - throw new InvalidParameterValueException( - String.format("Unsupported hypervisor: %s for VM migration, we support [%s] only", - vm.getHypervisorType(), - HypervisorType.getListOfHypervisorsSupportingFunctionality(Functionality.VmStorageMigration))); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.hypervisor.not.supported", Map.of("hypervisorType", vm.getHypervisorType())); } if (!vm.getHypervisorType().isFunctionalitySupported(Functionality.VmStorageMigrationWithSnapshots) && CollectionUtils.isNotEmpty(_vmSnapshotDao.findByVm(vmId))) { - throw new InvalidParameterValueException("Instance with Instance Snapshots cannot be migrated with storage, please remove all Instance Snapshots"); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.instance.snapshots.exist"); } Pair sourceDestinationHosts = getHostsForMigrateVmWithStorage(vm, destinationHost); @@ -7871,8 +7918,7 @@ public VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host destinatio if (!VirtualMachine.Type.User.equals(vm.getType())) { return migrateVirtualMachine(vmId, destinationHost); } - throw new InvalidParameterValueException(String.format("Migration of the VM: %s (ID: %s) from host %s (ID: %s) to destination host %s (ID: %s) doesn't involve migrating the volumes", - vm.getInstanceName(), vm.getUuid(), srcHost.getName(), srcHost.getUuid(), destinationHost.getName(), destinationHost.getUuid())); + throw Exceptions.invalidParameterValueException("vm.migrate.storage.no.volume.migration", Map.of("instance", vm, "srcHost", srcHost, "destHost", destinationHost)); } Map volToPoolObjectMap = getVolumePoolMappingForMigrateVmWithStorage(vm, volumeToPool); @@ -7921,7 +7967,7 @@ public UserVm moveVmToUser(final AssignVMCmd cmd) throws ResourceAllocationExcep Long callerId = caller.getId(); logger.trace("Verifying if caller [{}] is root or domain admin.", caller); if (!_accountMgr.isRootAdmin(callerId) && !_accountMgr.isDomainAdmin(callerId)) { - throw new InvalidParameterValueException(String.format("Only root or domain admins are allowed to assign VMs. Caller [%s] is of type [%s].", caller, caller.getType())); + throw Exceptions.invalidParameterValueException("vm.assign.permission.denied", Map.of("caller", caller, "callerType", caller.getType())); } Long vmId = cmd.getVmId(); @@ -7940,7 +7986,7 @@ public UserVm moveVmToUser(final AssignVMCmd cmd) throws ResourceAllocationExcep logger.trace("Verifying if the provided domain ID [{}] is valid.", domainId); if (projectId != null && domainId == null) { - throw new InvalidParameterValueException("Please provide a valid domain ID; cannot assign VM to a project if domain ID is NULL."); + throw Exceptions.invalidParameterValueException("vm.assign.domain.id.null"); } validateIfVmHasNoRules(vm, vmId); @@ -7989,11 +8035,11 @@ protected void validateIfVmSupportsMigration(UserVmVO vm, Long vmId) { logger.trace("Validating if VM [{}] exists and is not in state [{}].", vmId, State.Running); if (vm == null) { - throw new InvalidParameterValueException(String.format("There is no VM by ID [%s].", vmId)); + throw Exceptions.invalidParameterValueException("vm.assign.vm.not.found"); } else if (vm.getState() == State.Running) { - throw new InvalidParameterValueException(String.format("Unable to move VM [%s] in [%s] state.", vm, vm.getState())); + throw Exceptions.invalidParameterValueException("vm.assign.vm.not.right.state", Map.of("instance", vm, "instanceState", vm.getState())); } else if (UserVmManager.SHAREDFSVM.equals(vm.getUserVmType())) { - throw new InvalidParameterValueException("Migration is not supported for Shared FileSystem Instances."); + throw Exceptions.invalidParameterValueException("vm.assign.sharedfs.not.supported"); } } @@ -8009,23 +8055,23 @@ protected void validateIfVmHasNoRules(UserVmVO vm, Long vmId) throws InvalidPara List portForwardingRules = _portForwardingDao.listByVm(vmId); if (CollectionUtils.isNotEmpty(portForwardingRules)) { - throw new InvalidParameterValueException(String.format("Remove any Port Forwarding rules for VM [%s] before assigning it to another user.", vm)); + throw Exceptions.invalidParameterValueException("vm.assign.portforwarding.rules.exist", Map.of("instance", vm)); } List staticNatRules = _rulesDao.listStaticNatByVmId(vmId); if (CollectionUtils.isNotEmpty(staticNatRules)) { - throw new InvalidParameterValueException(String.format("Remove the StaticNat rules for VM [%s] before assigning it to another user.", vm)); + throw Exceptions.invalidParameterValueException("vm.assign.staticnat.rules.exist", Map.of("instance", vm)); } List loadBalancerVmMaps = _loadBalancerVMMapDao.listByInstanceId(vmId); if (CollectionUtils.isNotEmpty(loadBalancerVmMaps)) { - throw new InvalidParameterValueException(String.format("Remove the Load Balancing rules for VM [%s] before assigning it to another user.", vm)); + throw Exceptions.invalidParameterValueException("vm.assign.loadbalancer.rules.exist", Map.of("instance", vm)); } List ips = _ipAddressDao.findAllByAssociatedVmId(vmId); for (IPAddressVO ip : ips) { if (ip.isOneToOneNat()) { - throw new InvalidParameterValueException(String.format("Remove the One to One Nat rule for VM [%s] for IP [%s].", vm, ip)); + throw Exceptions.invalidParameterValueException("vm.assign.onetoonat.rule.exists", Map.of("instance", vm, "ip", ip)); } } } @@ -8036,8 +8082,7 @@ protected void validateIfVolumesHaveNoSnapshots(List volumes) throws I logger.trace("Verifying snapshots for volume [{}].", volume); List snapshots = _snapshotDao.listByStatusNotIn(volume.getId(), Snapshot.State.Destroyed, Snapshot.State.Error); if (CollectionUtils.isNotEmpty(snapshots)) { - throw new InvalidParameterValueException(String.format("Snapshots exist for volume [%s]. Detach volume or remove snapshots for the volume before assigning VM to " - + "another user.", volume.getName())); + throw Exceptions.invalidParameterValueException("vm.assign.volume.snapshots.exist", Map.of("volume", volume)); } } } @@ -8073,7 +8118,7 @@ protected void validateIfNewOwnerHasAccessToTemplate(UserVmVO vm, Account newAcc logger.trace("Validating if new owner [{}] has access to the template specified for VM [{}].", newAccount, vm); if (template == null) { - throw new InvalidParameterValueException(String.format("Template for VM [%s] cannot be found.", vm.getUuid())); + throw Exceptions.invalidParameterValueException("vm.assign.template.not.found", Map.of("instance", vm)); } logger.debug("Verifying if new owner [{}] has access to the template [{}].", newAccount, template.getUuid()); @@ -8081,7 +8126,7 @@ protected void validateIfNewOwnerHasAccessToTemplate(UserVmVO vm, Account newAcc _accountMgr.checkAccess(newAccount, AccessType.UseEntry, true, template); } catch (PermissionDeniedException e) { String newMsg = String.format("New owner [%s] does not have access to the template specified for VM [%s].", newAccount, vm); - throw new PermissionDeniedException(newMsg, e); + throw Exceptions.permissionDeniedException("vm.assign.template.access.denied", Map.of("account", newAccount, "instance", vm)); } } @@ -8109,7 +8154,7 @@ protected Network ensureDestinationNetwork(AssignVMCmd cmd, UserVmVO vm, Account return null; } if (CollectionUtils.isNotEmpty(securityGroupIdList)) { - throw new InvalidParameterValueException("Cannot move VM with security groups; security group feature is not enabled in this zone."); + throw Exceptions.invalidParameterValueException("vm.assign.securitygroup.zone.not.enabled"); } LinkedHashSet applicableNetworks = new LinkedHashSet<>(); @@ -8135,13 +8180,11 @@ protected Network ensureDestinationNetwork(AssignVMCmd cmd, UserVmVO vm, Account protected NetworkOfferingVO getOfferingWithRequiredAvailabilityForNetworkCreation() { List requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false); if (CollectionUtils.isEmpty(requiredOfferings)) { - throw new InvalidParameterValueException(String.format("Unable to find network offering with availability [%s] to automatically create the network as a part of VM " - + "creation.", Availability.Required)); + throw Exceptions.invalidParameterValueException("vm.assign.network.offering.required.not.found"); } NetworkOfferingVO firstRequiredOffering = requiredOfferings.get(0); if (firstRequiredOffering.getState() != NetworkOffering.State.Enabled) { - throw new InvalidParameterValueException(String.format("Required network offering ID [%s] is not in [%s] state.", firstRequiredOffering.getId(), - NetworkOffering.State.Enabled)); + throw Exceptions.invalidParameterValueException("vm.assign.network.offering.required.not.enabled", Map.of("offering", firstRequiredOffering)); } return firstRequiredOffering; } @@ -8190,7 +8233,7 @@ protected void executeStepsToChangeOwnershipOfVm(AssignVMCmd cmd, Account caller try { updateVmNetwork(cmd, caller, vm, newAccount, template); } catch (InsufficientCapacityException | ResourceAllocationException e) { - throw new CloudRuntimeException(String.format("Unable to update networks when assigning VM [%s] due to [%s].", vm, e.getMessage()), e); + throw Exceptions.cloudRuntimeException("vm.assign.networks.update.failed", Map.of("instance", vm), e); } logger.trace(String.format("Incrementing new account [%s] resource count.", newAccount)); @@ -8290,19 +8333,19 @@ protected void validateOldAndNewAccounts(Account oldAccount, Account newAccount, logger.trace("Validating old [{}] and new accounts [{}].", oldAccount, newAccount); if (oldAccount == null) { - throw new InvalidParameterValueException(String.format("Invalid old account [%s] for VM in domain [%s].", oldAccountId, domainId)); + throw Exceptions.invalidParameterValueException("vm.assign.old.account.invalid", Map.of("account", oldAccountId, "domain", domainId)); } if (newAccount == null) { - throw new InvalidParameterValueException(String.format("Invalid new account [%s] for VM in domain [%s].", newAccountName, domainId)); + throw Exceptions.invalidParameterValueException("vm.assign.new.account.invalid", Map.of("account", newAccountName, "domain", domainId)); } if (newAccount.getState() == Account.State.DISABLED) { - throw new InvalidParameterValueException(String.format("The new account owner [%s] is disabled.", newAccount)); + throw Exceptions.invalidParameterValueException("vm.assign.new.account.disabled", Map.of("account", newAccount)); } if (oldAccount.getAccountId() == newAccount.getAccountId()) { - throw new InvalidParameterValueException(String.format("The new account [%s] is the same as the old account.", newAccount)); + throw Exceptions.invalidParameterValueException("vm.assign.same.account", Map.of("account", newAccount)); } } @@ -8337,7 +8380,7 @@ protected void updateBasicTypeNetworkForVm(UserVmVO vm, Account newAccount, Virt DataCenterVO zone, List networkIdList, List securityGroupIdList) throws InsufficientCapacityException { if (networkIdList != null && !networkIdList.isEmpty()) { - throw new InvalidParameterValueException("Cannot move VM with Network IDs; this is a basic zone VM."); + throw Exceptions.invalidParameterValueException("vm.assign.basic.zone.network.ids.not.allowed"); } logger.trace("Cleanup of old security groups for VM [{}]. They will be recreated for the new account once the VM is started.", vm); @@ -8398,7 +8441,7 @@ protected void updateAdvancedTypeNetworkForVm(Account caller, UserVmVO vm, Accou NetworkVO defaultNetwork = addNicsToApplicableNetworksAndReturnDefaultNetwork(applicableNetworks, requestedIPv4ForNics, requestedIPv6ForNics, networks); if (applicableNetworks.isEmpty()) { - throw new InvalidParameterValueException("No network is specified, please specify one when you move the VM. For now, please add a network to VM on NICs tab."); + throw Exceptions.invalidParameterValueException("vm.assign.advanced.sg.no.network"); } else { allocateNetworksForVm(vm, networks); } @@ -8408,7 +8451,7 @@ protected void updateAdvancedTypeNetworkForVm(Account caller, UserVmVO vm, Accou } if (securityGroupIdList != null && !securityGroupIdList.isEmpty()) { - throw new InvalidParameterValueException("Cannot move VM with security groups; security group feature is not enabled in this zone."); + throw Exceptions.invalidParameterValueException("vm.assign.securitygroup.zone.not.enabled"); } addNetworksToNetworkIdList(vm, newAccount, networkIdList, applicableNetworks, requestedIPv4ForNics, requestedIPv6ForNics); @@ -8435,7 +8478,7 @@ protected void addDefaultNetworkToNetworkList(List networkList, Netwo logger.trace("Adding default network to network list."); if (defaultNetwork == null) { - throw new InvalidParameterValueException("Unable to find a default network to start a VM."); + throw Exceptions.invalidParameterValueException("vm.assign.default.network.not.found"); } networkList.add(_networkDao.findById(defaultNetwork.getId())); @@ -8455,7 +8498,7 @@ protected void addSecurityGroupsToVm(Account newAccount, UserVmVO vm, VirtualMac boolean isVmWare = (template.getHypervisorType() == HypervisorType.VMware); if (securityGroupIdList != null && isVmWare) { - throw new InvalidParameterValueException("Security group feature is not supported for VMWare hypervisor."); + throw Exceptions.invalidParameterValueException("vm.assign.securitygroup.vmware.not.supported"); } else if (!isVmWare && (defaultNetwork == null || _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork)) && _networkModel.canAddDefaultSecurityGroup()) { if (securityGroupIdList == null) { securityGroupIdList = new ArrayList<>(); @@ -8540,7 +8583,7 @@ protected void selectApplicableNetworkToCreateVm(Account newAccount, DataCenterV NetworkVO defaultNetwork; List virtualNetworks = _networkModel.listNetworksForAccount(newAccount.getId(), zone.getId(), Network.GuestType.Isolated); if (virtualNetworks.isEmpty()) { - throw new CloudRuntimeException(String.format("Could not find an applicable network to create virtual machine for account [%s].", newAccount)); + throw Exceptions.cloudRuntimeException("vm.assign.applicable.network.not.found", Map.of("account", newAccount)); } else if (virtualNetworks.size() > 1) { throw new InvalidParameterValueException(String.format("More than one default isolated network has been found for account [%s]; please specify networkIDs.", newAccount)); @@ -8636,16 +8679,14 @@ protected void addAdditionalNetworksToVm(UserVmVO vm, Account newAccount, List rootVols = _volsDao.findByInstanceAndType(vmId, Volume.Type.ROOT); if (rootVols.isEmpty()) { - InvalidParameterValueException ex = new InvalidParameterValueException("Can not find root volume for VM " + vm.getUuid()); - ex.addProxyObject(vm.getUuid(), "vmId"); - throw ex; + throw Exceptions.invalidParameterValueException("vm.restore.root.volume.not.found", Map.of("instance", vm)); } if (rootVols.size() > 1 && currentTemplate != null && !currentTemplate.isDeployAsIs()) { - InvalidParameterValueException ex = new InvalidParameterValueException("There are " + rootVols.size() + " root volumes for VM " + vm.getUuid()); - ex.addProxyObject(vm.getUuid(), "vmId"); - throw ex; + throw Exceptions.invalidParameterValueException("vm.restore.multiple.root.volumes", Map.of("count", rootVols.size(), "instance", vm)); } // If target VM has associated VM snapshots then don't allow restore of VM List vmSnapshots = _vmSnapshotDao.findByVm(vmId); if (vmSnapshots.size() > 0) { - throw new InvalidParameterValueException("Unable to restore Instance, please remove Instance Snapshots before restoring Instance"); + throw Exceptions.invalidParameterValueException("vm.restore.snapshots.exist"); } VMTemplateVO template = getRestoreVirtualMachineTemplate(caller, newTemplateId, rootVols, vm); @@ -8969,9 +9000,7 @@ public UserVm restoreVirtualMachine(final Account caller, final long vmId, final _itMgr.stop(vm.getUuid()); } catch (ResourceUnavailableException e) { logger.debug("Stop vm {} failed", vm, e); - CloudRuntimeException ex = new CloudRuntimeException("Stop vm failed for specified vmId"); - ex.addProxyObject(vm.getUuid(), "vmId"); - throw ex; + throw Exceptions.cloudRuntimeException("vm.restore.stop.failed"); } } @@ -9073,7 +9102,7 @@ public Pair doInTransaction(final TransactionStatus status) th password = _mgr.generateRandomPassword(); boolean result = resetVMPasswordInternal(vmId, password); if (!result) { - throw new CloudRuntimeException("VM reset is completed but failed to reset password for the virtual machine "); + throw Exceptions.cloudRuntimeException("vm.restore.password.reset.failed"); } vm.setPassword(password); } @@ -9100,9 +9129,7 @@ public Pair doInTransaction(final TransactionStatus status) th } } catch (Exception e) { logger.debug("Unable to start VM " + vm.getUuid(), e); - CloudRuntimeException ex = new CloudRuntimeException("Unable to start VM with specified id" + e.getMessage()); - ex.addProxyObject(vm.getUuid(), "vmId"); - throw ex; + throw Exceptions.cloudRuntimeException("vm.restore.start.failed"); } } @@ -9111,7 +9138,7 @@ public Pair doInTransaction(final TransactionStatus status) th } catch (ResourceAllocationException e) { logger.error("Failed to restore VM {} due to {}", vm, e.getMessage(), e); - throw new CloudRuntimeException("Failed to restore VM " + vm.getUuid() + " due to " + e.getMessage(), e); + throw Exceptions.cloudRuntimeException("vm.restore.failed", Map.of("instance", vm), e); } finally { ReservationHelper.closeAll(reservations); } @@ -9219,12 +9246,12 @@ private void checkRestoreVmFromTemplate(UserVmVO vm, VMTemplateVO template, List if (!template.isDirectDownload()) { tmplStore = _templateStoreDao.findByTemplateZoneReady(template.getId(), vm.getDataCenterId()); if (tmplStore == null) { - throw new InvalidParameterValueException("Cannot restore the vm as the template " + template.getUuid() + " isn't available in the zone"); + throw Exceptions.invalidParameterValueException("vm.restore.template.not.available.in.zone", Map.of("template", template)); } } else { tmplStore = _templateStoreDao.findByTemplate(template.getId(), DataStoreRole.Image); if (tmplStore == null || (tmplStore != null && !tmplStore.getDownloadState().equals(VMTemplateStorageResourceAssoc.Status.BYPASSED))) { - throw new InvalidParameterValueException("Cannot restore the vm as the bypassed template " + template.getUuid() + " isn't available in the zone"); + throw Exceptions.invalidParameterValueException("vm.restore.template.bypassed.not.available", Map.of("template", template)); } } @@ -9304,7 +9331,7 @@ else if (host.getHypervisorType() == HypervisorType.KVM) { cmd = null; } else { - throw new CloudRuntimeException("This hypervisor type is not supported on managed storage for this command."); + throw Exceptions.cloudRuntimeException("vm.restore.managed.storage.hypervisor.not.supported"); } if (cmd != null) { @@ -9323,7 +9350,7 @@ else if (host.getHypervisorType() == HypervisorType.KVM) { if (!answer.getResult()) { logger.warn("Failed to reset vm {} due to: {}", vm, answer.getDetails()); - throw new CloudRuntimeException("Unable to reset " + vm + " due to " + answer.getDetails()); + throw Exceptions.cloudRuntimeException("vm.restore.managed.storage.reset.failed", Map.of("instance", vm)); } } } @@ -9399,7 +9426,7 @@ private void encryptAndStorePassword(UserVmVO vm, String password) { } String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(sshPublicKeys, password); if (encryptedPasswd == null) { - throw new CloudRuntimeException("Error encrypting password"); + throw Exceptions.cloudRuntimeException("vm.password.encrypt.failed"); } vm.setDetail(VmDetailConstants.ENCRYPTED_PASSWORD, encryptedPasswd); @@ -9437,7 +9464,7 @@ public ConfigKey[] getConfigKeys() { public String getVmUserData(long vmId) { UserVmVO vm = _vmDao.findById(vmId); if (vm == null) { - throw new InvalidParameterValueException("Unable to find virtual machine with id " + vmId); + throw Exceptions.invalidParameterValueException("vm.userdata.vm.not.found"); } _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, vm); @@ -9490,7 +9517,7 @@ private void checkForUnattachedVolumes(long vmId, List volumes) { } if (!StringUtils.isEmpty(sb.toString())) { - throw new InvalidParameterValueException("The following supplied volumes are not DATADISK attached to the VM: " + sb); + throw Exceptions.invalidParameterValueException("vm.destroy.volumes.not.attached"); } } @@ -9498,12 +9525,10 @@ private void validateVolumes(List volumes) { for (VolumeVO volume : volumes) { if (!(volume.getVolumeType() == Volume.Type.ROOT || volume.getVolumeType() == Volume.Type.DATADISK)) { - throw new InvalidParameterValueException("Please specify volume of type " + Volume.Type.DATADISK + " or " + Volume.Type.ROOT); + throw Exceptions.invalidParameterValueException("vm.destroy.volume.type.invalid"); } if (volume.isDeleteProtection()) { - throw new InvalidParameterValueException(String.format( - "Volume [id = %s, name = %s] has delete protection enabled and cannot be deleted", - volume.getUuid(), volume.getName())); + throw Exceptions.invalidParameterValueException("vm.destroy.volume.delete.protection", Map.of("volume", volume)); } } } @@ -9574,10 +9599,10 @@ public UserVm importVM(final DataCenter zone, final Host host, final VirtualMach final VirtualMachine.PowerState powerState, final LinkedHashMap> networkNicMap) throws InsufficientCapacityException { return Transaction.execute((TransactionCallbackWithException) status -> { if (zone == null) { - throw new InvalidParameterValueException("Unable to import virtual machine with invalid zone"); + throw Exceptions.invalidParameterValueException("vm.import.zone.invalid"); } if (host == null && hypervisorType == HypervisorType.VMware) { - throw new InvalidParameterValueException("Unable to import virtual machine with invalid host"); + throw Exceptions.invalidParameterValueException("vm.import.host.invalid"); } final long id = _vmDao.getNextInSequence(Long.class, "id"); @@ -9605,7 +9630,7 @@ public UserVm importVM(final DataCenter zone, final Host host, final VirtualMach public Pair unmanageUserVM(Long vmId, Long paramHostId) { UserVmVO vm = _vmDao.findById(vmId); if (vm == null || vm.getRemoved() != null) { - throw new InvalidParameterValueException("Unable to find a VM with ID = " + vmId); + throw Exceptions.invalidParameterValueException("vm.unmanage.vm.not.found"); } vm = _vmDao.acquireInLockTable(vm.getId()); @@ -9614,7 +9639,7 @@ public Pair unmanageUserVM(Long vmId, Long paramHostId) { if (vm.getState() != State.Running && vm.getState() != State.Stopped) { String errorMsg = "Instance: " + vm.getName() + " is not running or stopped, cannot be unmanaged"; logger.debug(errorMsg); - throw new CloudRuntimeException(errorMsg); + throw Exceptions.cloudRuntimeException("vm.unmanage.vm.not.right.state", Map.of("instance", vm)); } if (!UnmanagedVMsManager.isSupported(vm.getHypervisorType())) { @@ -9632,7 +9657,7 @@ public Pair unmanageUserVM(Long vmId, Long paramHostId) { unmanageVMFromDB(vm.getId()); publishUnmanageVMUsageEvents(vm, volumes); } else { - throw new CloudRuntimeException("Error while unmanaging VM: " + vm.getUuid()); + throw Exceptions.cloudRuntimeException("vm.unmanage.failed", Map.of("instance", vm)); } return result; } catch (Exception e) { @@ -9656,9 +9681,7 @@ private void updateDetailsWithRootDiskAttributes(Map details, Vm private void checkRootDiskSizeAgainstBackup(Long instanceVolumeSize,DiskOffering rootDiskOffering, Long backupVolumeSize) { long instanceRootDiskSize = rootDiskOffering.isCustomized() ? instanceVolumeSize : rootDiskOffering.getDiskSize() / GiB_TO_BYTES; if (instanceRootDiskSize < backupVolumeSize) { - throw new InvalidParameterValueException( - String.format("Instance volume root disk size %d[GiB] cannot be less than the backed-up volume size %d[GiB].", - instanceVolumeSize, backupVolumeSize)); + throw Exceptions.invalidParameterValueException("vm.backup.root.disk.size.smaller.than.backup", Map.of("instanceSize", instanceVolumeSize, "backupSize", backupVolumeSize)); } } @@ -9666,22 +9689,22 @@ private void checkRootDiskSizeAgainstBackup(Long instanceVolumeSize,DiskOffering public UserVm allocateVMFromBackup(CreateVMFromBackupCmd cmd) throws InsufficientCapacityException, ResourceAllocationException, ResourceUnavailableException { BackupVO backup = backupDao.findById(cmd.getBackupId()); if (backup == null) { - throw new InvalidParameterValueException("Backup " + cmd.getBackupId() + " does not exist"); + throw Exceptions.invalidParameterValueException("vm.backup.not.found"); } backupManager.validateBackupForZone(backup.getZoneId()); if (!backupManager.canCreateInstanceFromBackup(cmd.getBackupId())) { - throw new CloudRuntimeException("Create instance from backup is not supported for this provider."); + throw Exceptions.cloudRuntimeException("vm.backup.create.instance.not.supported"); } DataCenter targetZone = _dcDao.findById(cmd.getZoneId()); if (targetZone == null) { - throw new InvalidParameterValueException("Unable to find zone by id=" + cmd.getZoneId()); + throw Exceptions.invalidParameterValueException("vm.backup.zone.not.found"); } if (cmd.getZoneId() != backup.getZoneId() && !backupManager.canCreateInstanceFromBackupAcrossZones(cmd.getBackupId())) { - throw new CloudRuntimeException("Create Instance from Backup on another Zone is not supported by this provider or the Backup Repository."); + throw Exceptions.cloudRuntimeException("vm.backup.cross.zone.not.supported"); } backupDao.loadDetails(backup); @@ -9695,16 +9718,16 @@ public UserVm allocateVMFromBackup(CreateVMFromBackupCmd cmd) throws Insufficien if (serviceOfferingId != null) { serviceOffering = serviceOfferingDao.findById(serviceOfferingId); if (serviceOffering == null) { - throw new InvalidParameterValueException("Unable to find service offering: " + serviceOffering.getId()); + throw Exceptions.invalidParameterValueException("vm.backup.service.offering.not.found"); } } else { String serviceOfferingUuid = backup.getDetail(ApiConstants.SERVICE_OFFERING_ID); if (serviceOfferingUuid == null) { - throw new CloudRuntimeException("Backup doesn't contain a Service Offering UUID. Please specify a valid Service Offering while creating the Instance"); + throw Exceptions.cloudRuntimeException("vm.backup.service.offering.uuid.missing"); } serviceOffering = serviceOfferingDao.findByUuid(serviceOfferingUuid); if (serviceOffering == null) { - throw new CloudRuntimeException("Unable to find Service Offering with the UUID stored in the Backup. Please specify a valid Service Offering while creating the Instance"); + throw Exceptions.cloudRuntimeException("vm.backup.service.offering.uuid.not.found"); } } verifyServiceOffering(cmd, serviceOffering); @@ -9714,16 +9737,16 @@ public UserVm allocateVMFromBackup(CreateVMFromBackupCmd cmd) throws Insufficien Long templateId = cmd.getTemplateId(); template = _templateDao.findById(templateId); if (template == null) { - throw new InvalidParameterValueException("Unable to use template " + templateId); + throw Exceptions.invalidParameterValueException("vm.backup.template.not.found"); } } else { String templateUuid = backup.getDetail(ApiConstants.TEMPLATE_ID); if (templateUuid == null) { - throw new CloudRuntimeException("Backup doesn't contain a Template UUID. Please specify a valid Template/ISO while creating the Instance"); + throw Exceptions.cloudRuntimeException("vm.backup.template.uuid.missing"); } template = _templateDao.findByUuid(templateUuid); if (template == null) { - throw new CloudRuntimeException("Unable to find Template with the UUID stored in the Backup. Please specify a valid Template/ISO while creating the Instance"); + throw Exceptions.cloudRuntimeException("vm.backup.template.uuid.not.found"); } } verifyTemplate(cmd, template, serviceOffering.getId()); @@ -9734,14 +9757,14 @@ public UserVm allocateVMFromBackup(CreateVMFromBackupCmd cmd) throws Insufficien boolean isIso = template.getFormat().equals(ImageFormat.ISO); if (diskOfferingId != null) { if (!isIso) { - throw new InvalidParameterValueException(ApiConstants.DISK_OFFERING_ID + " parameter is supported for creating instance from backup only for ISO. For creating VMs with templates, please use the parameter " + ApiConstants.DATADISKS_DETAILS); + throw Exceptions.invalidParameterValueException("vm.backup.disk.offering.iso.only"); } DiskOffering diskOffering = _diskOfferingDao.findById(diskOfferingId); if (diskOffering == null) { - throw new InvalidParameterValueException("Unable to find disk offering " + diskOfferingId); + throw Exceptions.invalidParameterValueException("vm.backup.disk.offering.not.found"); } if (diskOffering.isComputeOnly()) { - throw new InvalidParameterValueException(String.format("The disk offering %s provided is directly mapped to a service offering, please provide an individual disk offering", diskOffering)); + throw Exceptions.invalidParameterValueException("vm.backup.disk.offering.compute.only", Map.of("diskOffering", diskOffering)); } } @@ -9951,7 +9974,7 @@ private void postProcessingUnmanageVMVolumes(List volumes, UserVmVO vm void checkUnmanagingVMOngoingVolumeSnapshots(UserVmVO vm) { logger.debug("Checking if there are any ongoing snapshots on the ROOT volumes associated with VM {}", vm); if (checkStatusOfVolumeSnapshots(vm, Volume.Type.ROOT)) { - throw new CloudRuntimeException("There is/are unbacked up snapshot(s) on ROOT volume, vm unmanage is not permitted, please try again later."); + throw Exceptions.cloudRuntimeException("vm.unmanage.unbacked.snapshots"); } logger.debug("Found no ongoing snapshots on volume of type ROOT, for the vm {}", vm); } @@ -9959,9 +9982,9 @@ void checkUnmanagingVMOngoingVolumeSnapshots(UserVmVO vm) { void checkUnmanagingVMVolumes(UserVmVO vm, List volumes) { for (VolumeVO volume : volumes) { if (volume.getInstanceId() == null || !volume.getInstanceId().equals(vm.getId())) { - throw new CloudRuntimeException(String.format("Invalid state for volume %s of VM %s: it is not attached to VM", volume, vm)); + throw Exceptions.cloudRuntimeException("vm.unmanage.volume.not.attached", Map.of("volume", volume, "instance", vm)); } else if (volume.getVolumeType() != Volume.Type.ROOT && volume.getVolumeType() != Volume.Type.DATADISK) { - throw new CloudRuntimeException(String.format("Invalid type for volume %s: ROOT or DATADISK expected but got %s", volume, volume.getVolumeType())); + throw Exceptions.cloudRuntimeException("vm.unmanage.volume.type.invalid", Map.of("volume", volume, "volumeType", volume.getVolumeType())); } } } @@ -9993,12 +10016,12 @@ private Network getNetworkForOvfNetworkMapping(DataCenter zone, Account owner) t if (zone.isSecurityGroupEnabled() || _networkModel.isSecurityGroupSupportedForZone(zone.getId())) { network = _networkModel.getNetworkWithSGWithFreeIPs(owner, zone.getId()); if (network == null) { - throw new InvalidParameterValueException("No network with security enabled is found in zone ID: " + zone.getUuid()); + throw Exceptions.invalidParameterValueException("vm.deploy.ovf.sg.network.not.found", Map.of("zone", zone)); } } else { network = getDefaultNetwork(zone, owner, true); if (network == null) { - throw new InvalidParameterValueException(String.format("Default network not found for zone ID: %s and account ID: %s", zone.getUuid(), owner.getUuid())); + throw Exceptions.invalidParameterValueException("vm.deploy.ovf.default.network.not.found", Map.of("zone", zone, "account", owner)); } } return network; From a20d0ac1116c469656ef784ae1d680fa589036c7 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Thu, 25 Jun 2026 12:00:00 +0530 Subject: [PATCH 2/2] wip: VirtualMachineManagerImpl changes Signed-off-by: Abhishek Kumar --- client/conf/error-messages.json.in | 100 ++++++- .../cloud/vm/VirtualMachineManagerImpl.java | 246 ++++++++---------- 2 files changed, 209 insertions(+), 137 deletions(-) diff --git a/client/conf/error-messages.json.in b/client/conf/error-messages.json.in index 3bf03d106bb2..063319f0bb22 100644 --- a/client/conf/error-messages.json.in +++ b/client/conf/error-messages.json.in @@ -432,5 +432,103 @@ "vm.migrate.storage.vm.not.running": "Instance is not Running. Unable to migrate the Instance with storage.", "vm.assign.network.not.found": "Unable to find network with specified ID.", "vm.restore.vm.not.found": "Unable to find Instance with specified ID.", - "vm.restore.template.iso.not.found": "Unable to find template or ISO for the specified volume and Instance." + "vm.restore.template.iso.not.found": "Unable to find template or ISO for the specified volume and Instance.", + "vm.allocate.concurrent.operation": "Concurrent operation occurred while trying to allocate resources for the Instance.", + "vm.expunge.operation.timeout": "Operation timed out while expunging the Instance.", + "vm.expunge.concurrent.operation": "Concurrent operation while expunging the Instance.", + "vm.expunge.state.transition.failed": "Unable to expunge Instance {{instance}}: it is not in the correct state.", + "vm.expunge.command.failed": "Unable to expunge Instance {{instance}}: {{error}}.", + "vm.expunge.command.details.failed": "Unable to expunge Instance {{instance}}: {{error}}.", + "vm.start.concurrent.operation.exposed": "Unable to start Instance {{instance}}: {{error}}.", + "vm.start.concurrent.operation": "Unable to start Instance {{instance}} due to a concurrent operation.", + "vm.start.insufficient.capacity.exposed": "Unable to start Instance {{instance}}: {{error}}.", + "vm.start.insufficient.capacity": "Unable to start Instance {{instance}} due to insufficient capacity.", + "vm.start.network.unavailable": "Network is unavailable. Please contact your administrator.", + "vm.start.resource.unavailable": "Unable to start Instance {{instance}}: {{error}}.", + "vm.start.wrong.state": "Cannot start Instance {{instance}} in state {{state}}.", + "vm.start.template.not.found": "Template for the Instance cannot be found. Instance configuration needs to be updated.", + "vm.start.template.zone.not.found": "Template for the Instance cannot be found in this zone. Instance configuration needs to be updated.", + "vm.start.external.prepare.failed": "Failed to prepare Instance for external provisioning.", + "vm.start.affinity.conflict": "Unable to deploy Instance: affinity rules associated with the Instance conflict.", + "vm.start.deployment.failed.exposed": "Unable to start Instance: {{error}}.", + "vm.start.host.guid.not.found": "Unable to start Instance: host GUID does not exist in the database.", + "vm.start.systemvm.certificate.failed": "Failed to setup and secure agent for the system Instance {{instance}}.", + "vm.start.failed": "Unable to start Instance {{instance}}.", + "vm.network.zone.not.found": "Unable to find zone for the Instance's network.", + "vm.network.account.not.found": "Unable to find account for the Instance's network.", + "vm.network.domain.not.found": "Unable to find domain for the Instance's network.", + "vm.network.vpc.not.found": "Unable to find VPC for the Instance's network.", + "vm.stop.concurrent.operation": "Unable to stop Instance due to a concurrent operation.", + "vm.stop.forced.concurrent.operation": "Unable to stop Instance {{instance}} due to a concurrent operation.", + "vm.unmanage.kvm.no.host": "No available host to persist domain XML for Instance {{instance}}.", + "vm.unmanage.kvm.persist.failed": "Failed to persist domain XML for Instance {{instance}}.", + "vm.unmanage.kvm.command.failed": "Failed to send command to persist domain XML for Instance {{instance}}.", + "vm.stop.host.not.found": "Unable to stop Instance {{instance}}: host is not available.", + "vm.stop.host.preparing.maintenance": "Stop operation on Instance {{instance}} is not allowed as the host is preparing for maintenance mode.", + "vm.stop.state.transition.failed": "Unable to stop Instance {{instance}}: the Instance is not in the correct state.", + "vm.stop.cleanup.state.change.failed": "Unable to stop Instance {{instance}}.", + "vm.stop.cleanup.failed": "Failed to cleanup Instance {{instance}}.", + "vm.stop.not.stopping.state": "Unable to proceed with stopping Instance {{instance}} as it is not in 'Stopping' state.", + "vm.stop.answer.failed": "Unable to stop Instance {{instance}}: {{error}}.", + "vm.stop.no.answer": "Unable to stop Instance {{instance}}: no answer received from the hypervisor.", + "vm.stop.final.state.transition.failed": "Unable to stop Instance {{instance}}.", + "vm.stop.transaction.failed": "Unable to stop Instance {{instance}}.", + "vm.stop.no.transition": "Unable to stop Instance {{instance}}: {{error}}.", + "vm.destroy.state.transition.failed": "Unable to destroy Instance {{instance}}: it is not in the correct state.", + "vm.destroy.expunge.state.transition.failed": "Unable to expunge Instance {{instance}}: it is not in the correct state.", + "vm.destroy.no.transition": "Unable to destroy Instance {{instance}}: {{error}}.", + "vm.destroy.snapshots.delete.failed": "Unable to delete all snapshots for Instance {{instance}}.", + "vm.storage.migration.failed": "Failed to migrate storage for Instance {{instance}}: {{error}}.", + "vm.storage.migration.state.transition.failed": "Failed to change state of Instance {{instance}} after storage migration.", + "vm.migrate.pool.answer.failed": "Instance {{instance}} migration failed: {{error}}.", + "vm.migrate.pool.no.results": "No relevant migration results found.", + "vm.storage.migration.no.volume.mapping": "Unable to migrate Instance {{instance}}: missing volume to pool mapping.", + "vm.storage.migration.destination.failed": "Unable to migrate Instance: failed to create deployment destination with given volume to pool map.", + "vm.storage.migration.state.requested.failed": "Unable to migrate Instance {{instance}}.", + "vm.migrate.destination.pool.tags.mismatch": "Destination storage pool does not support the volume's disk offering due to tag mismatch.", + "vm.migrate.unregister.source.failed": "Failed to unregister Instance {{instance}} from source host {{host}} after migrating storage across datacenters.", + "vm.migrate.cross.cluster.volume.not.zone.wide": "Source and destination hosts are not in the same cluster and not all volumes are on zone-wide primary store; unable to migrate.", + "vm.migrate.state.transition.cancelled": "Migration cancelled: {{error}}.", + "vm.migrate.command.details": "Migration command failed: {{error}}.", + "vm.migrate.verification.failed": "Unable to complete migration for Instance {{instance}}: Instance not found on destination host.", + "vm.migrate.with.volume.pool.no.access": "Cannot migrate the volume to the storage pool: the target host does not have access to the specified storage pool.", + "vm.migrate.managed.storage.pool.mismatch": "A volume on managed storage can only be migrated to itself.", + "vm.migrate.managed.storage.no.access": "The target host does not have access to the volume's managed storage pool.", + "vm.migrate.no.storage.pools.available": "There are no storage pools available at the target to migrate the volume.", + "vm.migrate.with.volume.empty.map": "Migration of the Instance does not involve migrating any volumes.", + "vm.migrate.with.volume.verification.failed": "Unable to complete migration with volumes for Instance {{instance}}: Instance not found on destination host.", + "vm.migrate.checkpoint.recreation.failed": "Failed to recreate checkpoints after migration.", + "vm.migrate.away.vm.not.found": "Unable to find Instance to migrate away.", + "vm.migrate.away.no.host": "Unable to migrate Instance {{instance}} as it does not have a host id.", + "vm.migrate.away.affinity.conflict": "Unable to create deployment for migrating Instance {{instance}}: affinity rules conflict.", + "vm.migrate.away.failed": "Unable to migrate Instance {{instance}}.", + "vm.reboot.concurrent.operation": "Unable to reboot Instance due to a concurrent operation.", + "vm.reboot.active.snapshots": "Unable to reboot Instance {{instance}} as it has active Instance Snapshot tasks.", + "vm.reboot.host.not.found": "Unable to retrieve host for Instance {{instance}}.", + "vm.reboot.answer.failed": "Unable to reboot Instance {{instance}} on host {{host}}: {{error}}.", + "vm.reboot.operation.timeout": "Failed to reboot Instance {{instance}} on host {{host}}: operation timed out.", + "vm.upgrade.serviceoffering.null": "Unable to upgrade Instance: new service offering cannot be null.", + "vm.upgrade.serviceoffering.inactive": "Unable to upgrade Instance: service offering {{serviceOffering}} is inactive.", + "vm.upgrade.vm.wrong.state": "Unable to upgrade Instance {{instance}} in state {{instanceState}}; make sure the Instance is stopped or running.", + "vm.upgrade.same.serviceoffering": "Not upgrading Instance {{instance}} since it already has the requested service offering {{serviceOffering}}.", + "vm.upgrade.system.use.mismatch": "Unable to upgrade Instance: the system use property differs between the current and new service offering.", + "vm.upgrade.insufficient.resources": "Unable to upgrade Instance: not enough resources available for the new service offering.", + "vm.upgrade.disk.offering.tags.mismatch": "Unable to upgrade Instance: the current service offering tags must be a subset of the new service offering tags.", + "vm.upgrade.storage.local.to.shared": "Unable to upgrade Instance {{instance}}: target service offering uses local storage but the volume is in a shared storage pool.", + "vm.upgrade.storage.shared.to.local": "Unable to upgrade Instance {{instance}}: target service offering uses shared storage but the volume is in a local storage pool.", + "vm.scale.vm.not.found": "Unable to find Instance to scale.", + "vm.scale.no.host": "Unable to scale Instance {{instance}}: it does not have a host id.", + "vm.scale.affinity.conflict": "Unable to create deployment for scaling Instance {{instance}}: affinity rules conflict.", + "vm.scale.source.host.not.found": "Unable to find source host for Instance scaling migration.", + "vm.scale.cross.cluster.not.supported": "Source and destination hosts are not in the same cluster; unable to migrate for scaling.", + "vm.scale.vm.not.found.retry": "Unable to find Instance for scale migration.", + "vm.scale.vm.not.running": "Instance {{instance}} is not in Running state; unable to migrate for scaling.", + "vm.scale.migrate.failed": "Unable to migrate Instance {{instance}} for scaling: {{error}}.", + "vm.scale.migrate.verification.failed": "Unable to complete migration for scaling Instance {{instance}}: Instance not found on destination.", + "vm.scale.reconfigure.answer.failed": "Unable to scale Instance: {{error}}.", + "vm.migrate.concurrent.jobs.exceeded": "Number of concurrent migration jobs per datastore exceeded the threshold. Please try again after some time.", + "vm.addnic.pending.jobs.exceeded": "There are too many pending jobs to add network {{network}} to Instance {{instance}}.", + "vm.stop.work.vm.not.found": "Unable to find Instance to stop.", + "vm.updatenic.default.nic.not.found": "Unable to find the default NIC for the Instance.", + "vm.start.orchestrate.failed": "Unable to orchestrate the start of Instance {{instance}}." } diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index b69491b64668..63ccf25d8a29 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -72,6 +72,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.error.Exceptions; import org.apache.cloudstack.framework.ca.Certificate; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; @@ -204,6 +205,7 @@ import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientServerCapacityException; import com.cloud.exception.InvalidParameterValueException; +import org.apache.cloudstack.context.ResponseMessageResolver; import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; @@ -568,7 +570,7 @@ public void allocate(final String vmInstanceName, final VirtualMachineTemplate t _networkMgr.allocate(vmProfile, auxiliaryNetworks, extraDhcpOptions); } } catch (final ConcurrentOperationException e) { - throw new CloudRuntimeException("Concurrent operation while trying to allocate resources for the VM", e); + throw Exceptions.cloudRuntimeException("vm.allocate.concurrent.operation", Map.of(), e); } logger.debug("Allocating disks for {}", persistedVm); @@ -656,9 +658,9 @@ public void expunge(final String vmUuid) throws ResourceUnavailableException { try { advanceExpunge(vmUuid); } catch (final OperationTimedoutException e) { - throw new CloudRuntimeException("Operation timed out", e); + throw Exceptions.cloudRuntimeException("vm.expunge.operation.timeout", Map.of(), e); } catch (final ConcurrentOperationException e) { - throw new CloudRuntimeException("Concurrent operation ", e); + throw Exceptions.cloudRuntimeException("vm.expunge.concurrent.operation", Map.of(), e); } } @@ -699,12 +701,12 @@ protected void advanceExpunge(VMInstanceVO vm) throws ResourceUnavailableExcepti try { if (!stateTransitTo(vm, VirtualMachine.Event.ExpungeOperation, vm.getHostId())) { logger.debug("Unable to expunge the vm because it is not in the correct state: " + vm); - throw new CloudRuntimeException("Unable to expunge " + vm); + throw Exceptions.cloudRuntimeException("vm.expunge.state.transition.failed", Map.of("instance", vm)); } } catch (final NoTransitionException e) { logger.debug("Unable to expunge the vm because it is not in the correct state: " + vm); - throw new CloudRuntimeException("Unable to expunge " + vm, e); + throw Exceptions.cloudRuntimeException("vm.expunge.state.transition.failed", Map.of("instance", vm), e); } logger.debug("Expunging vm " + vm); @@ -777,7 +779,7 @@ private void handleUnsuccessfulExpungeOperation(List finalizeExpungeCom for (final Answer answer : cmds.getAnswers()) { if (!answer.getResult()) { logger.warn("Failed to expunge vm due to: {}", answer.getDetails()); - throw new CloudRuntimeException(String.format("Unable to expunge %s due to %s", vm, answer.getDetails())); + throw Exceptions.cloudRuntimeException("vm.expunge.command.failed", Map.of("instance", vm, "error", answer.getDetails())); } } } @@ -806,7 +808,7 @@ protected void handleUnsuccessfulCommands(Commands cmds, VMInstanceVO vm) throws if (!answer.getResult()) { String message = String.format("Unable to expunge %s due to [%s].", vmToString, details); logger.error(message); - throw new CloudRuntimeException(message); + throw Exceptions.cloudRuntimeException("vm.expunge.command.details.failed", Map.of("instance", vmToString, "error", details)); } logger.debug("Commands [{}] to {} got answer [{}].", cmdsStr, vmToString, details); @@ -934,21 +936,21 @@ public void start(final String vmUuid, final Map doInTransaction(final if (state != State.Stopped) { String msg = String.format("Cannot start %s in %s state", vm, state); logger.warn(msg); - throw new CloudRuntimeException(msg); + throw Exceptions.cloudRuntimeException("vm.start.wrong.state", Map.of("instance", vm, "state", state)); } } @@ -1150,13 +1152,13 @@ protected void checkIfTemplateNeededForCreatingVmVolumes(VMInstanceVO vm) { if (template == null) { String msg = "Template for the VM instance can not be found, VM instance configuration needs to be updated"; logger.error("{}. Template ID: {} seems to be removed", msg, vm.getTemplateId()); - throw new CloudRuntimeException(msg); + throw Exceptions.cloudRuntimeException("vm.start.template.not.found"); } final VMTemplateZoneVO templateZoneVO = templateZoneDao.findByZoneTemplate(vm.getDataCenterId(), template.getId()); if (templateZoneVO == null) { String msg = "Template for the VM instance can not be found in the zone ID: %s, VM instance configuration needs to be updated"; logger.error("{}. {}", msg, template); - throw new CloudRuntimeException(msg); + throw Exceptions.cloudRuntimeException("vm.start.template.zone.not.found"); } } @@ -1307,7 +1309,7 @@ protected void processPrepareExternalProvisioning(boolean firstStart, Host host, PrepareExternalProvisioningCommand cmd = new PrepareExternalProvisioningCommand(virtualMachineTO); cmd.setExternalDetails(externalDetails); Answer answer = null; - CloudRuntimeException cre = new CloudRuntimeException("Failed to prepare VM"); + CloudRuntimeException cre = Exceptions.cloudRuntimeException("vm.start.external.prepare.failed"); try { answer = _agentMgr.send(host.getId(), cmd); } catch (AgentUnavailableException | OperationTimedoutException e) { @@ -1453,7 +1455,7 @@ public void orchestrateStart(final String vmUuid, final Map unmanage(String vmUuid, Long paramHostId) { VMInstanceVO vm = _vmDao.findByUuid(vmUuid); if (vm == null || vm.getRemoved() != null) { - throw new CloudRuntimeException("Could not find VM with id = " + vmUuid); + throw Exceptions.cloudRuntimeException("vm.unmanage.vm.not.found"); } final List pendingWorkJobs = _workJobDao.listPendingWorkJobs(VirtualMachine.Type.Instance, vm.getId()); @@ -2116,7 +2118,7 @@ Long persistDomainForKVM(VMInstanceVO vm, Long paramHostId) { if (agentHostId == null) { String errorMsg = "No available host to persist domain XML for Instance: " + vmName; logger.debug(errorMsg); - throw new CloudRuntimeException(errorMsg); + throw Exceptions.cloudRuntimeException("vm.unmanage.kvm.no.host", Map.of("instance", vm)); } } else { agentHostId = paramHostId; @@ -2133,12 +2135,12 @@ Long persistDomainForKVM(VMInstanceVO vm, Long paramHostId) { if (!answer.getResult()) { String errorMsg = "Failed to persist domain XML for Instance: " + vmName + " on host ID: " + agentHostId; logger.debug(errorMsg); - throw new CloudRuntimeException(errorMsg); + throw Exceptions.cloudRuntimeException("vm.unmanage.kvm.persist.failed", Map.of("instance", vm)); } } catch (AgentUnavailableException | OperationTimedoutException e) { String errorMsg = "Failed to send command to persist domain XML for Instance: " + vmName + " on host ID: " + agentHostId; logger.error(errorMsg, e); - throw new CloudRuntimeException(errorMsg); + throw Exceptions.cloudRuntimeException("vm.unmanage.kvm.command.failed", Map.of("instance", vm)); } return agentHostId; } @@ -2472,7 +2474,7 @@ private void advanceStop(final VMInstanceVO vm, final boolean cleanUpEvenIfUnabl if (hostId == null) { if (!cleanUpEvenIfUnableToStop) { logger.debug("HostId is null but this is not a forced stop, cannot stop vm {} with state: {}", vm, vm.getState()); - throw new CloudRuntimeException("Unable to stop " + vm); + throw Exceptions.cloudRuntimeException("vm.stop.host.not.found", Map.of("instance", vm)); } try { stateTransitTo(vm, Event.AgentReportStopped, null, null); @@ -2490,7 +2492,7 @@ private void advanceStop(final VMInstanceVO vm, final boolean cleanUpEvenIfUnabl HostVO host = _hostDao.findById(hostId); if (!cleanUpEvenIfUnableToStop && vm.getState() == State.Running && host.getResourceState() == ResourceState.PrepareForMaintenance) { logger.debug("Host is in PrepareForMaintenance state - Stop VM operation on the VM: {} is not allowed", vm); - throw new CloudRuntimeException(String.format("Stop VM operation on the VM %s is not allowed as host is preparing for maintenance mode", vm)); + throw Exceptions.cloudRuntimeException("vm.stop.host.preparing.maintenance", Map.of("instance", vm)); } } @@ -2503,7 +2505,7 @@ private void advanceStop(final VMInstanceVO vm, final boolean cleanUpEvenIfUnabl } } catch (final NoTransitionException e1) { if (!cleanUpEvenIfUnableToStop) { - throw new CloudRuntimeException("We cannot stop " + vm + " when it is in state " + vm.getState()); + throw Exceptions.cloudRuntimeException("vm.stop.state.transition.failed", Map.of("instance", vm)); } final boolean doCleanup = true; logger.warn("Unable to transition the state but we're moving on because it's forced stop", e1); @@ -2515,22 +2517,22 @@ private void advanceStop(final VMInstanceVO vm, final boolean cleanUpEvenIfUnabl logger.debug("Updating work item to Done, id: {}", work.getId()); } if (!changeState(vm, Event.AgentReportStopped, null, work, Step.Done)) { - throw new CloudRuntimeException("Unable to stop " + vm); + throw Exceptions.cloudRuntimeException("vm.stop.cleanup.state.change.failed", Map.of("instance", vm)); } } catch (final NoTransitionException e) { logger.warn("Unable to cleanup {}", vm); - throw new CloudRuntimeException("Unable to stop " + vm, e); + throw Exceptions.cloudRuntimeException("vm.stop.cleanup.state.change.failed", Map.of("instance", vm), e); } } else { logger.debug("Failed to cleanup VM: {}", vm); - throw new CloudRuntimeException("Failed to cleanup " + vm + " , current state " + vm.getState()); + throw Exceptions.cloudRuntimeException("vm.stop.cleanup.failed", Map.of("instance", vm)); } } } if (vm.getState() != State.Stopping) { - throw new CloudRuntimeException("We cannot proceed with stop VM " + vm + " since it is not in 'Stopping' state, current state: " + vm.getState()); + throw Exceptions.cloudRuntimeException("vm.stop.not.stopping.state", Map.of("instance", vm)); } vmGuru.prepareStop(profile); @@ -2562,13 +2564,13 @@ private void advanceStop(final VMInstanceVO vm, final boolean cleanUpEvenIfUnabl } stopped = answer.getResult(); if (!stopped) { - throw new CloudRuntimeException("Unable to stop the Instance due to " + answer.getDetails()); + throw Exceptions.cloudRuntimeException("vm.stop.answer.failed", Map.of("instance", vm, "error", answer.getDetails())); } vmGuru.finalizeStop(profile, answer); final GPUDeviceTO gpuDevice = stop.getGpuDevice(); _resourceMgr.updateGPUDetailsForVmStop(vm, gpuDevice); } else { - throw new CloudRuntimeException("Invalid answer received in response to a StopCommand on " + vm.instanceName); + throw Exceptions.cloudRuntimeException("vm.stop.no.answer", Map.of("instance", vm)); } } catch (AgentUnavailableException | OperationTimedoutException e) { @@ -2582,7 +2584,7 @@ private void advanceStop(final VMInstanceVO vm, final boolean cleanUpEvenIfUnabl } catch (final NoTransitionException e) { logger.warn("Unable to transition the state " + vm, e); } - throw new CloudRuntimeException("Unable to stop " + vm); + throw Exceptions.cloudRuntimeException("vm.stop.final.state.transition.failed", Map.of("instance", vm)); } else { logger.warn("Unable to actually stop {} but continue with release because it's a force stop", vm); vmGuru.finalizeStop(profile, answer); @@ -2632,12 +2634,12 @@ public Boolean doInTransaction(TransactionStatus status) throws NoTransitionExce }); if (!result) { - throw new CloudRuntimeException("unable to stop " + vm); + throw Exceptions.cloudRuntimeException("vm.stop.transaction.failed", Map.of("instance", vm)); } } catch (final NoTransitionException e) { String message = String.format("Unable to stop %s due to [%s].", vm.toString(), e.getMessage()); logger.warn(message, e); - throw new CloudRuntimeException(message, e); + throw Exceptions.cloudRuntimeException("vm.stop.no.transition", Map.of("instance", vm, "error", e.getMessage()), e); } } @@ -2697,20 +2699,20 @@ public void doInTransactionWithoutResult(final TransactionStatus status) throws try { if (!stateTransitTo(vm, VirtualMachine.Event.DestroyRequested, vm.getHostId())) { logger.debug("Unable to destroy the vm because it is not in the correct state: {}", vm); - throw new CloudRuntimeException("Unable to destroy " + vm); + throw Exceptions.cloudRuntimeException("vm.destroy.state.transition.failed", Map.of("instance", vm)); } else { if (expunge) { backupManager.checkAndRemoveBackupOfferingBeforeExpunge(vm); if (!stateTransitTo(vm, VirtualMachine.Event.ExpungeOperation, vm.getHostId())) { logger.debug("Unable to expunge the vm because it is not in the correct state: {}", vm); - throw new CloudRuntimeException("Unable to expunge " + vm); + throw Exceptions.cloudRuntimeException("vm.destroy.expunge.state.transition.failed", Map.of("instance", vm)); } } } } catch (final NoTransitionException e) { String message = String.format("Unable to destroy %s due to [%s].", vm.toString(), e.getMessage()); logger.debug(message, e); - throw new CloudRuntimeException(message, e); + throw Exceptions.cloudRuntimeException("vm.destroy.no.transition", Map.of("instance", vm, "error", e.getMessage()), e); } } }); @@ -2727,7 +2729,7 @@ private void deleteVMSnapshots(VMInstanceVO vm, boolean expunge) { if (! vm.getHypervisorType().equals(HypervisorType.VMware)) { if (!_vmSnapshotMgr.deleteAllVMSnapshots(vm.getId(), null)) { logger.debug("Unable to delete all Snapshots for {}", vm); - throw new CloudRuntimeException("Unable to delete Instance Snapshots for " + vm); + throw Exceptions.cloudRuntimeException("vm.destroy.snapshots.delete.failed", Map.of("instance", vm)); } } else { @@ -2808,14 +2810,14 @@ private void orchestrateStorageMigration(final String vmUuid, final Map results = relevantAnswer.getVolumeTos(); if (results == null) { @@ -2923,7 +2925,7 @@ private void migrateThroughHypervisorOrStorage(VMInstanceVO vm, Map prepareVmStorageMigration(VMInstanceVO vm, Map volumeToPool) { Map volumeToPoolMap = new HashMap<>(); if (MapUtils.isEmpty(volumeToPool)) { - throw new CloudRuntimeException(String.format("Unable to migrate %s: missing volume to pool mapping.", vm.toString())); + throw Exceptions.cloudRuntimeException("vm.storage.migration.no.volume.mapping", Map.of("instance", vm)); } Cluster cluster = null; Long dataCenterId = null; @@ -2945,7 +2947,7 @@ private Map prepareVmStorageMigration(VMInstanceVO vm, Map< if (dataCenterId == null) { String msg = "Unable to migrate Instance: failed to create deployment destination with given volume to pool map"; logger.debug(msg); - throw new CloudRuntimeException(msg); + throw Exceptions.cloudRuntimeException("vm.storage.migration.destination.failed"); } final DataCenterDeployment destination = new DataCenterDeployment(dataCenterId, podId, clusterId, null, null, null); // Create a map of which volume should go in which storage pool. @@ -2956,7 +2958,7 @@ private Map prepareVmStorageMigration(VMInstanceVO vm, Map< } catch (final NoTransitionException e) { String msg = String.format("Unable to migrate Instance: %s", vm.getUuid()); logger.warn(msg, e); - throw new CloudRuntimeException(msg, e); + throw Exceptions.cloudRuntimeException("vm.storage.migration.state.requested.failed", Map.of("instance", vm), e); } return volumeToPoolMap; } @@ -2969,13 +2971,7 @@ private void checkDestinationForTags(StoragePool destPool, VMInstanceVO vm) { DiskOfferingVO diskOffering = _diskOfferingDao.findById(vol.getDiskOfferingId()); List volumeTags = StringUtils.csvTagsToList(diskOffering.getTags()); if(! matches(volumeTags, storageTags)) { - String msg = String.format("destination pool '%s' with tags '%s', does not support the volume diskoffering for volume '%s' (tags: '%s') ", - destPool.getName(), - StringUtils.listToCsvTags(storageTags), - vol.getName(), - StringUtils.listToCsvTags(volumeTags) - ); - throw new CloudRuntimeException(msg); + throw Exceptions.cloudRuntimeException("vm.migrate.destination.pool.tags.mismatch"); } } } @@ -3043,9 +3039,7 @@ private void removeStaleVmFromSource(VMInstanceVO vm, HostVO srcHost) { try { _agentMgr.send(srcHost.getId(), uvc); } catch (AgentUnavailableException | OperationTimedoutException e) { - throw new CloudRuntimeException(String.format( - "Failed to unregister VM: %s from source host: %s after successfully migrating VM's storage across VMware Datacenters", - vm, srcHost), e); + throw Exceptions.cloudRuntimeException("vm.migrate.unregister.source.failed", Map.of("instance", vm, "host", srcHost), e); } } @@ -3081,7 +3075,7 @@ private void orchestrateMigrate(final String vmUuid, final long srcHostId, final final VMInstanceVO vm = _vmDao.findByUuid(vmUuid); if (vm == null) { logger.debug("Unable to find the Instance {}", vmUuid); - throw new CloudRuntimeException("Unable to find a Instance with ID: " + vmUuid); + throw Exceptions.cloudRuntimeException("vm.migrate.vm.not.found"); } migrate(vm, srcHostId, dest); } @@ -3092,7 +3086,7 @@ protected void migrate(final VMInstanceVO vm, final long srcHostId, final Deploy final Host fromHost = _hostDao.findById(srcHostId); if (fromHost == null) { logger.info("Unable to find the host to migrate from: {}", srcHostId); - throw new CloudRuntimeException("Unable to find the host to migrate from: " + srcHostId); + throw Exceptions.cloudRuntimeException("vm.migrate.source.host.not.found"); } if (fromHost.getClusterId() != dest.getCluster().getId() && vm.getHypervisorType() != HypervisorType.VMware) { @@ -3101,9 +3095,7 @@ protected void migrate(final VMInstanceVO vm, final long srcHostId, final Deploy if (!_storagePoolDao.findById(volume.getPoolId()).getScope().equals(ScopeType.ZONE)) { logger.info("Source and destination host are not in same cluster and all volumes are not on zone wide primary store, unable to migrate to host: {}", dest.getHost()); - throw new CloudRuntimeException(String.format( - "Source and destination host are not in same cluster and all volumes are not on zone wide primary store, unable to migrate to host: %s", - dest.getHost())); + throw Exceptions.cloudRuntimeException("vm.migrate.cross.cluster.volume.not.zone.wide"); } } } @@ -3112,7 +3104,7 @@ protected void migrate(final VMInstanceVO vm, final long srcHostId, final Deploy if (vm.getState() != State.Running) { logger.debug("VM is not Running, unable to migrate the vm {}", vm); - throw new CloudRuntimeException("VM is not Running, unable to migrate the vm currently " + vm + " , current state: " + vm.getState().toString()); + throw Exceptions.cloudRuntimeException("vm.migrate.vm.not.running"); } AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM_MIGRATE; @@ -3201,7 +3193,7 @@ protected void migrate(final VMInstanceVO vm, final long srcHostId, final Deploy } catch (final NoTransitionException e3) { logger.warn(e3.getMessage()); } - throw new CloudRuntimeException("Migration cancelled because " + e2.getMessage()); + throw Exceptions.cloudRuntimeException("vm.migrate.state.transition.cancelled", Map.of("error", e2.getMessage())); } boolean migrated = false; @@ -3216,7 +3208,7 @@ protected void migrate(final VMInstanceVO vm, final long srcHostId, final Deploy String msg = String.format("Migration command failed for VM %s on source host id=%s to destination host %s: %s", vm.getInstanceName(), vm.getLastHostId(), dstHostId, details); logger.error(msg); - throw new CloudRuntimeException(details); + throw Exceptions.cloudRuntimeException("vm.migrate.command.details", Map.of("error", details)); } logger.info("Migration command successful for VM {}", vm.getInstanceName()); } catch (final OperationTimedoutException e) { @@ -3262,7 +3254,7 @@ protected void migrate(final VMInstanceVO vm, final long srcHostId, final Deploy logger.error("AgentUnavailableException while cleanup on source host: {}", fromHost, e); } cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.AgentReportStopped, true); - throw new CloudRuntimeException("Unable to complete migration for " + vm); + throw Exceptions.cloudRuntimeException("vm.migrate.verification.failed", Map.of("instance", vm)); } } catch (final OperationTimedoutException e) { logger.warn("Error while checking the vm {} on host {}", vm, dest.getHost(), e); @@ -3407,9 +3399,7 @@ protected Map buildMapUsingUserInformation(VirtualMachinePr executeManagedStorageChecksWhenTargetStoragePoolProvided(currentPool, volume, targetPool); if (targetHost != null && _poolHostDao.findByPoolHost(targetPool.getId(), targetHost.getId()) == null) { - throw new CloudRuntimeException( - String.format("Cannot migrate the volume [%s] to the storage pool [%s] while migrating VM [%s] to target host [%s]. The host does not have access to the storage pool entered.", - volume.getUuid(), targetPool.getUuid(), profile.getUuid(), targetHost.getUuid())); + throw Exceptions.cloudRuntimeException("vm.migrate.with.volume.pool.no.access"); } if (currentPool.getId() == targetPool.getId()) { logger.info("The volume [{}] is already allocated in storage pool [{}].", volume.getUuid(), targetPool.getUuid()); @@ -3439,8 +3429,7 @@ protected void executeManagedStorageChecksWhenTargetStoragePoolProvided(StorageP if (details != null && Boolean.parseBoolean(details.get(Storage.Capability.ALLOW_MIGRATE_OTHER_POOLS.toString()))) { return; } - throw new CloudRuntimeException(String.format("Currently, a volume on managed storage can only be 'migrated' to itself " + "[volumeId=%s, currentStoragePoolId=%s, targetStoragePoolId=%s].", - volume.getUuid(), currentPool.getUuid(), targetPool.getUuid())); + throw Exceptions.cloudRuntimeException("vm.migrate.managed.storage.pool.mismatch"); } /** @@ -3488,8 +3477,7 @@ protected void executeManagedStorageChecksWhenTargetStoragePoolNotProvided(Host return; } if (targetHost != null && _poolHostDao.findByPoolHost(currentPool.getId(), targetHost.getId()) == null) { - throw new CloudRuntimeException(String.format("The target host does not have access to the volume's managed storage pool. [volumeId=%s, storageId=%s, targetHostId=%s].", volume.getUuid(), - currentPool.getUuid(), targetHost.getUuid())); + throw Exceptions.cloudRuntimeException("vm.migrate.managed.storage.no.access"); } } @@ -3522,7 +3510,7 @@ protected void createVolumeToStoragePoolMappingIfPossible(VirtualMachineProfile Cluster targetCluster = _clusterDao.findById(plan.getClusterId()); msg = String.format("There are no storage pools available in the target cluster [%s] to migrate volume [%s]", targetCluster.getUuid(), volume.getUuid()); } - throw new CloudRuntimeException(msg); + throw Exceptions.cloudRuntimeException("vm.migrate.no.storage.pools.available"); } Collections.shuffle(storagePoolList); @@ -3645,8 +3633,7 @@ private void orchestrateMigrateWithStorage(final String vmUuid, final long srcHo final Map volumeToPoolMap = createMappingVolumeAndStoragePool(profile, destHost, volumeToPool); if (volumeToPoolMap == null || volumeToPoolMap.isEmpty()) { - throw new InvalidParameterValueException("Migration of the vm " + vm + "from host " + srcHost + " to destination host " + destHost + - " doesn't involve migrating the volumes."); + throw Exceptions.invalidParameterValueException("vm.migrate.with.volume.empty.map"); } AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM_MIGRATE; @@ -3719,7 +3706,7 @@ private void orchestrateMigrateWithStorage(final String vmUuid, final long srcHo logger.error("AgentUnavailableException while cleanup on source host: {}", srcHost, e); } cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.AgentReportStopped, true); - throw new CloudRuntimeException("VM not found on destination host. Unable to complete migration for " + vm); + throw Exceptions.cloudRuntimeException("vm.migrate.with.volume.verification.failed", Map.of("instance", vm)); } } catch (final OperationTimedoutException e) { logger.error("Error while checking the vm {} is on host {}", vm, destHost, e); @@ -3784,7 +3771,7 @@ protected void recreateCheckpointsKvmOnVmAfterMigration(VMInstanceVO vm, long ho answer = _agentMgr.send(hostId, recreateCheckpointsCommand); } catch (AgentUnavailableException | OperationTimedoutException e) { logger.error(String.format("Exception while sending command to host [%s] to recreate checkpoints with URLs [%s] of volumes [%s] on %s due to: [%s].", hostId, volumes.stream().map(VolumeObjectTO::getCheckpointPaths).collect(Collectors.toList()), volumes, vm, e.getMessage()), e); - throw new CloudRuntimeException(e); + throw Exceptions.cloudRuntimeException("vm.migrate.checkpoint.recreation.failed", Map.of(), e); } finally { if (answer != null && answer.getResult()) { logger.debug(String.format("Successfully recreated checkpoints on VM [%s].", vm)); @@ -3900,7 +3887,7 @@ private void orchestrateMigrateAway(final String vmUuid, final long srcHostId, f if (vm == null) { String message = String.format("Unable to find VM with uuid [%s].", vmUuid); logger.warn(message); - throw new CloudRuntimeException(message); + throw Exceptions.cloudRuntimeException("vm.migrate.away.vm.not.found"); } ServiceOfferingVO offeringVO = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId()); @@ -3910,7 +3897,7 @@ private void orchestrateMigrateAway(final String vmUuid, final long srcHostId, f if (hostId == null) { String message = String.format("Unable to migrate %s due to it does not have a host id.", vm.toString()); logger.warn(message); - throw new CloudRuntimeException(message); + throw Exceptions.cloudRuntimeException("vm.migrate.away.no.host", Map.of("instance", vm)); } final Host host = _hostDao.findById(hostId); @@ -3936,7 +3923,7 @@ private void orchestrateMigrateAway(final String vmUuid, final long srcHostId, f } catch (final AffinityConflictException e2) { String message = String.format("Unable to create deployment, affinity rules associated to the %s conflict.", vm.toString()); logger.warn(message, e2); - throw new CloudRuntimeException(message, e2); + throw Exceptions.cloudRuntimeException("vm.migrate.away.affinity.conflict", Map.of("instance", vm), e2); } if (dest == null) { logger.warn("Unable to find destination for migrating the vm {}", profile); @@ -3954,10 +3941,10 @@ private void orchestrateMigrateAway(final String vmUuid, final long srcHostId, f try { advanceStop(vmUuid, true); - throw new CloudRuntimeException("Unable to migrate " + vm); + throw Exceptions.cloudRuntimeException("vm.migrate.away.failed", Map.of("instance", vm)); } catch (final ResourceUnavailableException | ConcurrentOperationException | OperationTimedoutException e) { logger.error("Unable to stop {} due to [{}].", vm.toString(), e.getMessage(), e); - throw new CloudRuntimeException("Unable to migrate " + vm); + throw Exceptions.cloudRuntimeException("vm.migrate.away.failed", Map.of("instance", vm)); } } } @@ -4029,7 +4016,7 @@ public void reboot(final String vmUuid, final Map currentTags = StringUtils.csvTagsToList(currentDiskOffering.getTags()); final List newTags = StringUtils.csvTagsToList(newDiskOffering.getTags()); if (VolumeApiServiceImpl.MatchStoragePoolTagsWithDiskOffering.valueIn(vmInstance.getDataCenterId())) { if (!VolumeApiServiceImpl.doesNewDiskOfferingHasTagsAsOldDiskOffering(currentDiskOffering, newDiskOffering)) { - throw new InvalidParameterValueException("Unable to upgrade virtual machine; the current service offering " + " should have tags as subset of " + - "the new service offering tags. Current service offering tags: " + currentTags + "; " + "new service " + "offering tags: " + newTags); + throw Exceptions.invalidParameterValueException("vm.upgrade.disk.offering.tags.mismatch"); } } } @@ -4485,15 +4466,11 @@ protected void checkIfNewOfferingStorageScopeMatchesStoragePool(VirtualMachine v boolean isRootVolumeOnLocalStorage = isRootVolumeOnLocalStorage(vmInstance.getId()); if (newDiskOffering.isUseLocalStorage() && !isRootVolumeOnLocalStorage) { - String message = String .format("Unable to upgrade virtual machine %s, target offering use local storage but the storage pool where " - + "the volume is allocated is a shared storage.", vmInstance.toString()); - throw new InvalidParameterValueException(message); + throw Exceptions.invalidParameterValueException("vm.upgrade.storage.local.to.shared", Map.of("instance", vmInstance)); } if (!newDiskOffering.isUseLocalStorage() && isRootVolumeOnLocalStorage) { - String message = String.format("Unable to upgrade virtual machine %s, target offering use shared storage but the storage pool where " - + "the volume is allocated is a local storage.", vmInstance.toString()); - throw new InvalidParameterValueException(message); + throw Exceptions.invalidParameterValueException("vm.upgrade.storage.shared.to.local", Map.of("instance", vmInstance)); } } @@ -4571,7 +4548,7 @@ private void checkIfNetworkExistsForUserVM(VirtualMachine virtualMachine, Networ List allNics = _nicsDao.listByVmId(virtualMachine.getId()); for (NicVO nic : allNics) { if (nic.getNetworkId() == network.getId()) { - throw new CloudRuntimeException("A NIC already exists for VM:" + virtualMachine.getInstanceName() + " in network: " + network.getUuid()); + throw Exceptions.cloudRuntimeException("vm.addnic.already.exists", Map.of("instance", virtualMachine, "network", network)); } } } @@ -4751,7 +4728,7 @@ private boolean orchestrateRemoveVmFromNetwork(final VirtualMachine vm, final Ne if (nic.isDefaultNic() && vm.getType() == VirtualMachine.Type.User) { logger.warn("Failed to remove NIC from {} in {}, NIC is default.", vm, network); - throw new CloudRuntimeException("Failed to remove NIC from " + vm + " in " + network + ", NIC is default."); + throw Exceptions.cloudRuntimeException("vm.removenic.default.nic", Map.of("nic", nic, "instance", vm, "network", network)); } final Nic lock = _nicsDao.acquireInLockTable(nic.getId()); @@ -4802,7 +4779,7 @@ public void findHostAndMigrate(final String vmUuid, final Long newSvcOfferingId, final VMInstanceVO vm = _vmDao.findByUuid(vmUuid); if (vm == null) { - throw new CloudRuntimeException("Unable to find " + vmUuid); + throw Exceptions.cloudRuntimeException("vm.scale.vm.not.found"); } ServiceOfferingVO newServiceOffering = _offeringDao.findById(newSvcOfferingId); if (newServiceOffering.isDynamic()) { @@ -4814,7 +4791,7 @@ public void findHostAndMigrate(final String vmUuid, final Long newSvcOfferingId, final Long srcHostId = vm.getHostId(); final Long oldSvcOfferingId = vm.getServiceOfferingId(); if (srcHostId == null) { - throw new CloudRuntimeException("Unable to scale the vm because it doesn't have a host id"); + throw Exceptions.cloudRuntimeException("vm.scale.no.host", Map.of("instance", vm)); } final Host host = _hostDao.findById(srcHostId); final DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), null, null, null); @@ -4828,7 +4805,7 @@ public void findHostAndMigrate(final String vmUuid, final Long newSvcOfferingId, } catch (final AffinityConflictException e2) { String message = String.format("Unable to create deployment, affinity rules associated to the %s conflict.", vm.toString()); logger.warn(message, e2); - throw new CloudRuntimeException(message); + throw Exceptions.cloudRuntimeException("vm.scale.affinity.conflict", Map.of("instance", vm)); } if (dest != null) { @@ -4887,7 +4864,7 @@ private void orchestrateMigrateForScale(final String vmUuid, final long srcHostI if (fromHost == null) { String logMessageUnableToFindHost = String.format("Unable to find host to migrate from %s.", srcHostId); logger.info(logMessageUnableToFindHost); - throw new CloudRuntimeException(logMessageUnableToFindHost); + throw Exceptions.cloudRuntimeException("vm.scale.source.host.not.found"); } Host dstHost = _hostDao.findById(dstHostId); @@ -4896,7 +4873,7 @@ private void orchestrateMigrateForScale(final String vmUuid, final long srcHostI if (fromHostClusterId != destHostClusterId) { String logMessageHostsOnDifferentCluster = String.format("Source and destination host are not in same cluster, unable to migrate to %s", fromHost); logger.info(logMessageHostsOnDifferentCluster); - throw new CloudRuntimeException(logMessageHostsOnDifferentCluster); + throw Exceptions.cloudRuntimeException("vm.scale.cross.cluster.not.supported"); } final VirtualMachineGuru vmGuru = getVmGuru(vm); @@ -4905,13 +4882,13 @@ private void orchestrateMigrateForScale(final String vmUuid, final long srcHostI if (vm == null) { String message = String.format("Unable to find VM {\"uuid\": \"%s\"}.", vmUuid); logger.warn(message); - throw new CloudRuntimeException(message); + throw Exceptions.cloudRuntimeException("vm.scale.vm.not.found.retry"); } if (vm.getState() != State.Running) { String message = String.format("%s is not in \"Running\" state, unable to migrate it. Current state [%s].", vm.toString(), vm.getState()); logger.warn(message); - throw new CloudRuntimeException(message); + throw Exceptions.cloudRuntimeException("vm.scale.vm.not.running", Map.of("instance", vm)); } AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM_MIGRATE; @@ -4972,9 +4949,7 @@ private void orchestrateMigrateForScale(final String vmUuid, final long srcHostI try { final Answer ma = _agentMgr.send(vm.getLastHostId(), mc); if (ma == null || !ma.getResult()) { - String msg = String.format("Unable to migrate %s due to [%s].", vm.toString(), ma != null ? ma.getDetails() : "null answer returned"); - logger.error(msg); - throw new CloudRuntimeException(msg); + throw Exceptions.cloudRuntimeException("vm.scale.migrate.failed", Map.of("instance", vm, "error", (ma != null ? ma.getDetails() : "null answer returned"))); } } catch (final OperationTimedoutException e) { if (e.isActive()) { @@ -5004,7 +4979,7 @@ private void orchestrateMigrateForScale(final String vmUuid, final long srcHostI logger.error("Unable to cleanup source host [{}] due to [{}].", fromHost, e.getMessage(), e); } cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.AgentReportStopped, true); - throw new CloudRuntimeException("Unable to complete migration for " + vm); + throw Exceptions.cloudRuntimeException("vm.scale.migrate.verification.failed", Map.of("instance", vm)); } } catch (final OperationTimedoutException e) { logger.debug("Error while checking the {} on {}", vm, dstHost, e); @@ -5228,7 +5203,7 @@ private VMInstanceVO orchestrateReConfigureVm(String vmUuid, ServiceOffering old if (reconfigureAnswer == null || !reconfigureAnswer.getResult()) { logger.error("Unable to scale vm due to {}", (reconfigureAnswer == null ? "" : reconfigureAnswer.getDetails())); - throw new CloudRuntimeException("Unable to scale vm due to " + (reconfigureAnswer == null ? "" : reconfigureAnswer.getDetails())); + throw Exceptions.cloudRuntimeException("vm.scale.reconfigure.answer.failed", Map.of("error", (reconfigureAnswer == null ? "" : reconfigureAnswer.getDetails()))); } upgradeVmDb(vm.getId(), newServiceOffering, oldServiceOffering); @@ -5834,7 +5809,7 @@ private void checkConcurrentJobsPerDatastoreThreshhold(final StoragePool destPoo if (threshold != null && threshold > 0) { long count = _jobMgr.countPendingJobs("\"storageid\":\"" + destPool.getUuid() + "\"", MigrateVMCmd.class.getName(), MigrateVolumeCmd.class.getName(), MigrateVolumeCmdByAdmin.class.getName()); if (count > threshold) { - throw new CloudRuntimeException("Number of concurrent migration jobs per datastore exceeded the threshold: " + threshold.toString() + ". Please try again after some time."); + throw Exceptions.cloudRuntimeException("vm.migrate.concurrent.jobs.exceeded"); } } } @@ -5883,7 +5858,7 @@ public Outcome addVmToNetworkThroughJobQueue( VmWorkJobVO workJob = null; if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) { if (pendingWorkJobs.size() > 1) { - throw new CloudRuntimeException(String.format("The number of jobs to add network %s to vm %s are %d", network.getUuid(), vm.getInstanceName(), pendingWorkJobs.size())); + throw Exceptions.cloudRuntimeException("vm.addnic.pending.jobs.exceeded", Map.of("instance", vm, "network", network)); } workJob = pendingWorkJobs.get(0); } else { @@ -6009,8 +5984,7 @@ private Pair orchestrateStart(final VmWorkStart work) th orchestrateStart(vm.getUuid(), work.getParams(), work.getPlan(), _dpMgr.getDeploymentPlannerByName(work.getDeploymentPlanner())); } catch (CloudRuntimeException e){ logger.error("Unable to orchestrate start {} due to [{}].", vm, e.getMessage()); - CloudRuntimeException ex = new CloudRuntimeException(String.format("Unable to orchestrate the start of VM instance %s.", - ReflectionToStringBuilderUtils.reflectOnlySelectedFields(vm, "instanceName", "uuid"))); + CloudRuntimeException ex = Exceptions.cloudRuntimeException("vm.start.orchestrate.failed", Map.of("instance", vm)); return new Pair<>(JobInfo.Status.FAILED, JobSerializerHelper.toObjectSerializedString(ex)); } return new Pair<>(JobInfo.Status.SUCCEEDED, null); @@ -6022,7 +5996,7 @@ private Pair orchestrateStop(final VmWorkStop work) thro if (vm == null) { String message = String.format("Unable to find VM [%s].", work.getVmId()); logger.warn(message); - throw new CloudRuntimeException(message); + throw Exceptions.cloudRuntimeException("vm.stop.work.vm.not.found"); } orchestrateStop(vm.getUuid(), work.isCleanup()); @@ -6300,11 +6274,11 @@ private Pair orchestrateUpdateDefaultNic(final VmWorkUpd VMInstanceVO vm = findVmById(work.getVmId()); final NicVO nic = _entityMgr.findById(NicVO.class, work.getNicId()); if (nic == null) { - throw new CloudRuntimeException("Unable to find nic " + work.getNicId()); + throw Exceptions.cloudRuntimeException("vm.updatenic.nic.not.found"); } final NicVO defaultNic = _entityMgr.findById(NicVO.class, work.getDefaultNicId()); if (defaultNic == null) { - throw new CloudRuntimeException("Unable to find default nic " + work.getDefaultNicId()); + throw Exceptions.cloudRuntimeException("vm.updatenic.default.nic.not.found"); } final boolean result = orchestrateUpdateDefaultNicForVM(vm, nic, defaultNic); return new Pair<>(JobInfo.Status.SUCCEEDED,