CLOUDSTACK-5648:CopyTemplate and CopyISO across zones fails after NFS

migration to S3.
This commit is contained in:
Min Chen 2013-12-26 12:39:39 -08:00
parent 30d55cf0c4
commit 5d262d7b59
5 changed files with 51 additions and 22 deletions

View File

@ -59,8 +59,7 @@ public class CopyTemplateCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.SOURCE_ZONE_ID,
type = CommandType.UUID,
entityType = ZoneResponse.class,
required = true,
description = "ID of the zone the template is currently hosted on.")
description = "ID of the zone the template is currently hosted on. If not specified and template is cross-zone, then we will sync this template to region wide image store.")
private Long sourceZoneId;
/////////////////////////////////////////////////////
@ -137,7 +136,7 @@ public class CopyTemplateCmd extends BaseAsyncCmd {
}
response.setResponseName(getCommandName());
this.setResponseObject(response);
setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to copy template");
}

View File

@ -101,6 +101,8 @@ public interface TemplateManager {
DataStore getImageStore(long zoneId, long tmpltId);
DataStore getImageStore(long tmpltId);
Long getTemplateSize(long templateId, long zoneId);
DataStore getImageStore(String storeUuid, Long zoneId);

View File

@ -59,6 +59,8 @@ public interface TemplateDataStoreDao extends GenericDao<TemplateDataStoreVO, Lo
TemplateDataStoreVO findByTemplate(long templateId, DataStoreRole role);
TemplateDataStoreVO findReadyByTemplate(long templateId, DataStoreRole role);
TemplateDataStoreVO findByTemplateZone(long templateId, Long zoneId, DataStoreRole role);
List<TemplateDataStoreVO> listByTemplate(long templateId);

View File

@ -350,15 +350,20 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
}
@Override
public TemplateDataStoreVO findReadyOnCache(long templateId) {
public TemplateDataStoreVO findReadyByTemplate(long templateId, DataStoreRole role) {
SearchCriteria<TemplateDataStoreVO> sc = templateRoleSearch.create();
sc.setParameters("template_id", templateId);
sc.setParameters("store_role", DataStoreRole.ImageCache);
sc.setParameters("store_role", role);
sc.setParameters("destroyed", false);
sc.setParameters("state", ObjectInDataStoreStateMachine.State.Ready);
return findOneIncludingRemovedBy(sc);
}
@Override
public TemplateDataStoreVO findReadyOnCache(long templateId) {
return findReadyByTemplate(templateId, DataStoreRole.ImageCache);
}
@Override
public List<TemplateDataStoreVO> listOnCache(long templateId) {
SearchCriteria<TemplateDataStoreVO> sc = templateRoleSearch.create();

View File

@ -689,38 +689,47 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
Account caller = CallContext.current().getCallingAccount();
// Verify parameters
if (sourceZoneId.equals(destZoneId)) {
throw new InvalidParameterValueException("Please specify different source and destination zones.");
}
DataCenterVO sourceZone = _dcDao.findById(sourceZoneId);
if (sourceZone == null) {
throw new InvalidParameterValueException("Please specify a valid source zone.");
}
DataCenterVO dstZone = _dcDao.findById(destZoneId);
if (dstZone == null) {
throw new InvalidParameterValueException("Please specify a valid destination zone.");
}
VMTemplateVO template = _tmpltDao.findById(templateId);
if (template == null || template.getRemoved() != null) {
throw new InvalidParameterValueException("Unable to find template with id");
}
DataStore srcSecStore = getImageStore(sourceZoneId, templateId);
DataStore srcSecStore = null;
if (sourceZoneId != null) {
// template is on zone-wide secondary storage
srcSecStore = getImageStore(sourceZoneId, templateId);
} else {
// template is on region store
srcSecStore = getImageStore(templateId);
}
if (srcSecStore == null) {
throw new InvalidParameterValueException("There is no template " + templateId + " in zone " + sourceZoneId);
throw new InvalidParameterValueException("There is no template " + templateId + " ready on image store.");
}
if (template.isCrossZones()) {
//TODO: we may need UI still enable CopyTemplate in case of cross zone template to trigger sync to region store.
// sync template from cache store to region store if it is not there, for cases where we are going to migrate existing NFS to S3.
_tmpltSvr.syncTemplateToRegionStore(templateId, srcSecStore);
s_logger.debug("Template " + templateId + " is cross-zone, don't need to copy");
return template;
}
if (sourceZoneId != null) {
if (sourceZoneId.equals(destZoneId)) {
throw new InvalidParameterValueException("Please specify different source and destination zones.");
}
DataCenterVO sourceZone = _dcDao.findById(sourceZoneId);
if (sourceZone == null) {
throw new InvalidParameterValueException("Please specify a valid source zone.");
}
}
DataCenterVO dstZone = _dcDao.findById(destZoneId);
if (dstZone == null) {
throw new InvalidParameterValueException("Please specify a valid destination zone.");
}
DataStore dstSecStore = getImageStore(destZoneId, templateId);
if (dstSecStore != null) {
s_logger.debug("There is template " + templateId + " in secondary storage " + dstSecStore.getName() + " in zone " + destZoneId + " , don't need to copy");
@ -1692,6 +1701,18 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
return null;
}
// get the region wide image store where a template is READY on,
// just pick one is enough.
@Override
public DataStore getImageStore(long tmpltId) {
TemplateDataStoreVO tmpltStore = _tmplStoreDao.findReadyByTemplate(tmpltId, DataStoreRole.Image);
if (tmpltStore != null) {
return _dataStoreMgr.getDataStore(tmpltStore.getDataStoreId(), DataStoreRole.Image);
}
return null;
}
@Override
public Long getTemplateSize(long templateId, long zoneId) {
TemplateDataStoreVO templateStoreRef = _tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, zoneId, VMTemplateStorageResourceAssoc.Status.DOWNLOADED);