diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 251a496a288..c8ae73f15d1 100755 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -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 diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index db18e25a5a5..83b9938b82b 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -88,6 +88,7 @@ + diff --git a/core/src/com/cloud/agent/api/routing/IPAssocCommand.java b/core/src/com/cloud/agent/api/routing/IPAssocCommand.java index ced18f26737..ec1761a6e5a 100644 --- a/core/src/com/cloud/agent/api/routing/IPAssocCommand.java +++ b/core/src/com/cloud/agent/api/routing/IPAssocCommand.java @@ -29,6 +29,7 @@ public class IPAssocCommand extends RoutingCommand { private String publicIp; private boolean sourceNat; private boolean add; + private boolean oneToOneNat; private boolean firstIP; private String vlanId; private String vlanGateway; @@ -63,6 +64,10 @@ public class IPAssocCommand extends RoutingCommand { return add; } + public boolean isOneToOneNat(){ + return this.oneToOneNat; + } + public boolean isFirstIP() { return firstIP; } diff --git a/core/src/com/cloud/agent/api/storage/UploadAnswer.java b/core/src/com/cloud/agent/api/storage/UploadAnswer.java index 6bcda28d484..c7f13fb4c07 100644 --- a/core/src/com/cloud/agent/api/storage/UploadAnswer.java +++ b/core/src/com/cloud/agent/api/storage/UploadAnswer.java @@ -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; } diff --git a/core/src/com/cloud/agent/api/storage/UploadCommand.java b/core/src/com/cloud/agent/api/storage/UploadCommand.java index f8175bc20d1..a3f0695694b 100644 --- a/core/src/com/cloud/agent/api/storage/UploadCommand.java +++ b/core/src/com/cloud/agent/api/storage/UploadCommand.java @@ -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() { } diff --git a/core/src/com/cloud/event/EventTypes.java b/core/src/com/cloud/event/EventTypes.java old mode 100644 new mode 100755 index 4ad2523f831..b3707663dd6 --- a/core/src/com/cloud/event/EventTypes.java +++ b/core/src/com/cloud/event/EventTypes.java @@ -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"; diff --git a/core/src/com/cloud/server/ManagementServer.java b/core/src/com/cloud/server/ManagementServer.java index 8e5a88f40e2..7f437bf0b08 100755 --- a/core/src/com/cloud/server/ManagementServer.java +++ b/core/src/com/cloud/server/ManagementServer.java @@ -2236,5 +2236,18 @@ public interface ManagementServer { InstanceGroupVO getGroupForVm(long vmId); List searchForZoneWideVlans(long dcId, String vlanType,String vlanId); + + /** + * Extracts the volume to a particular location. + * @param url - the url where the volume needs to be extracted to + * @param zoneId - zone id of the volume + * @param volume id - the id of the volume + * @throws URISyntaxException + * @throws InternalErrorException + * + */ + void extractVolume(String url, Long volumeId, Long zoneId) throws + URISyntaxException, InternalErrorException; + } diff --git a/core/src/com/cloud/storage/StorageManager.java b/core/src/com/cloud/storage/StorageManager.java old mode 100644 new mode 100755 index a731b9be09e..7c249afea6d --- a/core/src/com/cloud/storage/StorageManager.java +++ b/core/src/com/cloud/storage/StorageManager.java @@ -331,4 +331,5 @@ public interface StorageManager extends Manager { VolumeVO allocate(VolumeType type, DiskOfferingVO offering, String name, Long size, VMTemplateVO template, T vm, AccountVO account); void create(T vm); + Long findHostIdForStoragePool(StoragePoolVO pool); } diff --git a/core/src/com/cloud/storage/StorageResource.java b/core/src/com/cloud/storage/StorageResource.java index 209e82d7325..d63883be1b7 100755 --- a/core/src/com/cloud/storage/StorageResource.java +++ b/core/src/com/cloud/storage/StorageResource.java @@ -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); } diff --git a/core/src/com/cloud/storage/Upload.java b/core/src/com/cloud/storage/Upload.java new file mode 100644 index 00000000000..197ef2795b9 --- /dev/null +++ b/core/src/com/cloud/storage/Upload.java @@ -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} +} diff --git a/core/src/com/cloud/storage/UploadVO.java b/core/src/com/cloud/storage/UploadVO.java new file mode 100755 index 00000000000..5f1e6adf3d6 --- /dev/null +++ b/core/src/com/cloud/storage/UploadVO.java @@ -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 . + * + */ + +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; + } + +} diff --git a/core/src/com/cloud/storage/VMTemplateHostVO.java b/core/src/com/cloud/storage/VMTemplateHostVO.java old mode 100644 new mode 100755 index 4393fb8696c..9e6c1e7b2cb --- a/core/src/com/cloud/storage/VMTemplateHostVO.java +++ b/core/src/com/cloud/storage/VMTemplateHostVO.java @@ -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; - } + } diff --git a/core/src/com/cloud/storage/dao/UploadDao.java b/core/src/com/cloud/storage/dao/UploadDao.java new file mode 100644 index 00000000000..78e3da1a397 --- /dev/null +++ b/core/src/com/cloud/storage/dao/UploadDao.java @@ -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 { + + List listByTypeUploadStatus(long typeId, Type type, + Status uploadState); + +} diff --git a/core/src/com/cloud/storage/dao/UploadDaoImpl.java b/core/src/com/cloud/storage/dao/UploadDaoImpl.java new file mode 100755 index 00000000000..225ec33e65f --- /dev/null +++ b/core/src/com/cloud/storage/dao/UploadDaoImpl.java @@ -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 implements UploadDao { + public static final Logger s_logger = Logger.getLogger(UploadDaoImpl.class.getName()); + protected final SearchBuilder 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 listByTypeUploadStatus(long typeId, UploadVO.Type type, UploadVO.Status uploadState) { + SearchCriteria 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); + } + }*/ +} \ No newline at end of file diff --git a/core/src/com/cloud/storage/dao/VMTemplateHostDao.java b/core/src/com/cloud/storage/dao/VMTemplateHostDao.java index 4294322f108..2d21481d69d 100755 --- a/core/src/com/cloud/storage/dao/VMTemplateHostDao.java +++ b/core/src/com/cloud/storage/dao/VMTemplateHostDao.java @@ -42,10 +42,7 @@ public interface VMTemplateHostDao extends GenericDao { List 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 listByTemplateStatus(long templateId, VMTemplateHostVO.Status downloadState); @@ -58,6 +55,5 @@ public interface VMTemplateHostDao extends GenericDao { List listDestroyed(long hostId); boolean templateAvailable(long templateId, long hostId); - - List listByTemplateUploadStatus(long templateId,Status UploadState); + } diff --git a/core/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java b/core/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java index abb9242d940..c584539c99e 100755 --- a/core/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java +++ b/core/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java @@ -50,25 +50,16 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase HostTemplatePoolSearch; protected final SearchBuilder TemplateStatusSearch; protected final SearchBuilder TemplateStatesSearch; - protected final SearchBuilder 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 listByHostId(long id) { @@ -202,13 +164,7 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase listByTemplateUploadStatus(long templateId, VMTemplateHostVO.Status uploadState) { - SearchCriteria sc = TemplateUploadStatusSearch.create(); - sc.setParameters("template_id", templateId); - sc.setParameters("upload_state", uploadState.toString()); - return listBy(sc); - } + @Override public List listByTemplateStatus(long templateId, VMTemplateHostVO.Status downloadState) { diff --git a/core/src/com/cloud/storage/template/FtpTemplateUploader.java b/core/src/com/cloud/storage/template/FtpTemplateUploader.java index 01c96e965bc..736df550de1 100644 --- a/core/src/com/cloud/storage/template/FtpTemplateUploader.java +++ b/core/src/com/cloud/storage/template/FtpTemplateUploader.java @@ -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 { diff --git a/core/src/com/cloud/storage/template/UploadManager.java b/core/src/com/cloud/storage/template/UploadManager.java index b2728af111d..df096235c85 100644 --- a/core/src/com/cloud/storage/template/UploadManager.java +++ b/core/src/com/cloud/storage/template/UploadManager.java @@ -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 diff --git a/core/src/com/cloud/storage/template/UploadManagerImpl.java b/core/src/com/cloud/storage/template/UploadManagerImpl.java index a20a8b77431..c0841e1489a 100644 --- a/core/src/com/cloud/storage/template/UploadManagerImpl.java +++ b/core/src/com/cloud/storage/template/UploadManagerImpl.java @@ -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)); diff --git a/server/src/com/cloud/api/BaseCmd.java b/server/src/com/cloud/api/BaseCmd.java old mode 100644 new mode 100755 index fc8bcb4cbfe..f5fc17f9ab8 --- a/server/src/com/cloud/api/BaseCmd.java +++ b/server/src/com/cloud/api/BaseCmd.java @@ -281,6 +281,7 @@ public abstract class BaseCmd { OS_TYPE_ID("ostypeid", BaseCmd.TYPE_LONG, "osTypeId"), OS_TYPE_NAME("ostypename", BaseCmd.TYPE_STRING, "osTypeName"), OP("op", BaseCmd.TYPE_STRING, "op"), + ONE_TO_ONE_NAT("onetoonenat",BaseCmd.TYPE_BOOLEAN,"oneToOneNat"), PAGE("page", BaseCmd.TYPE_INT, "page"), PAGESIZE("pagesize", BaseCmd.TYPE_INT, "pagesize"), PARENT_ID("parentid", BaseCmd.TYPE_LONG, "parentId"), @@ -344,6 +345,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"), diff --git a/server/src/com/cloud/api/commands/AssociateIPAddrCmd.java b/server/src/com/cloud/api/commands/AssociateIPAddrCmd.java index a4c06429d3a..c4a2da97eae 100644 --- a/server/src/com/cloud/api/commands/AssociateIPAddrCmd.java +++ b/server/src/com/cloud/api/commands/AssociateIPAddrCmd.java @@ -48,7 +48,8 @@ public class AssociateIPAddrCmd extends BaseCmd { s_properties.add(new Pair(BaseCmd.Properties.DOMAIN_ID, Boolean.FALSE)); s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE)); s_properties.add(new Pair(BaseCmd.Properties.USER_ID, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.ZONE_ID, Boolean.TRUE)); + s_properties.add(new Pair(BaseCmd.Properties.ZONE_ID, Boolean.TRUE)); + s_properties.add(new Pair(BaseCmd.Properties.ONE_TO_ONE_NAT, Boolean.FALSE)); } public String getName() { diff --git a/server/src/com/cloud/api/commands/ExtractIsoCmd.java b/server/src/com/cloud/api/commands/ExtractIsoCmd.java new file mode 100644 index 00000000000..6ef13c121ea --- /dev/null +++ b/server/src/com/cloud/api/commands/ExtractIsoCmd.java @@ -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> s_properties = new ArrayList>(); + + static { + s_properties.add(new Pair(BaseCmd.Properties.URL, Boolean.TRUE)); + s_properties.add(new Pair(BaseCmd.Properties.ID, Boolean.TRUE)); + s_properties.add(new Pair(BaseCmd.Properties.ZONE_ID, Boolean.TRUE)); + s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE)); + } + + @Override + public List> execute(Map 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> response = new ArrayList>(); + response.add(new Pair(BaseCmd.Properties.TEMPLATE_ID.getName(), templateId)); + response.add(new Pair(BaseCmd.Properties.NAME.getName(), template.getName())); + response.add(new Pair(BaseCmd.Properties.DISPLAY_TEXT.getName(), template.getDisplayText())); + response.add(new Pair(BaseCmd.Properties.URL.getName(), url)); + response.add(new Pair(BaseCmd.Properties.ZONE_ID.getName(), zoneId)); + response.add(new Pair(BaseCmd.Properties.ZONE_NAME.getName(), zone.getName())); + response.add(new Pair(BaseCmd.Properties.TEMPLATE_STATUS.getName(), "Processing")); + return response; + + } + + @Override + public String getName() { + return s_name; + } + + @Override + public List> getProperties() { + return s_properties; + } +} diff --git a/server/src/com/cloud/api/commands/ExtractTemplateCmd.java b/server/src/com/cloud/api/commands/ExtractTemplateCmd.java old mode 100644 new mode 100755 index a73c291bbcd..a7a5d55799a --- a/server/src/com/cloud/api/commands/ExtractTemplateCmd.java +++ b/server/src/com/cloud/api/commands/ExtractTemplateCmd.java @@ -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://")){ diff --git a/server/src/com/cloud/api/commands/ExtractVolumeCmd.java b/server/src/com/cloud/api/commands/ExtractVolumeCmd.java new file mode 100644 index 00000000000..6ae13327925 --- /dev/null +++ b/server/src/com/cloud/api/commands/ExtractVolumeCmd.java @@ -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> s_properties = new ArrayList>(); + + static { + s_properties.add(new Pair(BaseCmd.Properties.URL, Boolean.TRUE)); + s_properties.add(new Pair(BaseCmd.Properties.ID, Boolean.TRUE)); + s_properties.add(new Pair(BaseCmd.Properties.ZONE_ID, Boolean.TRUE)); + s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE)); + } + + @Override + public List> execute(Map 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> response = new ArrayList>(); + response.add(new Pair(BaseCmd.Properties.VOLUME_ID.getName(), volumeId)); + response.add(new Pair(BaseCmd.Properties.VOLUME_NAME.getName(), volume.getName())); + response.add(new Pair(BaseCmd.Properties.URL.getName(), url)); + response.add(new Pair(BaseCmd.Properties.ZONE_ID.getName(), zoneId)); + response.add(new Pair(BaseCmd.Properties.ZONE_NAME.getName(), zone.getName())); + response.add(new Pair(BaseCmd.Properties.STATUS.getName(), "Processing")); + return response; + } + + @Override + public String getName() { + return s_name; + } + + @Override + public List> getProperties() { + return s_properties; + } + +} diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index 851e3068772..35a63ae5bc2 100644 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -424,7 +424,7 @@ public class ConfigurationServerImpl implements ConfigurationServer { throw new RuntimeException("No home directory was detected. Set the HOME environment variable to point to your user profile or home directory."); } - String keygenOutput = Script.runSimpleBashScript("if [ -f ~/.ssh/id_rsa ] ; then true ; else yes '' | ssh-keygen -t rsa -q -O no-pty ; fi"); + String keygenOutput = Script.runSimpleBashScript("if [ -f ~/.ssh/id_rsa ] ; then true ; else yes '' | ssh-keygen -t rsa -q ; fi"); File privkeyfile = new File(homeDir + "/.ssh/id_rsa"); File pubkeyfile = new File(homeDir + "/.ssh/id_rsa.pub"); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index b8139961922..fc795f6de15 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -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{ diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java old mode 100644 new mode 100755 index 4f8176eada9..944f632518a --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -423,7 +423,8 @@ public class StorageManagerImpl implements StorageManager { return null; } - protected Long findHostIdForStoragePool(StoragePoolVO pool) { + @Override + public Long findHostIdForStoragePool(StoragePoolVO pool) { List poolHosts = _poolHostDao.listByHostStatus(pool.getId(), Status.Up); if (poolHosts.size() == 0) { diff --git a/server/src/com/cloud/storage/upload/UploadAbandonedState.java b/server/src/com/cloud/storage/upload/UploadAbandonedState.java index 3b51bd0a14d..ac3fa03ad64 100644 --- a/server/src/com/cloud/storage/upload/UploadAbandonedState.java +++ b/server/src/com/cloud/storage/upload/UploadAbandonedState.java @@ -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 { diff --git a/server/src/com/cloud/storage/upload/UploadCompleteState.java b/server/src/com/cloud/storage/upload/UploadCompleteState.java index 1d433b3fce2..4973e79187d 100644 --- a/server/src/com/cloud/storage/upload/UploadCompleteState.java +++ b/server/src/com/cloud/storage/upload/UploadCompleteState.java @@ -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 { diff --git a/server/src/com/cloud/storage/upload/UploadErrorState.java b/server/src/com/cloud/storage/upload/UploadErrorState.java index 185c0633b28..5fd872e6580 100644 --- a/server/src/com/cloud/storage/upload/UploadErrorState.java +++ b/server/src/com/cloud/storage/upload/UploadErrorState.java @@ -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 { diff --git a/server/src/com/cloud/storage/upload/UploadListener.java b/server/src/com/cloud/storage/upload/UploadListener.java old mode 100644 new mode 100755 index 73033de96b4..8fd0279dfc2 --- a/server/src/com/cloud/storage/upload/UploadListener.java +++ b/server/src/com/cloud/storage/upload/UploadListener.java @@ -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 stateMap = new HashMap(); - 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) { diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java old mode 100644 new mode 100755 index 9f1f77e0f70..759c30b0fdf --- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java +++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java @@ -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 _listenerMap = new ConcurrentHashMap(); + final Map _listenerMap = new ConcurrentHashMap(); @Override public void cancelAllUploads(Long templateId) { // TODO Auto-generated method stub - } - public boolean isTemplateUploadInProgress(Long templateId) { - List uploadsInProgress = - _vmTemplateHostDao.listByTemplateStatus(templateId, VMTemplateHostVO.Status.UPLOAD_IN_PROGRESS); + } + + private boolean isTypeUploadInProgress(Long typeId, Type type) { + List 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 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 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 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 { }*/ } - } + } diff --git a/server/test/async-job-component.xml b/server/test/async-job-component.xml index 03f23bd17a9..38602dc3e92 100644 --- a/server/test/async-job-component.xml +++ b/server/test/async-job-component.xml @@ -79,6 +79,7 @@ + diff --git a/setup/db/create-index-fk.sql b/setup/db/create-index-fk.sql old mode 100644 new mode 100755 index 5b80a2cabc6..66ab9628e48 --- a/setup/db/create-index-fk.sql +++ b/setup/db/create-index-fk.sql @@ -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; diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index c9b225ca384..3898c7fe3cf 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -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`) diff --git a/ui/new/css/main.css b/ui/new/css/main.css index 24058dc9571..872d7cc4068 100644 --- a/ui/new/css/main.css +++ b/ui/new/css/main.css @@ -1381,6 +1381,7 @@ a:visited { padding:0; } + .searchpanel { width:223px; height:27px; @@ -2179,6 +2180,34 @@ a:visited { padding:0 0 0 0; } +.grid_botactionpanel { + width:100%; + height:23px; + float:left; + margin:15px 0 0 0; + padding:0 0 0 0; +} + +.gridbot_buttons { + width:64px; + height:17px; + float:left; + color:#FFF; + background:url(../images/gridbot_actionbutton.gif) no-repeat top left; + text-align:center; + font-weight:normal; + font-size:12px; + margin:0 10px 0 0; + padding:4px 0 0 0; + cursor:pointer; + cursor:hand; +} + +.gridbot_buttons:hover { + background:url(../images/gridbot_actionbutton_hover.gif) no-repeat top left; +} + + .grid_actionbox { width:35px; height:17px; diff --git a/ui/new/images/gridbot_actionbutton.gif b/ui/new/images/gridbot_actionbutton.gif new file mode 100644 index 00000000000..05a3a84d8dd Binary files /dev/null and b/ui/new/images/gridbot_actionbutton.gif differ diff --git a/ui/new/images/gridbot_actionbutton_hover.gif b/ui/new/images/gridbot_actionbutton_hover.gif new file mode 100644 index 00000000000..f4bb2736f62 Binary files /dev/null and b/ui/new/images/gridbot_actionbutton_hover.gif differ diff --git a/ui/new/index.jsp b/ui/new/index.jsp index f3a3b430569..14abb69651d 100644 --- a/ui/new/index.jsp +++ b/ui/new/index.jsp @@ -54,6 +54,8 @@ long milliseconds = new Date().getTime(); + + Cloud.com CloudStack diff --git a/ui/new/jsp/account.jsp b/ui/new/jsp/account.jsp index ff73aa49790..2eceeda534e 100644 --- a/ui/new/jsp/account.jsp +++ b/ui/new/jsp/account.jsp @@ -1,149 +1,146 @@ - - - -<%@ page import="java.util.*" %> -<%@ page import="com.cloud.utils.*" %> - -<% - - Locale browserLocale = request.getLocale(); - CloudResourceBundle t = CloudResourceBundle.getBundle("resources/resource", browserLocale); -%> - - -
-
- Accounts
-

