Fix extractTemplateCmd.

This commit is contained in:
Min Chen 2013-04-22 21:48:57 -07:00
parent b8c5c67fbc
commit e40a06deae
12 changed files with 200 additions and 168 deletions

View File

@ -36,6 +36,7 @@ import com.cloud.exception.InternalErrorException;
import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.StorageUnavailableException; import com.cloud.exception.StorageUnavailableException;
import com.cloud.user.Account; import com.cloud.user.Account;
import com.cloud.utils.Pair;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
public interface TemplateApiService { public interface TemplateApiService {
@ -76,7 +77,7 @@ public interface TemplateApiService {
* - the command specifying the mode and id of the ISO * - the command specifying the mode and id of the ISO
* @return extractId. * @return extractId.
*/ */
Long extract(ExtractIsoCmd cmd) throws InternalErrorException; Pair<Long, String> extract(ExtractIsoCmd cmd) throws InternalErrorException;
/** /**
* Extracts a Template * Extracts a Template
@ -85,7 +86,7 @@ public interface TemplateApiService {
* - the command specifying the mode and id of the template * - the command specifying the mode and id of the template
* @return extractId * @return extractId
*/ */
Long extract(ExtractTemplateCmd cmd) throws InternalErrorException; Pair<Long, String> extract(ExtractTemplateCmd cmd) throws InternalErrorException;
VirtualMachineTemplate getTemplate(long templateId); VirtualMachineTemplate getTemplate(long templateId);

View File

@ -257,7 +257,7 @@ public interface ResponseGenerator {
SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group); SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group);
ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode); ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode, String url);
String toSerializedString(CreateCmdResponse response, String responseType); String toSerializedString(CreateCmdResponse response, String responseType);

View File

