Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
f455463
VM snapshots of running KVM instance using storage providers plugins …
slavkap Oct 16, 2019
a3e642c
Removed duplicated functionality
slavkap Sep 11, 2020
06e1236
Added requirements in global setting kvm.vmstoragesnapshot.enabled
slavkap Sep 14, 2020
1bac7e3
Added Apache license header
slavkap Oct 1, 2020
1f4bf9b
Removed commented code
slavkap Oct 1, 2020
2fbed98
If "kvm.vmstoragesnapshot.enabled" is null should be considered as false
slavkap Oct 1, 2020
97712e3
removed unused imports, replaced default template
slavkap Oct 22, 2020
8b632a7
"kvm.vmstoragesnapshot.enabled" set to dynamic
slavkap Oct 31, 2020
f1eb0f2
Getting status of freeze/thaw commands not the return code
slavkap Oct 31, 2020
1d23647
removed "CreatingKVM" VMsnapshot state and events related to it
slavkap Nov 6, 2020
0cfbfa2
renamed AllocatedKVM to AllocatedVM
slavkap Nov 6, 2020
1727bd1
loggin the result of "drive-backup" command
slavkap Nov 11, 2020
d235633
Merge branch 'master' into feature_kvmsnapshot
slavkap Nov 11, 2020
2eae9af
Merge branch 'master' into feature_kvmsnapshot
slavkap Feb 24, 2021
bf2f86b
Check which VM snapshot strategy could handle the vm snapshots
slavkap Mar 9, 2021
7f460b5
Merge branch 'master' into feature_kvmsnapshot
slavkap Mar 9, 2021
8d6016a
Added poolId in canHandle for KVM hypervisors
slavkap Mar 10, 2021
b736065
skip smoke tests if the hypervisor's OS type is CentOS
slavkap Jun 24, 2021
653c3bb
Added missed import in smoke test
slavkap Jun 26, 2021
845d326
Suggested change to use ` org.apache.commons.lang.StringUtils.isNotBl…
slavkap Jul 19, 2021
565b14c
Fix getting device on Ubuntu
slavkap Jul 19, 2021
ccee5e8
Merge branch 'main' into feature_kvmsnapshot
slavkap Sep 27, 2021
264f527
Removed new snapshot states and functionality for NFS
slavkap Oct 6, 2021
c012d67
Merge branch 'main' into feature_kvmsnapshot
slavkap Mar 7, 2022
f8dc5b0
Merge branch 'main' into feature_kvmsnapshot
slavkap Mar 7, 2022
1a4648c
throw CloudRuntimeException
slavkap Mar 11, 2022
313e1c2
Merge branch 'main' into feature_kvmsnapshot
slavkap Mar 11, 2022
8669879
exclude GROUP snapshots when listing snapshots
slavkap Mar 17, 2022
b6a5ea6
Merge branch 'main' into feature_kvmsnapshot
slavkap Mar 17, 2022
9cbe148
Skip tests if there is pool with NFS/Local
slavkap Mar 17, 2022
996cc45
address comments
slavkap Mar 30, 2022
4518956
Merge branch 'main' into feature_kvmsnapshot
slavkap Mar 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/src/main/java/com/cloud/storage/Snapshot.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

public interface Snapshot extends ControlledEntity, Identity, InternalIdentity, StateObject<Snapshot.State> {
public enum Type {
MANUAL, RECURRING, TEMPLATE, HOURLY, DAILY, WEEKLY, MONTHLY;
MANUAL, RECURRING, TEMPLATE, HOURLY, DAILY, WEEKLY, MONTHLY, GROUP;
private int max = 8;

public void setMax(int max) {
Expand Down
39 changes: 39 additions & 0 deletions core/src/main/java/com/cloud/agent/api/FreezeThawVMAnswer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//

package com.cloud.agent.api;

public class FreezeThawVMAnswer extends Answer {

public FreezeThawVMAnswer() {
super();
}

public FreezeThawVMAnswer(FreezeThawVMCommand command, boolean success, String details) {
super(command, success, details);
}

public FreezeThawVMAnswer(FreezeThawVMCommand command, Exception e) {
super(command, e);
}

public FreezeThawVMAnswer(FreezeThawVMCommand command) {
super(command);
}
}
56 changes: 56 additions & 0 deletions core/src/main/java/com/cloud/agent/api/FreezeThawVMCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//

package com.cloud.agent.api;

public class FreezeThawVMCommand extends Command{

public static final String FREEZE = "frozen";
public static final String THAW = "thawed";
public static final String STATUS = "status";

private String vmName;
private String option;

public FreezeThawVMCommand(String vmName) {
this.vmName = vmName;
}

public String getVmName() {
return vmName;
}

public void setVmName(String vmName) {
this.vmName = vmName;
}

public String getOption() {
return option;
}

public void setOption(String option) {
this.option = option;
}

@Override
public boolean executeInSequence() {
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,12 @@ public interface StorageStrategyFactory {

VMSnapshotStrategy getVmSnapshotStrategy(VMSnapshot vmSnapshot);

/**
* Used only for KVM hypervisors when allocating a VM snapshot
* @param vmId the ID of the virtual machine
* @param snapshotMemory for VM snapshots with memory
* @return VMSnapshotStrategy
*/
VMSnapshotStrategy getVmSnapshotStrategy(Long vmId, Long rootPoolId, boolean snapshotMemory);

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ public interface VMSnapshotStrategy {

StrategyPriority canHandle(VMSnapshot vmSnapshot);

/**
* Used only for KVM hypervisors when allocating a VM snapshot
* @param vmId the ID of the virtual machine
* @param snapshotMemory for VM snapshots with memory
* @return StrategyPriority
*/
StrategyPriority canHandle(Long vmId, Long poolId, boolean snapshotMemory);

/**
* Delete vm snapshot only from database. Introduced as a Vmware optimization in which vm snapshots are deleted when
* the vm gets deleted on hypervisor (no need to delete each vm snapshot before deleting vm, just mark them as deleted on DB)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import com.cloud.storage.GuestOSHypervisorVO;
import com.cloud.storage.GuestOSVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.GuestOSDao;
import com.cloud.storage.dao.GuestOSHypervisorDao;
Expand All @@ -67,6 +68,7 @@
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.fsm.NoTransitionException;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.snapshot.VMSnapshot;
import com.cloud.vm.snapshot.VMSnapshotVO;
Expand Down Expand Up @@ -332,7 +334,7 @@ private void updateVolumePath(List<VolumeObjectTO> volumeTOs) {
}
}

private void publishUsageEvent(String type, VMSnapshot vmSnapshot, UserVm userVm, VolumeObjectTO volumeTo) {
protected void publishUsageEvent(String type, VMSnapshot vmSnapshot, UserVm userVm, VolumeObjectTO volumeTo) {
VolumeVO volume = volumeDao.findById(volumeTo.getId());
Long diskOfferingId = volume.getDiskOfferingId();
Long offeringId = null;
Expand All @@ -350,7 +352,7 @@ private void publishUsageEvent(String type, VMSnapshot vmSnapshot, UserVm userVm
volumeTo.getSize(), VMSnapshot.class.getName(), vmSnapshot.getUuid(), details);
}

private void publishUsageEvent(String type, VMSnapshot vmSnapshot, UserVm userVm, Long vmSnapSize, Long virtualSize) {
protected void publishUsageEvent(String type, VMSnapshot vmSnapshot, UserVm userVm, Long vmSnapSize, Long virtualSize) {
try {
Map<String, String> details = new HashMap<>();
if (vmSnapshot != null) {
Expand Down Expand Up @@ -449,4 +451,20 @@ public boolean deleteVMSnapshotFromDB(VMSnapshot vmSnapshot, boolean unmanage) {
}
return vmSnapshotDao.remove(vmSnapshot.getId());
}

@Override
public StrategyPriority canHandle(Long vmId, Long rootPoolId, boolean snapshotMemory) {
UserVmVO vm = userVmDao.findById(vmId);
if (vm.getState() == State.Running && !snapshotMemory) {
return StrategyPriority.CANT_HANDLE;
}

List<VolumeVO> volumes = volumeDao.findByInstance(vmId);
for (VolumeVO volume : volumes) {
if (volume.getFormat() != ImageFormat.QCOW2) {
return StrategyPriority.CANT_HANDLE;
}
}
return StrategyPriority.DEFAULT;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.datastore.util.ScaleIOUtil;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;

import com.cloud.agent.api.VMSnapshotTO;
Expand All @@ -47,6 +48,7 @@
import com.cloud.server.ManagementServerImpl;
import com.cloud.storage.DiskOfferingVO;
import com.cloud.storage.Storage;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.VolumeDao;
Expand Down Expand Up @@ -105,6 +107,13 @@ public StrategyPriority canHandle(VMSnapshot vmSnapshot) {
throw new CloudRuntimeException("Failed to get the volumes for the vm snapshot: " + vmSnapshot.getUuid());
}

if (!VMSnapshot.State.Allocated.equals(vmSnapshot.getState())) {
List<VMSnapshotDetailsVO> vmDetails = vmSnapshotDetailsDao.findDetails(vmSnapshot.getId(), "SnapshotGroupId" );
if (CollectionUtils.isEmpty(vmDetails)) {
return StrategyPriority.CANT_HANDLE;
}
}

if (volumeTOs != null && !volumeTOs.isEmpty()) {
for (VolumeObjectTO volumeTO: volumeTOs) {
Long poolId = volumeTO.getPoolId();
Expand All @@ -118,6 +127,27 @@ public StrategyPriority canHandle(VMSnapshot vmSnapshot) {
return StrategyPriority.HIGHEST;
}

@Override
public StrategyPriority canHandle(Long vmId, Long rootPoolId, boolean snapshotMemory) {
if (snapshotMemory) {
return StrategyPriority.CANT_HANDLE;
}
List<VolumeObjectTO> volumeTOs = vmSnapshotHelper.getVolumeTOList(vmId);
if (volumeTOs == null || volumeTOs.isEmpty()) {
return StrategyPriority.CANT_HANDLE;
}

for (VolumeObjectTO volumeTO : volumeTOs) {
Long poolId = volumeTO.getPoolId();
Storage.StoragePoolType poolType = vmSnapshotHelper.getStoragePoolType(poolId);
if (poolType != Storage.StoragePoolType.PowerFlex || volumeTO.getFormat() != ImageFormat.RAW || poolId != rootPoolId) {
return StrategyPriority.CANT_HANDLE;
}
}

return StrategyPriority.HIGHEST;
}

@Override
public VMSnapshot takeVMSnapshot(VMSnapshot vmSnapshot) {
UserVm userVm = userVmDao.findById(vmSnapshot.getVmId());
Expand Down
Loading