bug 4286: Schema changes to include the upload table, Introducing extractIso command and extractVolume command

This commit is contained in:
nit 2010-09-15 17:51:42 +05:30
parent 4eef74f73d
commit f5ac46255c
31 changed files with 778 additions and 238 deletions

View File

@ -73,6 +73,7 @@ deleteIso=com.cloud.api.commands.DeleteIsoCmd;15
copyIso=com.cloud.api.commands.CopyIsoCmd;15
updateIsoPermissions=com.cloud.api.commands.UpdateIsoPermissionsCmd;15
listIsoPermissions=com.cloud.api.commands.ListIsoPermissionsCmd;15
extractIso=com.cloud.api.commands.ExtractIsoCmd;15
#### guest OS commands
listOsTypes=com.cloud.api.commands.ListGuestOsCmd;15
@ -179,6 +180,7 @@ detachVolume=com.cloud.api.commands.DetachVolumeCmd;15
createVolume=com.cloud.api.commands.CreateVolumeCmd;15
deleteVolume=com.cloud.api.commands.DeleteVolumeCmd;15
listVolumes=com.cloud.api.commands.ListVolumesCmd;15
extractVolume=com.cloud.api.commands.ExtractVolumeCmd;15
#### registration command: FIXME -- this really should be something in management server that
#### generates a new key for the user and they just have to

View File

@ -88,6 +88,7 @@
<dao name="ResourceCount" class="com.cloud.configuration.dao.ResourceCountDaoImpl"/>
<dao name="UserAccount" class="com.cloud.user.dao.UserAccountDaoImpl"/>
<dao name="VM Template Host" class="com.cloud.storage.dao.VMTemplateHostDaoImpl"/>
<dao name="Upload" class="com.cloud.storage.dao.UploadDaoImpl"/>
<dao name="VM Template Pool" class="com.cloud.storage.dao.VMTemplatePoolDaoImpl"/>
<dao name="VM Template Zone" class="com.cloud.storage.dao.VMTemplateZoneDaoImpl"/>
<dao name="Launch Permission" class="com.cloud.storage.dao.LaunchPermissionDaoImpl"/>

View File

