mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-1392: add create template from snapshot and volume
This commit is contained in:
parent
0978df95ad
commit
b30e39b0e3
@ -21,11 +21,13 @@ package org.apache.cloudstack.storage.image;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ImageService;
|
||||
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.SnapshotInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
||||
@ -37,6 +39,7 @@ import org.apache.cloudstack.framework.async.AsyncRpcConext;
|
||||
import org.apache.cloudstack.storage.datastore.DataObjectManager;
|
||||
import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
|
||||
import org.apache.cloudstack.storage.image.store.TemplateObject;
|
||||
import org.apache.cloudstack.storage.motion.DataMotionService;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -49,6 +52,8 @@ public class ImageServiceImpl implements ImageService {
|
||||
ObjectInDataStoreManager objectInDataStoreMgr;
|
||||
@Inject
|
||||
DataObjectManager dataObjectMgr;
|
||||
@Inject
|
||||
DataMotionService motionSrv;
|
||||
|
||||
class CreateTemplateContext<T> extends AsyncRpcConext<T> {
|
||||
final TemplateInfo srcTemplate;
|
||||
@ -140,17 +145,91 @@ public class ImageServiceImpl implements ImageService {
|
||||
return null;
|
||||
}
|
||||
|
||||
private class CopyTemplateContext<T> extends AsyncRpcConext<T> {
|
||||
final AsyncCallFuture<CommandResult> future;
|
||||
final DataObject object;
|
||||
/**
|
||||
* @param callback
|
||||
*/
|
||||
public CopyTemplateContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<CommandResult> future, DataObject object) {
|
||||
super(callback);
|
||||
this.future = future;
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public AsyncCallFuture<CommandResult> createTemplateFromSnapshotAsync(
|
||||
SnapshotInfo snapshot, TemplateInfo template, DataStore store) {
|
||||
// TODO Auto-generated method stub
|
||||
AsyncCallFuture<CommandResult> future = new AsyncCallFuture<CommandResult>();
|
||||
DataObject templateOnStore = null;
|
||||
try {
|
||||
templateOnStore = store.create(template);
|
||||
templateOnStore.processEvent(Event.CreateOnlyRequested);
|
||||
|
||||
CopyTemplateContext<CommandResult> context = new CopyTemplateContext<CommandResult>(null, future, templateOnStore);
|
||||
AsyncCallbackDispatcher<ImageServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().copyTemplateAsyncCallback(null, null))
|
||||
.setContext(context);
|
||||
this.motionSrv.copyAsync(snapshot, templateOnStore, caller);
|
||||
} catch (Exception e) {
|
||||
s_logger.debug("Failed to create template: " + template.getId() + "from snapshot: " + snapshot.getId() + ", due to " + e.toString());
|
||||
if (templateOnStore != null) {
|
||||
try {
|
||||
templateOnStore.processEvent(Event.OperationFailed);
|
||||
} catch (Exception e1) {
|
||||
|
||||
}
|
||||
}
|
||||
CommandResult result = new CommandResult();
|
||||
result.setResult(e.toString());
|
||||
future.complete(result);
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
protected Void copyTemplateAsyncCallback(AsyncCallbackDispatcher<ImageServiceImpl, CopyCommandResult> callback, CopyTemplateContext<CommandResult> context) {
|
||||
CopyCommandResult result = callback.getResult();
|
||||
AsyncCallFuture<CommandResult> future = context.future;
|
||||
DataObject object = context.object;
|
||||
CommandResult res = new CommandResult();
|
||||
if (result.isFailed()) {
|
||||
res.setResult(result.getResult());
|
||||
object.processEvent(Event.OperationFailed);
|
||||
} else {
|
||||
object.processEvent(Event.OperationSuccessed);
|
||||
}
|
||||
future.complete(res);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncCallFuture<CommandResult> createTemplateFromVolumeAsync(
|
||||
VolumeInfo volume, TemplateInfo template, DataStore store) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
AsyncCallFuture<CommandResult> future = new AsyncCallFuture<CommandResult>();
|
||||
DataObject templateOnStore = null;
|
||||
try {
|
||||
templateOnStore = store.create(template);
|
||||
templateOnStore.processEvent(Event.CreateOnlyRequested);
|
||||
|
||||
CopyTemplateContext<CommandResult> context = new CopyTemplateContext<CommandResult>(null, future, templateOnStore);
|
||||
AsyncCallbackDispatcher<ImageServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().copyTemplateAsyncCallback(null, null))
|
||||
.setContext(context);
|
||||
this.motionSrv.copyAsync(volume, templateOnStore, caller);
|
||||
} catch (Exception e) {
|
||||
s_logger.debug("Failed to create template: " + template.getId() + "from volume: " + volume.getId() + ", due to " + e.toString());
|
||||
if (templateOnStore != null) {
|
||||
try {
|
||||
templateOnStore.processEvent(Event.OperationFailed);
|
||||
} catch (Exception e1) {
|
||||
|
||||
}
|
||||
}
|
||||
CommandResult result = new CommandResult();
|
||||
result.setResult(e.toString());
|
||||
future.complete(result);
|
||||
}
|
||||
return future;
|
||||
}
|
||||
}
|
||||
|
||||
@ -668,9 +668,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
||||
String checkSum = this.templateMgr
|
||||
.getChecksum(hostId, answer.getPath());
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
|
||||
txn.start();
|
||||
|
||||
privateTemplate.setChecksum(checkSum);
|
||||
templateDao.update(privateTemplate.getId(), privateTemplate);
|
||||
@ -685,8 +683,9 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
||||
templateHostVO.setLastUpdated(new Date());
|
||||
templateHostVO.setSize(answer.getVirtualSize());
|
||||
templateHostVO.setPhysicalSize(answer.getphysicalSize());
|
||||
|
||||
templateHostDao.persist(templateHostVO);
|
||||
txn.close();
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
|
||||
@ -1716,8 +1716,17 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
||||
|
||||
try {
|
||||
TemplateInfo tmplInfo = this.tmplFactory.getTemplate(templateId);
|
||||
snapshot = _snapshotDao.findById(snapshotId);
|
||||
ZoneScope scope = new ZoneScope(snapshot.getDataCenterId());
|
||||
ZoneScope scope = null;
|
||||
Long zoneId = null;
|
||||
if (snapshotId != null) {
|
||||
snapshot = _snapshotDao.findById(snapshotId);
|
||||
zoneId = snapshot.getDataCenterId();
|
||||
|
||||
} else if (volumeId != null) {
|
||||
volume = _volumeDao.findById(volumeId);
|
||||
zoneId = volume.getDataCenterId();
|
||||
}
|
||||
scope = new ZoneScope(zoneId);
|
||||
List<DataStore> store = this.dataStoreMgr.getImageStores(scope);
|
||||
if (store.size() > 1) {
|
||||
throw new CloudRuntimeException("muliple image data store, don't know which one to use");
|
||||
@ -1727,7 +1736,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
||||
SnapshotInfo snapInfo = this.snapshotFactory.getSnapshot(snapshotId);
|
||||
future = this.imageSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store.get(0));
|
||||
} else if (volumeId != null) {
|
||||
volume = _volumeDao.findById(volumeId);
|
||||
VolumeInfo volInfo = this.volFactory.getVolume(volumeId);
|
||||
future = this.imageSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store.get(0));
|
||||
} else {
|
||||
@ -1748,7 +1756,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
||||
UsageEventVO usageEvent = new UsageEventVO(
|
||||
EventTypes.EVENT_TEMPLATE_CREATE,
|
||||
privateTemplate.getAccountId(),
|
||||
snapshot.getDataCenterId(),
|
||||
zoneId,
|
||||
privateTemplate.getId(), privateTemplate.getName(),
|
||||
null, privateTemplate.getSourceTemplateId(),
|
||||
privateTemplate.getSize());
|
||||
@ -1971,6 +1979,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
||||
}
|
||||
}
|
||||
privateTemplate.setSourceTemplateId(sourceTemplateId);
|
||||
privateTemplate.setImageDataStoreId(1);
|
||||
|
||||
VMTemplateVO template = this._tmpltDao.persist(privateTemplate);
|
||||
// Increment the number of templates
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user