Accounts

-
- -
- -
-
- <%=t.t("Details")%>
-
-
- -
- - -
-

Disk has been succesfully dettached …

-
-
- - -
-
-
-
-
- <%=t.t("id")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Role")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Account")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Domain")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("VMs")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("IPs")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Bytes.Received")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Bytes.Sent")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("State")%>:
-
-
-
-
-
-
-
-
- - \ No newline at end of file +<%@ page import="java.util.*" %> + +<%@ page import="com.cloud.utils.*" %> + +<% + Locale browserLocale = request.getLocale(); + CloudResourceBundle t = CloudResourceBundle.getBundle("resources/resource", browserLocale); +%> + +
+
+ Accounts
+

+ Accounts

+
+
+ +
+
+ <%=t.t("Details")%>
+
+
+
+ +
+
+
+
+
+

+ Detaching Disk …

+
+ +
+
+
+
+
+ <%=t.t("id")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Role")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Account")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Domain")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("VMs")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("IPs")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Bytes.Received")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Bytes.Sent")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("State")%>:
+
+
+
+
+
+
+
+
+
+ diff --git a/ui/new/jsp/alert.jsp b/ui/new/jsp/alert.jsp index 7879ff56c5a..ce1c4cee77f 100644 --- a/ui/new/jsp/alert.jsp +++ b/ui/new/jsp/alert.jsp @@ -1,12 +1,7 @@ - - <%@ page import="java.util.*" %> <%@ page import="com.cloud.utils.*" %> <% - Locale browserLocale = request.getLocale(); CloudResourceBundle t = CloudResourceBundle.getBundle("resources/resource", browserLocale); %> diff --git a/ui/new/jsp/event.jsp b/ui/new/jsp/event.jsp index 563ab2973c5..f63d11d6aca 100644 --- a/ui/new/jsp/event.jsp +++ b/ui/new/jsp/event.jsp @@ -1,12 +1,7 @@ - - <%@ page import="java.util.*" %> <%@ page import="com.cloud.utils.*" %> <% - Locale browserLocale = request.getLocale(); CloudResourceBundle t = CloudResourceBundle.getBundle("resources/resource", browserLocale); %> diff --git a/ui/new/jsp/ip_address.jsp b/ui/new/jsp/ip_address.jsp index 56aa7a927bd..ec5a18072e5 100644 --- a/ui/new/jsp/ip_address.jsp +++ b/ui/new/jsp/ip_address.jsp @@ -1,326 +1,382 @@ -<%@ page import="java.util.*" %> -<%@ page import="com.cloud.utils.*" %> - -<% - - Locale browserLocale = request.getLocale(); - CloudResourceBundle t = CloudResourceBundle.getBundle("resources/resource", browserLocale); -%> - - -
- -
- IP Address
- -

