mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-5017: Throw CloudRuntimeException in case of template/volume
download when ssvm is not ready so that caller can remove some leftover entries in template_store_ref and volume_store_ref.
This commit is contained in:
parent
84b5bfff74
commit
9a62239a92
|
|
@ -172,12 +172,26 @@ public class TemplateServiceImpl implements TemplateService {
|
|||
return;
|
||||
}
|
||||
|
||||
TemplateOpContext<TemplateApiResult> context = new TemplateOpContext<TemplateApiResult>(callback,
|
||||
templateOnStore, null);
|
||||
try {
|
||||
TemplateOpContext<TemplateApiResult> context = new TemplateOpContext<TemplateApiResult>(callback,
|
||||
templateOnStore, null);
|
||||
|
||||
AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context);
|
||||
store.getDriver().createAsync(store, templateOnStore, caller);
|
||||
AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context);
|
||||
store.getDriver().createAsync(store, templateOnStore, caller);
|
||||
} catch (CloudRuntimeException ex) {
|
||||
// clean up already persisted template_store_ref entry in case of createTemplateCallback is never called
|
||||
TemplateDataStoreVO templateStoreVO = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId());
|
||||
if (templateStoreVO != null) {
|
||||
TemplateInfo tmplObj = _templateFactory.getTemplate(template, store);
|
||||
tmplObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
|
||||
}
|
||||
TemplateApiResult result = new TemplateApiResult(template);
|
||||
result.setResult(ex.getMessage());
|
||||
if (callback != null) {
|
||||
callback.complete(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -732,11 +746,23 @@ public class TemplateServiceImpl implements TemplateService {
|
|||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Invoke datastore driver createAsync to create template on destination store");
|
||||
}
|
||||
TemplateOpContext<TemplateApiResult> context = new TemplateOpContext<TemplateApiResult>(null,
|
||||
(TemplateObject) templateOnStore, future);
|
||||
AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().copyTemplateCrossZoneCallBack(null, null)).setContext(context);
|
||||
destStore.getDriver().createAsync(destStore, templateOnStore, caller);
|
||||
try {
|
||||
TemplateOpContext<TemplateApiResult> context = new TemplateOpContext<TemplateApiResult>(null,
|
||||
(TemplateObject)templateOnStore, future);
|
||||
AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().copyTemplateCrossZoneCallBack(null, null)).setContext(context);
|
||||
destStore.getDriver().createAsync(destStore, templateOnStore, caller);
|
||||
} catch (CloudRuntimeException ex) {
|
||||
// clean up already persisted template_store_ref entry in case of createTemplateCallback is never called
|
||||
TemplateDataStoreVO templateStoreVO = _vmTemplateStoreDao.findByStoreTemplate(destStore.getId(), srcTemplate.getId());
|
||||
if (templateStoreVO != null) {
|
||||
TemplateInfo tmplObj = _templateFactory.getTemplate(srcTemplate, destStore);
|
||||
tmplObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
|
||||
}
|
||||
TemplateApiResult res = new TemplateApiResult((TemplateObject)templateOnStore);
|
||||
res.setResult(ex.getMessage());
|
||||
future.complete(res);
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
|
|||
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
|
||||
|
|
@ -55,7 +56,6 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
|||
import org.apache.cloudstack.storage.command.CommandResult;
|
||||
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
|
||||
import org.apache.cloudstack.storage.command.DeleteCommand;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
|
||||
import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
|
||||
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
|
||||
|
|
@ -165,12 +165,24 @@ public class VolumeServiceImpl implements VolumeService {
|
|||
DataObject volumeOnStore = dataStore.create(volume);
|
||||
volumeOnStore.processEvent(Event.CreateOnlyRequested);
|
||||
|
||||
CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore,
|
||||
future);
|
||||
AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().createVolumeCallback(null, null)).setContext(context);
|
||||
try {
|
||||
CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore,
|
||||
future);
|
||||
AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().createVolumeCallback(null, null)).setContext(context);
|
||||
|
||||
dataStore.getDriver().createAsync(dataStore, volumeOnStore, caller);
|
||||
dataStore.getDriver().createAsync(dataStore, volumeOnStore, caller);
|
||||
} catch (CloudRuntimeException ex) {
|
||||
// clean up already persisted volume_store_ref entry in case of createVolumeCallback is never called
|
||||
VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(dataStore.getId(), volume.getId());
|
||||
if (volStoreVO != null) {
|
||||
VolumeInfo volObj = volFactory.getVolume(volume, dataStore);
|
||||
volObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
|
||||
}
|
||||
VolumeApiResult volResult = new VolumeApiResult((VolumeObject)volumeOnStore);
|
||||
volResult.setResult(ex.getMessage());
|
||||
future.complete(volResult);
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
|
|
@ -1022,13 +1034,25 @@ public class VolumeServiceImpl implements VolumeService {
|
|||
|
||||
volumeOnStore.processEvent(Event.CreateOnlyRequested);
|
||||
|
||||
CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore,
|
||||
future);
|
||||
AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().registerVolumeCallback(null, null));
|
||||
caller.setContext(context);
|
||||
try {
|
||||
CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore,
|
||||
future);
|
||||
AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().registerVolumeCallback(null, null));
|
||||
caller.setContext(context);
|
||||
|
||||
store.getDriver().createAsync(store, volumeOnStore, caller);
|
||||
store.getDriver().createAsync(store, volumeOnStore, caller);
|
||||
} catch (CloudRuntimeException ex) {
|
||||
// clean up already persisted volume_store_ref entry in case of createVolumeCallback is never called
|
||||
VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), volume.getId());
|
||||
if (volStoreVO != null) {
|
||||
VolumeInfo volObj = volFactory.getVolume(volume, store);
|
||||
volObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
|
||||
}
|
||||
VolumeApiResult res = new VolumeApiResult((VolumeObject)volumeOnStore);
|
||||
res.setResult(ex.getMessage());
|
||||
future.complete(res);
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ import com.cloud.storage.upload.UploadListener;
|
|||
import com.cloud.template.VirtualMachineTemplate;
|
||||
import com.cloud.utils.component.ComponentContext;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@Component
|
||||
@Local(value = { DownloadMonitor.class })
|
||||
|
|
@ -169,8 +170,9 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
|
|||
}
|
||||
EndPoint ep = _epSelector.select(template);
|
||||
if (ep == null) {
|
||||
s_logger.warn("There is no secondary storage VM for downloading template to image store " + store.getName());
|
||||
return;
|
||||
String errMsg = "There is no secondary storage VM for downloading template to image store " + store.getName();
|
||||
s_logger.warn(errMsg);
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
DownloadListener dl = new DownloadListener(ep, store, template, _timer, this, dcmd,
|
||||
callback);
|
||||
|
|
|
|||
Loading…
Reference in New Issue