mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Use data motion service to implement copy template.
This commit is contained in:
parent
6f70fe28e8
commit
86913ab4d3
@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.apache.cloudstack.engine.subsystem.api.storage;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
|
||||
import org.apache.cloudstack.framework.async.AsyncCallFuture;
|
||||
|
||||
|
||||
@ -25,10 +26,25 @@ import org.apache.cloudstack.framework.async.AsyncCallFuture;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
|
||||
public interface TemplateService {
|
||||
AsyncCallFuture<CommandResult> createTemplateAsync(TemplateInfo template, DataStore store);
|
||||
AsyncCallFuture<CommandResult> createTemplateFromSnapshotAsync(SnapshotInfo snapshot, TemplateInfo template, DataStore store);
|
||||
AsyncCallFuture<CommandResult> createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, DataStore store);
|
||||
AsyncCallFuture<CommandResult> deleteTemplateAsync(TemplateInfo template);
|
||||
|
||||
public class TemplateApiResult extends CommandResult {
|
||||
private final TemplateInfo template;
|
||||
public TemplateApiResult(TemplateInfo template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
public TemplateInfo getTemplate() {
|
||||
return this.template;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AsyncCallFuture<TemplateApiResult> createTemplateAsync(TemplateInfo template, DataStore store);
|
||||
AsyncCallFuture<TemplateApiResult> createTemplateFromSnapshotAsync(SnapshotInfo snapshot, TemplateInfo template, DataStore store);
|
||||
AsyncCallFuture<TemplateApiResult> createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, DataStore store);
|
||||
AsyncCallFuture<TemplateApiResult> deleteTemplateAsync(TemplateInfo template);
|
||||
AsyncCallFuture<TemplateApiResult> copyTemplate(TemplateInfo srcTemplate,
|
||||
DataStore destStore);
|
||||
|
||||
void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId);
|
||||
void handleTemplateSync(DataStore store);
|
||||
|
||||
@ -28,15 +28,20 @@ import java.util.Set;
|
||||
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.DataMotionService;
|
||||
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.DataStoreManager;
|
||||
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.ObjectInDataStoreStateMachine;
|
||||
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;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
|
||||
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||
@ -68,8 +73,11 @@ import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.VMTemplateZoneVO;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.dao.VMTemplateZoneDao;
|
||||
@ -93,6 +101,8 @@ public class TemplateServiceImpl implements TemplateService {
|
||||
@Inject
|
||||
DataStoreManager _storeMgr;
|
||||
@Inject
|
||||
DataMotionService _motionSrv;
|
||||
@Inject
|
||||
ResourceLimitService _resourceLimitMgr;
|
||||
@Inject
|
||||
AccountManager _accountMgr;
|
||||
@ -120,33 +130,18 @@ public class TemplateServiceImpl implements TemplateService {
|
||||
UserVmDao _userVmDao;
|
||||
@Inject
|
||||
VolumeDao _volumeDao;
|
||||
@Inject
|
||||
TemplateDataFactory _templateFactory;
|
||||
|
||||
|
||||
class CreateTemplateContext<T> extends AsyncRpcConext<T> {
|
||||
final TemplateInfo srcTemplate;
|
||||
final DataStore store;
|
||||
final AsyncCallFuture<CommandResult> future;
|
||||
final DataObject templateOnStore;
|
||||
|
||||
public CreateTemplateContext(AsyncCompletionCallback<T> callback, TemplateInfo srcTemplate,
|
||||
AsyncCallFuture<CommandResult> future,
|
||||
DataStore store,
|
||||
DataObject templateOnStore
|
||||
) {
|
||||
super(callback);
|
||||
this.srcTemplate = srcTemplate;
|
||||
this.future = future;
|
||||
this.store = store;
|
||||
this.templateOnStore = templateOnStore;
|
||||
}
|
||||
}
|
||||
|
||||
class DeleteTemplateContext<T> extends AsyncRpcConext<T> {
|
||||
class TemplateOpContext<T> extends AsyncRpcConext<T> {
|
||||
final TemplateObject template;
|
||||
final AsyncCallFuture<CommandResult> future;
|
||||
final AsyncCallFuture<TemplateApiResult> future;
|
||||
|
||||
public DeleteTemplateContext(AsyncCompletionCallback<T> callback, TemplateObject template,
|
||||
AsyncCallFuture<CommandResult> future) {
|
||||
public TemplateOpContext(AsyncCompletionCallback<T> callback, TemplateObject template,
|
||||
AsyncCallFuture<TemplateApiResult> future) {
|
||||
super(callback);
|
||||
this.template = template;
|
||||
this.future = future;
|
||||
@ -156,7 +151,7 @@ public class TemplateServiceImpl implements TemplateService {
|
||||
return template;
|
||||
}
|
||||
|
||||
public AsyncCallFuture<CommandResult> getFuture() {
|
||||
public AsyncCallFuture<TemplateApiResult> getFuture() {
|
||||
return future;
|
||||
}
|
||||
|
||||
@ -164,21 +159,17 @@ public class TemplateServiceImpl implements TemplateService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncCallFuture<CommandResult> createTemplateAsync(
|
||||
public AsyncCallFuture<TemplateApiResult> createTemplateAsync(
|
||||
TemplateInfo template, DataStore store) {
|
||||
TemplateObject to = (TemplateObject) template;
|
||||
AsyncCallFuture<CommandResult> future = new AsyncCallFuture<CommandResult>();
|
||||
AsyncCallFuture<TemplateApiResult> future = new AsyncCallFuture<TemplateApiResult>();
|
||||
// persist template_store_ref entry
|
||||
DataObject templateOnStore = store.create(template);
|
||||
// update template_store_ref state
|
||||
templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested);
|
||||
|
||||
CreateTemplateContext<CommandResult> context = new CreateTemplateContext<CommandResult>(null,
|
||||
template,
|
||||
future,
|
||||
store,
|
||||
templateOnStore
|
||||
);
|
||||
TemplateOpContext<TemplateApiResult> context = new TemplateOpContext<TemplateApiResult>(null,
|
||||
(TemplateObject)templateOnStore, future);
|
||||
|
||||
AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context);
|
||||
store.getDriver().createAsync(templateOnStore, caller);
|
||||
@ -470,15 +461,14 @@ public class TemplateServiceImpl implements TemplateService {
|
||||
|
||||
|
||||
protected Void createTemplateCallback(AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> callback,
|
||||
CreateTemplateContext<CreateCmdResult> context) {
|
||||
TemplateObject template = (TemplateObject)context.srcTemplate;
|
||||
AsyncCallFuture<CommandResult> future = context.future;
|
||||
CommandResult result = new CommandResult();
|
||||
DataObject templateOnStore = context.templateOnStore;
|
||||
TemplateOpContext<CreateCmdResult> context) {
|
||||
TemplateObject template = (TemplateObject)context.getTemplate();
|
||||
AsyncCallFuture<TemplateApiResult> future = context.getFuture();
|
||||
TemplateApiResult result = new TemplateApiResult(template);
|
||||
CreateCmdResult callbackResult = callback.getResult();
|
||||
if (callbackResult.isFailed()) {
|
||||
try {
|
||||
templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
|
||||
template.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
|
||||
template.stateTransit(TemplateEvent.OperationFailed);
|
||||
} catch (NoTransitionException e) {
|
||||
s_logger.debug("Failed to update template state", e);
|
||||
@ -489,7 +479,7 @@ public class TemplateServiceImpl implements TemplateService {
|
||||
}
|
||||
|
||||
try {
|
||||
templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed);
|
||||
template.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed);
|
||||
template.stateTransit(TemplateEvent.OperationSucceeded);
|
||||
} catch (NoTransitionException e) {
|
||||
s_logger.debug("Failed to transit state", e);
|
||||
@ -503,22 +493,22 @@ public class TemplateServiceImpl implements TemplateService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncCallFuture<CommandResult> deleteTemplateAsync(
|
||||
public AsyncCallFuture<TemplateApiResult> deleteTemplateAsync(
|
||||
TemplateInfo template) {
|
||||
TemplateObject to = (TemplateObject) template;
|
||||
// update template_store_ref status
|
||||
to.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested);
|
||||
AsyncCallFuture<CommandResult> future = new AsyncCallFuture<CommandResult>();
|
||||
AsyncCallFuture<TemplateApiResult> future = new AsyncCallFuture<TemplateApiResult>();
|
||||
|
||||
DeleteTemplateContext<CommandResult> context = new DeleteTemplateContext<CommandResult>(null, to, future);
|
||||
TemplateOpContext<TemplateApiResult> context = new TemplateOpContext<TemplateApiResult>(null, to, future);
|
||||
AsyncCallbackDispatcher<TemplateServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().deleteTemplateCallback(null, null)).setContext(context);
|
||||
to.getDataStore().getDriver().deleteAsync(to, caller);
|
||||
return future;
|
||||
}
|
||||
|
||||
public Void deleteTemplateCallback(AsyncCallbackDispatcher<TemplateServiceImpl, CommandResult> callback, DeleteTemplateContext<CommandResult> context) {
|
||||
CommandResult result = callback.getResult();
|
||||
public Void deleteTemplateCallback(AsyncCallbackDispatcher<TemplateServiceImpl, TemplateApiResult> callback, TemplateOpContext<TemplateApiResult> context) {
|
||||
TemplateApiResult result = callback.getResult();
|
||||
TemplateObject vo = context.getTemplate();
|
||||
// we can only update state in template_store_ref table
|
||||
if (result.isSuccess()) {
|
||||
@ -531,19 +521,114 @@ public class TemplateServiceImpl implements TemplateService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncCallFuture<CommandResult> createTemplateFromSnapshotAsync(
|
||||
public AsyncCallFuture<TemplateApiResult> createTemplateFromSnapshotAsync(
|
||||
SnapshotInfo snapshot, TemplateInfo template, DataStore store) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncCallFuture<CommandResult> createTemplateFromVolumeAsync(
|
||||
public AsyncCallFuture<TemplateApiResult> createTemplateFromVolumeAsync(
|
||||
VolumeInfo volume, TemplateInfo template, DataStore store) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncCallFuture<TemplateApiResult> copyTemplate(TemplateInfo srcTemplate,
|
||||
DataStore destStore) {
|
||||
AsyncCallFuture<TemplateApiResult> future = new AsyncCallFuture<TemplateApiResult>();
|
||||
TemplateApiResult res = new TemplateApiResult(srcTemplate);
|
||||
try{
|
||||
// create one entry in template_store_ref
|
||||
TemplateDataStoreVO destTmpltStore = _vmTemplateStoreDao.findByStoreTemplate(destStore.getId(), srcTemplate.getId());
|
||||
if (destTmpltStore == null) {
|
||||
destTmpltStore = new TemplateDataStoreVO(destStore.getId(), srcTemplate.getId());
|
||||
destTmpltStore.setCopy(true);
|
||||
_vmTemplateStoreDao.persist(destTmpltStore);
|
||||
}
|
||||
TemplateInfo destTemplate = this._templateFactory.getTemplate(destTmpltStore.getTemplateId(), destStore);
|
||||
destTemplate.processEvent(Event.CreateOnlyRequested);
|
||||
srcTemplate.processEvent(Event.CopyingRequested);
|
||||
|
||||
CopyTemplateContext<TemplateApiResult> context = new CopyTemplateContext<TemplateApiResult>(null, future, srcTemplate,
|
||||
destTemplate,
|
||||
destStore);
|
||||
AsyncCallbackDispatcher<TemplateServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().copyTemplateCallBack(null, null))
|
||||
.setContext(context);
|
||||
this._motionSrv.copyAsync(srcTemplate, destTemplate, caller);
|
||||
} catch (Exception e) {
|
||||
s_logger.debug("Failed to copy volume", e);
|
||||
res.setResult(e.toString());
|
||||
future.complete(res);
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
protected Void copyTemplateCallBack(AsyncCallbackDispatcher<TemplateServiceImpl, CopyCommandResult> callback,
|
||||
CopyTemplateContext<TemplateApiResult> context) {
|
||||
TemplateInfo srcTemplate = context.getSrcTemplate();
|
||||
TemplateInfo destTemplate = context.getDestTemplate();
|
||||
CopyCommandResult result = callback.getResult();
|
||||
AsyncCallFuture<TemplateApiResult> future = context.getFuture();
|
||||
TemplateApiResult res = new TemplateApiResult(destTemplate);
|
||||
try {
|
||||
if (result.isFailed()) {
|
||||
res.setResult(result.getResult());
|
||||
destTemplate.processEvent(Event.OperationFailed);
|
||||
srcTemplate.processEvent(Event.OperationFailed);
|
||||
// remove entry from template_store_ref
|
||||
TemplateDataStoreVO destTmpltStore = _vmTemplateStoreDao.findByStoreTemplate(context.getDestStore().getId(), destTemplate.getId());
|
||||
_vmTemplateStoreDao.remove(destTmpltStore.getId());
|
||||
future.complete(res);
|
||||
return null;
|
||||
}
|
||||
srcTemplate.processEvent(Event.OperationSuccessed);
|
||||
destTemplate.processEvent(Event.OperationSuccessed);
|
||||
future.complete(res);
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
s_logger.debug("Failed to process copy template callback", e);
|
||||
res.setResult(e.toString());
|
||||
future.complete(res);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
class CopyTemplateContext<T> extends AsyncRpcConext<T> {
|
||||
final TemplateInfo srcTemplate;
|
||||
final TemplateInfo destTemplate;
|
||||
final DataStore destStore;
|
||||
final AsyncCallFuture<TemplateApiResult> future;
|
||||
|
||||
/**
|
||||
* @param callback
|
||||
*/
|
||||
public CopyTemplateContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<TemplateApiResult> future, TemplateInfo srcTemplate,
|
||||
TemplateInfo destTemplate, DataStore destStore) {
|
||||
super(callback);
|
||||
this.srcTemplate = srcTemplate;
|
||||
this.destTemplate = destTemplate;
|
||||
this.destStore = destStore;
|
||||
this.future = future;
|
||||
}
|
||||
|
||||
public TemplateInfo getSrcTemplate() {
|
||||
return srcTemplate;
|
||||
}
|
||||
|
||||
public TemplateInfo getDestTemplate() {
|
||||
return destTemplate;
|
||||
}
|
||||
|
||||
public DataStore getDestStore() {
|
||||
return destStore;
|
||||
}
|
||||
|
||||
public AsyncCallFuture<TemplateApiResult> getFuture() {
|
||||
return future;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
|
||||
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.TemplateInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
|
||||
@ -93,7 +94,7 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
VMTemplateDao imageDataDao;
|
||||
@Inject
|
||||
VolumeDao2 volumeDao;
|
||||
@Inject
|
||||
@Inject
|
||||
HostDao hostDao;
|
||||
@Inject
|
||||
HostPodDao podDao;
|
||||
@ -119,7 +120,7 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
HostVO host;
|
||||
String primaryName = "my primary data store";
|
||||
DataStore primaryStore;
|
||||
|
||||
|
||||
@Test(priority = -1)
|
||||
public void setUp() {
|
||||
ComponentContext.initComponentsLifeCycle();
|
||||
@ -137,7 +138,7 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
return;
|
||||
}
|
||||
//create data center
|
||||
DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24",
|
||||
DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24",
|
||||
null, null, NetworkType.Basic, null, null, true, true, null, null);
|
||||
dc = dcDao.persist(dc);
|
||||
dcId = dc.getId();
|
||||
@ -172,7 +173,7 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
host = hostDao.persist(host);
|
||||
|
||||
//primaryStore = createPrimaryDataStore();
|
||||
|
||||
|
||||
//CreateVolumeAnswer createVolumeFromImageAnswer = new CreateVolumeAnswer(UUID.randomUUID().toString());
|
||||
|
||||
/*try {
|
||||
@ -188,7 +189,7 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
|
||||
//Mockito.when(primaryStoreDao.findById(Mockito.anyLong())).thenReturn(primaryStore);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void injectMockito() {
|
||||
if (host == null) {
|
||||
@ -225,10 +226,10 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
image.setPrepopulate(true);
|
||||
image.setCrossZones(true);
|
||||
image.setExtractable(true);
|
||||
|
||||
|
||||
//image.setImageDataStoreId(storeId);
|
||||
image = imageDataDao.persist(image);
|
||||
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
@ -237,7 +238,7 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
DataStore store = createImageStore();
|
||||
VMTemplateVO image = createImageData();
|
||||
TemplateInfo template = imageDataFactory.getTemplate(image.getId(), store);
|
||||
AsyncCallFuture<CommandResult> future = imageService.createTemplateAsync(template, store);
|
||||
AsyncCallFuture<TemplateApiResult> future = imageService.createTemplateAsync(template, store);
|
||||
future.get();
|
||||
template = imageDataFactory.getTemplate(image.getId(), store);
|
||||
/*imageProviderMgr.configure("image Provider", new HashMap<String, Object>());
|
||||
@ -259,7 +260,7 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
public void createTemplateTest() {
|
||||
createTemplate();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreatePrimaryStorage() {
|
||||
DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample primary data store provider");
|
||||
@ -282,13 +283,13 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
params.put("roles", DataStoreRole.Primary.toString());
|
||||
params.put("uuid", UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString());
|
||||
params.put("providerName", String.valueOf(provider.getName()));
|
||||
|
||||
|
||||
DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
|
||||
this.primaryStore = lifeCycle.initialize(params);
|
||||
ClusterScope scope = new ClusterScope(clusterId, podId, dcId);
|
||||
lifeCycle.attachCluster(this.primaryStore, scope);
|
||||
}
|
||||
|
||||
|
||||
private DataStore createImageStore() {
|
||||
DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample image data store provider");
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
@ -306,7 +307,7 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
public void testcreateImageStore() {
|
||||
createImageStore();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public DataStore createPrimaryDataStore() {
|
||||
try {
|
||||
@ -324,16 +325,16 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
params.put("roles", DataStoreRole.Primary.toString());
|
||||
params.put("uuid", UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString());
|
||||
params.put("providerName", String.valueOf(provider.getName()));
|
||||
|
||||
|
||||
DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
|
||||
DataStore store = lifeCycle.initialize(params);
|
||||
ClusterScope scope = new ClusterScope(clusterId, podId, dcId);
|
||||
lifeCycle.attachCluster(store, scope);
|
||||
|
||||
|
||||
/*
|
||||
PrimaryDataStoreProvider provider = primaryDataStoreProviderMgr.getDataStoreProvider("sample primary data store provider");
|
||||
primaryDataStoreProviderMgr.configure("primary data store mgr", new HashMap<String, Object>());
|
||||
|
||||
|
||||
List<PrimaryDataStoreVO> ds = primaryStoreDao.findPoolByName(this.primaryName);
|
||||
if (ds.size() >= 1) {
|
||||
PrimaryDataStoreVO store = ds.get(0);
|
||||
@ -341,8 +342,8 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
return provider.getDataStore(store.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("url", this.getPrimaryStorageUrl());
|
||||
params.put("dcId", dcId.toString());
|
||||
@ -385,8 +386,8 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//@Test(priority=3)
|
||||
|
||||
//@Test(priority=3)
|
||||
public void createDataDisk() {
|
||||
DataStore primaryStore = this.primaryStore;
|
||||
VolumeVO volume = createVolume(null, primaryStore.getId());
|
||||
@ -402,8 +403,8 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//@Test(priority=3)
|
||||
|
||||
//@Test(priority=3)
|
||||
public void createAndDeleteDataDisk() {
|
||||
DataStore primaryStore = this.primaryStore;
|
||||
VolumeVO volume = createVolume(null, primaryStore.getId());
|
||||
@ -418,7 +419,7 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
//delete the volume
|
||||
vol = volumeFactory.getVolume(volume.getId(), primaryStore);
|
||||
future = volumeService.expungeVolumeAsync(vol);
|
||||
|
||||
@ -36,6 +36,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
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.TemplateService.TemplateApiResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||
import org.apache.cloudstack.framework.async.AsyncCallFuture;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||
@ -180,7 +181,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te
|
||||
throw new CloudRuntimeException("Unable to find image store to download template "+ profile.getTemplate());
|
||||
}
|
||||
for (DataStore imageStore : imageStores) {
|
||||
AsyncCallFuture<CommandResult> future = this.imageService
|
||||
AsyncCallFuture<TemplateApiResult> future = this.imageService
|
||||
.createTemplateAsync(this.imageFactory.getTemplate(template.getId(), imageStore), imageStore);
|
||||
try {
|
||||
future.get();
|
||||
@ -226,10 +227,10 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te
|
||||
|
||||
for (DataStore imageStore : imageStores) {
|
||||
s_logger.info("Delete template from image store: " + imageStore.getName());
|
||||
AsyncCallFuture<CommandResult> future = this.imageService
|
||||
AsyncCallFuture<TemplateApiResult> future = this.imageService
|
||||
.deleteTemplateAsync(this.imageFactory.getTemplate(template.getId(), imageStore));
|
||||
try {
|
||||
CommandResult result = future.get();
|
||||
TemplateApiResult result = future.get();
|
||||
success = result.isSuccess();
|
||||
if ( !success )
|
||||
break;
|
||||
|
||||
@ -64,6 +64,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
|
||||
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.TemplateInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||
@ -945,49 +947,63 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
//Copy will just find one eligible image store for the destination zone and copy template there, not propagate to all image stores
|
||||
TemplateInfo srcTemplate = this.tmplFactory.getTemplate(template.getId(), srcSecStore);
|
||||
// Copy will just find one eligible image store for the destination zone
|
||||
// and copy template there, not propagate to all image stores
|
||||
// for that zone
|
||||
for ( DataStore dstSecStore : dstSecStores ) {
|
||||
for (DataStore dstSecStore : dstSecStores) {
|
||||
TemplateDataStoreVO dstTmpltStore = null;
|
||||
try {
|
||||
dstTmpltStore = this._tmplStoreDao.findByStoreTemplate(dstSecStore.getId(), tmpltId, true);
|
||||
if (dstTmpltStore != null) {
|
||||
dstTmpltStore = _tmplStoreDao.lockRow(dstTmpltStore.getId(), true);
|
||||
if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOADED) {
|
||||
if (dstTmpltStore.getDestroyed() == false) {
|
||||
return true; // already downloaded on this image store
|
||||
} else {
|
||||
dstTmpltStore.setDestroyed(false);
|
||||
_tmplStoreDao.update(dstTmpltStore.getId(), dstTmpltStore);
|
||||
return true;
|
||||
}
|
||||
} else if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOAD_ERROR){
|
||||
if (dstTmpltStore.getDestroyed() == true) {
|
||||
dstTmpltStore.setDestroyed(false);
|
||||
dstTmpltStore.setDownloadState(Status.NOT_DOWNLOADED);
|
||||
dstTmpltStore.setDownloadPercent(0);
|
||||
dstTmpltStore.setCopy(true);
|
||||
dstTmpltStore.setErrorString("");
|
||||
dstTmpltStore.setJobId(null);
|
||||
_tmplStoreDao.update(dstTmpltStore.getId(), dstTmpltStore);
|
||||
}
|
||||
}
|
||||
}
|
||||
dstTmpltStore = this._tmplStoreDao.findByStoreTemplate(dstSecStore.getId(), tmpltId, true);
|
||||
if (dstTmpltStore != null) {
|
||||
dstTmpltStore = _tmplStoreDao.lockRow(dstTmpltStore.getId(), true);
|
||||
if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOADED) {
|
||||
if (dstTmpltStore.getDestroyed() == false) {
|
||||
return true; // already downloaded on this image
|
||||
// store
|
||||
} else {
|
||||
dstTmpltStore.setDestroyed(false);
|
||||
_tmplStoreDao.update(dstTmpltStore.getId(), dstTmpltStore);
|
||||
return true;
|
||||
}
|
||||
} else if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOAD_ERROR) {
|
||||
if (dstTmpltStore.getDestroyed() == true) {
|
||||
dstTmpltStore.setDestroyed(false);
|
||||
dstTmpltStore.setDownloadState(Status.NOT_DOWNLOADED);
|
||||
dstTmpltStore.setDownloadPercent(0);
|
||||
dstTmpltStore.setCopy(true);
|
||||
dstTmpltStore.setErrorString("");
|
||||
dstTmpltStore.setJobId(null);
|
||||
_tmplStoreDao.update(dstTmpltStore.getId(), dstTmpltStore);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
txn.commit();
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
if(_downloadMonitor.copyTemplate(template, srcSecStore, dstSecStore) ) {
|
||||
AsyncCallFuture<TemplateApiResult> future = this.tmpltSvr.copyTemplate(srcTemplate, dstSecStore);
|
||||
try {
|
||||
TemplateApiResult result = future.get();
|
||||
if (result.isFailed()) {
|
||||
s_logger.debug("copy template failed:" + result.getResult());
|
||||
return false;
|
||||
}
|
||||
// if(_downloadMonitor.copyTemplate(template, srcSecStore,
|
||||
// dstSecStore) ) {
|
||||
_tmpltDao.addTemplateToZone(template, dstZoneId);
|
||||
|
||||
if(account.getId() != Account.ACCOUNT_ID_SYSTEM){
|
||||
if (account.getId() != Account.ACCOUNT_ID_SYSTEM) {
|
||||
UsageEventUtils.publishUsageEvent(copyEventType, account.getId(), dstZoneId, tmpltId, null, null, null, srcTmpltStore.getSize(),
|
||||
template.getClass().getName(), template.getUuid());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
s_logger.debug("failed to copy template to image store:" + dstSecStore.getName() + " ,will try next one");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1002,17 +1018,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
||||
Long destZoneId = cmd.getDestinationZoneId();
|
||||
Account caller = UserContext.current().getCaller();
|
||||
|
||||
/*
|
||||
if (_swiftMgr.isSwiftEnabled()) {
|
||||
throw new CloudRuntimeException("copytemplate API is disabled in Swift setup, templates in Swift can be accessed by all Zones");
|
||||
}
|
||||
|
||||
if (_s3Mgr.isS3Enabled()) {
|
||||
throw new CloudRuntimeException(
|
||||
"copytemplate API is disabled in S3 setup -- S3 templates are accessible in all zones.");
|
||||
}
|
||||
*/
|
||||
|
||||
//Verify parameters
|
||||
if (sourceZoneId == destZoneId) {
|
||||
throw new InvalidParameterValueException("Please specify different source and destination zones.");
|
||||
@ -1769,7 +1774,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
||||
if (store.size() > 1) {
|
||||
throw new CloudRuntimeException("muliple image data store, don't know which one to use");
|
||||
}
|
||||
AsyncCallFuture<CommandResult> future = null;
|
||||
AsyncCallFuture<TemplateApiResult> future = null;
|
||||
if (snapshotId != null) {
|
||||
SnapshotInfo snapInfo = this.snapshotFactory.getSnapshot(snapshotId);
|
||||
future = this.tmpltSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store.get(0));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user