IP Address -

-
-
- -
-
- <%=t.t("Details")%>
-
- <%=t.t("Port Forwarding")%>
-
- <%=t.t("Load Balancer")%>
-
-
-
-
-
- -
-
-
-
- IP:
-
-
-
-
-
-
-
-
-
- Zone:
-
-
-
-
-
-
-
-
-
- VLAN:
-
-
-
-
-
-
-
-
-
- <%=t.t("Level")%>:
-
-
-
-
-
-
-
-
-
- Source NAT:
-
-
-
-
-
-
-
-
-
- Network Type:
-
-
-
-
-
-
-
-
-
- Domain:
-
-
-
-
-
-
-
-
-
- Account:
-
-
-
-
-
-
-
-
-
- Allocated:
-
-
-
-
-
-
-
- - - -
-
-
-
Public Port
-
-
-
Private Port
-
-
-
Protocol
-
-
-
Instance
-
-
- - - -
-
- -
-
- -
-
- -
-
- -
-
- -
- -
- -
-
-
8080
-
-
-
80
-
-
-
8 GB
-
-
-
Instance Name
-
- - -
- -
-
-
8080
-
-
-
80
-
-
-
8 GB
-
-
-
Instance Name
-
- -
-
- - - - -
-
-
-
Name
-
-
-
Public Port
-
-
-
Private Port
-
-
-
Algorithm
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
- -
- -
-
-
LB#1
-
-
-
8080
-
-
-
80
-
-
-
Source
-
-
-
-
-
-
-
-
-
- -
- -
- -
-
-
-
-
-
-
-
1-2-2-TEST
-
- -
- -
-
- -
-
-
-
-
-
1-2-2-TEST
-
- -
- -
-
-
-
-
- -
-
-
LB#1
-
-
-
8080
-
-
-
80
-
-
-
Source
-
- - -
- -
- -
- \ No newline at end of file +<%@ page import="java.util.*" %> + +<%@ page import="com.cloud.utils.*" %> + +<% + Locale browserLocale = request.getLocale(); + CloudResourceBundle t = CloudResourceBundle.getBundle("resources/resource", browserLocale); +%> + +
+
+ IP Address
+