@ -33,6 +33,7 @@ import com.cloud.exception.InternalErrorException;
import com.cloud.template.VirtualMachineTemplate; import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account; import com.cloud.user.Account;
import com.cloud.user.UserContext; import com.cloud.user.UserContext;
import com.cloud.utils.Pair;
@APICommand(name = "extractIso", description="Extracts an ISO", responseObject=ExtractResponse.class) @APICommand(name = "extractIso", description="Extracts an ISO", responseObject=ExtractResponse.class)
public class ExtractIsoCmd extends BaseAsyncCmd { public class ExtractIsoCmd extends BaseAsyncCmd {
@ -123,9 +124,16 @@ public class ExtractIsoCmd extends BaseAsyncCmd {
public void execute(){ public void execute(){
try { try {
UserContext.current().setEventDetails(getEventDescription()); UserContext.current().setEventDetails(getEventDescription());
Long uploadId = _templateService.extract(this); Pair<Long, String> uploadPair = _templateService.extract(this);
if (uploadId != null){ if (uploadPair != null){
ExtractResponse response = _responseGenerator.createExtractResponse(uploadId, id, zoneId, getEntityOwnerId(), mode); ExtractResponse response = null;
if (uploadPair.second() != null ) {
// region-wide image store
response = _responseGenerator.createExtractResponse(null, id, zoneId, getEntityOwnerId(), mode, uploadPair.second());
} else {
// nfs image store
response = _responseGenerator.createExtractResponse(uploadPair.first(), id, zoneId, getEntityOwnerId(), mode, null);
}
response.setResponseName(getCommandName()); response.setResponseName(getCommandName());
response.setObjectName("iso"); response.setObjectName("iso");
this.setResponseObject(response); this.setResponseObject(response);

View File

@ -34,6 +34,7 @@ import com.cloud.exception.InternalErrorException;
import com.cloud.template.VirtualMachineTemplate; import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account; import com.cloud.user.Account;
import com.cloud.user.UserContext; import com.cloud.user.UserContext;
import com.cloud.utils.Pair;
@APICommand(name = "extractTemplate", description="Extracts a template", responseObject=ExtractResponse.class) @APICommand(name = "extractTemplate", description="Extracts a template", responseObject=ExtractResponse.class)
public class ExtractTemplateCmd extends BaseAsyncCmd { public class ExtractTemplateCmd extends BaseAsyncCmd {
@ -125,9 +126,16 @@ public class ExtractTemplateCmd extends BaseAsyncCmd {
public void execute(){ public void execute(){
try { try {
UserContext.current().setEventDetails(getEventDescription()); UserContext.current().setEventDetails(getEventDescription());
Long uploadId = _templateService.extract(this); Pair<Long, String> uploadPair = _templateService.extract(this);
if (uploadId != null){ if (uploadPair != null){
ExtractResponse response = _responseGenerator.createExtractResponse(uploadId, id, zoneId, getEntityOwnerId(), mode); ExtractResponse response = null;
if (uploadPair.second() != null ) {
// region-wide image store
response = _responseGenerator.createExtractResponse(null, id, zoneId, getEntityOwnerId(), mode, uploadPair.second());
} else {
// nfs image store
response = _responseGenerator.createExtractResponse(uploadPair.first(), id, zoneId, getEntityOwnerId(), mode, null);
}
response.setResponseName(getCommandName()); response.setResponseName(getCommandName());
this.setResponseObject(response); this.setResponseObject(response);
} else { } else {

View File

@ -24,6 +24,7 @@ import com.cloud.agent.api.Command;
public interface EndPoint { public interface EndPoint {
public long getId(); public long getId();
public String getHostAddr();
public Answer sendMessage(Command cmd); public Answer sendMessage(Command cmd);
public void sendMessageAsync(Command cmd, AsyncCompletionCallback<Answer> callback); public void sendMessageAsync(Command cmd, AsyncCompletionCallback<Answer> callback);
void sendMessageAsyncWithListener(Command cmd, Listener listner); void sendMessageAsyncWithListener(Command cmd, Listener listner);

View File

@ -30,7 +30,13 @@ public class LocalHostEndpoint implements EndPoint {
return 0; return 0;
} }
@Override @Override
public String getHostAddr() {
return "127.0.0.0";
}
@Override
public Answer sendMessage(Command cmd) { public Answer sendMessage(Command cmd) {
if (cmd instanceof CopyCommand) { if (cmd instanceof CopyCommand) {
return resource.executeRequest(cmd); return resource.executeRequest(cmd);

View File

@ -63,6 +63,7 @@ public class RemoteHostEndPoint implements EndPoint {
return ep; return ep;
} }
@Override
public String getHostAddr() { public String getHostAddr() {
return this.hostAddress; return this.hostAddress;
} }

View File

@ -242,6 +242,7 @@ import com.cloud.storage.ImageStore;
import com.cloud.storage.S3; import com.cloud.storage.S3;
import com.cloud.storage.Snapshot; import com.cloud.storage.Snapshot;
import com.cloud.storage.SnapshotVO; import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Upload;
import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.Storage.TemplateType;
@ -1525,8 +1526,8 @@ public class ApiResponseHelper implements ResponseGenerator {
} }
@Override @Override
public ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode) { public ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode, String url) {
UploadVO uploadInfo = ApiDBUtils.findUploadById(uploadId);
ExtractResponse response = new ExtractResponse(); ExtractResponse response = new ExtractResponse();
response.setObjectName("template"); response.setObjectName("template");
VMTemplateVO template = ApiDBUtils.findTemplateById(id); VMTemplateVO template = ApiDBUtils.findTemplateById(id);
@ -1538,11 +1539,19 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setZoneName(zone.getName()); response.setZoneName(zone.getName());
} }
response.setMode(mode); response.setMode(mode);
response.setUploadId(uploadInfo.getUuid()); if (uploadId == null) {
response.setState(uploadInfo.getUploadState().toString()); // region-wide image store
response.setUrl(url);
response.setState(Upload.Status.DOWNLOAD_URL_CREATED.toString());
} else {
UploadVO uploadInfo = ApiDBUtils.findUploadById(uploadId);
response.setUploadId(uploadInfo.getUuid());
response.setState(uploadInfo.getUploadState().toString());
response.setUrl(uploadInfo.getUploadUrl());
}
Account account = ApiDBUtils.findAccountById(accountId); Account account = ApiDBUtils.findAccountById(accountId);
response.setAccountId(account.getUuid()); response.setAccountId(account.getUuid());
response.setUrl(uploadInfo.getUploadUrl());
return response; return response;
} }

View File

@ -17,6 +17,8 @@
package com.cloud.storage.upload; package com.cloud.storage.upload;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobManager;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
import com.cloud.storage.Upload.Mode; import com.cloud.storage.Upload.Mode;
@ -37,7 +39,7 @@ public interface UploadMonitor extends Manager{
public void cancelAllUploads(Long templateId); public void cancelAllUploads(Long templateId);
public Long extractTemplate(VMTemplateVO template, String url, public Long extractTemplate(VMTemplateVO template, String url,
VMTemplateHostVO tmpltHostRef,Long dataCenterId, long eventId, long asyncJobId, AsyncJobManager asyncMgr); TemplateDataStoreVO tmpltStoreRef,Long dataCenterId, long eventId, long asyncJobId, AsyncJobManager asyncMgr);
boolean isTypeUploadInProgress(Long typeId, Type type); boolean isTypeUploadInProgress(Long typeId, Type type);
@ -51,7 +53,7 @@ public interface UploadMonitor extends Manager{
long asyncJobId, AsyncJobManager asyncMgr); long asyncJobId, AsyncJobManager asyncMgr);
UploadVO createEntityDownloadURL(VMTemplateVO template, UploadVO createEntityDownloadURL(VMTemplateVO template,
VMTemplateHostVO vmTemplateHost, Long dataCenterId, long eventId); TemplateDataStoreVO vmTemplateStore, Long dataCenterId, long eventId);
void createVolumeDownloadURL(Long entityId, String path, Type type, void createVolumeDownloadURL(Long entityId, String path, Type type,
Long dataCenterId, Long uploadId); Long dataCenterId, Long uploadId);

View File

@ -32,14 +32,22 @@ import javax.ejb.Local;
import javax.inject.Inject; import javax.inject.Inject;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
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.EndPoint;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.cloud.agent.AgentManager; import com.cloud.agent.AgentManager;
import com.cloud.agent.Listener; import com.cloud.agent.Listener;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command; import com.cloud.agent.api.Command;
import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand; import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand; import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
import com.cloud.agent.api.storage.ListTemplateAnswer;
import com.cloud.agent.api.storage.UploadCommand; import com.cloud.agent.api.storage.UploadCommand;
import com.cloud.agent.api.storage.UploadProgressCommand.RequestType; import com.cloud.agent.api.storage.UploadProgressCommand.RequestType;
import com.cloud.agent.manager.Commands; import com.cloud.agent.manager.Commands;
@ -56,6 +64,7 @@ import com.cloud.storage.Upload;
import com.cloud.storage.Upload.Mode; import com.cloud.storage.Upload.Mode;
import com.cloud.storage.Upload.Status; import com.cloud.storage.Upload.Status;
import com.cloud.storage.Upload.Type; import com.cloud.storage.Upload.Type;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.UploadVO; import com.cloud.storage.UploadVO;
import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateVO;
@ -103,6 +112,10 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor {
ResourceManager _resourceMgr; ResourceManager _resourceMgr;
@Inject @Inject
SecondaryStorageVmManager _ssvmMgr; SecondaryStorageVmManager _ssvmMgr;
@Inject
EndPointSelector _epSelector;
@Inject
DataStoreManager storeMgr;
private String _name; private String _name;
private Boolean _sslCopy = new Boolean(false); private Boolean _sslCopy = new Boolean(false);
@ -169,7 +182,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor {
@Override @Override
public Long extractTemplate( VMTemplateVO template, String url, public Long extractTemplate( VMTemplateVO template, String url,
VMTemplateHostVO vmTemplateHost,Long dataCenterId, long eventId, long asyncJobId, AsyncJobManager asyncMgr){ TemplateDataStoreVO vmTemplateHost,Long dataCenterId, long eventId, long asyncJobId, AsyncJobManager asyncMgr){
Type type = (template.getFormat() == ImageFormat.ISO) ? Type.ISO : Type.TEMPLATE ; Type type = (template.getFormat() == ImageFormat.ISO) ? Type.ISO : Type.TEMPLATE ;
@ -199,18 +212,12 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor {
} }
@Override @Override
public UploadVO createEntityDownloadURL(VMTemplateVO template, VMTemplateHostVO vmTemplateHost, Long dataCenterId, long eventId) { public UploadVO createEntityDownloadURL(VMTemplateVO template, TemplateDataStoreVO vmTemplateHost, Long dataCenterId, long eventId) {
String errorString = ""; String errorString = "";
boolean success = false; boolean success = false;
Host secStorage = ApiDBUtils.findHostById(vmTemplateHost.getHostId());
Type type = (template.getFormat() == ImageFormat.ISO) ? Type.ISO : Type.TEMPLATE ; Type type = (template.getFormat() == ImageFormat.ISO) ? Type.ISO : Type.TEMPLATE ;
//Check if ssvm is up
HostVO ssvm = _ssvmMgr.pickSsvmHost(ApiDBUtils.findHostById(vmTemplateHost.getHostId()));
if( ssvm == null ) {
throw new CloudRuntimeException("There is no secondary storage VM for secondary storage host " + secStorage.getId());
}
//Check if it already exists. //Check if it already exists.
List<UploadVO> extractURLList = _uploadDao.listByTypeUploadStatus(template.getId(), type, UploadVO.Status.DOWNLOAD_URL_CREATED); List<UploadVO> extractURLList = _uploadDao.listByTypeUploadStatus(template.getId(), type, UploadVO.Status.DOWNLOAD_URL_CREATED);
@ -219,25 +226,28 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor {
} }
// It doesn't exist so create a DB entry. // It doesn't exist so create a DB entry.
UploadVO uploadTemplateObj = new UploadVO(vmTemplateHost.getHostId(), template.getId(), new Date(), UploadVO uploadTemplateObj = new UploadVO(vmTemplateHost.getDataStoreId(), template.getId(), new Date(),
Status.DOWNLOAD_URL_NOT_CREATED, 0, type, Mode.HTTP_DOWNLOAD); Status.DOWNLOAD_URL_NOT_CREATED, 0, type, Mode.HTTP_DOWNLOAD);
uploadTemplateObj.setInstallPath(vmTemplateHost.getInstallPath()); uploadTemplateObj.setInstallPath(vmTemplateHost.getInstallPath());
_uploadDao.persist(uploadTemplateObj); _uploadDao.persist(uploadTemplateObj);
// find an endpoint to send command
DataStore store = this.storeMgr.getDataStore(vmTemplateHost.getDataStoreId(), DataStoreRole.Image);
EndPoint ep = _epSelector.select(store);
try{ try{
// Create Symlink at ssvm // Create Symlink at ssvm
String path = vmTemplateHost.getInstallPath(); String path = vmTemplateHost.getInstallPath();
String uuid = UUID.randomUUID().toString() + "." + template.getFormat().getFileExtension(); // adding "." + vhd/ova... etc. String uuid = UUID.randomUUID().toString() + "." + template.getFormat().getFileExtension(); // adding "." + vhd/ova... etc.
CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(secStorage.getParent(), path, uuid); CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreVO)store).getParent(), path, uuid);
try { Answer ans = ep.sendMessage(cmd);
send(ssvm.getId(), cmd, null); if (ans == null || !ans.getResult()) {
} catch (AgentUnavailableException e) { errorString = "Unable to create a link for " +type+ " id:"+template.getId() + "," + ans.getDetails();
errorString = "Unable to create a link for " +type+ " id:"+template.getId() + "," + e.getMessage(); s_logger.error(errorString);
s_logger.error(errorString, e);
throw new CloudRuntimeException(errorString); throw new CloudRuntimeException(errorString);
} }
//Construct actual URL locally now that the symlink exists at SSVM //Construct actual URL locally now that the symlink exists at SSVM
String extractURL = generateCopyUrl(ssvm.getPublicIpAddress(), uuid); String extractURL = generateCopyUrl(ep.getHostAddr(), uuid);
UploadVO vo = _uploadDao.createForUpdate(); UploadVO vo = _uploadDao.createForUpdate();
vo.setLastUpdated(new Date()); vo.setLastUpdated(new Date());
vo.setUploadUrl(extractURL); vo.setUploadUrl(extractURL);

View File

@ -67,7 +67,6 @@ 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.SnapshotInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; 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.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.VolumeDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
@ -78,6 +77,7 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -88,8 +88,6 @@ import com.cloud.agent.api.ComputeChecksumCommand;
import com.cloud.agent.api.downloadTemplateFromSwiftToSecondaryStorageCommand; import com.cloud.agent.api.downloadTemplateFromSwiftToSecondaryStorageCommand;
import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand; import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand;
import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.DestroyCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.api.to.SwiftTO; import com.cloud.agent.api.to.SwiftTO;
import com.cloud.api.ApiDBUtils; import com.cloud.api.ApiDBUtils;
@ -353,7 +351,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
@Override @Override
@ActionEvent(eventType = EventTypes.EVENT_ISO_EXTRACT, eventDescription = "extracting ISO", async = true) @ActionEvent(eventType = EventTypes.EVENT_ISO_EXTRACT, eventDescription = "extracting ISO", async = true)
public Long extract(ExtractIsoCmd cmd) { public Pair<Long, String> extract(ExtractIsoCmd cmd) {
Account account = UserContext.current().getCaller(); Account account = UserContext.current().getCaller();
Long templateId = cmd.getId(); Long templateId = cmd.getId();
Long zoneId = cmd.getZoneId(); Long zoneId = cmd.getZoneId();
@ -362,9 +360,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
Long eventId = cmd.getStartEventId(); Long eventId = cmd.getStartEventId();
// FIXME: async job needs fixing // FIXME: async job needs fixing
Long uploadId = extract(account, templateId, url, zoneId, mode, eventId, true, null, _asyncMgr); Pair<Long, String> uploadPair = extract(account, templateId, url, zoneId, mode, eventId, true, null, _asyncMgr);
if (uploadId != null){ if (uploadPair != null){
return uploadId; return uploadPair;
}else { }else {
throw new CloudRuntimeException("Failed to extract the iso"); throw new CloudRuntimeException("Failed to extract the iso");
} }
@ -372,7 +370,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
@Override @Override
@ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_EXTRACT, eventDescription = "extracting template", async = true) @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_EXTRACT, eventDescription = "extracting template", async = true)
public Long extract(ExtractTemplateCmd cmd) { public Pair<Long, String> extract(ExtractTemplateCmd cmd) {
Account caller = UserContext.current().getCaller(); Account caller = UserContext.current().getCaller();
Long templateId = cmd.getId(); Long templateId = cmd.getId();
Long zoneId = cmd.getZoneId(); Long zoneId = cmd.getZoneId();
@ -381,9 +379,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
Long eventId = cmd.getStartEventId(); Long eventId = cmd.getStartEventId();
// FIXME: async job needs fixing // FIXME: async job needs fixing
Long uploadId = extract(caller, templateId, url, zoneId, mode, eventId, false, null, _asyncMgr); Pair<Long, String> uploadPair = extract(caller, templateId, url, zoneId, mode, eventId, false, null, _asyncMgr);
if (uploadId != null){ if (uploadPair != null){
return uploadId; return uploadPair;
}else { }else {
throw new CloudRuntimeException("Failed to extract the teamplate"); throw new CloudRuntimeException("Failed to extract the teamplate");
} }
@ -402,7 +400,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
return vmTemplate; return vmTemplate;
} }
private Long extract(Account caller, Long templateId, String url, Long zoneId, String mode, Long eventId, boolean isISO, AsyncJobVO job, AsyncJobManager mgr) { private Pair<Long, String> extract(Account caller, Long templateId, String url, Long zoneId, String mode, Long eventId, boolean isISO, AsyncJobVO job, AsyncJobManager mgr) {
String desc = Upload.Type.TEMPLATE.toString(); String desc = Upload.Type.TEMPLATE.toString();
if (isISO) { if (isISO) {
desc = Upload.Type.ISO.toString(); desc = Upload.Type.ISO.toString();
@ -434,15 +432,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
} }
} }
if (zoneId == null && _swiftMgr.isSwiftEnabled()) {
zoneId = _swiftMgr.chooseZoneForTmpltExtract(templateId);
}
if (zoneId == null && _s3Mgr.isS3Enabled()) { if (zoneId != null && _dcDao.findById(zoneId) == null) {
zoneId = _s3Mgr.chooseZoneForTemplateExtract(template);
}
if (_dcDao.findById(zoneId) == null) {
throw new IllegalArgumentException("Please specify a valid zone."); throw new IllegalArgumentException("Please specify a valid zone.");
} }
@ -452,39 +443,33 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
_accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template); _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
List<HostVO> sservers = getSecondaryStorageHosts(zoneId); List<DataStore> ssStores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId));
VMTemplateHostVO tmpltHostRef = null; TemplateDataStoreVO tmpltStoreRef = null;
if (sservers != null) { ImageStoreEntity tmpltStore = null;
for(HostVO secondaryStorageHost: sservers){ if (ssStores != null) {
tmpltHostRef = _tmpltHostDao.findByHostTemplate(secondaryStorageHost.getId(), templateId); for(DataStore store: ssStores){
if (tmpltHostRef != null){ tmpltStoreRef = this._tmplStoreDao.findByStoreTemplate(store.getId(), templateId);
if (tmpltHostRef.getDownloadState() != com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { if (tmpltStoreRef != null){
tmpltHostRef = null; if (tmpltStoreRef.getDownloadState() == com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
} tmpltStore = (ImageStoreEntity)store;
else {
break; break;
} }
} }
} }
} }
if (tmpltHostRef == null && _swiftMgr.isSwiftEnabled()) { if (tmpltStoreRef == null) {
SwiftTO swift = _swiftMgr.getSwiftTO(templateId);
if (swift != null && sservers != null) {
downloadTemplateFromSwiftToSecondaryStorage(zoneId, templateId);
}
} else if (tmpltHostRef == null && _s3Mgr.isS3Enabled()) {
if (sservers != null) {
_s3Mgr.downloadTemplateFromS3ToSecondaryStorage(zoneId,
templateId, _primaryStorageDownloadWait);
}
}
if (tmpltHostRef == null) {
throw new InvalidParameterValueException("The " + desc + " has not been downloaded "); throw new InvalidParameterValueException("The " + desc + " has not been downloaded ");
} }
if ( tmpltStore.getProviderName().equalsIgnoreCase("S3") || tmpltStore.getProviderName().equalsIgnoreCase("Swift")){
// for S3 and Swift, no need to do anything, just return template url for extract template, here we use "-1" to indicate these case
return new Pair<Long, String>(null, tmpltStoreRef.getInstallPath());
}
// for NFS image store case, control will come here
Upload.Mode extractMode; Upload.Mode extractMode;
if (mode == null || (!mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equalsIgnoreCase(Upload.Mode.HTTP_DOWNLOAD.toString())) ){ if (mode == null || (!mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equalsIgnoreCase(Upload.Mode.HTTP_DOWNLOAD.toString())) ){
throw new InvalidParameterValueException("Please specify a valid extract Mode. Supported modes: "+ Upload.Mode.FTP_UPLOAD + ", " + Upload.Mode.HTTP_DOWNLOAD); throw new InvalidParameterValueException("Please specify a valid extract Mode. Supported modes: "+ Upload.Mode.FTP_UPLOAD + ", " + Upload.Mode.HTTP_DOWNLOAD);
@ -520,12 +505,12 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
throw new IllegalArgumentException(template.getName() + " upload is in progress. Please wait for some time to schedule another upload for the same"); throw new IllegalArgumentException(template.getName() + " upload is in progress. Please wait for some time to schedule another upload for the same");
} }
return _uploadMonitor.extractTemplate(template, url, tmpltHostRef, zoneId, eventId, job.getId(), mgr); return new Pair<Long, String>(_uploadMonitor.extractTemplate(template, url, tmpltStoreRef, zoneId, eventId, job.getId(), mgr), null);
} }
UploadVO vo = _uploadMonitor.createEntityDownloadURL(template, tmpltHostRef, zoneId, eventId); UploadVO vo = _uploadMonitor.createEntityDownloadURL(template, tmpltStoreRef, zoneId, eventId);
if (vo != null){ if (vo != null){
return vo.getId(); return new Pair<Long, String>(vo.getId(), null);
}else{ }else{
return null; return null;
} }
@ -537,7 +522,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
if(pool.getDataCenterId() == zoneId) { if(pool.getDataCenterId() == zoneId) {
s_logger.info("Schedule to preload template " + template.getId() + " into primary storage " + pool.getId()); s_logger.info("Schedule to preload template " + template.getId() + " into primary storage " + pool.getId());
this._preloadExecutor.execute(new Runnable() { this._preloadExecutor.execute(new Runnable() {
public void run() { @Override
public void run() {
try { try {
reallyRun(); reallyRun();
} catch(Throwable e) { } catch(Throwable e) {