mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Move data store specific extract template/iso logic from
TemplateManager to data store driver.
This commit is contained in:
parent
2473ceb111
commit
ef03d5a122
@ -75,18 +75,18 @@ public interface TemplateApiService {
|
|||||||
*
|
*
|
||||||
* @param cmd
|
* @param cmd
|
||||||
* - the command specifying the mode and id of the ISO
|
* - the command specifying the mode and id of the ISO
|
||||||
* @return extractId.
|
* @return extractUrl extract url.
|
||||||
*/
|
*/
|
||||||
Pair<Long, String> extract(ExtractIsoCmd cmd) throws InternalErrorException;
|
String extract(ExtractIsoCmd cmd) throws InternalErrorException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts a Template
|
* Extracts a Template
|
||||||
*
|
*
|
||||||
* @param cmd
|
* @param cmd
|
||||||
* - the command specifying the mode and id of the template
|
* - the command specifying the mode and id of the template
|
||||||
* @return extractId
|
* @return extractUrl extract url
|
||||||
*/
|
*/
|
||||||
Pair<Long, String> extract(ExtractTemplateCmd cmd) throws InternalErrorException;
|
String extract(ExtractTemplateCmd cmd) throws InternalErrorException;
|
||||||
|
|
||||||
VirtualMachineTemplate getTemplate(long templateId);
|
VirtualMachineTemplate getTemplate(long templateId);
|
||||||
|
|
||||||
|
|||||||
@ -215,6 +215,8 @@ public interface ResponseGenerator {
|
|||||||
|
|
||||||
ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode, String url);
|
ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode, String url);
|
||||||
|
|
||||||
|
ExtractResponse createExtractResponse(Long id, Long zoneId, Long accountId, String mode, String url);
|
||||||
|
|
||||||
String toSerializedString(CreateCmdResponse response, String responseType);
|
String toSerializedString(CreateCmdResponse response, String responseType);
|
||||||
|
|
||||||
AsyncJobResponse createAsyncJobResponse(AsyncJob job);
|
AsyncJobResponse createAsyncJobResponse(AsyncJob job);
|
||||||
|
|||||||
@ -124,16 +124,9 @@ public class ExtractIsoCmd extends BaseAsyncCmd {
|
|||||||
public void execute(){
|
public void execute(){
|
||||||
try {
|
try {
|
||||||
UserContext.current().setEventDetails(getEventDescription());
|
UserContext.current().setEventDetails(getEventDescription());
|
||||||
Pair<Long, String> uploadPair = _templateService.extract(this);
|
String uploadUrl = _templateService.extract(this);
|
||||||
if (uploadPair != null){
|
if (uploadUrl != null) {
|
||||||
ExtractResponse response = null;
|
ExtractResponse response = _responseGenerator.createExtractResponse(id, zoneId, getEntityOwnerId(), mode, uploadUrl);
|
||||||
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);
|
||||||
|
|||||||
@ -126,16 +126,9 @@ public class ExtractTemplateCmd extends BaseAsyncCmd {
|
|||||||
public void execute(){
|
public void execute(){
|
||||||
try {
|
try {
|
||||||
UserContext.current().setEventDetails(getEventDescription());
|
UserContext.current().setEventDetails(getEventDescription());
|
||||||
Pair<Long, String> uploadPair = _templateService.extract(this);
|
String uploadUrl = _templateService.extract(this);
|
||||||
if (uploadPair != null){
|
if (uploadUrl != null) {
|
||||||
ExtractResponse response = null;
|
ExtractResponse response = _responseGenerator.createExtractResponse(id, zoneId, getEntityOwnerId(), mode, uploadUrl);
|
||||||
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 {
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
|||||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||||
|
|
||||||
import com.cloud.storage.ImageStore;
|
import com.cloud.storage.ImageStore;
|
||||||
|
import com.cloud.storage.Storage.ImageFormat;
|
||||||
|
|
||||||
public interface ImageStoreEntity extends DataStore, ImageStore {
|
public interface ImageStoreEntity extends DataStore, ImageStore {
|
||||||
TemplateInfo getTemplate(long templateId);
|
TemplateInfo getTemplate(long templateId);
|
||||||
@ -40,4 +41,6 @@ public interface ImageStoreEntity extends DataStore, ImageStore {
|
|||||||
Set<TemplateInfo> listTemplates();
|
Set<TemplateInfo> listTemplates();
|
||||||
|
|
||||||
String getMountPoint(); // get the mount point on ssvm.
|
String getMountPoint(); // get the mount point on ssvm.
|
||||||
|
|
||||||
|
String createEntityExtractUrl(String installPath, ImageFormat format); // get the entity download URL
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,6 +42,7 @@ import org.apache.log4j.Logger;
|
|||||||
|
|
||||||
import com.cloud.agent.api.to.DataStoreTO;
|
import com.cloud.agent.api.to.DataStoreTO;
|
||||||
import com.cloud.storage.DataStoreRole;
|
import com.cloud.storage.DataStoreRole;
|
||||||
|
import com.cloud.storage.Storage.ImageFormat;
|
||||||
import com.cloud.storage.dao.VMTemplateDao;
|
import com.cloud.storage.dao.VMTemplateDao;
|
||||||
import com.cloud.utils.component.ComponentContext;
|
import com.cloud.utils.component.ComponentContext;
|
||||||
|
|
||||||
@ -189,7 +190,13 @@ public class ImageStoreImpl implements ImageStoreEntity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMountPoint() {
|
public String getMountPoint() {
|
||||||
return this.imageDataStoreVO.getParent();
|
return imageDataStoreVO.getParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String createEntityExtractUrl(String installPath, ImageFormat format) {
|
||||||
|
return driver.createEntityExtractUrl(this, installPath, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cloudstack.storage.image;
|
package org.apache.cloudstack.storage.image;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
|
||||||
|
|
||||||
|
import com.cloud.storage.Storage.ImageFormat;
|
||||||
|
|
||||||
public interface ImageStoreDriver extends DataStoreDriver {
|
public interface ImageStoreDriver extends DataStoreDriver {
|
||||||
|
String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@ package org.apache.cloudstack.storage.datastore.driver;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@ -40,6 +41,7 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
|||||||
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
|
||||||
import org.apache.cloudstack.storage.image.ImageStoreDriver;
|
import org.apache.cloudstack.storage.image.ImageStoreDriver;
|
||||||
|
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
|
||||||
import org.apache.cloudstack.storage.image.store.ImageStoreImpl;
|
import org.apache.cloudstack.storage.image.store.ImageStoreImpl;
|
||||||
import org.apache.cloudstack.storage.image.store.TemplateObject;
|
import org.apache.cloudstack.storage.image.store.TemplateObject;
|
||||||
import org.apache.cloudstack.storage.snapshot.SnapshotObject;
|
import org.apache.cloudstack.storage.snapshot.SnapshotObject;
|
||||||
@ -48,6 +50,7 @@ import org.apache.log4j.Logger;
|
|||||||
import com.cloud.agent.AgentManager;
|
import com.cloud.agent.AgentManager;
|
||||||
import com.cloud.agent.api.Answer;
|
import com.cloud.agent.api.Answer;
|
||||||
import com.cloud.agent.api.DeleteSnapshotBackupCommand2;
|
import com.cloud.agent.api.DeleteSnapshotBackupCommand2;
|
||||||
|
import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
|
||||||
import com.cloud.agent.api.storage.DeleteTemplateCommand;
|
import com.cloud.agent.api.storage.DeleteTemplateCommand;
|
||||||
import com.cloud.agent.api.storage.DeleteVolumeCommand;
|
import com.cloud.agent.api.storage.DeleteVolumeCommand;
|
||||||
import com.cloud.agent.api.storage.DownloadAnswer;
|
import com.cloud.agent.api.storage.DownloadAnswer;
|
||||||
@ -55,12 +58,18 @@ import com.cloud.agent.api.to.DataObjectType;
|
|||||||
import com.cloud.agent.api.to.DataStoreTO;
|
import com.cloud.agent.api.to.DataStoreTO;
|
||||||
import com.cloud.agent.api.to.DataTO;
|
import com.cloud.agent.api.to.DataTO;
|
||||||
import com.cloud.agent.api.to.NfsTO;
|
import com.cloud.agent.api.to.NfsTO;
|
||||||
|
import com.cloud.configuration.Config;
|
||||||
|
import com.cloud.configuration.dao.ConfigurationDao;
|
||||||
import com.cloud.event.EventTypes;
|
import com.cloud.event.EventTypes;
|
||||||
import com.cloud.event.UsageEventUtils;
|
import com.cloud.event.UsageEventUtils;
|
||||||
import com.cloud.host.dao.HostDao;
|
import com.cloud.host.dao.HostDao;
|
||||||
import com.cloud.storage.DataStoreRole;
|
import com.cloud.storage.DataStoreRole;
|
||||||
import com.cloud.storage.SnapshotVO;
|
import com.cloud.storage.SnapshotVO;
|
||||||
import com.cloud.storage.Storage.ImageFormat;
|
import com.cloud.storage.Storage.ImageFormat;
|
||||||
|
import com.cloud.storage.Upload.Mode;
|
||||||
|
import com.cloud.storage.Upload.Status;
|
||||||
|
import com.cloud.storage.Upload.Type;
|
||||||
|
import com.cloud.storage.UploadVO;
|
||||||
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
||||||
import com.cloud.storage.VMTemplateVO;
|
import com.cloud.storage.VMTemplateVO;
|
||||||
import com.cloud.storage.VMTemplateZoneVO;
|
import com.cloud.storage.VMTemplateZoneVO;
|
||||||
@ -99,6 +108,8 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
|
|||||||
@Inject
|
@Inject
|
||||||
AccountDao _accountDao;
|
AccountDao _accountDao;
|
||||||
@Inject
|
@Inject
|
||||||
|
ConfigurationDao _configDao;
|
||||||
|
@Inject
|
||||||
SecondaryStorageVmManager _ssvmMgr;
|
SecondaryStorageVmManager _ssvmMgr;
|
||||||
@Inject
|
@Inject
|
||||||
TemplateDataStoreDao _templateStoreDao;
|
TemplateDataStoreDao _templateStoreDao;
|
||||||
@ -405,4 +416,39 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) {
|
||||||
|
// find an endpoint to send command
|
||||||
|
EndPoint ep = _epSelector.select(store);
|
||||||
|
// Create Symlink at ssvm
|
||||||
|
String path = installPath;
|
||||||
|
String uuid = UUID.randomUUID().toString() + "." + format.getFileExtension();
|
||||||
|
CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreEntity) store).getMountPoint(), path, uuid);
|
||||||
|
Answer ans = ep.sendMessage(cmd);
|
||||||
|
if (ans == null || !ans.getResult()) {
|
||||||
|
String errorString = "Unable to create a link for entity at " + installPath + " on ssvm," + ans.getDetails();
|
||||||
|
s_logger.error(errorString);
|
||||||
|
throw new CloudRuntimeException(errorString);
|
||||||
|
}
|
||||||
|
// Construct actual URL locally now that the symlink exists at SSVM
|
||||||
|
return generateCopyUrl(ep.getPublicAddr(), uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateCopyUrl(String ipAddress, String uuid){
|
||||||
|
|
||||||
|
String hostname = ipAddress;
|
||||||
|
String scheme = "http";
|
||||||
|
boolean _sslCopy = false;
|
||||||
|
String sslCfg = _configDao.getValue(Config.SecStorageEncryptCopy.toString());
|
||||||
|
if ( sslCfg != null ){
|
||||||
|
_sslCopy = Boolean.parseBoolean(sslCfg);
|
||||||
|
}
|
||||||
|
if (_sslCopy) {
|
||||||
|
hostname = ipAddress.replace(".", "-");
|
||||||
|
hostname = hostname + ".realhostip.com";
|
||||||
|
scheme = "https";
|
||||||
|
}
|
||||||
|
return scheme + "://" + hostname + "/userdata/" + uuid;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,6 +48,7 @@ import org.apache.cloudstack.storage.image.store.TemplateObject;
|
|||||||
import org.apache.cloudstack.storage.snapshot.SnapshotObject;
|
import org.apache.cloudstack.storage.snapshot.SnapshotObject;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import com.amazonaws.services.s3.model.CannedAccessControlList;
|
||||||
import com.cloud.agent.AgentManager;
|
import com.cloud.agent.AgentManager;
|
||||||
import com.cloud.agent.api.Answer;
|
import com.cloud.agent.api.Answer;
|
||||||
import com.cloud.agent.api.DeleteSnapshotBackupCommand2;
|
import com.cloud.agent.api.DeleteSnapshotBackupCommand2;
|
||||||
@ -78,6 +79,7 @@ import com.cloud.storage.secondary.SecondaryStorageVmManager;
|
|||||||
import com.cloud.storage.snapshot.SnapshotManager;
|
import com.cloud.storage.snapshot.SnapshotManager;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.user.dao.AccountDao;
|
import com.cloud.user.dao.AccountDao;
|
||||||
|
import com.cloud.utils.S3Utils;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
import com.cloud.vm.dao.UserVmDao;
|
import com.cloud.vm.dao.UserVmDao;
|
||||||
|
|
||||||
@ -422,4 +424,29 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) {
|
||||||
|
// for S3, no need to do anything, just return template url for
|
||||||
|
// extract template. but we need to set object acl as public_read to
|
||||||
|
// make the url accessible
|
||||||
|
S3TO s3 = (S3TO)getStoreTO(store);
|
||||||
|
String key = installPath;
|
||||||
|
try {
|
||||||
|
S3Utils.setObjectAcl(s3, s3.getBucketName(), key, CannedAccessControlList.PublicRead);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
s_logger.error("Failed to set ACL on S3 object " + key + " to PUBLIC_READ", ex);
|
||||||
|
throw new CloudRuntimeException("Failed to set ACL on S3 object " + key + " to PUBLIC_READ");
|
||||||
|
}
|
||||||
|
// construct the url from s3
|
||||||
|
StringBuffer s3url = new StringBuffer();
|
||||||
|
s3url.append(s3.isHttps() ? "https://" : "http://");
|
||||||
|
s3url.append(s3.getEndPoint());
|
||||||
|
s3url.append("/");
|
||||||
|
s3url.append(s3.getBucketName());
|
||||||
|
s3url.append("/");
|
||||||
|
s3url.append(key);
|
||||||
|
return s3url.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,6 +37,7 @@ import org.apache.cloudstack.storage.image.ImageStoreDriver;
|
|||||||
import com.cloud.agent.api.to.DataObjectType;
|
import com.cloud.agent.api.to.DataObjectType;
|
||||||
import com.cloud.agent.api.to.DataStoreTO;
|
import com.cloud.agent.api.to.DataStoreTO;
|
||||||
import com.cloud.agent.api.to.DataTO;
|
import com.cloud.agent.api.to.DataTO;
|
||||||
|
import com.cloud.storage.Storage.ImageFormat;
|
||||||
import com.cloud.storage.dao.VMTemplateDao;
|
import com.cloud.storage.dao.VMTemplateDao;
|
||||||
|
|
||||||
//http-read-only based image store
|
//http-read-only based image store
|
||||||
@ -134,4 +135,12 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver {
|
|||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,6 +61,7 @@ import com.cloud.agent.api.to.SwiftTO;
|
|||||||
import com.cloud.api.query.dao.UserVmJoinDao;
|
import com.cloud.api.query.dao.UserVmJoinDao;
|
||||||
import com.cloud.event.EventTypes;
|
import com.cloud.event.EventTypes;
|
||||||
import com.cloud.event.UsageEventUtils;
|
import com.cloud.event.UsageEventUtils;
|
||||||
|
import com.cloud.exception.UnsupportedServiceException;
|
||||||
import com.cloud.host.dao.HostDao;
|
import com.cloud.host.dao.HostDao;
|
||||||
import com.cloud.storage.Storage.ImageFormat;
|
import com.cloud.storage.Storage.ImageFormat;
|
||||||
import com.cloud.storage.DataStoreRole;
|
import com.cloud.storage.DataStoreRole;
|
||||||
@ -424,4 +425,10 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) {
|
||||||
|
throw new UnsupportedServiceException("Extract entity url is not yet supported for Swift image store provider");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,9 +16,6 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.api;
|
package com.cloud.api;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
|
||||||
import static java.util.Collections.singletonList;
|
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
@ -40,7 +37,6 @@ import org.apache.cloudstack.affinity.AffinityGroup;
|
|||||||
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
||||||
import org.apache.cloudstack.api.ApiConstants.HostDetails;
|
import org.apache.cloudstack.api.ApiConstants.HostDetails;
|
||||||
import org.apache.cloudstack.api.ApiConstants.VMDetails;
|
import org.apache.cloudstack.api.ApiConstants.VMDetails;
|
||||||
import org.apache.cloudstack.api.BaseCmd;
|
|
||||||
import org.apache.cloudstack.api.ResponseGenerator;
|
import org.apache.cloudstack.api.ResponseGenerator;
|
||||||
import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
|
import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
|
||||||
import org.apache.cloudstack.api.response.AccountResponse;
|
import org.apache.cloudstack.api.response.AccountResponse;
|
||||||
@ -184,7 +180,6 @@ import com.cloud.configuration.ResourceLimit;
|
|||||||
import com.cloud.dao.EntityManager;
|
import com.cloud.dao.EntityManager;
|
||||||
import com.cloud.dc.ClusterVO;
|
import com.cloud.dc.ClusterVO;
|
||||||
import com.cloud.dc.DataCenter;
|
import com.cloud.dc.DataCenter;
|
||||||
import com.cloud.dc.DataCenterVO;
|
|
||||||
import com.cloud.dc.HostPodVO;
|
import com.cloud.dc.HostPodVO;
|
||||||
import com.cloud.dc.Pod;
|
import com.cloud.dc.Pod;
|
||||||
import com.cloud.dc.StorageNetworkIpRange;
|
import com.cloud.dc.StorageNetworkIpRange;
|
||||||
@ -266,16 +261,10 @@ 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.Upload;
|
||||||
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.StoragePool;
|
import com.cloud.storage.StoragePool;
|
||||||
import com.cloud.storage.Swift;
|
import com.cloud.storage.Swift;
|
||||||
import com.cloud.storage.UploadVO;
|
import com.cloud.storage.UploadVO;
|
||||||
import com.cloud.storage.VMTemplateHostVO;
|
|
||||||
import com.cloud.storage.VMTemplateS3VO;
|
|
||||||
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
|
|
||||||
import com.cloud.storage.VMTemplateSwiftVO;
|
|
||||||
import com.cloud.storage.VMTemplateVO;
|
import com.cloud.storage.VMTemplateVO;
|
||||||
import com.cloud.storage.Volume;
|
import com.cloud.storage.Volume;
|
||||||
import com.cloud.storage.VolumeVO;
|
import com.cloud.storage.VolumeVO;
|
||||||
@ -1601,6 +1590,29 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||||||
return listSgs.get(0);
|
return listSgs.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: we need to deprecate uploadVO, since extract is done in a synchronous fashion
|
||||||
|
@Override
|
||||||
|
public ExtractResponse createExtractResponse(Long id, Long zoneId, Long accountId, String mode, String url) {
|
||||||
|
|
||||||
|
ExtractResponse response = new ExtractResponse();
|
||||||
|
response.setObjectName("template");
|
||||||
|
VMTemplateVO template = ApiDBUtils.findTemplateById(id);
|
||||||
|
response.setId(template.getUuid());
|
||||||
|
response.setName(template.getName());
|
||||||
|
if (zoneId != null) {
|
||||||
|
DataCenter zone = ApiDBUtils.findZoneById(zoneId);
|
||||||
|
response.setZoneId(zone.getUuid());
|
||||||
|
response.setZoneName(zone.getName());
|
||||||
|
}
|
||||||
|
response.setMode(mode);
|
||||||
|
response.setUrl(url);
|
||||||
|
response.setState(Upload.Status.DOWNLOAD_URL_CREATED.toString());
|
||||||
|
Account account = ApiDBUtils.findAccountById(accountId);
|
||||||
|
response.setAccountId(account.getUuid());
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode, String url) {
|
public ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode, String url) {
|
||||||
|
|
||||||
@ -3480,6 +3492,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public NicSecondaryIpResponse createSecondaryIPToNicResponse(NicSecondaryIp result) {
|
public NicSecondaryIpResponse createSecondaryIPToNicResponse(NicSecondaryIp result) {
|
||||||
NicSecondaryIpResponse response = new NicSecondaryIpResponse();
|
NicSecondaryIpResponse response = new NicSecondaryIpResponse();
|
||||||
NicVO nic = _entityMgr.findById(NicVO.class, result.getNicId());
|
NicVO nic = _entityMgr.findById(NicVO.class, result.getNicId());
|
||||||
@ -3492,6 +3505,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public NicResponse createNicResponse(Nic result) {
|
public NicResponse createNicResponse(Nic result) {
|
||||||
NicResponse response = new NicResponse();
|
NicResponse response = new NicResponse();
|
||||||
NetworkVO network = _entityMgr.findById(NetworkVO.class, result.getNetworkId());
|
NetworkVO network = _entityMgr.findById(NetworkVO.class, result.getNetworkId());
|
||||||
@ -3713,6 +3727,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public NetworkACLResponse createNetworkACLResponse(NetworkACL networkACL) {
|
public NetworkACLResponse createNetworkACLResponse(NetworkACL networkACL) {
|
||||||
NetworkACLResponse response = new NetworkACLResponse();
|
NetworkACLResponse response = new NetworkACLResponse();
|
||||||
response.setId(networkACL.getUuid());
|
response.setId(networkACL.getUuid());
|
||||||
|
|||||||
@ -384,7 +384,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 Pair<Long, String> extract(ExtractIsoCmd cmd) {
|
public 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();
|
||||||
@ -392,18 +392,12 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
String mode = cmd.getMode();
|
String mode = cmd.getMode();
|
||||||
Long eventId = cmd.getStartEventId();
|
Long eventId = cmd.getStartEventId();
|
||||||
|
|
||||||
// FIXME: async job needs fixing
|
return extract(account, templateId, url, zoneId, mode, eventId, true);
|
||||||
Pair<Long, String> uploadPair = extract(account, templateId, url, zoneId, mode, eventId, true, null, _asyncMgr);
|
|
||||||
if (uploadPair != null) {
|
|
||||||
return uploadPair;
|
|
||||||
} else {
|
|
||||||
throw new CloudRuntimeException("Failed to extract the iso");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 Pair<Long, String> extract(ExtractTemplateCmd cmd) {
|
public 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();
|
||||||
@ -418,13 +412,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
TemplateAdapter adapter = getAdapter(template.getHypervisorType());
|
TemplateAdapter adapter = getAdapter(template.getHypervisorType());
|
||||||
TemplateProfile profile = adapter.prepareExtractTemplate(cmd);
|
TemplateProfile profile = adapter.prepareExtractTemplate(cmd);
|
||||||
|
|
||||||
// FIXME: async job needs fixing
|
return extract(caller, templateId, url, zoneId, mode, eventId, false);
|
||||||
Pair<Long, String> uploadPair = extract(caller, templateId, url, zoneId, mode, eventId, false, null, _asyncMgr);
|
|
||||||
if (uploadPair != null) {
|
|
||||||
return uploadPair;
|
|
||||||
} else {
|
|
||||||
throw new CloudRuntimeException("Failed to extract the teamplate");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -440,8 +428,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
return vmTemplate;
|
return vmTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Pair<Long, String> extract(Account caller, Long templateId, String url, Long zoneId, String mode, Long eventId, boolean isISO,
|
private 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();
|
||||||
@ -505,82 +492,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
throw new InvalidParameterValueException("The " + desc + " has not been downloaded ");
|
throw new InvalidParameterValueException("The " + desc + " has not been downloaded ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmpltStore.getProviderName().equalsIgnoreCase("Swift")) {
|
return tmpltStore.createEntityExtractUrl(tmpltStoreRef.getInstallPath(), template.getFormat());
|
||||||
throw new UnsupportedServiceException("ExtractTemplate is not yet supported for Swift image store provider");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tmpltStore.getProviderName().equalsIgnoreCase("S3")) {
|
|
||||||
// for S3, no need to do anything, just return template url for
|
|
||||||
// extract template. but we need to set object acl as public_read to
|
|
||||||
// make the url accessible
|
|
||||||
S3TO s3 = (S3TO) tmpltStore.getTO();
|
|
||||||
String key = tmpltStoreRef.getLocalDownloadPath();
|
|
||||||
try {
|
|
||||||
S3Utils.setObjectAcl(s3, s3.getBucketName(), key, CannedAccessControlList.PublicRead);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
s_logger.error("Failed to set ACL on S3 object " + key + " to PUBLIC_READ", ex);
|
|
||||||
throw new CloudRuntimeException("Failed to set ACL on S3 object " + key + " to PUBLIC_READ");
|
|
||||||
}
|
|
||||||
// construct the url from s3
|
|
||||||
StringBuffer s3url = new StringBuffer();
|
|
||||||
s3url.append(s3.isHttps() ? "https://" : "http://");
|
|
||||||
s3url.append(s3.getEndPoint());
|
|
||||||
s3url.append("/");
|
|
||||||
s3url.append(s3.getBucketName());
|
|
||||||
s3url.append("/");
|
|
||||||
s3url.append(key);
|
|
||||||
|
|
||||||
return new Pair<Long, String>(null, s3url.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// for NFS image store case, control will come here
|
|
||||||
Upload.Mode extractMode;
|
|
||||||
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);
|
|
||||||
} else {
|
|
||||||
extractMode = mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) ? Upload.Mode.FTP_UPLOAD : Upload.Mode.HTTP_DOWNLOAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extractMode == Upload.Mode.FTP_UPLOAD) {
|
|
||||||
URI uri = null;
|
|
||||||
try {
|
|
||||||
uri = new URI(url);
|
|
||||||
if ((uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("ftp"))) {
|
|
||||||
throw new InvalidParameterValueException("Unsupported scheme for url: " + url);
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
throw new InvalidParameterValueException("Invalid url given: " + url);
|
|
||||||
}
|
|
||||||
|
|
||||||
String host = uri.getHost();
|
|
||||||
try {
|
|
||||||
InetAddress hostAddr = InetAddress.getByName(host);
|
|
||||||
if (hostAddr.isAnyLocalAddress() || hostAddr.isLinkLocalAddress() || hostAddr.isLoopbackAddress() || hostAddr.isMulticastAddress()) {
|
|
||||||
throw new InvalidParameterValueException("Illegal host specified in url");
|
|
||||||
}
|
|
||||||
if (hostAddr instanceof Inet6Address) {
|
|
||||||
throw new InvalidParameterValueException("IPV6 addresses not supported (" + hostAddr.getHostAddress() + ")");
|
|
||||||
}
|
|
||||||
} catch (UnknownHostException uhe) {
|
|
||||||
throw new InvalidParameterValueException("Unable to resolve " + host);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_uploadMonitor.isTypeUploadInProgress(templateId, isISO ? Type.ISO : Type.TEMPLATE)) {
|
|
||||||
throw new IllegalArgumentException(template.getName()
|
|
||||||
+ " upload is in progress. Please wait for some time to schedule another upload for the same");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Pair<Long, String>(_uploadMonitor.extractTemplate(template, url, tmpltStoreRef, zoneId, eventId, job.getId(), mgr), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
UploadVO vo = _uploadMonitor.createEntityDownloadURL(template, tmpltStoreRef, zoneId, eventId);
|
|
||||||
if (vo != null) {
|
|
||||||
return new Pair<Long, String>(vo.getId(), null);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void prepareTemplateInAllStoragePools(final VMTemplateVO template, long zoneId) {
|
public void prepareTemplateInAllStoragePools(final VMTemplateVO template, long zoneId) {
|
||||||
|
|||||||
@ -305,12 +305,12 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
|
|||||||
// status to trigger callback.
|
// status to trigger callback.
|
||||||
td.setStatus(Status.POST_DOWNLOAD_FINISHED);
|
td.setStatus(Status.POST_DOWNLOAD_FINISHED);
|
||||||
// set template size for S3
|
// set template size for S3
|
||||||
if (td instanceof S3TemplateDownloader){
|
S3TemplateDownloader std = (S3TemplateDownloader) td;
|
||||||
long size = ((S3TemplateDownloader)td).totalBytes;
|
long size = std.totalBytes;
|
||||||
DownloadJob dnld = jobs.get(jobId);
|
DownloadJob dnld = jobs.get(jobId);
|
||||||
dnld.setTemplatesize(size);
|
dnld.setTemplatesize(size);
|
||||||
dnld.setTemplatePhysicalSize(size);
|
dnld.setTemplatePhysicalSize(size);
|
||||||
}
|
dnld.setTmpltPath(std.getDownloadLocalPath()); // update template path to include file name.
|
||||||
}
|
}
|
||||||
dj.cleanup();
|
dj.cleanup();
|
||||||
break;
|
break;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user