mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-7688, CLOUDSTACK-7747: restricted various operations for VM with VM snapshots which breaks VM snapshots.
Now they are informed that they cannot perform the operation.
To perform operation they have to remove VM snapshots of VM.
(cherry picked from commit f43ffb9a0f)
Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
Conflicts:
server/src/com/cloud/storage/VolumeApiServiceImpl.java
server/src/com/cloud/vm/UserVmManagerImpl.java
server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
This commit is contained in:
parent
6fa3d82554
commit
08e5993a45
|
|
@ -802,6 +802,16 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
throw new InvalidParameterValueException("No such volume");
|
||||
}
|
||||
|
||||
/* Does the caller have authority to act on this volume? */
|
||||
_accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume);
|
||||
|
||||
if(volume.getInstanceId() != null) {
|
||||
// Check that Vm to which this volume is attached does not have VM Snapshots
|
||||
if (_vmSnapshotDao.findByVm(volume.getInstanceId()).size() > 0) {
|
||||
throw new InvalidParameterValueException("Volume cannot be resized which is attached to VM with VM Snapshots");
|
||||
}
|
||||
}
|
||||
|
||||
DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
|
||||
DiskOfferingVO newDiskOffering = null;
|
||||
|
||||
|
|
@ -974,6 +984,16 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
hosts = new long[] {userVm.getLastHostId()};
|
||||
}
|
||||
|
||||
StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
|
||||
|
||||
if (storagePool.isManaged() && storagePool.getHypervisor() == HypervisorType.Any && hosts != null && hosts.length > 0) {
|
||||
HostVO host = _hostDao.findById(hosts[0]);
|
||||
|
||||
if (currentSize != newSize && host.getHypervisorType() == HypervisorType.XenServer && !userVm.getState().equals(State.Stopped)) {
|
||||
throw new InvalidParameterValueException(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Xen only works offline, SR does not support VDI.resizeOnline */
|
||||
if (_volsDao.getHypervisorType(volume.getId()) == HypervisorType.XenServer && !userVm.getState().equals(State.Stopped)) {
|
||||
throw new InvalidParameterValueException("VM must be stopped or disk detached in order to resize with the Xen HV");
|
||||
|
|
@ -1403,11 +1423,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
// Permissions check
|
||||
_accountMgr.checkAccess(caller, null, true, volume);
|
||||
|
||||
// Check that the volume is a data volume
|
||||
if (volume.getVolumeType() != Volume.Type.DATADISK) {
|
||||
throw new InvalidParameterValueException("Please specify a data volume.");
|
||||
}
|
||||
|
||||
// Check that the volume is currently attached to a VM
|
||||
if (vmId == null) {
|
||||
throw new InvalidParameterValueException("The specified volume is not attached to a VM.");
|
||||
|
|
@ -1570,6 +1585,11 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
vm = _vmInstanceDao.findById(instanceId);
|
||||
}
|
||||
|
||||
// Check that Vm to which this volume is attached does not have VM Snapshots
|
||||
if (vm != null && _vmSnapshotDao.findByVm(vm.getId()).size() > 0) {
|
||||
throw new InvalidParameterValueException("Volume cannot be migrated, please remove all VM snapshots for VM to which this volume is attached");
|
||||
}
|
||||
|
||||
if (vm != null && vm.getState() == State.Running) {
|
||||
// Check if the underlying hypervisor supports storage motion.
|
||||
Long hostId = vm.getHostId();
|
||||
|
|
@ -1796,6 +1816,13 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
throw new InvalidParameterValueException("Can't find zone by id " + volume.getDataCenterId());
|
||||
}
|
||||
|
||||
if (volume.getInstanceId() != null) {
|
||||
// Check that Vm to which this volume is attached does not have VM Snapshots
|
||||
if (_vmSnapshotDao.findByVm(volume.getInstanceId()).size() > 0) {
|
||||
throw new InvalidParameterValueException("Volume snapshot is not allowed, please detach it from VM with VM Snapshots");
|
||||
}
|
||||
}
|
||||
|
||||
if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) {
|
||||
throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zone.getName());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
|||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
|
|
@ -263,7 +265,6 @@ import com.cloud.vm.dao.UserVmCloneSettingDao;
|
|||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
import com.cloud.vm.snapshot.VMSnapshotManager;
|
||||
import com.cloud.vm.snapshot.VMSnapshotVO;
|
||||
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||
|
|
@ -821,6 +822,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
"; make sure the virtual machine is stopped");
|
||||
}
|
||||
|
||||
// If target VM has associated VM snapshots then don't allow upgrading of VM
|
||||
List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
|
||||
if (vmSnapshots.size() > 0) {
|
||||
throw new InvalidParameterValueException("Unable to change service offering for VM, please remove VM snapshots before changing service offering of VM");
|
||||
}
|
||||
|
||||
_accountMgr.checkAccess(caller, null, true, vmInstance);
|
||||
|
||||
// Check resource limits for CPU and Memory.
|
||||
|
|
@ -850,19 +857,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
// Check that the specified service offering ID is valid
|
||||
_itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering);
|
||||
|
||||
// remove diskAndMemory VM snapshots
|
||||
List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
|
||||
for (VMSnapshotVO vmSnapshotVO : vmSnapshots) {
|
||||
if(vmSnapshotVO.getType() == VMSnapshot.Type.DiskAndMemory){
|
||||
if(!_vmSnapshotMgr.deleteAllVMSnapshots(vmId, VMSnapshot.Type.DiskAndMemory)){
|
||||
String errMsg = "Failed to remove VM snapshot during upgrading, snapshot id " + vmSnapshotVO.getId();
|
||||
s_logger.debug(errMsg);
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
_itMgr.upgradeVmDb(vmId, svcOffId);
|
||||
if (newServiceOffering.isDynamic()) {
|
||||
//save the custom values to the database.
|
||||
|
|
@ -929,19 +923,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
// Check that the specified service offering ID is valid
|
||||
_itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering);
|
||||
|
||||
// remove diskAndMemory VM snapshots
|
||||
List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
|
||||
for (VMSnapshotVO vmSnapshotVO : vmSnapshots) {
|
||||
if(vmSnapshotVO.getType() == VMSnapshot.Type.DiskAndMemory){
|
||||
if(!_vmSnapshotMgr.deleteAllVMSnapshots(vmId, VMSnapshot.Type.DiskAndMemory)){
|
||||
String errMsg = "Failed to remove VM snapshot during upgrading, snapshot id " + vmSnapshotVO.getId();
|
||||
s_logger.debug(errMsg);
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
_itMgr.upgradeVmDb(vmId, svcOffId);
|
||||
if (newServiceOffering.isDynamic()) {
|
||||
//save the custom values to the database.
|
||||
|
|
@ -979,6 +960,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
if(vmInstance == null) {
|
||||
throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
|
||||
}
|
||||
|
||||
// Check that Vm does not have VM Snapshots
|
||||
if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
|
||||
throw new InvalidParameterValueException("NIC cannot be added to VM with VM Snapshots");
|
||||
}
|
||||
|
||||
NetworkVO network = _networkDao.findById(networkId);
|
||||
if(network == null) {
|
||||
throw new InvalidParameterValueException("unable to find a network with id " + networkId);
|
||||
|
|
@ -1062,6 +1049,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
if(vmInstance == null) {
|
||||
throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
|
||||
}
|
||||
|
||||
// Check that Vm does not have VM Snapshots
|
||||
if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
|
||||
throw new InvalidParameterValueException("NIC cannot be removed from VM with VM Snapshots");
|
||||
}
|
||||
|
||||
NicVO nic = _nicDao.findById(nicId);
|
||||
if (nic == null){
|
||||
throw new InvalidParameterValueException("unable to find a nic with id " + nicId);
|
||||
|
|
@ -1119,6 +1112,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
if (vmInstance == null){
|
||||
throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
|
||||
}
|
||||
|
||||
// Check that Vm does not have VM Snapshots
|
||||
if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
|
||||
throw new InvalidParameterValueException("NIC cannot be updated for VM with VM Snapshots");
|
||||
}
|
||||
|
||||
NicVO nic = _nicDao.findById(nicId);
|
||||
if (nic == null){
|
||||
throw new InvalidParameterValueException("unable to find a nic with id " + nicId);
|
||||
|
|
@ -1291,6 +1290,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
// Verify input parameters
|
||||
VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
|
||||
|
||||
if (vmInstance != null) {
|
||||
// If target VM has associated VM snapshots then don't allow upgrading of VM
|
||||
List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
|
||||
if (vmSnapshots.size() > 0) {
|
||||
throw new InvalidParameterValueException("Unable to scale VM, please remove VM snapshots before scaling VM");
|
||||
}
|
||||
}
|
||||
|
||||
if (vmInstance.getState().equals(State.Stopped)) {
|
||||
upgradeStoppedVirtualMachine(vmId, newServiceOfferingId, customParameters);
|
||||
return true;
|
||||
|
|
@ -4043,6 +4050,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
"Data disks attached to the vm, can not migrate. Need to dettach data disks at first");
|
||||
}
|
||||
|
||||
// Check that Vm does not have VM Snapshots
|
||||
if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
|
||||
throw new InvalidParameterValueException("VM's disk cannot be migrated, please remove all the VM Snapshots for this VM");
|
||||
}
|
||||
|
||||
HypervisorType destHypervisorType = destPool.getHypervisor();
|
||||
if (destHypervisorType == null) {
|
||||
destHypervisorType = _clusterDao.findById(
|
||||
|
|
@ -4486,6 +4498,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
"status: " + destinationHost.getState() + ", state: " + destinationHost.getResourceState());
|
||||
}
|
||||
|
||||
// Check that Vm does not have VM Snapshots
|
||||
if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
|
||||
throw new InvalidParameterValueException("VM with VM Snapshots cannot be migrated with storage, please remove all VM snapshots");
|
||||
}
|
||||
|
||||
List<VolumeVO> vmVolumes = _volsDao.findUsableVolumesForInstance(vm.getId());
|
||||
Map<Volume, StoragePool> volToPoolObjectMap = new HashMap<Volume, StoragePool>();
|
||||
if (!isVMUsingLocalStorage(vm) && destinationHost.getClusterId().equals(srcHost.getClusterId())) {
|
||||
|
|
@ -5012,22 +5029,34 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
}
|
||||
|
||||
VolumeVO root = rootVols.get(0);
|
||||
Long templateId = root.getTemplateId();
|
||||
boolean isISO = false;
|
||||
if(templateId == null) {
|
||||
// Assuming that for a vm deployed using ISO, template ID is set to NULL
|
||||
isISO = true;
|
||||
templateId = vm.getIsoId();
|
||||
}
|
||||
if ( !Volume.State.Allocated.equals(root.getState()) || newTemplateId != null ){
|
||||
Long templateId = root.getTemplateId();
|
||||
boolean isISO = false;
|
||||
if (templateId == null) {
|
||||
// Assuming that for a vm deployed using ISO, template ID is set to NULL
|
||||
isISO = true;
|
||||
templateId = vm.getIsoId();
|
||||
}
|
||||
|
||||
VMTemplateVO template = null;
|
||||
//newTemplateId can be either template or ISO id. In the following snippet based on the vm deployment (from template or ISO) it is handled accordingly
|
||||
if(newTemplateId != null) {
|
||||
template = _templateDao.findById(newTemplateId);
|
||||
_accountMgr.checkAccess(caller, null, true, template);
|
||||
if (isISO) {
|
||||
if (!template.getFormat().equals(ImageFormat.ISO)) {
|
||||
throw new InvalidParameterValueException("Invalid ISO id provided to restore the VM ");
|
||||
// If target VM has associated VM snapshots then don't allow restore of VM
|
||||
List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
|
||||
if (vmSnapshots.size() > 0) {
|
||||
throw new InvalidParameterValueException("Unable to restore VM, please remove VM snapshots before restoring VM");
|
||||
}
|
||||
|
||||
VMTemplateVO template = null;
|
||||
//newTemplateId can be either template or ISO id. In the following snippet based on the vm deployment (from template or ISO) it is handled accordingly
|
||||
if (newTemplateId != null) {
|
||||
template = _templateDao.findById(newTemplateId);
|
||||
_accountMgr.checkAccess(caller, null, true, template);
|
||||
if (isISO) {
|
||||
if (!template.getFormat().equals(ImageFormat.ISO)) {
|
||||
throw new InvalidParameterValueException("Invalid ISO id provided to restore the VM ");
|
||||
}
|
||||
} else {
|
||||
if (template.getFormat().equals(ImageFormat.ISO)) {
|
||||
throw new InvalidParameterValueException("Invalid template id provided to restore the VM ");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (template.getFormat().equals(ImageFormat.ISO)) {
|
||||
|
|
|
|||
|
|
@ -262,6 +262,11 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
|
|||
throw new InvalidParameterValueException("Creating VM snapshot failed due to VM:" + vmId + " is a system VM or does not exist");
|
||||
}
|
||||
|
||||
if (_snapshotDao.listByInstanceId(vmId, Snapshot.State.BackedUp).size() > 0) {
|
||||
throw new InvalidParameterValueException(
|
||||
"VM snapshot for this VM is not allowed. This VM has volumes attached which has snapshots, please remove all snapshots before taking VM snapshot");
|
||||
}
|
||||
|
||||
// check hypervisor capabilities
|
||||
if(!_hypervisorCapabilitiesDao.isVmSnapshotEnabled(userVmVo.getHypervisorType(), "default"))
|
||||
throw new InvalidParameterValueException("VM snapshot is not enabled for hypervisor type: " + userVmVo.getHypervisorType());
|
||||
|
|
@ -577,6 +582,13 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
|
|||
"VM Snapshot reverting failed due to vm is not in the state of Running or Stopped.");
|
||||
}
|
||||
|
||||
if (userVm.getState() == VirtualMachine.State.Running && vmSnapshotVo.getType() == VMSnapshot.Type.Disk || userVm.getState() == VirtualMachine.State.Stopped
|
||||
&& vmSnapshotVo.getType() == VMSnapshot.Type.DiskAndMemory) {
|
||||
throw new InvalidParameterValueException(
|
||||
"VM Snapshot revert not allowed. This will result in VM state change. You can revert running VM to disk and memory type snapshot and stopped VM to disk type"
|
||||
+ " snapshot");
|
||||
}
|
||||
|
||||
// if snapshot is not created, error out
|
||||
if (vmSnapshotVo.getState() != VMSnapshot.State.Ready) {
|
||||
throw new InvalidParameterValueException(
|
||||
|
|
|
|||
Loading…
Reference in New Issue