+ IP Address +

+
+
+ +
+
+ <%=t.t("Details")%>
+
+ <%=t.t("Port Forwarding")%>
+
+ <%=t.t("Load Balancer")%>
+
+
+
+ +
+
+
+
+
+

+ Detaching Disk …

+
+ +
+
+
+
+
+ IP:
+
+
+
+
+
+
+
+
+
+ Zone:
+
+
+
+
+
+
+
+
+
+ VLAN:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Level")%>:
+
+
+
+
+
+
+
+
+
+ Source NAT:
+
+
+
+
+
+
+
+
+
+ Network Type:
+
+
+
+
+
+
+
+
+
+ Domain:
+
+
+
+
+
+
+
+
+
+ Account:
+
+
+
+
+
+
+
+
+
+ Allocated:
+
+
+
+
+
+
+
+
+ + + + + + + +
+ diff --git a/ui/new/jsp/iso.jsp b/ui/new/jsp/iso.jsp index 57f68875187..cb730cf7e7b 100644 --- a/ui/new/jsp/iso.jsp +++ b/ui/new/jsp/iso.jsp @@ -1,127 +1,149 @@ - - -<%@ page import="java.util.*" %> -<%@ page import="com.cloud.utils.*" %> - -<% - - Locale browserLocale = request.getLocale(); - CloudResourceBundle t = CloudResourceBundle.getBundle("resources/resource", browserLocale); -%> - - -
- -
- ISO
- -

