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 javax.inject.Inject;
|
||||||
|
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
|
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.CreateCmdResult;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
|
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.DataStore;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ImageService;
|
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;
|
||||||
|
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.SnapshotInfo;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent;
|
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
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.DataObjectManager;
|
||||||
import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
|
import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
|
||||||
import org.apache.cloudstack.storage.image.store.TemplateObject;
|
import org.apache.cloudstack.storage.image.store.TemplateObject;
|
||||||
|
import org.apache.cloudstack.storage.motion.DataMotionService;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -49,6 +52,8 @@ public class ImageServiceImpl implements ImageService {
|
|||||||
ObjectInDataStoreManager objectInDataStoreMgr;
|
ObjectInDataStoreManager objectInDataStoreMgr;
|
||||||
@Inject
|
@Inject
|
||||||
DataObjectManager dataObjectMgr;
|
DataObjectManager dataObjectMgr;
|
||||||
|
@Inject
|
||||||
|
DataMotionService motionSrv;
|
||||||
|
|
||||||
class CreateTemplateContext<T> extends AsyncRpcConext<T> {
|
class CreateTemplateContext<T> extends AsyncRpcConext<T> {
|
||||||
final TemplateInfo srcTemplate;
|
final TemplateInfo srcTemplate;
|
||||||
@ -140,17 +145,91 @@ public class ImageServiceImpl implements ImageService {
|
|||||||
return null;
|
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
|
@Override
|
||||||
public AsyncCallFuture<CommandResult> createTemplateFromSnapshotAsync(
|
public AsyncCallFuture<CommandResult> createTemplateFromSnapshotAsync(
|
||||||
SnapshotInfo snapshot, TemplateInfo template, DataStore store) {
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncCallFuture<CommandResult> createTemplateFromVolumeAsync(
|
public AsyncCallFuture<CommandResult> createTemplateFromVolumeAsync(
|
||||||
VolumeInfo volume, TemplateInfo template, DataStore store) {
|
VolumeInfo volume, TemplateInfo template, DataStore store) {
|
||||||
// TODO Auto-generated method stub
|
AsyncCallFuture<CommandResult> future = new AsyncCallFuture<CommandResult>();
|
||||||
return null;
|
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
|
String checkSum = this.templateMgr
|
||||||
.getChecksum(hostId, answer.getPath());
|
.getChecksum(hostId, answer.getPath());
|
||||||
|
|
||||||
Transaction txn = Transaction.currentTxn();
|
|
||||||
|
|
||||||
txn.start();
|
|
||||||
|
|
||||||
privateTemplate.setChecksum(checkSum);
|
privateTemplate.setChecksum(checkSum);
|
||||||
templateDao.update(privateTemplate.getId(), privateTemplate);
|
templateDao.update(privateTemplate.getId(), privateTemplate);
|
||||||
@ -685,8 +683,9 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||||||
templateHostVO.setLastUpdated(new Date());
|
templateHostVO.setLastUpdated(new Date());
|
||||||
templateHostVO.setSize(answer.getVirtualSize());
|
templateHostVO.setSize(answer.getVirtualSize());
|
||||||
templateHostVO.setPhysicalSize(answer.getphysicalSize());
|
templateHostVO.setPhysicalSize(answer.getphysicalSize());
|
||||||
|
|
||||||
templateHostDao.persist(templateHostVO);
|
templateHostDao.persist(templateHostVO);
|
||||||
txn.close();
|
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1716,8 +1716,17 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
TemplateInfo tmplInfo = this.tmplFactory.getTemplate(templateId);
|
TemplateInfo tmplInfo = this.tmplFactory.getTemplate(templateId);
|
||||||
snapshot = _snapshotDao.findById(snapshotId);
|
ZoneScope scope = null;
|
||||||
ZoneScope scope = new ZoneScope(snapshot.getDataCenterId());
|
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);
|
List<DataStore> store = this.dataStoreMgr.getImageStores(scope);
|
||||||
if (store.size() > 1) {
|
if (store.size() > 1) {
|
||||||
throw new CloudRuntimeException("muliple image data store, don't know which one to use");
|
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);
|
SnapshotInfo snapInfo = this.snapshotFactory.getSnapshot(snapshotId);
|
||||||
future = this.imageSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store.get(0));
|
future = this.imageSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store.get(0));
|
||||||
} else if (volumeId != null) {
|
} else if (volumeId != null) {
|
||||||
volume = _volumeDao.findById(volumeId);
|
|
||||||
VolumeInfo volInfo = this.volFactory.getVolume(volumeId);
|
VolumeInfo volInfo = this.volFactory.getVolume(volumeId);
|
||||||
future = this.imageSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store.get(0));
|
future = this.imageSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store.get(0));
|
||||||
} else {
|
} else {
|
||||||
@ -1748,7 +1756,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
UsageEventVO usageEvent = new UsageEventVO(
|
UsageEventVO usageEvent = new UsageEventVO(
|
||||||
EventTypes.EVENT_TEMPLATE_CREATE,
|
EventTypes.EVENT_TEMPLATE_CREATE,
|
||||||
privateTemplate.getAccountId(),
|
privateTemplate.getAccountId(),
|
||||||
snapshot.getDataCenterId(),
|
zoneId,
|
||||||
privateTemplate.getId(), privateTemplate.getName(),
|
privateTemplate.getId(), privateTemplate.getName(),
|
||||||
null, privateTemplate.getSourceTemplateId(),
|
null, privateTemplate.getSourceTemplateId(),
|
||||||
privateTemplate.getSize());
|
privateTemplate.getSize());
|
||||||
@ -1971,6 +1979,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
privateTemplate.setSourceTemplateId(sourceTemplateId);
|
privateTemplate.setSourceTemplateId(sourceTemplateId);
|
||||||
|
privateTemplate.setImageDataStoreId(1);
|
||||||
|
|
||||||
VMTemplateVO template = this._tmpltDao.persist(privateTemplate);
|
VMTemplateVO template = this._tmpltDao.persist(privateTemplate);
|
||||||
// Increment the number of templates
|
// Increment the number of templates
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user