@ -4,8 +4,7 @@ import java.io.File;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.UploadVO;
public class UploadAnswer extends Answer {
@ -13,7 +12,7 @@ public class UploadAnswer extends Answer {
private String jobId;
private int uploadPct;
private String errorString;
private VMTemplateHostVO.Status uploadStatus;
private UploadVO.Status uploadStatus;
private String uploadPath;
private String installPath;
public Long templateSize = 0L;
@ -29,7 +28,7 @@ public class UploadAnswer extends Answer {
return uploadStatus.toString();
}
public VMTemplateHostVO.Status getUploadStatus() {
public UploadVO.Status getUploadStatus() {
return uploadStatus;
}
@ -48,7 +47,7 @@ public class UploadAnswer extends Answer {
}
public UploadAnswer(String jobId, int uploadPct, String errorString,
Status uploadStatus, String fileSystemPath, String installPath, long templateSize) {
UploadVO.Status uploadStatus, String fileSystemPath, String installPath, long templateSize) {
super();
this.jobId = jobId;
this.uploadPct = uploadPct;
@ -60,7 +59,7 @@ public class UploadAnswer extends Answer {
}
public UploadAnswer(String jobId, int uploadPct, Command command,
Status uploadStatus, String fileSystemPath, String installPath) {
UploadVO.Status uploadStatus, String fileSystemPath, String installPath) {
super(command);
this.jobId = jobId;
this.uploadPct = uploadPct;
@ -81,7 +80,7 @@ public class UploadAnswer extends Answer {
return path;
}
public void setUploadStatus(VMTemplateHostVO.Status uploadStatus) {
public void setUploadStatus(UploadVO.Status uploadStatus) {
this.uploadStatus = uploadStatus;
}

View File

@ -1,6 +1,7 @@
package com.cloud.agent.api.storage;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.Upload.Type;
import com.cloud.storage.VMTemplateVO;
import com.cloud.agent.api.storage.AbstractUploadCommand;
import com.cloud.agent.api.storage.DownloadCommand.PasswordAuth;
@ -17,6 +18,7 @@ public class UploadCommand extends AbstractUploadCommand {
private PasswordAuth auth;
private long templateSizeInBytes;
private long id;
private Type type;
public UploadCommand(VMTemplateVO template, String url, VMTemplateHostVO vmTemplateHost) {
@ -29,6 +31,15 @@ public class UploadCommand extends AbstractUploadCommand {
}
public UploadCommand(String url, long id, long sizeInBytes, String installPath, Type type){
this.template = null;
this.url = url;
this.installPath = installPath;
this.id = id;
this.type = type;
this.templateSizeInBytes = sizeInBytes;
}
protected UploadCommand() {
}

8
core/src/com/cloud/event/EventTypes.java Normal file → Executable file
View File

@ -87,7 +87,10 @@ public class EventTypes {
public static final String EVENT_VOLUME_CREATE = "VOLUME.CREATE";
public static final String EVENT_VOLUME_DELETE = "VOLUME.DELETE";
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_SUCCESS = "VOLUME.UPLOAD.SUCCESS";
public static final String EVENT_VOLUME_UPLOAD_FAILED = "VOLUME.UPLOAD.FAILED";
// Domains
public static final String EVENT_DOMAIN_CREATE = "DOMAIN.CREATE";
@ -107,6 +110,9 @@ public class EventTypes {
public static final String EVENT_ISO_COPY = "ISO.COPY";
public static final String EVENT_ISO_ATTACH = "ISO.ATTACH";
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_START = "ISO.UPLOAD.START";
public static final String EVENT_ISO_UPLOAD_SUCCESS = "ISO.UPLOAD.SUCCESS";
//SSVM
public static final String EVENT_SSVM_CREATE = "SSVM.CREATE";

1
core/src/com/cloud/storage/StorageManager.java Normal file → Executable file
View File

@ -331,4 +331,5 @@ public interface StorageManager extends Manager {
<T extends VMInstanceVO> VolumeVO allocate(VolumeType type, DiskOfferingVO offering, String name, Long size, VMTemplateVO template, T vm, AccountVO account);
<T extends VMInstanceVO> void create(T vm);
Long findHostIdForStoragePool(StoragePoolVO pool);
}

View File

@ -165,8 +165,7 @@ public abstract class StorageResource extends ServerResourceBase implements Serv
return Answer.createUnsupportedCommandAnswer(cmd);
}
private Answer execute(UploadCommand cmd) {
s_logger.warn(" Nitin got the cmd " +cmd);
private Answer execute(UploadCommand cmd) {
return _uploadManager.handleUploadCommand(cmd);
}

View File

@ -0,0 +1,7 @@
package com.cloud.storage;
public interface Upload {
public static enum Status {UNKNOWN, ABANDONED, UPLOADED, NOT_UPLOADED, UPLOAD_ERROR, UPLOAD_IN_PROGRESS}
public static enum Type {VOLUME, TEMPLATE, ISO}
}

View File

@ -0,0 +1,219 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.storage;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import com.cloud.utils.db.GenericDaoBase;
/**
* Table for storing all the upload information.
* @author nitin
*
*/
@Entity
@Table(name="upload")
public class UploadVO implements Upload {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
Long id;
@Column(name="host_id")
private long hostId;
@Column(name="type_id")
private long typeId;
@Column(name=GenericDaoBase.CREATED_COLUMN)
private Date created = null;
@Column(name="last_updated")
@Temporal(value=TemporalType.TIMESTAMP)
private Date lastUpdated = null;
@Column (name="upload_pct")
private int uploadPercent;
@Column (name="type")
@Enumerated(EnumType.STRING)
private Type type;
@Column (name="upload_state")
@Enumerated(EnumType.STRING)
private Status uploadState;
@Column (name="error_str")
private String errorString;
@Column (name="job_id")
private String jobId;
@Column (name="url")
private String uploadUrl;
public long getHostId() {
return hostId;
}
public void setHostId(long hostId) {
this.hostId = hostId;
}
public Long getId() {
return id;
}
public Date getCreated() {
return created;
}
public Date getLastUpdated() {
return lastUpdated;
}
public void setLastUpdated(Date date) {
lastUpdated = date;
}
public UploadVO(long hostId, long templateId) {
super();
this.hostId = hostId;
this.typeId = templateId;
}
public UploadVO(long hostId, long typeId, Date lastUpdated,
Status uploadState, int uploadPercent, Type type,
String errorString, String jobId, String uploadUrl) {
super();
this.hostId = hostId;
this.typeId = typeId;
this.lastUpdated = lastUpdated;
this.uploadState = uploadState;
this.uploadPercent = uploadPercent;
this.type = type;
this.errorString = errorString;
this.jobId = jobId;
this.uploadUrl = uploadUrl;
}
protected UploadVO() {
}
public UploadVO(Long uploadId) {
this.id = uploadId;
}
public void setErrorString(String errorString) {
this.errorString = errorString;
}
public String getErrorString() {
return errorString;
}
public void setJobId(String jobId) {
this.jobId = jobId;
}
public String getJobId() {
return jobId;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof UploadVO) {
UploadVO other = (UploadVO)obj;
if (id == null && other.getId() == null) {
return (this.typeId==other.getTypeId() && this.hostId==other.getHostId() && this.type == other.getType());
} else if (id == null && other.getId() != null) {
return false;
} else if (id != null && other.getId() == null) {
return false;
} else {
return (this.id.equals(other.getId()));
}
}
return false;
}
@Override
public int hashCode() {
return id.hashCode();
}
public int getUploadPercent() {
return uploadPercent;
}
public void setUploadPercent(int uploadPercent) {
this.uploadPercent = uploadPercent;
}
public Status getUploadState() {
return uploadState;
}
public void setUploadState(Status uploadState) {
this.uploadState = uploadState;
}
public long getTypeId() {
return typeId;
}
public void setTypeId(long typeId) {
this.typeId = typeId;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public String getUploadUrl() {
return uploadUrl;
}
public void setUploadUrl(String uploadUrl) {
this.uploadUrl = uploadUrl;
}
public void setId(Long id) {
this.id = id;
}
public void setCreated(Date created) {
this.created = created;
}
}

61
core/src/com/cloud/storage/VMTemplateHostVO.java Normal file → Executable file
View File

@ -60,36 +60,23 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc {
@Column (name="download_pct")
private int downloadPercent;
@Column (name="upload_pct")
private int uploadPercent;
@Column (name="size")
private long size;
@Column (name="download_state")
@Enumerated(EnumType.STRING)
private Status downloadState;
@Column (name="upload_state")
@Enumerated(EnumType.STRING)
private Status uploadState;
private Status downloadState;
@Column (name="local_path")
private String localDownloadPath;
@Column (name="error_str")
private String errorString;
@Column (name="upload_error_str")
private String upload_errorString;
@Column (name="job_id")
private String jobId;
@Column (name="upload_job_id")
private String uploadJobId;
@Column (name="pool_id")
private Long poolId;
@ -99,9 +86,6 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc {
@Column (name="url")
private String downloadUrl;
@Column (name="upload_url")
private String uploadUrl;
@Column(name="is_copy")
private boolean isCopy = false;
@ -279,44 +263,5 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc {
public boolean isCopy() {
return isCopy;
}
public int getUploadPercent() {
return uploadPercent;
}
public void setUploadPercent(int uploadPercent) {
this.uploadPercent = uploadPercent;
}
public Status getUploadState() {
return uploadState;
}
public void setUploadState(Status uploadState) {
this.uploadState = uploadState;
}
public String getUpload_errorString() {
return upload_errorString;
}
public void setUpload_errorString(String uploadErrorString) {
upload_errorString = uploadErrorString;
}
public String getUploadUrl() {
return uploadUrl;
}
public void setUploadUrl(String uploadUrl) {
this.uploadUrl = uploadUrl;
}
public String getUploadJobId() {
return uploadJobId;
}
public void setUploadJobId(String uploadJobId) {
this.uploadJobId = uploadJobId;
}
}

View File

@ -0,0 +1,15 @@
package com.cloud.storage.dao;
import java.util.List;
import com.cloud.storage.UploadVO;
import com.cloud.storage.Upload.Status;
import com.cloud.storage.Upload.Type;
import com.cloud.utils.db.GenericDao;
public interface UploadDao extends GenericDao<UploadVO, Long> {
List<UploadVO> listByTypeUploadStatus(long typeId, Type type,
Status uploadState);
}

View File

@ -0,0 +1,74 @@
package com.cloud.storage.dao;
import java.sql.PreparedStatement;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.storage.UploadVO;
import com.cloud.utils.DateUtil;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
@Local(value={UploadDao.class})
public class UploadDaoImpl extends GenericDaoBase<UploadVO, Long> implements UploadDao {
public static final Logger s_logger = Logger.getLogger(UploadDaoImpl.class.getName());
protected final SearchBuilder<UploadVO> typeUploadStatusSearch;
protected static final String UPDATE_UPLOAD_INFO =
"UPDATE upload SET upload_state = ?, upload_pct= ?, last_updated = ? "
+ ", upload_error_str = ?, upload_job_id = ? "
+ "WHERE host_id = ? and type_id = ? and type = ?";
protected static final String UPLOADS_STATE_DC=
"SELECT * FROM upload t, host h where t.host_id = h.id and h.data_center_id=? "
+ " and t.type_id=? and t.upload_state = ?" ;
public UploadDaoImpl() {
typeUploadStatusSearch = createSearchBuilder();
typeUploadStatusSearch.and("type_id", typeUploadStatusSearch.entity().getTypeId(), SearchCriteria.Op.EQ);
typeUploadStatusSearch.and("upload_state", typeUploadStatusSearch.entity().getUploadState(), SearchCriteria.Op.EQ);
typeUploadStatusSearch.and("type", typeUploadStatusSearch.entity().getType(), SearchCriteria.Op.EQ);
typeUploadStatusSearch.done();
}
@Override
public List<UploadVO> listByTypeUploadStatus(long typeId, UploadVO.Type type, UploadVO.Status uploadState) {
SearchCriteria<UploadVO> sc = typeUploadStatusSearch.create();
sc.setParameters("type_id", typeId);
sc.setParameters("type", type);
sc.setParameters("upload_state", uploadState.toString());
return listBy(sc);
}
/*
public void updateUploadStatus(long hostId, long typeId, int uploadPercent, UploadVO.Status uploadState,
String uploadJobId, String uploadUrl ) {
Transaction txn = Transaction.currentTxn();
PreparedStatement pstmt = null;
try {
Date now = new Date();
String sql = UPDATE_UPLOAD_INFO;
pstmt = txn.prepareAutoCloseStatement(sql);
pstmt.setString(1, uploadState.toString());
pstmt.setInt(2, uploadPercent);
pstmt.setString(3, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), now));
pstmt.setString(4, uploadJobId);
pstmt.setLong(5, hostId);
pstmt.setLong(6, typeId);
pstmt.setString(7, uploadUrl);
pstmt.executeUpdate();
} catch (Exception e) {
s_logger.warn("Exception: ", e);
}
}*/
}

View File

@ -42,10 +42,7 @@ public interface VMTemplateHostDao extends GenericDao<VMTemplateHostVO, Long> {
List<VMTemplateHostVO> listByTemplatePool(long templateId, long poolId);
void update(VMTemplateHostVO instance);
void updateUploadStatus(long hostId, long templateId, int uploadPercent, Status uploadState,
String jobId, String uploadUrl );
void update(VMTemplateHostVO instance);
List<VMTemplateHostVO> listByTemplateStatus(long templateId, VMTemplateHostVO.Status downloadState);
@ -58,6 +55,5 @@ public interface VMTemplateHostDao extends GenericDao<VMTemplateHostVO, Long> {
List<VMTemplateHostVO> listDestroyed(long hostId);
boolean templateAvailable(long templateId, long hostId);
List<VMTemplateHostVO> listByTemplateUploadStatus(long templateId,Status UploadState);
}

View File

@ -50,25 +50,16 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase<VMTemplateHostVO, Long
protected final SearchBuilder<VMTemplateHostVO> HostTemplatePoolSearch;
protected final SearchBuilder<VMTemplateHostVO> TemplateStatusSearch;
protected final SearchBuilder<VMTemplateHostVO> TemplateStatesSearch;
protected final SearchBuilder<VMTemplateHostVO> TemplateUploadStatusSearch;
protected static final String UPDATE_TEMPLATE_HOST_REF =
"UPDATE template_host_ref SET download_state = ?, download_pct= ?, last_updated = ? "
+ ", error_str = ?, local_path = ?, job_id = ? "
+ "WHERE host_id = ? and template_id = ?";
protected static final String UPDATE_UPLOAD_INFO =
"UPDATE template_host_ref SET upload_state = ?, upload_pct= ?, last_updated = ? "
+ ", upload_error_str = ?, upload_job_id = ? "
+ "WHERE host_id = ? and template_id = ?";
protected static final String UPDATE_TEMPLATE_HOST_REF =
"UPDATE type_host_ref SET download_state = ?, download_pct= ?, last_updated = ? "
+ ", error_str = ?, local_path = ?, job_id = ? "
+ "WHERE host_id = ? and type_id = ?";
protected static final String DOWNLOADS_STATE_DC=
"SELECT * FROM template_host_ref t, host h where t.host_id = h.id and h.data_center_id=? "
+ " and t.template_id=? and t.download_state = ?" ;
protected static final String UPLOADS_STATE_DC=
"SELECT * FROM template_host_ref t, host h where t.host_id = h.id and h.data_center_id=? "
+ " and t.template_id=? and t.upload_state = ?" ;
protected static final String DOWNLOADS_STATE_DC_POD=
"SELECT * FROM template_host_ref t, host h where t.host_id = h.id and h.data_center_id=? and h.pod_id=? "
@ -79,9 +70,6 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase<VMTemplateHostVO, Long
+ " where t.template_id=? and t.download_state=?";
protected static final String UPLOADS_STATE=
"SELECT * FROM template_host_ref t "
+ " where t.template_id=? and t.upload_state=?";
public VMTemplateHostDaoImpl () {
HostSearch = createSearchBuilder();
@ -112,12 +100,7 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase<VMTemplateHostVO, Long
TemplateStatusSearch = createSearchBuilder();
TemplateStatusSearch.and("template_id", TemplateStatusSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
TemplateStatusSearch.and("download_state", TemplateStatusSearch.entity().getDownloadState(), SearchCriteria.Op.EQ);
TemplateStatusSearch.done();
TemplateUploadStatusSearch = createSearchBuilder();
TemplateUploadStatusSearch.and("template_id", TemplateUploadStatusSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
TemplateUploadStatusSearch.and("upload_state", TemplateUploadStatusSearch.entity().getUploadState(), SearchCriteria.Op.EQ);
TemplateUploadStatusSearch.done();
TemplateStatusSearch.done();
TemplateStatesSearch = createSearchBuilder();
TemplateStatesSearch.and("template_id", TemplateStatesSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
@ -149,28 +132,7 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase<VMTemplateHostVO, Long
} catch (Exception e) {
s_logger.warn("Exception: ", e);
}
}
public void updateUploadStatus(long hostId, long templateId, int uploadPercent, Status uploadState,
String uploadJobId, String uploadUrl ) {
Transaction txn = Transaction.currentTxn();
PreparedStatement pstmt = null;
try {
Date now = new Date();
String sql = UPDATE_UPLOAD_INFO;
pstmt = txn.prepareAutoCloseStatement(sql);
pstmt.setString(1, uploadState.toString());
pstmt.setInt(2, uploadPercent);
pstmt.setString(3, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), now));
pstmt.setString(4, uploadJobId);
pstmt.setLong(5, hostId);
pstmt.setLong(6, templateId);
pstmt.setString(7, uploadUrl);
pstmt.executeUpdate();
} catch (Exception e) {
s_logger.warn("Exception: ", e);
}
}
}
@Override
public List<VMTemplateHostVO> listByHostId(long id) {
@ -202,13 +164,7 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase<VMTemplateHostVO, Long
return findOneBy(sc);
}
@Override
public List<VMTemplateHostVO> listByTemplateUploadStatus(long templateId, VMTemplateHostVO.Status uploadState) {
SearchCriteria<VMTemplateHostVO> sc = TemplateUploadStatusSearch.create();
sc.setParameters("template_id", templateId);
sc.setParameters("upload_state", uploadState.toString());
return listBy(sc);
}
@Override
public List<VMTemplateHostVO> listByTemplateStatus(long templateId, VMTemplateHostVO.Status downloadState) {

View File

@ -34,7 +34,7 @@ public class FtpTemplateUploader implements TemplateUploader {
this.ftpUrl = url;
this.completionCallback = callback;
this.templateSizeinBytes = templateSizeinBytes;
s_logger.warn("Nitin in FtpTemplateUploader " +url + " "+sourcePath);
}
public long upload(UploadCompleteCallback callback )
@ -50,7 +50,7 @@ public class FtpTemplateUploader implements TemplateUploader {
}
Date start = new Date();
s_logger.warn("Nitin in FtpTemplateUploader ");
StringBuffer sb = new StringBuffer();
// check for authentication else assume its anonymous access.
/* if (user != null && password != null)
@ -90,17 +90,16 @@ public class FtpTemplateUploader implements TemplateUploader {
done = true;
}
}
status = TemplateUploader.Status.UPLOAD_FINISHED;
s_logger.warn("Nitin in FtpTemplateUploader " +status);
status = TemplateUploader.Status.UPLOAD_FINISHED;
return totalBytes;
} catch (MalformedURLException e) {
status = TemplateUploader.Status.UNRECOVERABLE_ERROR;
errorString = e.getMessage();
s_logger.error("Nitin in FtpTemplateUploader " +errorString);
s_logger.error(errorString);
} catch (IOException e) {
status = TemplateUploader.Status.UNRECOVERABLE_ERROR;
errorString = e.getMessage();
s_logger.error("Nitin in FtpTemplateUploader " +errorString);
s_logger.error(errorString);
}
finally
{

View File

@ -1,14 +1,10 @@
package com.cloud.storage.template;
import java.util.List;
import java.util.Map;
import com.cloud.agent.api.storage.UploadAnswer;
import com.cloud.agent.api.storage.UploadCommand;
import com.cloud.agent.api.storage.UploadCommand;
import com.cloud.storage.StorageResource;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Upload.Status;
import com.cloud.utils.component.Manager;
public interface UploadManager extends Manager {
@ -26,7 +22,7 @@ public interface UploadManager extends Manager {
* @param jobId job Id
* @return status of the upload job
*/
public VMTemplateHostVO.Status getUploadStatus2(String jobId);
public Status getUploadStatus2(String jobId);
/**
* Get the upload percent of a upload job

View File

@ -24,6 +24,7 @@ import com.cloud.agent.api.storage.UploadAnswer;
import com.cloud.agent.api.storage.UploadCommand;
import com.cloud.storage.StorageLayer;
import com.cloud.storage.StorageResource;
import com.cloud.storage.UploadVO;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.template.TemplateUploader.UploadCompleteCallback;
@ -225,31 +226,31 @@ public class UploadManagerImpl implements UploadManager {
return Status.UNKNOWN;
}
public static VMTemplateHostVO.Status convertStatus(Status tds) {
public static UploadVO.Status convertStatus(Status tds) {
switch (tds) {
case ABORTED:
return VMTemplateHostVO.Status.NOT_UPLOADED;
return UploadVO.Status.NOT_UPLOADED;
case UPLOAD_FINISHED:
return VMTemplateHostVO.Status.UPLOAD_IN_PROGRESS;
return UploadVO.Status.UPLOAD_IN_PROGRESS;
case IN_PROGRESS:
return VMTemplateHostVO.Status.UPLOAD_IN_PROGRESS;
return UploadVO.Status.UPLOAD_IN_PROGRESS;
case NOT_STARTED:
return VMTemplateHostVO.Status.NOT_UPLOADED;
return UploadVO.Status.NOT_UPLOADED;
case RECOVERABLE_ERROR:
return VMTemplateHostVO.Status.NOT_UPLOADED;
return UploadVO.Status.NOT_UPLOADED;
case UNKNOWN:
return VMTemplateHostVO.Status.UNKNOWN;
return UploadVO.Status.UNKNOWN;
case UNRECOVERABLE_ERROR:
return VMTemplateHostVO.Status.UPLOAD_ERROR;
return UploadVO.Status.UPLOAD_ERROR;
case POST_UPLOAD_FINISHED:
return VMTemplateHostVO.Status.UPLOADED;
return UploadVO.Status.UPLOADED;
default:
return VMTemplateHostVO.Status.UNKNOWN;
return UploadVO.Status.UNKNOWN;
}
}
@Override
public com.cloud.storage.VMTemplateHostVO.Status getUploadStatus2(String jobId) {
public com.cloud.storage.UploadVO.Status getUploadStatus2(String jobId) {
return convertStatus(getUploadStatus(jobId));
}
@Override
@ -265,7 +266,7 @@ public class UploadManagerImpl implements UploadManager {
if (jobId != null)
uj = jobs.get(jobId);
if (uj == null) {
return new UploadAnswer(null, 0, "Cannot find job", com.cloud.storage.VMTemplateHostVO.Status.UNKNOWN, "", "", 0);
return new UploadAnswer(null, 0, "Cannot find job", com.cloud.storage.UploadVO.Status.UNKNOWN, "", "", 0);
}
TemplateUploader td = uj.getTemplateUploader();
switch (cmd.getRequest()) {
@ -294,31 +295,20 @@ public class UploadManagerImpl implements UploadManager {
@Override
public UploadAnswer handleUploadCommand(UploadCommand cmd) {
s_logger.warn(" handliing the upload " +cmd.getInstallPath() + " " + cmd.getId());
s_logger.warn("Handling the upload " +cmd.getInstallPath() + " " + cmd.getId());
if (cmd instanceof UploadProgressCommand) {
return handleUploadProgressCmd((UploadProgressCommand) cmd);
}
/*
if (cmd.getUrl() == null) {
return new UploadAnswer(null, 0, "Template is corrupted on storage due to an invalid url , cannot Upload", com.cloud.storage.VMTemplateStorageResourceAssoc.Status.UPLOAD_ERROR, "", "", 0);
}
if (cmd.getName() == null) {
return new UploadAnswer(null, 0, "Invalid Name", com.cloud.storage.VMTemplateStorageResourceAssoc.Status.UPLOAD_ERROR, "", "", 0);
}*/
// String installPathPrefix = null;
// installPathPrefix = publicTemplateRepo;
String user = null;
String password = null;
String password = null;
String jobId = uploadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(),
cmd.getFormat(), cmd.getAccountId(), cmd.getDescription(),
cmd.getChecksum(), cmd.getInstallPath(), user, password,
cmd.getTemplateSizeInBytes());
sleep();
if (jobId == null) {
return new UploadAnswer(null, 0, "Internal Error", com.cloud.storage.VMTemplateStorageResourceAssoc.Status.UPLOAD_ERROR, "", "", 0);
return new UploadAnswer(null, 0, "Internal Error", com.cloud.storage.UploadVO.Status.UPLOAD_ERROR, "", "", 0);
}
return new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId),
getUploadTemplateSize(jobId));

1
server/src/com/cloud/api/BaseCmd.java Normal file → Executable file
View File

@ -344,6 +344,7 @@ public abstract class BaseCmd {
SOURCE_ID("sourceid", BaseCmd.TYPE_LONG, "sourceid"),
SOURCE_TYPE("sourcetype",BaseCmd.TYPE_STRING,"sourcetype"),
STORAGE_TYPE("storagetype", BaseCmd.TYPE_STRING, "storageType"),
STATUS("status", BaseCmd.TYPE_STRING, "status"),
SUCCESS("success", BaseCmd.TYPE_BOOLEAN, "success"),
SUM_ACROSS_ZONE("sumacrosszone", BaseCmd.TYPE_BOOLEAN, "sumAcrossZone"),
SYSTEM_VM_TYPE("systemvmtype", BaseCmd.TYPE_STRING, "systemvmtype"),

View File

@ -0,0 +1,92 @@
package com.cloud.api.commands;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import com.cloud.api.BaseCmd;
import com.cloud.api.ServerApiException;
import com.cloud.dc.DataCenterVO;
import com.cloud.server.ManagementServer;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
public class ExtractIsoCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(ExtractIsoCmd.class.getName());
private static final String s_name = "extractisoresponse";
private static final List<Pair<Enum, Boolean>> s_properties = new ArrayList<Pair<Enum, Boolean>>();
static {
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.URL, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.ID, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.ZONE_ID, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE));
}
@Override
public List<Pair<String, Object>> execute(Map<String, Object> params) {
String url = (String) params.get(BaseCmd.Properties.URL.getName());
Long templateId = (Long) params.get(BaseCmd.Properties.ID.getName());
Long zoneId = (Long) params.get(BaseCmd.Properties.ZONE_ID.getName());
Account account = (Account) params.get(BaseCmd.Properties.ACCOUNT_OBJ.getName());
ManagementServer managementServer = getManagementServer();
VMTemplateVO template = managementServer.findTemplateById(templateId.longValue());
if (template == null) {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Unable to find ISO with id " + templateId);
}
if (template.getName().startsWith("xs-tools") ){
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Unable to extract the ISO " + template.getName() + " It is not supported yet");
}
if (template.getFormat() != ImageFormat.ISO ){
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Unsupported format, could not extract the ISO");
}
if(url.toLowerCase().contains("file://")){
throw new ServerApiException(BaseCmd.PARAM_ERROR, "file:// type urls are currently unsupported");
}
if (account != null) {
if(!isAdmin(account.getType())){
if (template.getAccountId() != account.getId()){
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find ISO with ID: " + templateId + " for account: " + account.getAccountName());
}
}else if(!managementServer.isChildDomain(account.getDomainId(), managementServer.findDomainIdByAccountId(template.getAccountId())) ) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to extract ISO " + templateId + " to " + url + ", permission denied.");
}
}
try {
managementServer.extractTemplate(url, templateId, zoneId);
} catch (Exception e) {
s_logger.error(e.getMessage(), e);
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Internal Error Extracting the ISO " + e.getMessage());
}
DataCenterVO zone = managementServer.getDataCenterBy(zoneId);
List<Pair<String, Object>> response = new ArrayList<Pair<String, Object>>();
response.add(new Pair<String, Object>(BaseCmd.Properties.TEMPLATE_ID.getName(), templateId));
response.add(new Pair<String, Object>(BaseCmd.Properties.NAME.getName(), template.getName()));
response.add(new Pair<String, Object>(BaseCmd.Properties.DISPLAY_TEXT.getName(), template.getDisplayText()));
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_NAME.getName(), zone.getName()));
response.add(new Pair<String, Object>(BaseCmd.Properties.TEMPLATE_STATUS.getName(), "Processing"));
return response;
}
@Override
public String getName() {
return s_name;
}
@Override
public List<Pair<Enum, Boolean>> getProperties() {
return s_properties;
}
}

View File

@ -12,6 +12,7 @@ import com.cloud.api.ServerApiException;
import com.cloud.dc.DataCenterVO;
import com.cloud.server.ManagementServer;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
@ -41,8 +42,8 @@ public class ExtractTemplateCmd extends BaseCmd {
if (template == null) {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Unable to find template with id " + templateId);
}
if (template.getName().startsWith("xs-tools") ){
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Unable to extract the template " + template.getName() + " It is not supported yet");
if (template.getFormat() == ImageFormat.ISO ){
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Unsupported format, could not extract the template");
}
if(url.toLowerCase().contains("file://")){

View File

@ -0,0 +1,86 @@
package com.cloud.api.commands;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import com.cloud.api.BaseCmd;
import com.cloud.api.ServerApiException;
import com.cloud.dc.DataCenterVO;
import com.cloud.server.ManagementServer;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeVO;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
public class ExtractVolumeCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(ExtractVolumeCmd.class.getName());
private static final String s_name = "extractvolumeresponse";
private static final List<Pair<Enum, Boolean>> s_properties = new ArrayList<Pair<Enum, Boolean>>();
static {
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.URL, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.ID, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.ZONE_ID, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE));
}
@Override
public List<Pair<String, Object>> execute(Map<String, Object> params) {
String url = (String) params.get(BaseCmd.Properties.URL.getName());
Long volumeId = (Long) params.get(BaseCmd.Properties.ID.getName());
Long zoneId = (Long) params.get(BaseCmd.Properties.ZONE_ID.getName());
Account account = (Account) params.get(BaseCmd.Properties.ACCOUNT_OBJ.getName());
ManagementServer managementServer = getManagementServer();
VolumeVO volume = managementServer.findVolumeById(volumeId);
if (volume == null) {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Unable to find volume with id " + volumeId);
}
if(url.toLowerCase().contains("file://")){
throw new ServerApiException(BaseCmd.PARAM_ERROR, "file:// type urls are currently unsupported");
}
if (account != null) {
if(!isAdmin(account.getType())){
if (volume.getAccountId() != account.getId()){
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find volume with ID: " + volumeId + " for account: " + account.getAccountName());
}
}else if(!managementServer.isChildDomain(account.getDomainId(), volume.getDomainId())){
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to extract volume " + volumeId + " to " + url + ", permission denied.");
}
}
try {
managementServer.extractVolume(url, volumeId, zoneId);
} catch (Exception e) {
s_logger.error(e.getMessage(), e);
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Internal Error Extracting the volume " + e.getMessage());
}
DataCenterVO zone = managementServer.getDataCenterBy(zoneId);
List<Pair<String, Object>> response = new ArrayList<Pair<String, Object>>();
response.add(new Pair<String, Object>(BaseCmd.Properties.VOLUME_ID.getName(), volumeId));
response.add(new Pair<String, Object>(BaseCmd.Properties.VOLUME_NAME.getName(), volume.getName()));
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_NAME.getName(), zone.getName()));
response.add(new Pair<String, Object>(BaseCmd.Properties.STATUS.getName(), "Processing"));
return response;
}
@Override
public String getName() {
return s_name;
}
@Override
public List<Pair<Enum, Boolean>> getProperties() {
return s_properties;
}
}

View File

@ -54,6 +54,8 @@ import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.GetVncPortAnswer;
import com.cloud.agent.api.GetVncPortCommand;
import com.cloud.agent.api.storage.CopyVolumeAnswer;
import com.cloud.agent.api.storage.CopyVolumeCommand;
import com.cloud.alert.AlertManager;
import com.cloud.alert.AlertVO;
import com.cloud.alert.dao.AlertDao;
@ -4799,7 +4801,49 @@ public class ManagementServerImpl implements ManagementServer {
public VlanVO findVlanById(long vlanDbId) {
return _vlanDao.findById(vlanDbId);
}
@Override
public void extractVolume(String url, Long volumeId, Long zoneId) throws URISyntaxException, 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.");
}
VolumeVO volume = findVolumeById(volumeId);
String secondaryStorageURL = _storageMgr.getSecondaryStorageURL(zoneId);
StoragePoolVO srcPool = _poolDao.findById(volume.getPoolId());
Long sourceHostId = _storageMgr.findHostIdForStoragePool(srcPool);
// Copy the volume from the source storage pool to secondary storage
CopyVolumeCommand cvCmd = new CopyVolumeCommand(volume.getId(), volume.getPath(), srcPool, secondaryStorageURL, true);
CopyVolumeAnswer cvAnswer = (CopyVolumeAnswer) _agentMgr.easySend(sourceHostId, cvCmd);
if (cvAnswer == null || !cvAnswer.getResult()) {
throw new InternalErrorException("Failed to copy the volume from the source primary storage pool to secondary storage.");
}
}
@Override
public void extractTemplate(String url, Long templateId, Long zoneId) throws URISyntaxException{

3
server/src/com/cloud/storage/StorageManagerImpl.java Normal file → Executable file
View File

@ -423,7 +423,8 @@ public class StorageManagerImpl implements StorageManager {
return null;
}
protected Long findHostIdForStoragePool(StoragePoolVO pool) {
@Override
public Long findHostIdForStoragePool(StoragePoolVO pool) {
List<StoragePoolHostVO> poolHosts = _poolHostDao.listByHostStatus(pool.getId(), Status.Up);
if (poolHosts.size() == 0) {

View File

@ -1,7 +1,7 @@
package com.cloud.storage.upload;
import com.cloud.agent.api.storage.UploadProgressCommand.RequestType;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.Upload.Status;
public class UploadAbandonedState extends UploadInactiveState {

View File

@ -1,7 +1,7 @@
package com.cloud.storage.upload;
import com.cloud.agent.api.storage.UploadProgressCommand.RequestType;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.Upload.Status;
public class UploadCompleteState extends UploadInactiveState {

View File

@ -4,7 +4,7 @@ import org.apache.log4j.Level;
import com.cloud.agent.api.storage.UploadAnswer;
import com.cloud.agent.api.storage.UploadProgressCommand.RequestType;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.Upload.Status;
public class UploadErrorState extends UploadInactiveState {

91
server/src/com/cloud/storage/upload/UploadListener.java Normal file → Executable file
View File

@ -27,10 +27,13 @@ import com.cloud.event.EventTypes;
import com.cloud.event.EventVO;
import com.cloud.host.HostVO;
import com.cloud.storage.Storage;
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.VMTemplateHostDao;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.Upload.Status;
import com.cloud.storage.Upload.Type;
import com.cloud.storage.download.DownloadState.DownloadEvent;
import com.cloud.storage.upload.UploadMonitorImpl;
import com.cloud.storage.upload.UploadState.UploadEvent;
@ -79,13 +82,12 @@ public class UploadListener implements Listener {
public static final String UPLOAD_ABANDONED=Status.ABANDONED.toString();
private HostVO sserver;
private VMTemplateVO template;
private HostVO sserver;
private boolean uploadActive = true;
private VMTemplateHostDao vmTemplateHostDao;
private UploadDao uploadDao;
private final UploadMonitorImpl uploadMonitor;
private UploadState currState;
@ -98,17 +100,24 @@ public class UploadListener implements Listener {
private TimeoutTask timeoutTask;
private Date lastUpdated = new Date();
private String jobId;
private Long accountId;
private String typeName;
private Type type;
private final Map<String, UploadState> stateMap = new HashMap<String, UploadState>();
private Long templateHostId;
private Long uploadId;
public UploadListener(HostVO host, VMTemplateVO template, Timer _timer, VMTemplateHostDao dao, Long templHostId, UploadMonitorImpl uploadMonitor, UploadCommand cmd) {
this.sserver = host;
this.template = template;
this.vmTemplateHostDao = dao;
public UploadListener(HostVO host, Timer _timer, UploadDao uploadDao,
Long uploadId, UploadMonitorImpl uploadMonitor, UploadCommand cmd,
Long accountId, String typeName, Type type) {
this.sserver = host;
this.uploadDao = uploadDao;
this.uploadMonitor = uploadMonitor;
this.cmd = cmd;
this.templateHostId = templHostId;
this.uploadId = uploadId;
this.accountId = accountId;
this.typeName = typeName;
this.type = type;
initStateMachine();
this.currState = getState(Status.NOT_UPLOADED.toString());
this.timer = _timer;
@ -203,11 +212,19 @@ public class UploadListener implements Listener {
public void setUploadInactive(Status reason) {
uploadActive=false;
uploadMonitor.handleUploadEvent(sserver, template, reason);
uploadMonitor.handleUploadEvent(sserver, accountId, typeName, type, uploadId, reason);
}
public void logUploadStart() {
uploadMonitor.logEvent(template.getAccountId(), EventTypes.EVENT_TEMPLATE_UPLOAD_START, "Storage server " + sserver.getName() + " started upload of template " + template.getName(), EventVO.LEVEL_INFO);
String event;
if (type == Type.TEMPLATE){
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() {
@ -268,7 +285,7 @@ public class UploadListener implements Listener {
}
public void log(String message, Level level) {
s_logger.log(level, message + ", template=" + template.getName() + " at host " + sserver.getName());
s_logger.log(level, message + ", " + type.toString() + " = " + typeName + " at host " + sserver.getName());
}
public void setDisconnected() {
@ -294,44 +311,44 @@ public class UploadListener implements Listener {
public void updateDatabase(Status state, String uploadErrorString) {
VMTemplateHostVO vo = vmTemplateHostDao.createForUpdate();
UploadVO vo = uploadDao.createForUpdate();
vo.setUploadState(state);
vo.setLastUpdated(new Date());
vo.setUpload_errorString(uploadErrorString);
vmTemplateHostDao.update(getTemplateHostId(), vo);
vo.setErrorString(uploadErrorString);
uploadDao.update(getUploadId(), vo);
}
public void updateDatabase(Status state, String uploadUrl,String uploadErrorString) {
VMTemplateHostVO vo = vmTemplateHostDao.createForUpdate();
UploadVO vo = uploadDao.createForUpdate();
vo.setUploadState(state);
vo.setLastUpdated(new Date());
vo.setUploadUrl(uploadUrl);
vo.setUploadJobId(null);
vo.setJobId(null);
vo.setUploadPercent(0);
vo.setUpload_errorString(uploadErrorString);
vo.setErrorString(uploadErrorString);
vmTemplateHostDao.update(getTemplateHostId(), vo);
uploadDao.update(getUploadId(), vo);
}
private Long getTemplateHostId() {
if (templateHostId == null){
private Long getUploadId() {
/*if (uploadId == null){
VMTemplateHostVO templHost = vmTemplateHostDao.findByHostTemplate(sserver.getId(), template.getId());
templateHostId = templHost.getId();
}
return templateHostId;
uploadId = templHost.getId();
}*/ //TO DO
return uploadId;
}
public synchronized void updateDatabase(UploadAnswer answer) {
VMTemplateHostVO updateBuilder = vmTemplateHostDao.createForUpdate();
UploadVO updateBuilder = uploadDao.createForUpdate();
updateBuilder.setUploadPercent(answer.getUploadPct());
updateBuilder.setUploadState(answer.getUploadStatus());
updateBuilder.setLastUpdated(new Date());
updateBuilder.setUpload_errorString(answer.getErrorString());
updateBuilder.setUploadJobId(answer.getJobId());
updateBuilder.setErrorString(answer.getErrorString());
updateBuilder.setJobId(answer.getJobId());
vmTemplateHostDao.update(getTemplateHostId(), updateBuilder);
uploadDao.update(getUploadId(), updateBuilder);
}
public void sendCommand(RequestType reqType) {
@ -352,8 +369,16 @@ public class UploadListener implements Listener {
}
public void logDisconnect() {
s_logger.warn("Unable to monitor upload progress of " + template.getName() + " at host " + sserver.getName());
uploadMonitor.logEvent(template.getAccountId(), EventTypes.EVENT_TEMPLATE_UPLOAD_FAILED, "Storage server " + sserver.getName() + " disconnected during upload of template " + template.getName(), EventVO.LEVEL_WARN);
s_logger.warn("Unable to monitor upload progress of " + typeName + " at host " + sserver.getName());
String event;
if (type == Type.TEMPLATE){
event = EventTypes.EVENT_TEMPLATE_UPLOAD_FAILED;
}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) {

View File

@ -29,13 +29,18 @@ import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.storage.StoragePoolHostVO;
import com.cloud.storage.Upload;
import com.cloud.storage.UploadVO;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateStoragePoolVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Upload.Type;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.UploadDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateHostDao;
import com.cloud.storage.dao.VMTemplatePoolDao;
@ -46,7 +51,7 @@ import com.cloud.vm.dao.SecondaryStorageVmDao;
/**
* @author nitin
*
* Monitors the progress of upload.
*/
@Local(value={UploadMonitor.class})
public class UploadMonitorImpl implements UploadMonitor {
@ -56,6 +61,8 @@ public class UploadMonitorImpl implements UploadMonitor {
private String _hyperVisorType;
@Inject
VMTemplateHostDao _vmTemplateHostDao;
@Inject
UploadDao _uploadDao;
@Inject
VMTemplatePoolDao _vmTemplatePoolDao;
@Inject
@ -65,9 +72,7 @@ public class UploadMonitorImpl implements UploadMonitor {
@Inject
HostDao _serverDao = null;
@Inject
private final DataCenterDao _dcDao = null;
HostDao _serverDao = null;
@Inject
VMTemplateDao _templateDao = null;
@Inject
@ -84,42 +89,79 @@ public class UploadMonitorImpl implements UploadMonitor {
Timer _timer;
final Map<VMTemplateHostVO, UploadListener> _listenerMap = new ConcurrentHashMap<VMTemplateHostVO, UploadListener>();
final Map<UploadVO, UploadListener> _listenerMap = new ConcurrentHashMap<UploadVO, UploadListener>();
@Override
public void cancelAllUploads(Long templateId) {
// TODO Auto-generated method stub
}
public boolean isTemplateUploadInProgress(Long templateId) {
List<VMTemplateHostVO> uploadsInProgress =
_vmTemplateHostDao.listByTemplateStatus(templateId, VMTemplateHostVO.Status.UPLOAD_IN_PROGRESS);
}
private boolean isTypeUploadInProgress(Long typeId, Type type) {
List<UploadVO> uploadsInProgress =
_uploadDao.listByTypeUploadStatus(typeId, type, UploadVO.Status.UPLOAD_IN_PROGRESS);
return (uploadsInProgress.size() != 0);
}
public void extractVolume(VolumeVO volume, String url, Long dataCenterId, String installPath){
if ( isTypeUploadInProgress(volume.getId(), Type.VOLUME) ){
return;
}
List<HostVO> storageServers = _serverDao.listByTypeDataCenter(Host.Type.SecondaryStorage, dataCenterId);
HostVO sserver = storageServers.get(0);
UploadVO uploadVolumeObj = new UploadVO(sserver.getId(), volume.getId(), new Date(),
Upload.Status.NOT_UPLOADED, 0, Type.VOLUME,
null, "jobid0000", url);
_uploadDao.persist(uploadVolumeObj);
//_vmTemplateHostDao.updateUploadStatus(sserver.getId(), template.getId(), 0, VMTemplateStorageResourceAssoc.Status.NOT_UPLOADED, "jobid0000", url);
start();
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);
_listenerMap.put(uploadVolumeObj, ul);
long result = send(sserver.getId(), ucmd, ul);
if (result == -1) {
s_logger.warn("Unable to start upload of volume " + volume.getName() + " from " + sserver.getName() + " to " +url);
ul.setDisconnected();
ul.scheduleStatusCheck(RequestType.GET_OR_RESTART);
}
}
@Override
public void extractTemplate( VMTemplateVO template, String url,
VMTemplateHostVO vmTemplateHost,Long dataCenterId){
if (isTemplateUploadInProgress(template.getId()) ){
return;
Type type = (template.getFormat() == ImageFormat.ISO) ? Type.ISO : Type.TEMPLATE ;
if (isTypeUploadInProgress(template.getId(), type) ){
return; // TO DO raise an exception.
}
List<HostVO> storageServers = _serverDao.listByTypeDataCenter(Host.Type.SecondaryStorage, dataCenterId);
HostVO sserver = storageServers.get(0);
_vmTemplateHostDao.updateUploadStatus(sserver.getId(), template.getId(), 0, VMTemplateStorageResourceAssoc.Status.NOT_UPLOADED, "jobid0000", url);
UploadVO uploadTemplateObj = new UploadVO(sserver.getId(), template.getId(), new Date(),
Upload.Status.NOT_UPLOADED, 0, type,
null, "jobid0000", url);
_uploadDao.persist(uploadTemplateObj);
if(vmTemplateHost != null) {
start();
UploadCommand ucmd = new UploadCommand(template, url, vmTemplateHost);
UploadListener ul = new UploadListener(sserver, template, _timer, _vmTemplateHostDao, vmTemplateHost.getId(), this, ucmd);
_listenerMap.put(vmTemplateHost, ul);
UploadListener ul = new UploadListener(sserver, _timer, _uploadDao, uploadTemplateObj.getId(), this, ucmd, template.getAccountId(), template.getName(), type);//TO DO - remove template
_listenerMap.put(uploadTemplateObj, ul);
long result = send(sserver.getId(), ucmd, ul);
if (result == -1) {
s_logger.warn("Unable to start upload of template " + template.getUniqueName() + " from " + sserver.getName() + " to " +url);
s_logger.warn("Unable to start upload of " + template.getUniqueName() + " from " + sserver.getName() + " to " +url);
ul.setDisconnected();
ul.scheduleStatusCheck(RequestType.GET_OR_RESTART);
}
@ -169,23 +211,39 @@ public class UploadMonitorImpl implements UploadMonitor {
return true;
}
public void handleUploadEvent(HostVO host, VMTemplateVO template, Status upldStatus) {
public String getEvent(Upload.Status status, 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 ((upldStatus == VMTemplateStorageResourceAssoc.Status.UPLOADED) || (upldStatus==Status.ABANDONED)){
VMTemplateHostVO vmTemplateHost = new VMTemplateHostVO(host.getId(), template.getId());
UploadListener oldListener = _listenerMap.get(vmTemplateHost);
if (status == Upload.Status.UPLOAD_ERROR || status == Upload.Status.ABANDONED){
if(type == Type.TEMPLATE) return EventTypes.EVENT_TEMPLATE_UPLOAD_FAILED;
if(type == Type.ISO) return EventTypes.EVENT_ISO_UPLOAD_FAILED;
if(type == Type.VOLUME) return EventTypes.EVENT_VOLUME_UPLOAD_FAILED;
}
return null;
}
public void handleUploadEvent(HostVO host, Long accountId, String typeName, Type type, Long uploadId, com.cloud.storage.Upload.Status reason) {
if ((reason == Upload.Status.UPLOADED) || (reason==Upload.Status.ABANDONED)){
UploadVO uploadObj = new UploadVO(uploadId);
UploadListener oldListener = _listenerMap.get(uploadObj);
if (oldListener != null) {
_listenerMap.remove(vmTemplateHost);
_listenerMap.remove(uploadObj);
}
}
if (upldStatus == VMTemplateStorageResourceAssoc.Status.UPLOADED) {
logEvent(template.getAccountId(), EventTypes.EVENT_TEMPLATE_UPLOAD_SUCCESS, template.getName() + " successfully uploaded from storage server " + host.getName(), EventVO.LEVEL_INFO);
if (reason == Upload.Status.UPLOADED) {
logEvent(accountId, getEvent(reason, type), typeName + " successfully uploaded from storage server " + host.getName(), EventVO.LEVEL_INFO);
}
if (upldStatus == Status.UPLOAD_ERROR) {
logEvent(template.getAccountId(), EventTypes.EVENT_TEMPLATE_UPLOAD_FAILED, template.getName() + " failed to upload from storage server " + host.getName(), EventVO.LEVEL_ERROR);
if (reason == Upload.Status.UPLOAD_ERROR) {
logEvent(accountId, getEvent(reason, type), typeName + " failed to upload from storage server " + host.getName(), EventVO.LEVEL_ERROR);
}
if (upldStatus == Status.ABANDONED) {
logEvent(template.getAccountId(), EventTypes.EVENT_TEMPLATE_UPLOAD_FAILED, template.getName() + " :aborted upload from storage server " + host.getName(), EventVO.LEVEL_WARN);
if (reason == Upload.Status.ABANDONED) {
logEvent(accountId, getEvent(reason, type), typeName + " :aborted upload from storage server " + host.getName(), EventVO.LEVEL_WARN);
}
/*VMTemplateHostVO vmTemplateHost = _vmTemplateHostDao.findByHostTemplate(host.getId(), template.getId());
@ -261,7 +319,7 @@ public class UploadMonitorImpl implements UploadMonitor {
@Override
public void handleUploadTemplateSync(long sserverId, Map<String, TemplateInfo> templateInfo) {
HostVO storageHost = _serverDao.findById(sserverId);
/*HostVO storageHost = _serverDao.findById(sserverId);
if (storageHost == null) {
s_logger.warn("Huh? Agent id " + sserverId + " does not correspond to a row in hosts table?");
return;
@ -300,7 +358,7 @@ public class UploadMonitorImpl implements UploadMonitor {
templateInfo.remove(uniqueName);
continue;
}
/*if (tmpltHost != null && tmpltHost.getUploadState() != Status.UPLOADED) {
if (tmpltHost != null && tmpltHost.getUploadState() != Status.UPLOADED) {
s_logger.info("Template Sync did not find " + uniqueName + " ready on server " + sserverId + ", will request upload to start/resume shortly");
} else if (tmpltHost == null) {
@ -310,5 +368,5 @@ public class UploadMonitorImpl implements UploadMonitor {
}*/
}
}
}

View File

@ -79,6 +79,7 @@
<dao name="UserAccount" class="com.vmops.user.dao.UserAccountDaoImpl"/>
<dao name="Usage IPAddress" class="com.vmops.usage.dao.UsageIPAddressDaoImpl"/>
<dao name="VM Template Host" class="com.vmops.storage.dao.VMTemplateHostDaoImpl"/>
<dao name="Upload" class="com.vmops.storage.dao.UploadDaoImpl"/>
<dao name="VM Template Pool" class="com.vmops.storage.dao.VMTemplatePoolDaoImpl"/>
<dao name="Launch Permission" class="com.vmops.storage.dao.LaunchPermissionDaoImpl"/>
<dao name="Configuration" class="com.vmops.configuration.dao.ConfigurationDaoImpl"/>

4
setup/db/create-index-fk.sql Normal file → Executable file
View File

@ -159,6 +159,10 @@ ALTER TABLE `cloud`.`template_host_ref` ADD INDEX `i_template_host_ref__host_id`
ALTER TABLE `cloud`.`template_host_ref` ADD CONSTRAINT `fk_template_host_ref__template_id` FOREIGN KEY `fk_template_host_ref__template_id` (`template_id`) REFERENCES `vm_template` (`id`) ON DELETE CASCADE;
ALTER TABLE `cloud`.`template_host_ref` ADD INDEX `i_template_host_ref__template_id`(`template_id`);
ALTER TABLE `cloud`.`upload` ADD CONSTRAINT `fk_upload__host_id` FOREIGN KEY `fk_upload__host_id` (`host_id`) REFERENCES `host` (`id`) ON DELETE CASCADE;
ALTER TABLE `cloud`.`upload` ADD INDEX `i_upload__host_id`(`host_id`);
ALTER TABLE `cloud`.`upload` ADD INDEX `i_upload__type_id`(`type_id`);
ALTER TABLE `cloud`.`template_zone_ref` ADD CONSTRAINT `fk_template_zone_ref__zone_id` FOREIGN KEY `fk_template_zone_ref__zone_id` (`zone_id`) REFERENCES `data_center` (`id`) ON DELETE CASCADE;
ALTER TABLE `cloud`.`template_zone_ref` ADD INDEX `i_template_zone_ref__zone_id`(`zone_id`);
ALTER TABLE `cloud`.`template_zone_ref` ADD CONSTRAINT `fk_template_zone_ref__template_id` FOREIGN KEY `fk_template_zone_ref__template_id` (`template_id`) REFERENCES `vm_template` (`id`) ON DELETE CASCADE;

View File

@ -24,6 +24,7 @@ DROP TABLE IF EXISTS `cloud`.`pricing`;
DROP TABLE IF EXISTS `cloud`.`sequence`;
DROP TABLE IF EXISTS `cloud`.`user_vm`;
DROP TABLE IF EXISTS `cloud`.`template_host_ref`;
DROP TABLE IF EXISTS `cloud`.`upload`;
DROP TABLE IF EXISTS `cloud`.`template_zone_ref`;
DROP TABLE IF EXISTS `cloud`.`ha_work`;
DROP TABLE IF EXISTS `cloud`.`dc_vnet_alloc`;
@ -627,6 +628,21 @@ CREATE TABLE `cloud`.`domain_router` (
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET=utf8 COMMENT = 'information about the domR instance';
CREATE TABLE `cloud`.`upload` (
`id` bigint unsigned NOT NULL auto_increment,
`host_id` bigint unsigned NOT NULL,
`type_id` bigint unsigned NOT NULL,
`type` varchar(255),
`created` DATETIME NOT NULL,
`last_updated` DATETIME,
`job_id` varchar(255),
`upload_pct` int(10) unsigned,
`upload_state` varchar(255),
`error_str` varchar(255),
`url` varchar(255),
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`template_host_ref` (
`id` bigint unsigned NOT NULL auto_increment,
`host_id` bigint unsigned NOT NULL,
@ -635,18 +651,13 @@ CREATE TABLE `cloud`.`template_host_ref` (
`created` DATETIME NOT NULL,
`last_updated` DATETIME,
`job_id` varchar(255),
`upload_job_id` varchar(255),
`download_pct` int(10) unsigned,
`upload_pct` int(10) unsigned,
`size` bigint unsigned,
`download_state` varchar(255),
`upload_state` varchar(255),
`error_str` varchar(255),
`upload_error_str` varchar(255),
`local_path` varchar(255),
`install_path` varchar(255),
`url` varchar(255),
`upload_url` varchar(255),
`destroyed` tinyint(1) COMMENT 'indicates whether the template_host entry was destroyed by the user or not',
`is_copy` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'indicates whether this was copied ',
PRIMARY KEY (`id`)