ISO -

-
-
- -
-
- <%=t.t("Details")%>
-
-
-
-
-
- <%=t.t("ID")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Zone")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Name")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Display.Text")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Status")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Bootable")%>:
-
-
-
-
-
-
-
-
-
-
-
- <%=t.t("Account")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Created")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Size")%>:
-
-
-
-
-
-
- -
-
- \ No newline at end of file +<%@ page import="java.util.*" %> + +<%@ page import="com.cloud.utils.*" %> + +<% + Locale browserLocale = request.getLocale(); + CloudResourceBundle t = CloudResourceBundle.getBundle("resources/resource", browserLocale); +%> + +
+
+ ISO
+

+ ISO +

+
+
+ +
+
+ <%=t.t("Details")%>
+
+
+
+ +
+
+
+
+
+

+ Detaching Disk …

+
+ +
+
+
+
+
+ <%=t.t("ID")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Zone")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Name")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Display.Text")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Status")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Bootable")%>:
+
+
+
+
+
+
+
+
+
+
+
+ <%=t.t("Account")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Created")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Size")%>:
+
+
+
+
+
+
+
+
+
+ diff --git a/ui/new/jsp/router.jsp b/ui/new/jsp/router.jsp new file mode 100644 index 00000000000..26433f65969 --- /dev/null +++ b/ui/new/jsp/router.jsp @@ -0,0 +1,159 @@ +<%@ page import="java.util.*" %> + +<%@ page import="com.cloud.utils.*" %> + +<% + Locale browserLocale = request.getLocale(); + CloudResourceBundle t = CloudResourceBundle.getBundle("resources/resource", browserLocale); +%> + +
+ +

