bug 4286: Making extractIsoCmd and extractTemplateCmd async

This commit is contained in:
nit 2010-09-17 17:04:07 +05:30
parent fceb9378ca
commit 636dc041c7
13 changed files with 199 additions and 106 deletions

View File

@ -76,21 +76,14 @@ public class EventTypes {
public static final String EVENT_TEMPLATE_DELETE = "TEMPLATE.DELETE"; public static final String EVENT_TEMPLATE_DELETE = "TEMPLATE.DELETE";
public static final String EVENT_TEMPLATE_UPDATE = "TEMPLATE.UPDATE"; public static final String EVENT_TEMPLATE_UPDATE = "TEMPLATE.UPDATE";
public static final String EVENT_TEMPLATE_COPY = "TEMPLATE.COPY"; public static final String EVENT_TEMPLATE_COPY = "TEMPLATE.COPY";
public static final String EVENT_TEMPLATE_DOWNLOAD_START = "TEMPLATE.DOWNLOAD.START"; public static final String EVENT_TEMPLATE_UPLOAD = "TEMPLATE.UPLOAD";
public static final String EVENT_TEMPLATE_DOWNLOAD_SUCCESS = "TEMPLATE.DOWNLOAD.SUCCESS";
public static final String EVENT_TEMPLATE_DOWNLOAD_FAILED = "TEMPLATE.DOWNLOAD.FAILED";
public static final String EVENT_TEMPLATE_UPLOAD_FAILED = "TEMPLATE.UPLOAD.FAILED";
public static final String EVENT_TEMPLATE_UPLOAD_START = "TEMPLATE.UPLOAD.START";
public static final String EVENT_TEMPLATE_UPLOAD_SUCCESS = "TEMPLATE.UPLOAD.SUCCESS";
// Volume Events // Volume Events
public static final String EVENT_VOLUME_CREATE = "VOLUME.CREATE"; public static final String EVENT_VOLUME_CREATE = "VOLUME.CREATE";
public static final String EVENT_VOLUME_DELETE = "VOLUME.DELETE"; public static final String EVENT_VOLUME_DELETE = "VOLUME.DELETE";
public static final String EVENT_VOLUME_ATTACH = "VOLUME.ATTACH"; public static final String EVENT_VOLUME_ATTACH = "VOLUME.ATTACH";
public static final String EVENT_VOLUME_DETACH = "VOLUME.DETACH"; public static final String EVENT_VOLUME_DETACH = "VOLUME.DETACH";
public static final String EVENT_VOLUME_UPLOAD_START = "VOLUME.UPLOAD.START"; public static final String EVENT_VOLUME_UPLOAD = "VOLUME.UPLOAD";
public static final String EVENT_VOLUME_UPLOAD_SUCCESS = "VOLUME.UPLOAD.SUCCESS";
public static final String EVENT_VOLUME_UPLOAD_FAILED = "VOLUME.UPLOAD.FAILED";
// Domains // Domains
public static final String EVENT_DOMAIN_CREATE = "DOMAIN.CREATE"; public static final String EVENT_DOMAIN_CREATE = "DOMAIN.CREATE";
@ -110,9 +103,7 @@ public class EventTypes {
public static final String EVENT_ISO_COPY = "ISO.COPY"; public static final String EVENT_ISO_COPY = "ISO.COPY";
public static final String EVENT_ISO_ATTACH = "ISO.ATTACH"; public static final String EVENT_ISO_ATTACH = "ISO.ATTACH";
public static final String EVENT_ISO_DETACH = "ISO.DETACH"; public static final String EVENT_ISO_DETACH = "ISO.DETACH";
public static final String EVENT_ISO_UPLOAD_FAILED = "ISO.UPLOAD.FAILED"; public static final String EVENT_ISO_UPLOAD = "ISO.UPLOAD";
public static final String EVENT_ISO_UPLOAD_START = "ISO.UPLOAD.START";
public static final String EVENT_ISO_UPLOAD_SUCCESS = "ISO.UPLOAD.SUCCESS";
//SSVM //SSVM
public static final String EVENT_SSVM_CREATE = "SSVM.CREATE"; public static final String EVENT_SSVM_CREATE = "SSVM.CREATE";

View File

@ -2194,7 +2194,7 @@ public interface ManagementServer {
* @param template id - the id of the template * @param template id - the id of the template
* *
*/ */
void extractTemplate(String url, Long templateId, Long zoneId) throws URISyntaxException; void extractTemplate(String url, Long templateId, Long zoneId, long eventId, long asyncJobId) throws URISyntaxException;
Map<String, String> listCapabilities(); Map<String, String> listCapabilities();
GuestOSVO getGuestOs(Long guestOsId); GuestOSVO getGuestOs(Long guestOsId);
@ -2248,6 +2248,7 @@ public interface ManagementServer {
*/ */
void extractVolume(String url, Long volumeId, Long zoneId) throws void extractVolume(String url, Long volumeId, Long zoneId) throws
URISyntaxException, InternalErrorException; URISyntaxException, InternalErrorException;
long extractTemplateAsync(String url, Long templateId, Long zoneId) throws URISyntaxException;
} }

View File

@ -73,9 +73,11 @@ public class FtpTemplateUploader implements TemplateUploader {
{ {
URL url = new URL( sb.toString() ); URL url = new URL( sb.toString() );
URLConnection urlc = url.openConnection(); URLConnection urlc = url.openConnection();
File sourceFile = new File(sourcePath);
templateSizeinBytes = sourceFile.length();
outputStream = new BufferedOutputStream( urlc.getOutputStream() ); outputStream = new BufferedOutputStream( urlc.getOutputStream() );
inputStream = new BufferedInputStream( new FileInputStream( new File(sourcePath) ) ); inputStream = new BufferedInputStream( new FileInputStream(sourceFile) );
status = TemplateUploader.Status.IN_PROGRESS; status = TemplateUploader.Status.IN_PROGRESS;

6
server/src/com/cloud/api/commands/ExtractIsoCmd.java Normal file → Executable file
View File

@ -60,9 +60,9 @@ public class ExtractIsoCmd extends BaseCmd {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to extract ISO " + templateId + " to " + url + ", permission denied."); throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to extract ISO " + templateId + " to " + url + ", permission denied.");
} }
} }
Long jobId;
try { try {
managementServer.extractTemplate(url, templateId, zoneId); jobId = managementServer.extractTemplateAsync(url, templateId, zoneId);
} catch (Exception e) { } catch (Exception e) {
s_logger.error(e.getMessage(), e); s_logger.error(e.getMessage(), e);
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Internal Error Extracting the ISO " + e.getMessage()); throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Internal Error Extracting the ISO " + e.getMessage());
@ -75,7 +75,7 @@ public class ExtractIsoCmd extends BaseCmd {
response.add(new Pair<String, Object>(BaseCmd.Properties.URL.getName(), url)); response.add(new Pair<String, Object>(BaseCmd.Properties.URL.getName(), url));
response.add(new Pair<String, Object>(BaseCmd.Properties.ZONE_ID.getName(), zoneId)); response.add(new Pair<String, Object>(BaseCmd.Properties.ZONE_ID.getName(), zoneId));
response.add(new Pair<String, Object>(BaseCmd.Properties.ZONE_NAME.getName(), zone.getName())); response.add(new Pair<String, Object>(BaseCmd.Properties.ZONE_NAME.getName(), zone.getName()));
response.add(new Pair<String, Object>(BaseCmd.Properties.TEMPLATE_STATUS.getName(), "Processing")); response.add(new Pair<String, Object>(BaseCmd.Properties.JOB_ID.getName(), jobId));
return response; return response;
} }

View File

@ -59,9 +59,9 @@ public class ExtractTemplateCmd extends BaseCmd {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to extract template " + templateId + " to " + url + ", permission denied."); throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to extract template " + templateId + " to " + url + ", permission denied.");
} }
} }
Long jobId;
try { try {
managementServer.extractTemplate(url, templateId, zoneId); jobId = managementServer.extractTemplateAsync(url, templateId, zoneId);
} catch (Exception e) { } catch (Exception e) {
s_logger.error(e.getMessage(), e); s_logger.error(e.getMessage(), e);
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Internal Error Extracting the template " + e.getMessage()); throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Internal Error Extracting the template " + e.getMessage());
@ -74,7 +74,7 @@ public class ExtractTemplateCmd extends BaseCmd {
response.add(new Pair<String, Object>(BaseCmd.Properties.URL.getName(), url)); response.add(new Pair<String, Object>(BaseCmd.Properties.URL.getName(), url));
response.add(new Pair<String, Object>(BaseCmd.Properties.ZONE_ID.getName(), zoneId)); response.add(new Pair<String, Object>(BaseCmd.Properties.ZONE_ID.getName(), zoneId));
response.add(new Pair<String, Object>(BaseCmd.Properties.ZONE_NAME.getName(), zone.getName())); response.add(new Pair<String, Object>(BaseCmd.Properties.ZONE_NAME.getName(), zone.getName()));
response.add(new Pair<String, Object>(BaseCmd.Properties.TEMPLATE_STATUS.getName(), "Processing")); response.add(new Pair<String, Object>(BaseCmd.Properties.JOB_ID.getName(), jobId));
return response; return response;
} }
@ -83,6 +83,10 @@ public class ExtractTemplateCmd extends BaseCmd {
return s_name; return s_name;
} }
public static String getStaticName() {
return "ExtractTemplate";
}
@Override @Override
public List<Pair<Enum, Boolean>> getProperties() { public List<Pair<Enum, Boolean>> getProperties() {
return s_properties; return s_properties;

View File

@ -24,9 +24,6 @@ public class ExtractJobResultObject {
@Param(name="name") @Param(name="name")
private String name; private String name;
@Param(name="host_id")
private Long hostId;
@Param(name="uploadPercentage") @Param(name="uploadPercentage")
private int uploadPercent; private int uploadPercent;
@ -36,9 +33,6 @@ public class ExtractJobResultObject {
@Param(name="accountid") @Param(name="accountid")
long accountId; long accountId;
@Param(name="account")
private String accountName;
@Param(name="result_string") @Param(name="result_string")
String result_string; String result_string;
@ -126,14 +120,6 @@ public class ExtractJobResultObject {
return name; return name;
} }
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public String getAccountName() {
return accountName;
}
public void setSize(long size) { public void setSize(long size) {
this.size = size; this.size = size;
} }

View File

@ -72,6 +72,7 @@ import com.cloud.api.commands.DeleteIsoCmd;
import com.cloud.api.commands.DeleteTemplateCmd; import com.cloud.api.commands.DeleteTemplateCmd;
import com.cloud.api.commands.DeleteUserCmd; import com.cloud.api.commands.DeleteUserCmd;
import com.cloud.api.commands.DeployVMCmd; import com.cloud.api.commands.DeployVMCmd;
import com.cloud.api.commands.ExtractTemplateCmd;
import com.cloud.api.commands.PrepareForMaintenanceCmd; import com.cloud.api.commands.PrepareForMaintenanceCmd;
import com.cloud.api.commands.PreparePrimaryStorageForMaintenanceCmd; import com.cloud.api.commands.PreparePrimaryStorageForMaintenanceCmd;
import com.cloud.api.commands.ReconnectHostCmd; import com.cloud.api.commands.ReconnectHostCmd;
@ -96,6 +97,7 @@ import com.cloud.async.executor.DeleteRuleParam;
import com.cloud.async.executor.DeleteTemplateParam; import com.cloud.async.executor.DeleteTemplateParam;
import com.cloud.async.executor.DeployVMParam; import com.cloud.async.executor.DeployVMParam;
import com.cloud.async.executor.DisassociateIpAddressParam; import com.cloud.async.executor.DisassociateIpAddressParam;
import com.cloud.async.executor.ExtractTemplateParam;
import com.cloud.async.executor.LoadBalancerParam; import com.cloud.async.executor.LoadBalancerParam;
import com.cloud.async.executor.NetworkGroupIngressParam; import com.cloud.async.executor.NetworkGroupIngressParam;
import com.cloud.async.executor.ResetVMPasswordParam; import com.cloud.async.executor.ResetVMPasswordParam;
@ -4845,8 +4847,7 @@ public class ManagementServerImpl implements ManagementServer {
} }
@Override @Override
public void extractTemplate(String url, Long templateId, Long zoneId) throws URISyntaxException{ public long extractTemplateAsync(String url, Long templateId, Long zoneId) throws URISyntaxException{
URI uri = new URI(url); URI uri = new URI(url);
if ( (uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("ftp") )) { if ( (uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("ftp") )) {
throw new IllegalArgumentException("Unsupported scheme for url: " + url); throw new IllegalArgumentException("Unsupported scheme for url: " + url);
@ -4875,8 +4876,33 @@ public class ManagementServerImpl implements ManagementServer {
if (tmpltHostRef != null && tmpltHostRef.getDownloadState() != com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED){ if (tmpltHostRef != null && tmpltHostRef.getDownloadState() != com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED){
throw new IllegalArgumentException("The template hasnt been downloaded "); throw new IllegalArgumentException("The template hasnt been downloaded ");
} }
long userId = UserContext.current().getUserId();
long accountId = template.getAccountId();
String event = template.getFormat() == ImageFormat.ISO ? EventTypes.EVENT_ISO_UPLOAD : EventTypes.EVENT_TEMPLATE_UPLOAD;
long eventId = saveScheduledEvent(userId, accountId, event, "Extraction job");
_tmpltMgr.extract(template, url, tmpltHostRef, zoneId); ExtractTemplateParam param = new ExtractTemplateParam(userId, templateId, zoneId, eventId , url);
Gson gson = GsonHelper.getBuilder().create();
AsyncJobVO job = new AsyncJobVO();
job.setUserId(userId);
job.setAccountId(accountId);
job.setCmd("ExtractTemplate");
job.setCmdInfo(gson.toJson(param));
job.setCmdOriginator(ExtractTemplateCmd.getStaticName());
return _asyncMgr.submitAsyncJob(job);
}
@Override
public void extractTemplate(String url, Long templateId, Long zoneId, long eventId, long asyncJobId) throws URISyntaxException{
VMTemplateVO template = findTemplateById(templateId);
VMTemplateHostVO tmpltHostRef = findTemplateHostRef(templateId, zoneId);
String event = template.getFormat() == ImageFormat.ISO ? EventTypes.EVENT_ISO_UPLOAD : EventTypes.EVENT_TEMPLATE_UPLOAD;
saveStartedEvent(template.getAccountId(), template.getAccountId(), event, "Starting upload of " +template.getName()+ " to " +url, eventId);
_tmpltMgr.extract(template, url, tmpltHostRef, zoneId, eventId, asyncJobId, _asyncMgr);
} }

View File

@ -17,24 +17,21 @@ import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command; import com.cloud.agent.api.Command;
import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.StartupStorageCommand;
import com.cloud.agent.api.storage.DownloadCommand;
import com.cloud.agent.api.storage.DownloadProgressCommand;
import com.cloud.agent.api.storage.UploadAnswer; import com.cloud.agent.api.storage.UploadAnswer;
import com.cloud.agent.api.storage.UploadCommand; import com.cloud.agent.api.storage.UploadCommand;
import com.cloud.agent.api.storage.UploadProgressCommand; import com.cloud.agent.api.storage.UploadProgressCommand;
import com.cloud.agent.api.storage.UploadProgressCommand.RequestType; import com.cloud.agent.api.storage.UploadProgressCommand.RequestType;
import com.cloud.async.AsyncJobManager;
import com.cloud.async.AsyncJobResult;
import com.cloud.async.executor.ExtractJobResultObject;
import com.cloud.event.EventTypes; import com.cloud.event.EventTypes;
import com.cloud.event.EventVO; import com.cloud.event.EventVO;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
import com.cloud.storage.Storage; import com.cloud.storage.Storage;
import com.cloud.storage.UploadVO; import com.cloud.storage.UploadVO;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.dao.UploadDao; import com.cloud.storage.dao.UploadDao;
import com.cloud.storage.dao.VMTemplateHostDao;
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.download.DownloadState.DownloadEvent;
import com.cloud.storage.upload.UploadMonitorImpl; import com.cloud.storage.upload.UploadMonitorImpl;
import com.cloud.storage.upload.UploadState.UploadEvent; import com.cloud.storage.upload.UploadState.UploadEvent;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
@ -103,13 +100,41 @@ public class UploadListener implements Listener {
private Long accountId; private Long accountId;
private String typeName; private String typeName;
private Type type; private Type type;
private long asyncJobId;
private long eventId;
private AsyncJobManager asyncMgr;
private ExtractJobResultObject resultObj;
public AsyncJobManager getAsyncMgr() {
return asyncMgr;
}
public void setAsyncMgr(AsyncJobManager asyncMgr) {
this.asyncMgr = asyncMgr;
}
public long getAsyncJobId() {
return asyncJobId;
}
public void setAsyncJobId(long asyncJobId) {
this.asyncJobId = asyncJobId;
}
public long getEventId() {
return eventId;
}
public void setEventId(long eventId) {
this.eventId = eventId;
}
private final Map<String, UploadState> stateMap = new HashMap<String, UploadState>(); private final Map<String, UploadState> stateMap = new HashMap<String, UploadState>();
private Long uploadId; private Long uploadId;
public UploadListener(HostVO host, Timer _timer, UploadDao uploadDao, public UploadListener(HostVO host, Timer _timer, UploadDao uploadDao,
Long uploadId, UploadMonitorImpl uploadMonitor, UploadCommand cmd, Long uploadId, UploadMonitorImpl uploadMonitor, UploadCommand cmd,
Long accountId, String typeName, Type type) { Long accountId, String typeName, Type type, long eventId, long asyncJobId, AsyncJobManager asyncMgr) {
this.sserver = host; this.sserver = host;
this.uploadDao = uploadDao; this.uploadDao = uploadDao;
this.uploadMonitor = uploadMonitor; this.uploadMonitor = uploadMonitor;
@ -123,6 +148,10 @@ public class UploadListener implements Listener {
this.timer = _timer; this.timer = _timer;
this.timeoutTask = new TimeoutTask(this); this.timeoutTask = new TimeoutTask(this);
this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL); this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL);
this.eventId = eventId;
this.asyncJobId = asyncJobId;
this.asyncMgr = asyncMgr;
this.resultObj = new ExtractJobResultObject(accountId, typeName, currState, 0, uploadId);
updateDatabase(Status.NOT_UPLOADED, cmd.getUrl(),""); updateDatabase(Status.NOT_UPLOADED, cmd.getUrl(),"");
} }
@ -212,19 +241,12 @@ public class UploadListener implements Listener {
public void setUploadInactive(Status reason) { public void setUploadInactive(Status reason) {
uploadActive=false; uploadActive=false;
uploadMonitor.handleUploadEvent(sserver, accountId, typeName, type, uploadId, reason); uploadMonitor.handleUploadEvent(sserver, accountId, typeName, type, uploadId, reason, eventId);
} }
public void logUploadStart() { public void logUploadStart() {
String event; String event = uploadMonitor.getEvent(type);
if (type == Type.TEMPLATE){ uploadMonitor.logEvent(accountId, event, "Storage server " + sserver.getName() + " started upload of " +type.toString() + " " + typeName, EventVO.LEVEL_INFO,eventId);
event = EventTypes.EVENT_TEMPLATE_UPLOAD_START;
}else if (type == Type.ISO){
event = EventTypes.EVENT_ISO_UPLOAD_START;
}else{
event = EventTypes.EVENT_VOLUME_UPLOAD_START;
}
uploadMonitor.logEvent(accountId, event, "Storage server " + sserver.getName() + " started upload of " +type.toString() + " " + typeName, EventVO.LEVEL_INFO);
} }
public void cancelTimeoutTask() { public void cancelTimeoutTask() {
@ -310,6 +332,10 @@ public class UploadListener implements Listener {
} }
public void updateDatabase(Status state, String uploadErrorString) { public void updateDatabase(Status state, String uploadErrorString) {
resultObj.setResult_string(uploadErrorString);
resultObj.setState(state.toString());
asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L);
asyncMgr.updateAsyncJobStatus(asyncJobId, AsyncJobResult.STATUS_IN_PROGRESS, resultObj);
UploadVO vo = uploadDao.createForUpdate(); UploadVO vo = uploadDao.createForUpdate();
vo.setUploadState(state); vo.setUploadState(state);
@ -319,6 +345,11 @@ public class UploadListener implements Listener {
} }
public void updateDatabase(Status state, String uploadUrl,String uploadErrorString) { public void updateDatabase(Status state, String uploadUrl,String uploadErrorString) {
resultObj.setResult_string(uploadErrorString);
resultObj.setState(state.toString());
asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L);
asyncMgr.updateAsyncJobStatus(asyncJobId, AsyncJobResult.STATUS_IN_PROGRESS, resultObj);
UploadVO vo = uploadDao.createForUpdate(); UploadVO vo = uploadDao.createForUpdate();
vo.setUploadState(state); vo.setUploadState(state);
@ -341,6 +372,18 @@ public class UploadListener implements Listener {
public synchronized void updateDatabase(UploadAnswer answer) { public synchronized void updateDatabase(UploadAnswer answer) {
resultObj.setResult_string(answer.getErrorString());
resultObj.setState(answer.getUploadStatus().toString());
resultObj.setUploadPercent(answer.getUploadPct());
if (answer.getUploadStatus() == Status.UPLOAD_IN_PROGRESS){
asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L);
asyncMgr.updateAsyncJobStatus(asyncJobId, AsyncJobResult.STATUS_IN_PROGRESS, resultObj);
}else if(answer.getUploadStatus() == Status.UPLOADED){
asyncMgr.completeAsyncJob(asyncJobId, AsyncJobResult.STATUS_SUCCEEDED, 0, resultObj);
}else{
asyncMgr.completeAsyncJob(asyncJobId, AsyncJobResult.STATUS_FAILED, 0, resultObj);
}
UploadVO updateBuilder = uploadDao.createForUpdate(); UploadVO updateBuilder = uploadDao.createForUpdate();
updateBuilder.setUploadPercent(answer.getUploadPct()); updateBuilder.setUploadPercent(answer.getUploadPct());
updateBuilder.setUploadState(answer.getUploadStatus()); updateBuilder.setUploadState(answer.getUploadStatus());
@ -371,14 +414,8 @@ public class UploadListener implements Listener {
public void logDisconnect() { public void logDisconnect() {
s_logger.warn("Unable to monitor upload progress of " + typeName + " at host " + sserver.getName()); s_logger.warn("Unable to monitor upload progress of " + typeName + " at host " + sserver.getName());
String event; String event;
if (type == Type.TEMPLATE){ event = uploadMonitor.getEvent(type);
event = EventTypes.EVENT_TEMPLATE_UPLOAD_FAILED; uploadMonitor.logEvent(accountId, event, "Storage server " + sserver.getName() + " disconnected during upload of " + typeName, EventVO.LEVEL_WARN, eventId);
}else if (type == Type.ISO){
event = EventTypes.EVENT_ISO_UPLOAD_FAILED;
}else{
event = EventTypes.EVENT_VOLUME_UPLOAD_FAILED;
}
uploadMonitor.logEvent(accountId, event, "Storage server " + sserver.getName() + " disconnected during upload of " + typeName, EventVO.LEVEL_WARN);
} }
public void scheduleImmediateStatusCheck(RequestType request) { public void scheduleImmediateStatusCheck(RequestType request) {

View File

@ -20,13 +20,14 @@ package com.cloud.storage.upload;
import java.util.Map; import java.util.Map;
import com.cloud.async.AsyncJobManager;
import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.template.TemplateInfo; import com.cloud.storage.template.TemplateInfo;
import com.cloud.utils.component.Manager; import com.cloud.utils.component.Manager;
/** /**
* Monitor upload progress of all templates. * Monitor upload progress of all entities.
* @author nitin * @author nitin
* *
*/ */
@ -35,7 +36,7 @@ public interface UploadMonitor extends Manager{
public void cancelAllUploads(Long templateId); public void cancelAllUploads(Long templateId);
public void extractTemplate(VMTemplateVO template, String url, public void extractTemplate(VMTemplateVO template, String url,
VMTemplateHostVO tmpltHostRef,Long dataCenterId); VMTemplateHostVO tmpltHostRef,Long dataCenterId, long eventId, long asyncJobId, AsyncJobManager asyncMgr);
void handleUploadTemplateSync(long sserverId, void handleUploadTemplateSync(long sserverId,
Map<String, TemplateInfo> templateInfo); Map<String, TemplateInfo> templateInfo);

View File

@ -20,6 +20,7 @@ import com.cloud.agent.api.Command;
import com.cloud.agent.api.storage.UploadCommand; import com.cloud.agent.api.storage.UploadCommand;
import com.cloud.agent.api.storage.UploadProgressCommand; import com.cloud.agent.api.storage.UploadProgressCommand;
import com.cloud.agent.api.storage.UploadProgressCommand.RequestType; import com.cloud.agent.api.storage.UploadProgressCommand.RequestType;
import com.cloud.async.AsyncJobManager;
import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.DataCenterDao;
import com.cloud.event.EventTypes; import com.cloud.event.EventTypes;
@ -123,7 +124,7 @@ public class UploadMonitorImpl implements UploadMonitor {
start(); start();
UploadCommand ucmd = new UploadCommand(url, volume.getId(), volume.getSize(), installPath, Type.VOLUME); UploadCommand ucmd = new UploadCommand(url, volume.getId(), volume.getSize(), installPath, Type.VOLUME);
UploadListener ul = new UploadListener(sserver, _timer, _uploadDao, uploadVolumeObj.getId(), this, ucmd, volume.getAccountId(), volume.getName(), Type.VOLUME); UploadListener ul = new UploadListener(sserver, _timer, _uploadDao, uploadVolumeObj.getId(), this, ucmd, volume.getAccountId(), volume.getName(), Type.VOLUME, dataCenterId, dataCenterId, null);
_listenerMap.put(uploadVolumeObj, ul); _listenerMap.put(uploadVolumeObj, ul);
long result = send(sserver.getId(), ucmd, ul); long result = send(sserver.getId(), ucmd, ul);
@ -137,7 +138,7 @@ public class UploadMonitorImpl implements UploadMonitor {
@Override @Override
public void extractTemplate( VMTemplateVO template, String url, public void extractTemplate( VMTemplateVO template, String url,
VMTemplateHostVO vmTemplateHost,Long dataCenterId){ VMTemplateHostVO 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 ;
@ -156,7 +157,7 @@ public class UploadMonitorImpl implements UploadMonitor {
if(vmTemplateHost != null) { if(vmTemplateHost != null) {
start(); start();
UploadCommand ucmd = new UploadCommand(template, url, vmTemplateHost); UploadCommand ucmd = new UploadCommand(template, url, vmTemplateHost);
UploadListener ul = new UploadListener(sserver, _timer, _uploadDao, uploadTemplateObj.getId(), this, ucmd, template.getAccountId(), template.getName(), type);//TO DO - remove template UploadListener ul = new UploadListener(sserver, _timer, _uploadDao, uploadTemplateObj.getId(), this, ucmd, template.getAccountId(), template.getName(), type, eventId, asyncJobId, asyncMgr);
_listenerMap.put(uploadTemplateObj, ul); _listenerMap.put(uploadTemplateObj, ul);
long result = send(sserver.getId(), ucmd, ul); long result = send(sserver.getId(), ucmd, ul);
@ -211,23 +212,16 @@ public class UploadMonitorImpl implements UploadMonitor {
return true; return true;
} }
public String getEvent(Upload.Status status, Type type){ public String getEvent(Type type){
if (status == Upload.Status.UPLOADED){
if(type == Type.TEMPLATE) return EventTypes.EVENT_TEMPLATE_UPLOAD_SUCCESS;
if(type == Type.ISO) return EventTypes.EVENT_ISO_UPLOAD_SUCCESS;
if(type == Type.VOLUME) return EventTypes.EVENT_VOLUME_UPLOAD_SUCCESS;
}
if (status == Upload.Status.UPLOAD_ERROR || status == Upload.Status.ABANDONED){ if(type == Type.TEMPLATE) return EventTypes.EVENT_TEMPLATE_UPLOAD;
if(type == Type.TEMPLATE) return EventTypes.EVENT_TEMPLATE_UPLOAD_FAILED; if(type == Type.ISO) return EventTypes.EVENT_ISO_UPLOAD;
if(type == Type.ISO) return EventTypes.EVENT_ISO_UPLOAD_FAILED; if(type == Type.VOLUME) return EventTypes.EVENT_VOLUME_UPLOAD;
if(type == Type.VOLUME) return EventTypes.EVENT_VOLUME_UPLOAD_FAILED;
}
return null; return null;
} }
public void handleUploadEvent(HostVO host, Long accountId, String typeName, Type type, Long uploadId, com.cloud.storage.Upload.Status reason) { public void handleUploadEvent(HostVO host, Long accountId, String typeName, Type type, Long uploadId, com.cloud.storage.Upload.Status reason, long eventId) {
if ((reason == Upload.Status.UPLOADED) || (reason==Upload.Status.ABANDONED)){ if ((reason == Upload.Status.UPLOADED) || (reason==Upload.Status.ABANDONED)){
UploadVO uploadObj = new UploadVO(uploadId); UploadVO uploadObj = new UploadVO(uploadId);
@ -237,13 +231,13 @@ public class UploadMonitorImpl implements UploadMonitor {
} }
} }
if (reason == Upload.Status.UPLOADED) { if (reason == Upload.Status.UPLOADED) {
logEvent(accountId, getEvent(reason, type), typeName + " successfully uploaded from storage server " + host.getName(), EventVO.LEVEL_INFO); logEvent(accountId, getEvent(type), typeName + " successfully uploaded from storage server " + host.getName(), EventVO.LEVEL_INFO, eventId);
} }
if (reason == Upload.Status.UPLOAD_ERROR) { if (reason == Upload.Status.UPLOAD_ERROR) {
logEvent(accountId, getEvent(reason, type), typeName + " failed to upload from storage server " + host.getName(), EventVO.LEVEL_ERROR); logEvent(accountId, getEvent(type), typeName + " failed to upload from storage server " + host.getName(), EventVO.LEVEL_ERROR, eventId);
} }
if (reason == Upload.Status.ABANDONED) { if (reason == Upload.Status.ABANDONED) {
logEvent(accountId, getEvent(reason, type), typeName + " :aborted upload from storage server " + host.getName(), EventVO.LEVEL_WARN); logEvent(accountId, getEvent(type), typeName + " :aborted upload from storage server " + host.getName(), EventVO.LEVEL_WARN, eventId);
} }
/*VMTemplateHostVO vmTemplateHost = _vmTemplateHostDao.findByHostTemplate(host.getId(), template.getId()); /*VMTemplateHostVO vmTemplateHost = _vmTemplateHostDao.findByHostTemplate(host.getId(), template.getId());
@ -306,13 +300,14 @@ public class UploadMonitorImpl implements UploadMonitor {
} }
public void logEvent(long accountId, String evtType, String description, String level) { public void logEvent(long accountId, String evtType, String description, String level, long eventId) {
EventVO event = new EventVO(); EventVO event = new EventVO();
event.setUserId(1); event.setUserId(1);
event.setAccountId(accountId); event.setAccountId(accountId);
event.setType(evtType); event.setType(evtType);
event.setDescription(description); event.setDescription(description);
event.setLevel(level); event.setLevel(level);
event.setStartId(eventId);
_eventDao.persist(event); _eventDao.persist(event);
} }

32
server/src/com/cloud/template/TemplateManager.java Normal file → Executable file
View File

@ -20,6 +20,7 @@ package com.cloud.template;
import java.net.URI; import java.net.URI;
import java.util.List; import java.util.List;
import com.cloud.async.AsyncJobManager;
import com.cloud.exception.InternalErrorException; import com.cloud.exception.InternalErrorException;
import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.StorageUnavailableException; import com.cloud.exception.StorageUnavailableException;
@ -98,7 +99,34 @@ public interface TemplateManager extends Manager {
* @param sourceZoneId * @param sourceZoneId
* @param destZoneId * @param destZoneId
* @return true if success * @return true if success
* @throws InternalErrorException * @throws InternalErrorException URI uri = new URI(url);
if ( (uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("ftp") )) {
throw new IllegalArgumentException("Unsupported scheme for url: " + url);
}
String host = uri.getHost();
try {
InetAddress hostAddr = InetAddress.getByName(host);
if (hostAddr.isAnyLocalAddress() || hostAddr.isLinkLocalAddress() || hostAddr.isLoopbackAddress() || hostAddr.isMulticastAddress() ) {
throw new IllegalArgumentException("Illegal host specified in url");
}
if (hostAddr instanceof Inet6Address) {
throw new IllegalArgumentException("IPV6 addresses not supported (" + hostAddr.getHostAddress() + ")");
}
} catch (UnknownHostException uhe) {
throw new IllegalArgumentException("Unable to resolve " + host);
}
if (_dcDao.findById(zoneId) == null) {
throw new IllegalArgumentException("Please specify a valid zone.");
}
VMTemplateVO template = findTemplateById(templateId);
VMTemplateHostVO tmpltHostRef = findTemplateHostRef(templateId, zoneId);
if (tmpltHostRef != null && tmpltHostRef.getDownloadState() != com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED){
throw new IllegalArgumentException("The template hasnt been downloaded ");
}
* @throws StorageUnavailableException * @throws StorageUnavailableException
* @throws InvalidParameterValueException * @throws InvalidParameterValueException
*/ */
@ -128,6 +156,6 @@ public interface TemplateManager extends Manager {
boolean templateIsDeleteable(VMTemplateHostVO templateHostRef); boolean templateIsDeleteable(VMTemplateHostVO templateHostRef);
void extract(VMTemplateVO template, String url, VMTemplateHostVO tmpltHostRef, Long zoneId); void extract(VMTemplateVO template, String url, VMTemplateHostVO tmpltHostRef, Long zoneId, long eventId, long asyncJobId, AsyncJobManager asyncMgr);
} }

View File

@ -32,6 +32,7 @@ import com.cloud.agent.api.Answer;
import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.DestroyCommand;
import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.DownloadAnswer;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.async.AsyncJobManager;
import com.cloud.configuration.ResourceCount.ResourceType; import com.cloud.configuration.ResourceCount.ResourceType;
import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.DataCenterVO; import com.cloud.dc.DataCenterVO;
@ -148,8 +149,8 @@ public class TemplateManagerImpl implements TemplateManager {
} }
@Override @Override
public void extract(VMTemplateVO template, String url, VMTemplateHostVO tmpltHostRef, Long zoneId){ public void extract(VMTemplateVO template, String url, VMTemplateHostVO tmpltHostRef, Long zoneId, long eventId, long asyncJobId, AsyncJobManager asyncMgr){
_uploadMonitor.extractTemplate(template, url, tmpltHostRef, zoneId); _uploadMonitor.extractTemplate(template, url, tmpltHostRef, zoneId, eventId, asyncJobId, asyncMgr);
} }
@Override @DB @Override @DB

View File

@ -12,14 +12,14 @@
<zones> <zones>
<zone> <zone>
<id>1</id> <id>1</id>
<name>ZONE1</name> <name>NM</name>
<dns1>72.52.126.11</dns1> <dns1>4.2.2.2</dns1>
<dns2>72.52.126.12</dns2> <dns2>10.10.10.14</dns2>
<internalDns1>192.168.10.253</internalDns1> <internalDns1>4.2.2.2</internalDns1>
<internalDns2>192.168.10.254</internalDns2> <internalDns2>4.2.2.2</internalDns2>
<gateway>172.16.0.1</gateway> <gateway>10.91.28.1</gateway>
<netmask>255.255.0.0</netmask> <netmask>255.255.255.0</netmask>
<ipAddressRange>172.16.1.1-172.16.255.253</ipAddressRange> <vnet>560-579</vnet>
<guestNetworkCidr>10.1.1.0/24</guestNetworkCidr> <guestNetworkCidr>10.1.1.0/24</guestNetworkCidr>
</zone> </zone>
</zones> </zones>
@ -35,24 +35,46 @@
<pods> <pods>
<pod> <pod>
<id>1</id> <id>1</id>
<name>POD1</name> <name>NM</name>
<zoneId>1</zoneId> <zoneId>1</zoneId>
<gateway>192.168.2.1</gateway> <gateway>10.91.28.1</gateway>
<cidr>192.168.2.0/24</cidr> <cidr>10.91.28.0/24</cidr>
<ipAddressRange>192.168.2.20-192.168.2.170</ipAddressRange> <ipAddressRange>10.91.28.160-10.91.28.179</ipAddressRange>
</pod> </pod>
</pods> </pods>
<!--
<storagePools>
<storagePool>
<zoneId>1</zoneId>
<podId>1</podId>
<name>idc-ss</name>
<hostAddress>10.91.28.6</hostAddress>
<hostPath>/export/home/nitin/primary</hostPath>
</storagePool>
</storagePools>
-->
<!-- <!--
<secondaryStorages>
<secondaryStorage>
<zoneId>1</zoneId>
<podId>1</podId>
<url>nfs://10.91.28.6/export/home/nitin/secondary</url>
</secondaryStorage>
</secondaryStorages>
-->
<vlans> <vlans>
<vlan> <vlan>
<zoneId>1</zoneId> <zoneId>1</zoneId>
<vlanId>30</vlanId> <vlanId>30</vlanId>
<vlanType>VirtualNetwork</vlanType> <vlanType>VirtualNetwork</vlanType>
<gateway>192.168.30.1</gateway> <gateway>10.91.30.1</gateway>
<netmask>255.255.255.0</netmask> <netmask>255.255.255.0</netmask>
<ipAddressRange>192.168.30.10-192.168.30.19</ipAddressRange> <ipAddressRange>10.91.30.160-10.91.30.179</ipAddressRange>
</vlan> </vlan>
</vlans>
<!--
<vlan> <vlan>
<zoneId>1</zoneId> <zoneId>1</zoneId>
<vlanId>31</vlanId> <vlanId>31</vlanId>
@ -61,7 +83,6 @@
<netmask>255.255.255.0</netmask> <netmask>255.255.255.0</netmask>
<ipAddressRange>192.168.31.10-192.168.31.19</ipAddressRange> <ipAddressRange>192.168.31.10-192.168.31.19</ipAddressRange>
</vlan> </vlan>
</vlans>
--> -->
<!-- <!--
* id is the unique id of the service offering * id is the unique id of the service offering