Merge release branch 4.9 to master

This closes #1644

* 4.9:
  CLOUDSTACK-4858 Honors the snapshot.backup.rightafter configuration variable Unhides snapshot.backup.rightafter from global configuration
This commit is contained in:
Rajani Karuturi 2017-02-08 12:37:21 +05:30
commit 25f1552e37
7 changed files with 79 additions and 3 deletions

View File

@ -44,7 +44,10 @@ import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation;
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
import org.apache.cloudstack.engine.subsystem.api.storage.StorageStrategyFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
@ -188,6 +191,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
StorageManager storageMgr;
@Inject
protected UserVmCloneSettingDao _vmCloneSettingDao;
@Inject
StorageStrategyFactory _storageStrategyFactory;
private final StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
protected List<StoragePoolAllocator> _storagePoolAllocators;
@ -393,6 +398,24 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
DataStoreRole dataStoreRole = getDataStoreRole(snapshot);
SnapshotInfo snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), dataStoreRole);
if(snapInfo == null && dataStoreRole == DataStoreRole.Image) {
// snapshot is not backed up to secondary, let's do that now.
snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), DataStoreRole.Primary);
if (snapInfo == null) {
throw new CloudRuntimeException("Cannot find snapshot " + snapshot.getId());
}
// We need to copy the snapshot onto secondary.
SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.BACKUP);
snapshotStrategy.backupSnapshot(snapInfo);
// Attempt to grab it again.
snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), dataStoreRole);
if (snapInfo == null) {
throw new CloudRuntimeException("Cannot find snapshot " + snapshot.getId() + " on secondary and could not create backup");
}
}
// don't try to perform a sync if the DataStoreRole of the snapshot is equal to DataStoreRole.Primary
if (!DataStoreRole.Primary.equals(dataStoreRole)) {
try {

View File

@ -47,6 +47,7 @@ public class SnapshotStateMachineManagerImpl implements SnapshotStateMachineMana
stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationFailed, Snapshot.State.Error);
stateMachine.addTransition(Snapshot.State.BackedUp, Event.DestroyRequested, Snapshot.State.Destroying);
stateMachine.addTransition(Snapshot.State.BackedUp, Event.CopyingRequested, Snapshot.State.Copying);
stateMachine.addTransition(Snapshot.State.BackedUp, Event.BackupToSecondary, Snapshot.State.BackingUp);
stateMachine.addTransition(Snapshot.State.Copying, Event.OperationSucceeded, Snapshot.State.BackedUp);
stateMachine.addTransition(Snapshot.State.Copying, Event.OperationFailed, Snapshot.State.BackedUp);
stateMachine.addTransition(Snapshot.State.Destroying, Event.OperationSucceeded, Snapshot.State.Destroyed);

View File

@ -39,6 +39,7 @@ import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
import org.apache.cloudstack.storage.datastore.PrimaryDataStoreImpl;
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
import com.cloud.configuration.Config;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
@ -382,8 +383,24 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
snapshot = result.getSnapshot();
DataStore primaryStore = snapshot.getDataStore();
boolean backupFlag = Boolean.parseBoolean(configDao.getValue(Config.BackupSnapshotAfterTakingSnapshot.toString()));
SnapshotInfo backupedSnapshot = backupSnapshot(snapshot);
SnapshotInfo backupedSnapshot;
if(backupFlag) {
backupedSnapshot = backupSnapshot(snapshot);
} else {
// Fake it to get the transitions to fire in the proper order
s_logger.debug("skipping backup of snapshot due to configuration "+Config.BackupSnapshotAfterTakingSnapshot.toString());
SnapshotObject snapObj = (SnapshotObject)snapshot;
try {
snapObj.processEvent(Snapshot.Event.OperationNotPerformed);
} catch (NoTransitionException e) {
s_logger.debug("Failed to change state: " + snapshot.getId() + ": " + e.toString());
throw new CloudRuntimeException(e.toString());
}
backupedSnapshot = snapshot;
}
try {
SnapshotInfo parent = snapshot.getParent();

View File

@ -511,7 +511,7 @@ public enum Config {
null),
SnapshotDeltaMax("Snapshots", SnapshotManager.class, Integer.class, "snapshot.delta.max", "16", "max delta snapshots between two full snapshots.", null),
BackupSnapshotAfterTakingSnapshot(
"Hidden",
"Snapshots",
SnapshotManager.class,
Boolean.class,
"snapshot.backup.rightafter",

View File

@ -1095,7 +1095,13 @@ public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implement
DataStoreRole dataStoreRole = getDataStoreRole(snapshot, _snapshotStoreDao, dataStoreMgr);
SnapshotDataStoreVO snapshotStoreRef = _snapshotStoreDao.findBySnapshot(snapshotId, dataStoreRole);
if(snapshotStoreRef == null) {
// The snapshot was not backed up to secondary. Find the snap on primary
snapshotStoreRef = _snapshotStoreDao.findBySnapshot(snapshotId, DataStoreRole.Primary);
if(snapshotStoreRef == null) {
throw new CloudRuntimeException("Could not find snapshot");
}
}
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(), snapshot.getDataCenterId(), snapshotId, snapshot.getName(),
null, null, snapshotStoreRef.getPhysicalSize(), volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid());

View File

@ -75,7 +75,10 @@ import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation;
import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
import org.apache.cloudstack.engine.subsystem.api.storage.StorageStrategyFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
@ -255,6 +258,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
@Inject
private SnapshotDataFactory _snapshotFactory;
@Inject
StorageStrategyFactory _storageStrategyFactory;
@Inject
private TemplateService _tmpltSvr;
@Inject
private DataStoreManager _dataStoreMgr;
@ -1496,6 +1501,21 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
SnapshotInfo snapInfo = _snapshotFactory.getSnapshot(snapshotId, dataStoreRole);
if (dataStoreRole == DataStoreRole.Image) {
if (snapInfo == null) {
snapInfo = _snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Primary);
if(snapInfo == null) {
throw new CloudRuntimeException("Cannot find snapshot "+snapshotId);
}
// We need to copy the snapshot onto secondary.
SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.BACKUP);
snapshotStrategy.backupSnapshot(snapInfo);
// Attempt to grab it again.
snapInfo = _snapshotFactory.getSnapshot(snapshotId, dataStoreRole);
if(snapInfo == null) {
throw new CloudRuntimeException("Cannot find snapshot " + snapshotId + " on secondary and could not create backup");
}
}
DataStore snapStore = snapInfo.getDataStore();
if (snapStore != null) {

View File

@ -69,6 +69,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
import org.apache.cloudstack.engine.subsystem.api.storage.StorageStrategyFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
@ -165,6 +166,9 @@ public class TemplateManagerImplTest {
@Inject
VMTemplateDetailsDao tmpltDetailsDao;
@Inject
StorageStrategyFactory storageStrategyFactory;
public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
AtomicInteger ai = new AtomicInteger(0);
public CustomThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
@ -457,6 +461,11 @@ public class TemplateManagerImplTest {
return Mockito.mock(VMTemplateDao.class);
}
@Bean
public StorageStrategyFactory storageStrategyFactory() {
return Mockito.mock(StorageStrategyFactory.class);
}
@Bean
public VMTemplatePoolDao vmTemplatePoolDao() {
return Mockito.mock(VMTemplatePoolDao.class);