+ Router +

+
+
+ +
+
+ <%=t.t("Details")%>
+
+
+
+ +
+
+
+
+
+

+ Detaching Disk …

+
+ +
+
+
+
+
+ <%=t.t("Status")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Zone")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Name")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Public IP")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Private IP")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Guest IP")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Host")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Network Domain")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Account")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Created")%>:
+
+
+
+
+
+
+
+
+
+ diff --git a/ui/new/jsp/snapshot.jsp b/ui/new/jsp/snapshot.jsp index 107cdf24fde..eada1550537 100644 --- a/ui/new/jsp/snapshot.jsp +++ b/ui/new/jsp/snapshot.jsp @@ -1,104 +1,127 @@ - - -<%@ page import="java.util.*" %> -<%@ page import="com.cloud.utils.*" %> - -<% - - Locale browserLocale = request.getLocale(); - CloudResourceBundle t = CloudResourceBundle.getBundle("resources/resource", browserLocale); -%> - - -
- -
- Instance
- -

Snapshot -

-
-
- -
-
- <%=t.t("Details")%>
-
-
-
-
-
- <%=t.t("ID")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Name")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Volume")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Interval.Type")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Created")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Account")%>:
-
-
-
-
-
-
-
-
-
- <%=t.t("Domain")%>:
-
-
-
-
-
-
-
-
- \ No newline at end of file +<%@ page import="java.util.*" %> + +<%@ page import="com.cloud.utils.*" %> + +<% + Locale browserLocale = request.getLocale(); + CloudResourceBundle t = CloudResourceBundle.getBundle("resources/resource", browserLocale); +%> + +
+
+ Instance
+

+ Snapshot +

+
+
+ +
+
+ <%=t.t("Details")%>
+
+
+
+ +
+
+
+
+
+

+ Detaching Disk …

+
+ +
+
+
+
+
+ <%=t.t("ID")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Name")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Volume")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Interval.Type")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Created")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Account")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("Domain")%>:
+
+
+
+
+
+
+
+
+
+ diff --git a/ui/new/jsp/template.jsp b/ui/new/jsp/template.jsp index 45db59599f5..5d1b92a84fa 100644 --- a/ui/new/jsp/template.jsp +++ b/ui/new/jsp/template.jsp @@ -1,172 +1,206 @@ - - <%@ page import="java.util.*" %> + <%@ page import="com.cloud.utils.*" %> <% - Locale browserLocale = request.getLocale(); CloudResourceBundle t = CloudResourceBundle.getBundle("resources/resource", browserLocale); %> -
-
Instance
- -

Template +

+ Template

-