mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-5648:CopyTemplate and CopyISO across zones fails after NFS
migration to S3.
This commit is contained in:
parent
7e54ca8831
commit
35ba14d88d
|
|
@ -18,6 +18,8 @@ package org.apache.cloudstack.api.command.user.template;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandJobType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
|
|
@ -26,12 +28,9 @@ import org.apache.cloudstack.api.BaseAsyncCmd;
|
|||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.TemplateResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.StorageUnavailableException;
|
||||
|
|
@ -56,7 +55,7 @@ public class CopyTemplateCmd extends BaseAsyncCmd {
|
|||
private Long id;
|
||||
|
||||
@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;
|
||||
|
||||
|
||||
|
|
@ -110,10 +109,12 @@ public class CopyTemplateCmd extends BaseAsyncCmd {
|
|||
return "copying template: " + getId() + " from zone: " + getSourceZoneId() + " to zone: " + getDestinationZoneId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiCommandJobType getInstanceType() {
|
||||
return ApiCommandJobType.Template;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getInstanceId() {
|
||||
return getId();
|
||||
}
|
||||
|
|
@ -132,7 +133,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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,6 +103,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);
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Even
|
|||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -343,15 +343,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();
|
||||
|
|
|
|||
|
|
@ -694,38 +694,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);
|
||||
if (srcSecStore == null) {
|
||||
throw new InvalidParameterValueException("There is no template " + templateId + " in zone " + sourceZoneId);
|
||||
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 (template.isCrossZones()){
|
||||
//TODO: we may need UI still enable CopyTemplate in case of cross zone template to trigger sync to region store.
|
||||
if (srcSecStore == null) {
|
||||
throw new InvalidParameterValueException("There is no template " + templateId + " ready on image store.");
|
||||
}
|
||||
|
||||
if (template.isCrossZones()) {
|
||||
// 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
|
||||
|
|
@ -1706,6 +1715,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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue