From bd4508589bac8c09841416ae2202682983479599 Mon Sep 17 00:00:00 2001 From: Chip Childers Date: Fri, 8 Mar 2013 14:28:23 -0500 Subject: [PATCH 01/16] Revert "CLOUDSTACK-874 Ability to delete Events and Alerts" This reverts commit 5e4c2c8a9eb339fb467aea15582a79cd2feef4bf. --- api/src/com/cloud/alert/Alert.java | 1 - api/src/com/cloud/event/Event.java | 1 - .../com/cloud/server/ManagementService.java | 38 +--- .../apache/cloudstack/api/ApiConstants.java | 1 - client/tomcatconf/commands.properties.in | 4 - core/src/com/cloud/alert/AlertVO.java | 38 ++-- core/src/com/cloud/event/EventVO.java | 163 +++++++++--------- core/src/com/cloud/event/dao/EventDao.java | 5 - .../src/com/cloud/event/dao/EventDaoImpl.java | 71 ++------ server/src/com/cloud/alert/dao/AlertDao.java | 7 - .../src/com/cloud/alert/dao/AlertDaoImpl.java | 85 --------- server/src/com/cloud/api/ApiDispatcher.java | 6 +- .../com/cloud/api/query/QueryManagerImpl.java | 3 - .../com/cloud/api/query/vo/EventJoinVO.java | 9 - .../src/com/cloud/configuration/Config.java | 5 +- .../cloud/server/ManagementServerImpl.java | 109 +----------- setup/db/db/schema-410to420.sql | 45 ----- 17 files changed, 118 insertions(+), 473 deletions(-) diff --git a/api/src/com/cloud/alert/Alert.java b/api/src/com/cloud/alert/Alert.java index 31768cf193d..050f97f2ef3 100644 --- a/api/src/com/cloud/alert/Alert.java +++ b/api/src/com/cloud/alert/Alert.java @@ -30,5 +30,4 @@ public interface Alert extends Identity, InternalIdentity { Date getCreatedDate(); Date getLastSent(); Date getResolved(); - boolean getArchived(); } diff --git a/api/src/com/cloud/event/Event.java b/api/src/com/cloud/event/Event.java index b8def4c6281..1a61636828a 100644 --- a/api/src/com/cloud/event/Event.java +++ b/api/src/com/cloud/event/Event.java @@ -40,5 +40,4 @@ public interface Event extends ControlledEntity, Identity, InternalIdentity { String getLevel(); long getStartId(); String getParameters(); - boolean getArchived(); } diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java index 1e6ca8d0b67..1736da3778c 100755 --- a/api/src/com/cloud/server/ManagementService.java +++ b/api/src/com/cloud/server/ManagementService.java @@ -29,8 +29,6 @@ import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd; import org.apache.cloudstack.api.command.admin.host.ListHostsCmd; import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd; import org.apache.cloudstack.api.command.admin.pod.ListPodsByCmd; -import org.apache.cloudstack.api.command.admin.resource.ArchiveAlertsCmd; -import org.apache.cloudstack.api.command.admin.resource.DeleteAlertsCmd; import org.apache.cloudstack.api.command.admin.resource.ListAlertsCmd; import org.apache.cloudstack.api.command.admin.resource.ListCapacityCmd; import org.apache.cloudstack.api.command.admin.resource.UploadCustomCertificateCmd; @@ -42,12 +40,12 @@ import org.apache.cloudstack.api.command.admin.systemvm.UpgradeSystemVMCmd; import org.apache.cloudstack.api.command.admin.vlan.ListVlanIpRangesCmd; import org.apache.cloudstack.api.command.user.address.ListPublicIpAddressesCmd; import org.apache.cloudstack.api.command.user.config.ListCapabilitiesCmd; -import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd; -import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd; import org.apache.cloudstack.api.command.user.guest.ListGuestOsCategoriesCmd; import org.apache.cloudstack.api.command.user.guest.ListGuestOsCmd; import org.apache.cloudstack.api.command.user.iso.ListIsosCmd; import org.apache.cloudstack.api.command.user.iso.UpdateIsoCmd; +import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd; +import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd; import org.apache.cloudstack.api.command.user.ssh.CreateSSHKeyPairCmd; import org.apache.cloudstack.api.command.user.ssh.DeleteSSHKeyPairCmd; import org.apache.cloudstack.api.command.user.ssh.ListSSHKeyPairsCmd; @@ -57,10 +55,12 @@ import org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd; import org.apache.cloudstack.api.command.user.vm.GetVMPasswordCmd; import org.apache.cloudstack.api.command.user.vmgroup.UpdateVMGroupCmd; import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd; +import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd; import com.cloud.alert.Alert; import com.cloud.capacity.Capacity; import com.cloud.configuration.Configuration; +import com.cloud.dc.DataCenter; import com.cloud.dc.Pod; import com.cloud.dc.Vlan; import com.cloud.domain.Domain; @@ -72,6 +72,8 @@ import com.cloud.host.Host; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.HypervisorCapabilities; import com.cloud.network.IpAddress; +import com.cloud.offering.DiskOffering; +import com.cloud.offering.ServiceOffering; import com.cloud.org.Cluster; import com.cloud.storage.GuestOS; import com.cloud.storage.GuestOsCategory; @@ -192,34 +194,6 @@ public interface ManagementService { */ Pair, Integer> searchForAlerts(ListAlertsCmd cmd); - /** - * Archive alerts - * @param cmd - * @return True on success. False otherwise. - */ - boolean archiveAlerts(ArchiveAlertsCmd cmd); - - /** - * Delete alerts - * @param cmd - * @return True on success. False otherwise. - */ - boolean deleteAlerts(DeleteAlertsCmd cmd); - - /** - * Archive events - * @param cmd - * @return True on success. False otherwise. - */ - boolean archiveEvents(ArchiveEventsCmd cmd); - - /** - * Delete events - * @param cmd - * @return True on success. False otherwise. - */ - boolean deleteEvents(DeleteEventsCmd cmd); - /** * list all the capacity rows in capacity operations table * diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index b40b26ce57c..1b544fd1641 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -459,7 +459,6 @@ public class ApiConstants { public static final String UCS_BLADE_DN = "bladedn"; public static final String UCS_BLADE_ID = "bladeid"; public static final String VM_GUEST_IP = "vmguestip"; - public static final String OLDER_THAN = "olderthan"; public enum HostDetails { all, capacity, events, stats, min; diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 5018236e5e2..dd0c3f894fd 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -218,13 +218,9 @@ listZones=15 #### events commands listEvents=15 listEventTypes=15 -archiveEvents=15 -deleteEvents=15 #### alerts commands listAlerts=3 -archiveAlerts=1 -deleteAlerts=1 #### system capacity commands listCapacity=3 diff --git a/core/src/com/cloud/alert/AlertVO.java b/core/src/com/cloud/alert/AlertVO.java index 3f014aa2b1f..f6089d65043 100755 --- a/core/src/com/cloud/alert/AlertVO.java +++ b/core/src/com/cloud/alert/AlertVO.java @@ -28,7 +28,9 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; +import org.apache.cloudstack.api.Identity; import com.cloud.utils.db.GenericDao; +import org.apache.cloudstack.api.InternalIdentity; @Entity @Table(name="alert") @@ -66,19 +68,16 @@ public class AlertVO implements Alert { @Temporal(TemporalType.TIMESTAMP) @Column(name="resolved", updatable=true, nullable=true) private Date resolved; - + @Column(name="uuid") private String uuid; - @Column(name="archived") - private boolean archived; - public AlertVO() { - this.uuid = UUID.randomUUID().toString(); + this.uuid = UUID.randomUUID().toString(); } public AlertVO(Long id) { this.id = id; - this.uuid = UUID.randomUUID().toString(); + this.uuid = UUID.randomUUID().toString(); } @Override @@ -104,12 +103,12 @@ public class AlertVO implements Alert { } public Long getClusterId() { - return clusterId; - } - public void setClusterId(Long clusterId) { - this.clusterId = clusterId; - } - @Override + return clusterId; + } + public void setClusterId(Long clusterId) { + this.clusterId = clusterId; + } + @Override public Long getPodId() { return podId; } @@ -165,19 +164,10 @@ public class AlertVO implements Alert { @Override public String getUuid() { - return this.uuid; + return this.uuid; } - + public void setUuid(String uuid) { - this.uuid = uuid; - } - - @Override - public boolean getArchived() { - return archived; - } - - public void setArchived(Boolean archived) { - this.archived = archived; + this.uuid = uuid; } } diff --git a/core/src/com/cloud/event/EventVO.java b/core/src/com/cloud/event/EventVO.java index 2c30eadebdc..ac46f24b2ee 100644 --- a/core/src/com/cloud/event/EventVO.java +++ b/core/src/com/cloud/event/EventVO.java @@ -29,75 +29,74 @@ import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Transient; +import org.apache.cloudstack.api.Identity; import com.cloud.utils.db.GenericDao; +import org.apache.cloudstack.api.InternalIdentity; @Entity @Table(name="event") public class EventVO implements Event { - @Id + @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") - private long id = -1; + private long id = -1; - @Column(name="type") - private String type; - - @Enumerated(value=EnumType.STRING) - @Column(name="state") + @Column(name="type") + private String type; + + @Enumerated(value=EnumType.STRING) + @Column(name="state") private State state = State.Completed; - @Column(name="description", length=1024) - private String description; + @Column(name="description", length=1024) + private String description; - @Column(name=GenericDao.CREATED_COLUMN) - private Date createDate; + @Column(name=GenericDao.CREATED_COLUMN) + private Date createDate; @Column(name="user_id") private long userId; - @Column(name="account_id") - private long accountId; + @Column(name="account_id") + private long accountId; @Column(name="domain_id") private long domainId; - @Column(name="level") - private String level = LEVEL_INFO; - - @Column(name="start_id") + @Column(name="level") + private String level = LEVEL_INFO; + + @Column(name="start_id") private long startId; - @Column(name="parameters", length=1024) - private String parameters; + @Column(name="parameters", length=1024) + private String parameters; + + @Column(name="uuid") + private String uuid; - @Column(name="uuid") - private String uuid; + @Transient + private int totalSize; - @Column(name="archived") - private boolean archived; - - @Transient - private int totalSize; - - public static final String LEVEL_INFO = "INFO"; - public static final String LEVEL_WARN = "WARN"; - public static final String LEVEL_ERROR = "ERROR"; - - public EventVO() { - this.uuid = UUID.randomUUID().toString(); - } - - public long getId() { - return id; - } - @Override + public static final String LEVEL_INFO = "INFO"; + public static final String LEVEL_WARN = "WARN"; + public static final String LEVEL_ERROR = "ERROR"; + + public EventVO() { + this.uuid = UUID.randomUUID().toString(); + } + + public long getId() { + return id; + } + @Override public String getType() { - return type; - } - public void setType(String type) { - this.type = type; - } - @Override + return type; + } + public void setType(String type) { + this.type = type; + } + @Override public State getState() { return state; } @@ -106,27 +105,27 @@ public class EventVO implements Event { this.state = state; } - @Override + @Override public String getDescription() { - return description; - } - public void setDescription(String description) { - this.description = description; - } - @Override + return description; + } + public void setDescription(String description) { + this.description = description; + } + @Override public Date getCreateDate() { - return createDate; - } - public void setCreatedDate(Date createdDate) { - createDate = createdDate; - } - @Override + return createDate; + } + public void setCreatedDate(Date createdDate) { + createDate = createdDate; + } + @Override public long getUserId() { - return userId; - } - public void setUserId(long userId) { - this.userId = userId; - } + return userId; + } + public void setUserId(long userId) { + this.userId = userId; + } @Override public long getAccountId() { return accountId; @@ -166,29 +165,21 @@ public class EventVO implements Event { this.startId = startId; } - @Override + @Override public String getParameters() { - return parameters; - } - public void setParameters(String parameters) { - this.parameters = parameters; - } + return parameters; + } + public void setParameters(String parameters) { + this.parameters = parameters; + } + + @Override + public String getUuid() { + return this.uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } - @Override - public String getUuid() { - return this.uuid; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - - @Override - public boolean getArchived() { - return archived; - } - - public void setArchived(Boolean archived) { - this.archived = archived; - } } diff --git a/core/src/com/cloud/event/dao/EventDao.java b/core/src/com/cloud/event/dao/EventDao.java index da5f47a90b4..bfcb818f20f 100644 --- a/core/src/com/cloud/event/dao/EventDao.java +++ b/core/src/com/cloud/event/dao/EventDao.java @@ -30,9 +30,4 @@ public interface EventDao extends GenericDao { public List listOlderEvents(Date oldTime); EventVO findCompletedEvent(long startId); - - public List listToArchiveOrDeleteEvents(List ids, String type, Date olderThan, Long accountId); - - public void archiveEvents(List events); - } diff --git a/core/src/com/cloud/event/dao/EventDaoImpl.java b/core/src/com/cloud/event/dao/EventDaoImpl.java index 6ba59c56b0a..44fbb030dcc 100644 --- a/core/src/com/cloud/event/dao/EventDaoImpl.java +++ b/core/src/com/cloud/event/dao/EventDaoImpl.java @@ -30,34 +30,24 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.db.SearchCriteria.Op; @Component @Local(value={EventDao.class}) public class EventDaoImpl extends GenericDaoBase implements EventDao { - public static final Logger s_logger = Logger.getLogger(EventDaoImpl.class.getName()); - protected final SearchBuilder CompletedEventSearch; - protected final SearchBuilder ToArchiveOrDeleteEventSearch; + public static final Logger s_logger = Logger.getLogger(EventDaoImpl.class.getName()); + protected final SearchBuilder CompletedEventSearch; + + public EventDaoImpl () { + CompletedEventSearch = createSearchBuilder(); + CompletedEventSearch.and("state",CompletedEventSearch.entity().getState(),SearchCriteria.Op.EQ); + CompletedEventSearch.and("startId", CompletedEventSearch.entity().getStartId(), SearchCriteria.Op.EQ); + CompletedEventSearch.done(); + } - public EventDaoImpl () { - CompletedEventSearch = createSearchBuilder(); - CompletedEventSearch.and("state",CompletedEventSearch.entity().getState(),SearchCriteria.Op.EQ); - CompletedEventSearch.and("startId", CompletedEventSearch.entity().getStartId(), SearchCriteria.Op.EQ); - CompletedEventSearch.done(); - - ToArchiveOrDeleteEventSearch = createSearchBuilder(); - ToArchiveOrDeleteEventSearch.and("id", ToArchiveOrDeleteEventSearch.entity().getId(), Op.IN); - ToArchiveOrDeleteEventSearch.and("type", ToArchiveOrDeleteEventSearch.entity().getType(), Op.EQ); - ToArchiveOrDeleteEventSearch.and("accountId", ToArchiveOrDeleteEventSearch.entity().getAccountId(), Op.EQ); - ToArchiveOrDeleteEventSearch.and("createDateL", ToArchiveOrDeleteEventSearch.entity().getCreateDate(), Op.LT); - ToArchiveOrDeleteEventSearch.done(); - } - - @Override - public List searchAllEvents(SearchCriteria sc, Filter filter) { - return listIncludingRemovedBy(sc, filter); - } + @Override + public List searchAllEvents(SearchCriteria sc, Filter filter) { + return listIncludingRemovedBy(sc, filter); + } @Override public List listOlderEvents(Date oldTime) { @@ -65,8 +55,9 @@ public class EventDaoImpl extends GenericDaoBase implements Event SearchCriteria sc = createSearchCriteria(); sc.addAnd("createDate", SearchCriteria.Op.LT, oldTime); return listIncludingRemovedBy(sc, null); + } - + @Override public EventVO findCompletedEvent(long startId) { SearchCriteria sc = CompletedEventSearch.create(); @@ -74,36 +65,4 @@ public class EventDaoImpl extends GenericDaoBase implements Event sc.setParameters("startId", startId); return findOneIncludingRemovedBy(sc); } - - @Override - public List listToArchiveOrDeleteEvents(List ids, String type, Date olderThan, Long accountId) { - SearchCriteria sc = ToArchiveOrDeleteEventSearch.create(); - if (ids != null) { - sc.setParameters("id", ids.toArray(new Object[ids.size()])); - } - if (type != null) { - sc.setParameters("type", type); - } - if (olderThan != null) { - sc.setParameters("createDateL", olderThan); - } - if (accountId != null) { - sc.setParameters("accountId", accountId); - } - return search(sc, null); - } - - @Override - public void archiveEvents(List events) { - - Transaction txn = Transaction.currentTxn(); - txn.start(); - for (EventVO event : events) { - event = lockRow(event.getId(), true); - event.setArchived(true); - update(event.getId(), event); - txn.commit(); - } - txn.close(); - } } diff --git a/server/src/com/cloud/alert/dao/AlertDao.java b/server/src/com/cloud/alert/dao/AlertDao.java index fda814d051d..eb1faa51a2b 100755 --- a/server/src/com/cloud/alert/dao/AlertDao.java +++ b/server/src/com/cloud/alert/dao/AlertDao.java @@ -16,9 +16,6 @@ // under the License. package com.cloud.alert.dao; -import java.util.Date; -import java.util.List; - import com.cloud.alert.AlertVO; import com.cloud.utils.db.GenericDao; @@ -26,8 +23,4 @@ public interface AlertDao extends GenericDao { AlertVO getLastAlert(short type, long dataCenterId, Long podId, Long clusterId); // This is for backward compatibility AlertVO getLastAlert(short type, long dataCenterId, Long podId); - - public boolean deleteAlert(List Ids, String type, Date olderThan, Long zoneId); - public boolean archiveAlert(List Ids, String type, Date olderThan, Long zoneId); - public List listOlderAlerts(Date oldTime); } diff --git a/server/src/com/cloud/alert/dao/AlertDaoImpl.java b/server/src/com/cloud/alert/dao/AlertDaoImpl.java index 4b9bc6a2988..2f3be882edd 100755 --- a/server/src/com/cloud/alert/dao/AlertDaoImpl.java +++ b/server/src/com/cloud/alert/dao/AlertDaoImpl.java @@ -16,7 +16,6 @@ // under the License. package com.cloud.alert.dao; -import java.util.Date; import java.util.List; import javax.ejb.Local; @@ -26,26 +25,11 @@ import org.springframework.stereotype.Component; import com.cloud.alert.AlertVO; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; @Component @Local(value = { AlertDao.class }) public class AlertDaoImpl extends GenericDaoBase implements AlertDao { - - protected final SearchBuilder AlertSearchByIdsAndType; - - public AlertDaoImpl() { - AlertSearchByIdsAndType = createSearchBuilder(); - AlertSearchByIdsAndType.and("id", AlertSearchByIdsAndType.entity().getId(), Op.IN); - AlertSearchByIdsAndType.and("type", AlertSearchByIdsAndType.entity().getType(), Op.EQ); - AlertSearchByIdsAndType.and("createdDateL", AlertSearchByIdsAndType.entity().getCreatedDate(), Op.LT); - AlertSearchByIdsAndType.and("data_center_id", AlertSearchByIdsAndType.entity().getDataCenterId(), Op.EQ); - AlertSearchByIdsAndType.done(); - } - @Override public AlertVO getLastAlert(short type, long dataCenterId, Long podId, Long clusterId) { Filter searchFilter = new Filter(AlertVO.class, "createdDate", Boolean.FALSE, Long.valueOf(0), Long.valueOf(1)); @@ -84,73 +68,4 @@ public class AlertDaoImpl extends GenericDaoBase implements Alert } return null; } - - @Override - public boolean archiveAlert(List Ids, String type, Date olderThan, Long zoneId) { - SearchCriteria sc = AlertSearchByIdsAndType.create(); - - if (Ids != null) { - sc.setParameters("id", Ids.toArray(new Object[Ids.size()])); - } - if(type != null) { - sc.setParameters("type", type); - } - if(zoneId != null) { - sc.setParameters("data_center_id", zoneId); - } - if(olderThan != null) { - sc.setParameters("createdDateL", olderThan); - } - boolean result = true;; - List alerts = listBy(sc); - if (Ids != null && alerts.size() < Ids.size()) { - result = false; - return result; - } - Transaction txn = Transaction.currentTxn(); - txn.start(); - for (AlertVO alert : alerts) { - alert = lockRow(alert.getId(), true); - alert.setArchived(true); - update(alert.getId(), alert); - txn.commit(); - } - txn.close(); - return result; - } - - @Override - public boolean deleteAlert(List ids, String type, Date olderThan, Long zoneId) { - SearchCriteria sc = AlertSearchByIdsAndType.create(); - - if (ids != null) { - sc.setParameters("id", ids.toArray(new Object[ids.size()])); - } - if(type != null) { - sc.setParameters("type", type); - } - if(zoneId != null) { - sc.setParameters("data_center_id", zoneId); - } - if(olderThan != null) { - sc.setParameters("createdDateL", olderThan); - } - boolean result = true; - List alerts = listBy(sc); - if (ids != null && alerts.size() < ids.size()) { - result = false; - return result; - } - remove(sc); - return result; - } - - @Override - public List listOlderAlerts(Date oldTime) { - if (oldTime == null) return null; - SearchCriteria sc = createSearchCriteria(); - sc.addAnd("createDate", SearchCriteria.Op.LT, oldTime); - return listIncludingRemovedBy(sc, null); - } - } diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java index f7a32364cf8..764b3aeceaa 100755 --- a/server/src/com/cloud/api/ApiDispatcher.java +++ b/server/src/com/cloud/api/ApiDispatcher.java @@ -50,8 +50,6 @@ import org.apache.cloudstack.api.InternalIdentity; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.Validate; -import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd; -import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd; import org.apache.cloudstack.api.command.user.event.ListEventsCmd; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -393,7 +391,7 @@ public class ApiDispatcher { // This piece of code is for maintaining backward compatibility // and support both the date formats(Bug 9724) // Do the date messaging for ListEventsCmd only - if (cmdObj instanceof ListEventsCmd || cmdObj instanceof DeleteEventsCmd || cmdObj instanceof ArchiveEventsCmd) { + if (cmdObj instanceof ListEventsCmd) { boolean isObjInNewDateFormat = isObjInNewDateFormat(paramObj.toString()); if (isObjInNewDateFormat) { DateFormat newFormat = BaseCmd.NEW_INPUT_FORMAT; @@ -408,8 +406,6 @@ public class ApiDispatcher { date = messageDate(date, 0, 0, 0); } else if (field.getName().equals("endDate")) { date = messageDate(date, 23, 59, 59); - } else if (field.getName().equals("olderThan")) { - date = messageDate(date, 0, 0, 0); } field.set(cmdObj, date); } diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 35fe2f35275..8d8663a4010 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -397,7 +397,6 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ); sb.and("startId", sb.entity().getStartId(), SearchCriteria.Op.EQ); sb.and("createDate", sb.entity().getCreateDate(), SearchCriteria.Op.BETWEEN); - sb.and("archived", sb.entity().getArchived(), SearchCriteria.Op.EQ); SearchCriteria sc = sb.create(); // building ACL condition @@ -431,8 +430,6 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sc.setParameters("createDateL", endDate); } - sc.setParameters("archived", false); - Pair, Integer> eventPair = null; // event_view will not have duplicate rows for each event, so searchAndCount should be good enough. if ((entryTime != null) && (duration != null)) { diff --git a/server/src/com/cloud/api/query/vo/EventJoinVO.java b/server/src/com/cloud/api/query/vo/EventJoinVO.java index 12d7e5ae4d0..f29a942a59f 100644 --- a/server/src/com/cloud/api/query/vo/EventJoinVO.java +++ b/server/src/com/cloud/api/query/vo/EventJoinVO.java @@ -104,8 +104,6 @@ public class EventJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name="project_name") private String projectName; - @Column(name="archived") - private boolean archived; public EventJoinVO() { @@ -315,12 +313,5 @@ public class EventJoinVO extends BaseViewVO implements ControlledViewEntity { this.parameters = parameters; } - public boolean getArchived() { - return archived; - } - - public void setArchived(Boolean archived) { - this.archived = archived; - } } diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 64465a2034c..418f97d8c71 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -204,10 +204,9 @@ public enum Config { SecStorageSessionMax("Advanced", AgentManager.class, Integer.class, "secstorage.session.max", "50", "The max number of command execution sessions that a SSVM can handle", null), SecStorageCmdExecutionTimeMax("Advanced", AgentManager.class, Integer.class, "secstorage.cmd.execution.time.max", "30", "The max command execution time in minute", null), SecStorageProxy("Advanced", AgentManager.class, String.class, "secstorage.proxy", null, "http proxy used by ssvm, in http://username:password@proxyserver:port format", null), - AlertPurgeInterval("Advanced", ManagementServer.class, Integer.class, "alert.purge.interval", "86400", "The interval (in seconds) to wait before running the alert purge thread", null), - AlertPurgeDelay("Advanced", ManagementServer.class, Integer.class, "alert.purge.delay", "0", "Alerts older than specified number days will be purged. Set this value to 0 to never delete alerts", null), - DirectAttachNetworkEnabled("Advanced", ManagementServer.class, Boolean.class, "direct.attach.network.externalIpAllocator.enabled", "false", "Direct-attach VMs using external DHCP server", "true,false"), + + DirectAttachNetworkEnabled("Advanced", ManagementServer.class, Boolean.class, "direct.attach.network.externalIpAllocator.enabled", "false", "Direct-attach VMs using external DHCP server", "true,false"), DirectAttachNetworkExternalAPIURL("Advanced", ManagementServer.class, String.class, "direct.attach.network.externalIpAllocator.url", null, "Direct-attach VMs using external DHCP server (API url)", null), CheckPodCIDRs("Advanced", ManagementServer.class, String.class, "check.pod.cidrs", "true", "If true, different pods must belong to different CIDR subnets.", "true,false"), NetworkGcWait("Advanced", ManagementServer.class, Integer.class, "network.gc.wait", "600", "Time (in seconds) to wait before shutting down a network that's not in used", null), diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index d70c45f1f8a..11400de7328 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -47,7 +47,6 @@ import javax.management.MalformedObjectNameException; import javax.management.NotCompliantMBeanException; import javax.naming.ConfigurationException; -import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ApiConstants; @@ -126,7 +125,6 @@ import com.cloud.alert.AlertManager; import com.cloud.alert.AlertVO; import com.cloud.alert.dao.AlertDao; import com.cloud.api.ApiDBUtils; -import com.cloud.api.query.vo.EventJoinVO; import com.cloud.async.AsyncJobExecutor; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobResult; @@ -190,7 +188,6 @@ import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import com.cloud.info.ConsoleProxyInfo; import com.cloud.keystore.KeystoreManager; import com.cloud.network.IpAddress; -import com.cloud.network.as.ConditionVO; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.IPAddressVO; import com.cloud.network.dao.LoadBalancerDao; @@ -265,7 +262,6 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.JoinBuilder.JoinType; -import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; @@ -299,7 +295,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe public static final Logger s_logger = Logger.getLogger(ManagementServerImpl.class.getName()); @Inject - public AccountManager _accountMgr; + private AccountManager _accountMgr; @Inject private AgentManager _agentMgr; @Inject @@ -315,7 +311,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Inject private SecondaryStorageVmDao _secStorageVmDao; @Inject - public EventDao _eventDao; + private EventDao _eventDao; @Inject private DataCenterDao _dcDao; @Inject @@ -351,7 +347,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Inject private AccountDao _accountDao; @Inject - public AlertDao _alertDao; + private AlertDao _alertDao; @Inject private CapacityDao _capacityDao; @Inject @@ -375,7 +371,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Inject private AsyncJobManager _asyncMgr; private int _purgeDelay; - private int _alertPurgeDelay; @Inject private InstanceGroupDao _vmGroupDao; @Inject @@ -422,7 +417,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe EventUtils _forceEventUtilsRef; */ private final ScheduledExecutorService _eventExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker")); - private final ScheduledExecutorService _alertExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AlertChecker")); private KeystoreManager _ksMgr; private Map _configs; @@ -452,15 +446,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe _eventExecutor.scheduleAtFixedRate(new EventPurgeTask(), cleanup, cleanup, TimeUnit.SECONDS); } - //Alerts purge configurations - int alertPurgeInterval = NumbersUtil.parseInt(_configDao.getValue(Config.AlertPurgeInterval.key()), - 60 * 60 * 24); // 1 day. - _alertPurgeDelay = NumbersUtil.parseInt(_configDao.getValue(Config.AlertPurgeDelay.key()), 0); - if (_alertPurgeDelay != 0) { - _alertExecutor.scheduleAtFixedRate(new AlertPurgeTask(), alertPurgeInterval, alertPurgeInterval, - TimeUnit.SECONDS); - } - String[] availableIds = TimeZone.getAvailableIDs(); _availableIdsMap = new HashMap(availableIds.length); for (String id : availableIds) { @@ -553,42 +538,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return _eventDao.search(sc, null); } - @Override - public boolean archiveEvents(ArchiveEventsCmd cmd) { - List ids = cmd.getIds(); - boolean result =true; - - List events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getOlderThan(), cmd.getEntityOwnerId()); - ControlledEntity[] sameOwnerEvents = events.toArray(new ControlledEntity[events.size()]); - _accountMgr.checkAccess(UserContext.current().getCaller(), null, true, sameOwnerEvents); - - if (ids != null && events.size() < ids.size()) { - result = false; - return result; - } - _eventDao.archiveEvents(events); - return result; - } - - @Override - public boolean deleteEvents(DeleteEventsCmd cmd) { - List ids = cmd.getIds(); - boolean result =true; - - List events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getOlderThan(), cmd.getEntityOwnerId()); - ControlledEntity[] sameOwnerEvents = events.toArray(new ControlledEntity[events.size()]); - _accountMgr.checkAccess(UserContext.current().getCaller(), null, true, sameOwnerEvents); - - if (ids != null && events.size() < ids.size()) { - result = false; - return result; - } - for (EventVO event : events) { - _eventDao.remove(event.getId()); - } - return result; - } - private Date massageDate(Date date, int hourOfDay, int minute, int second) { Calendar cal = Calendar.getInstance(); cal.setTime(date); @@ -1714,25 +1663,10 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe sc.addAnd("type", SearchCriteria.Op.EQ, type); } - sc.addAnd("archived", SearchCriteria.Op.EQ, false); Pair, Integer> result = _alertDao.searchAndCount(sc, searchFilter); return new Pair, Integer>(result.first(), result.second()); } - @Override - public boolean archiveAlerts(ArchiveAlertsCmd cmd) { - Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), null); - boolean result = _alertDao.archiveAlert(cmd.getIds(), cmd.getType(), cmd.getOlderThan(), zoneId); - return result; - } - - @Override - public boolean deleteAlerts(DeleteAlertsCmd cmd) { - Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), null); - boolean result = _alertDao.deleteAlert(cmd.getIds(), cmd.getType(), cmd.getOlderThan(), zoneId); - return result; - } - @Override public List listTopConsumedResources(ListCapacityCmd cmd) { @@ -2234,10 +2168,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe cmdList.add(AddIpToVmNicCmd.class); cmdList.add(RemoveIpFromVmNicCmd.class); cmdList.add(ListNicsCmd.class); - cmdList.add(ArchiveAlertsCmd.class); - cmdList.add(DeleteAlertsCmd.class); - cmdList.add(ArchiveEventsCmd.class); - cmdList.add(DeleteEventsCmd.class); return cmdList; } @@ -2275,39 +2205,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe } } - protected class AlertPurgeTask implements Runnable { - @Override - public void run() { - try { - GlobalLock lock = GlobalLock.getInternLock("AlertPurge"); - if (lock == null) { - s_logger.debug("Couldn't get the global lock"); - return; - } - if (!lock.lock(30)) { - s_logger.debug("Couldn't lock the db"); - return; - } - try { - final Calendar purgeCal = Calendar.getInstance(); - purgeCal.add(Calendar.DAY_OF_YEAR, - _alertPurgeDelay); - Date purgeTime = purgeCal.getTime(); - s_logger.debug("Deleting alerts older than: " + purgeTime.toString()); - List oldAlerts = _alertDao.listOlderAlerts(purgeTime); - s_logger.debug("Found " + oldAlerts.size() + " events to be purged"); - for (AlertVO alert : oldAlerts) { - _alertDao.expunge(alert.getId()); - } - } catch (Exception e) { - s_logger.error("Exception ", e); - } finally { - lock.unlock(); - } - } catch (Exception e) { - s_logger.error("Exception ", e); - } - } - } @Override public Pair, Integer> searchForStoragePools(Criteria c) { diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index ca15bdaf781..f3112a1da27 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -140,48 +140,3 @@ CREATE TABLE nic_secondary_ips ( ALTER TABLE `cloud`.`nics` ADD COLUMN secondary_ip SMALLINT DEFAULT '0' COMMENT 'secondary ips configured for the nic'; ALTER TABLE `cloud`.`user_ip_address` ADD COLUMN dnat_vmip VARCHAR(40); - -ALTER TABLE `cloud`.`alert` ADD COLUMN `archived` tinyint(1) unsigned NOT NULL DEFAULT 0; -ALTER TABLE `cloud`.`event` ADD COLUMN `archived` tinyint(1) unsigned NOT NULL DEFAULT 0; -INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'alert.purge.interval', '86400', 'The interval (in seconds) to wait before running the alert purge thread'); -INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'alert.purge.delay', '0', 'Alerts older than specified number days will be purged. Set this value to 0 to never delete alerts'); - -DROP VIEW IF EXISTS `cloud`.`event_view`; -CREATE VIEW `cloud`.`event_view` AS - select - event.id, - event.uuid, - event.type, - event.state, - event.description, - event.created, - event.level, - event.parameters, - event.start_id, - eve.uuid start_uuid, - event.user_id, - event.archived, - user.username user_name, - account.id account_id, - account.uuid account_uuid, - account.account_name account_name, - account.type account_type, - domain.id domain_id, - domain.uuid domain_uuid, - domain.name domain_name, - domain.path domain_path, - projects.id project_id, - projects.uuid project_uuid, - projects.name project_name - from - `cloud`.`event` - inner join - `cloud`.`account` ON event.account_id = account.id - inner join - `cloud`.`domain` ON event.domain_id = domain.id - inner join - `cloud`.`user` ON event.user_id = user.id - left join - `cloud`.`projects` ON projects.project_account_id = event.account_id - left join - `cloud`.`event` eve ON event.start_id = eve.id; From f539f40e3505e80a60b75b3e98fbab269a0fbde3 Mon Sep 17 00:00:00 2001 From: Sanjay Tripathi Date: Wed, 27 Feb 2013 11:39:58 +0530 Subject: [PATCH 02/16] CLOUDSTACK-874: Ability to delete Events and Alerts This feature will provide the functionality to delete or archive the Alerts/Events. Delete or archive alerts APIs are available only for root-admin, delete or archive events are available for regular users. --- api/src/com/cloud/alert/Alert.java | 1 + api/src/com/cloud/event/Event.java | 1 + .../com/cloud/server/ManagementService.java | 38 +++- .../apache/cloudstack/api/ApiConstants.java | 1 + .../admin/resource/ArchiveAlertsCmd.java | 100 +++++++++++ .../admin/resource/DeleteAlertsCmd.java | 99 +++++++++++ .../command/user/event/ArchiveEventsCmd.java | 105 +++++++++++ .../command/user/event/DeleteEventsCmd.java | 105 +++++++++++ client/tomcatconf/commands.properties.in | 4 + core/src/com/cloud/alert/AlertVO.java | 38 ++-- core/src/com/cloud/event/EventVO.java | 163 +++++++++--------- core/src/com/cloud/event/dao/EventDao.java | 5 + .../src/com/cloud/event/dao/EventDaoImpl.java | 71 ++++++-- server/src/com/cloud/alert/dao/AlertDao.java | 7 + .../src/com/cloud/alert/dao/AlertDaoImpl.java | 85 +++++++++ server/src/com/cloud/api/ApiDispatcher.java | 6 +- .../com/cloud/api/query/QueryManagerImpl.java | 3 + .../com/cloud/api/query/vo/EventJoinVO.java | 9 + .../src/com/cloud/configuration/Config.java | 5 +- .../cloud/server/ManagementServerImpl.java | 109 +++++++++++- .../cloud/alert/AlertControlsUnitTest.java | 67 +++++++ .../cloud/event/EventControlsUnitTest.java | 68 ++++++++ setup/db/db/schema-410to420.sql | 45 +++++ 23 files changed, 1017 insertions(+), 118 deletions(-) create mode 100644 api/src/org/apache/cloudstack/api/command/admin/resource/ArchiveAlertsCmd.java create mode 100644 api/src/org/apache/cloudstack/api/command/admin/resource/DeleteAlertsCmd.java create mode 100644 api/src/org/apache/cloudstack/api/command/user/event/ArchiveEventsCmd.java create mode 100644 api/src/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java create mode 100644 server/test/com/cloud/alert/AlertControlsUnitTest.java create mode 100644 server/test/com/cloud/event/EventControlsUnitTest.java diff --git a/api/src/com/cloud/alert/Alert.java b/api/src/com/cloud/alert/Alert.java index 050f97f2ef3..31768cf193d 100644 --- a/api/src/com/cloud/alert/Alert.java +++ b/api/src/com/cloud/alert/Alert.java @@ -30,4 +30,5 @@ public interface Alert extends Identity, InternalIdentity { Date getCreatedDate(); Date getLastSent(); Date getResolved(); + boolean getArchived(); } diff --git a/api/src/com/cloud/event/Event.java b/api/src/com/cloud/event/Event.java index 1a61636828a..b8def4c6281 100644 --- a/api/src/com/cloud/event/Event.java +++ b/api/src/com/cloud/event/Event.java @@ -40,4 +40,5 @@ public interface Event extends ControlledEntity, Identity, InternalIdentity { String getLevel(); long getStartId(); String getParameters(); + boolean getArchived(); } diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java index 1736da3778c..1e6ca8d0b67 100755 --- a/api/src/com/cloud/server/ManagementService.java +++ b/api/src/com/cloud/server/ManagementService.java @@ -29,6 +29,8 @@ import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd; import org.apache.cloudstack.api.command.admin.host.ListHostsCmd; import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd; import org.apache.cloudstack.api.command.admin.pod.ListPodsByCmd; +import org.apache.cloudstack.api.command.admin.resource.ArchiveAlertsCmd; +import org.apache.cloudstack.api.command.admin.resource.DeleteAlertsCmd; import org.apache.cloudstack.api.command.admin.resource.ListAlertsCmd; import org.apache.cloudstack.api.command.admin.resource.ListCapacityCmd; import org.apache.cloudstack.api.command.admin.resource.UploadCustomCertificateCmd; @@ -40,12 +42,12 @@ import org.apache.cloudstack.api.command.admin.systemvm.UpgradeSystemVMCmd; import org.apache.cloudstack.api.command.admin.vlan.ListVlanIpRangesCmd; import org.apache.cloudstack.api.command.user.address.ListPublicIpAddressesCmd; import org.apache.cloudstack.api.command.user.config.ListCapabilitiesCmd; +import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd; +import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd; import org.apache.cloudstack.api.command.user.guest.ListGuestOsCategoriesCmd; import org.apache.cloudstack.api.command.user.guest.ListGuestOsCmd; import org.apache.cloudstack.api.command.user.iso.ListIsosCmd; import org.apache.cloudstack.api.command.user.iso.UpdateIsoCmd; -import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd; -import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd; import org.apache.cloudstack.api.command.user.ssh.CreateSSHKeyPairCmd; import org.apache.cloudstack.api.command.user.ssh.DeleteSSHKeyPairCmd; import org.apache.cloudstack.api.command.user.ssh.ListSSHKeyPairsCmd; @@ -55,12 +57,10 @@ import org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd; import org.apache.cloudstack.api.command.user.vm.GetVMPasswordCmd; import org.apache.cloudstack.api.command.user.vmgroup.UpdateVMGroupCmd; import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd; -import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd; import com.cloud.alert.Alert; import com.cloud.capacity.Capacity; import com.cloud.configuration.Configuration; -import com.cloud.dc.DataCenter; import com.cloud.dc.Pod; import com.cloud.dc.Vlan; import com.cloud.domain.Domain; @@ -72,8 +72,6 @@ import com.cloud.host.Host; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.HypervisorCapabilities; import com.cloud.network.IpAddress; -import com.cloud.offering.DiskOffering; -import com.cloud.offering.ServiceOffering; import com.cloud.org.Cluster; import com.cloud.storage.GuestOS; import com.cloud.storage.GuestOsCategory; @@ -194,6 +192,34 @@ public interface ManagementService { */ Pair, Integer> searchForAlerts(ListAlertsCmd cmd); + /** + * Archive alerts + * @param cmd + * @return True on success. False otherwise. + */ + boolean archiveAlerts(ArchiveAlertsCmd cmd); + + /** + * Delete alerts + * @param cmd + * @return True on success. False otherwise. + */ + boolean deleteAlerts(DeleteAlertsCmd cmd); + + /** + * Archive events + * @param cmd + * @return True on success. False otherwise. + */ + boolean archiveEvents(ArchiveEventsCmd cmd); + + /** + * Delete events + * @param cmd + * @return True on success. False otherwise. + */ + boolean deleteEvents(DeleteEventsCmd cmd); + /** * list all the capacity rows in capacity operations table * diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 1b544fd1641..b40b26ce57c 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -459,6 +459,7 @@ public class ApiConstants { public static final String UCS_BLADE_DN = "bladedn"; public static final String UCS_BLADE_ID = "bladeid"; public static final String VM_GUEST_IP = "vmguestip"; + public static final String OLDER_THAN = "olderthan"; public enum HostDetails { all, capacity, events, stats, min; diff --git a/api/src/org/apache/cloudstack/api/command/admin/resource/ArchiveAlertsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/resource/ArchiveAlertsCmd.java new file mode 100644 index 00000000000..2a1a47a13ed --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/resource/ArchiveAlertsCmd.java @@ -0,0 +1,100 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command.admin.resource; + +import java.util.Date; +import java.util.List; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.AlertResponse; +import org.apache.cloudstack.api.response.ConditionResponse; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.log4j.Logger; + +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.user.Account; + +@APICommand(name = "archiveAlerts", description = "Archive one or more alerts.", responseObject = SuccessResponse.class) +public class ArchiveAlertsCmd extends BaseCmd { + + public static final Logger s_logger = Logger.getLogger(ArchiveAlertsCmd.class.getName()); + + private static final String s_name = "archivealertsresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = AlertResponse.class, + description = "the IDs of the alerts") + private List ids; + + @Parameter(name=ApiConstants.OLDER_THAN, type=CommandType.DATE, description="archive alerts older than this date (use format \"yyyy-MM-dd\")") + private Date olderThan; + + @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "archive by alert type") + private String type; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public List getIds() { + return ids; + } + + public Date getOlderThan() { + return olderThan; + } + + public String getType() { + return type; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute() { + if(ids == null && type == null && olderThan == null) { + throw new InvalidParameterValueException("either ids, type or olderthan must be specified"); + } + boolean result = _mgr.archiveAlerts(this); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Unable to archive Alerts, one or more parameters has invalid values"); + } + } +} diff --git a/api/src/org/apache/cloudstack/api/command/admin/resource/DeleteAlertsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/resource/DeleteAlertsCmd.java new file mode 100644 index 00000000000..f03793c4f6d --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/resource/DeleteAlertsCmd.java @@ -0,0 +1,99 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command.admin.resource; + +import java.util.Date; +import java.util.List; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.AlertResponse; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.log4j.Logger; + +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.user.Account; + +@APICommand(name = "deleteAlerts", description = "Delete one or more alerts.", responseObject = SuccessResponse.class) +public class DeleteAlertsCmd extends BaseCmd { + + public static final Logger s_logger = Logger.getLogger(DeleteAlertsCmd.class.getName()); + + private static final String s_name = "deletealertsresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = AlertResponse.class, + description = "the IDs of the alerts") + private List ids; + + @Parameter(name=ApiConstants.OLDER_THAN, type=CommandType.DATE, description="delete alerts older than (including) this date (use format \"yyyy-MM-dd\")") + private Date olderThan; + + @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "delete by alert type") + private String type; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public List getIds() { + return ids; + } + + public Date getOlderThan() { + return olderThan; + } + + public String getType() { + return type; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute() { + if(ids == null && type == null && olderThan == null) { + throw new InvalidParameterValueException("either ids, type or olderthan must be specified"); + } + boolean result = _mgr.deleteAlerts(this); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Unable to delete Alerts, one or more parameters has invalid values"); + } + } +} diff --git a/api/src/org/apache/cloudstack/api/command/user/event/ArchiveEventsCmd.java b/api/src/org/apache/cloudstack/api/command/user/event/ArchiveEventsCmd.java new file mode 100644 index 00000000000..481607c9f0b --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/event/ArchiveEventsCmd.java @@ -0,0 +1,105 @@ +//Licensed to the Apache Software Foundation (ASF) under one +//or more contributor license agreements. See the NOTICE file +//distributed with this work for additional information +//regarding copyright ownership. The ASF licenses this file +//to you under the Apache License, Version 2.0 (the +//"License"); you may not use this file except in compliance +//with the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, +//software distributed under the License is distributed on an +//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +//KIND, either express or implied. See the License for the +//specific language governing permissions and limitations +//under the License. +package org.apache.cloudstack.api.command.user.event; + +import java.util.Date; +import java.util.List; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.AlertResponse; +import org.apache.cloudstack.api.response.EventResponse; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.log4j.Logger; + +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@APICommand(name = "archiveEvents", description = "Archive one or more events.", responseObject = SuccessResponse.class) +public class ArchiveEventsCmd extends BaseCmd { + + public static final Logger s_logger = Logger.getLogger(ArchiveEventsCmd.class.getName()); + + private static final String s_name = "archiveeventsresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = EventResponse.class, + description = "the IDs of the events") + private List ids; + + @Parameter(name=ApiConstants.OLDER_THAN, type=CommandType.DATE, description="archive events older than (including) this date (use format \"yyyy-MM-dd\" or the new format \"yyyy-MM-dd HH:mm:ss\")") + private Date olderThan; + + @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "archive by event type") + private String type; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public List getIds() { + return ids; + } + + public Date getOlderThan() { + return olderThan; + } + + public String getType() { + return type; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Account account = UserContext.current().getCaller(); + if (account != null) { + return account.getId(); + } + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute() { + if(ids == null && type == null && olderThan == null) { + throw new InvalidParameterValueException("either ids, type or olderthan must be specified"); + } + boolean result = _mgr.archiveEvents(this); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Unable to archive Events, one or more parameters has invalid values"); + } + } +} diff --git a/api/src/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java b/api/src/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java new file mode 100644 index 00000000000..55ca92a5dfe --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java @@ -0,0 +1,105 @@ +//Licensed to the Apache Software Foundation (ASF) under one +//or more contributor license agreements. See the NOTICE file +//distributed with this work for additional information +//regarding copyright ownership. The ASF licenses this file +//to you under the Apache License, Version 2.0 (the +//"License"); you may not use this file except in compliance +//with the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, +//software distributed under the License is distributed on an +//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +//KIND, either express or implied. See the License for the +//specific language governing permissions and limitations +//under the License. +package org.apache.cloudstack.api.command.user.event; + +import java.util.Date; +import java.util.List; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.AlertResponse; +import org.apache.cloudstack.api.response.EventResponse; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.log4j.Logger; + +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@APICommand(name = "deleteEvents", description = "Delete one or more events.", responseObject = SuccessResponse.class) +public class DeleteEventsCmd extends BaseCmd { + + public static final Logger s_logger = Logger.getLogger(DeleteEventsCmd.class.getName()); + + private static final String s_name = "deleteeventsresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = EventResponse.class, + description = "the IDs of the events") + private List ids; + + @Parameter(name=ApiConstants.OLDER_THAN, type=CommandType.DATE, description="delete events older than (including) this date (use format \"yyyy-MM-dd\" or the new format \"yyyy-MM-dd HH:mm:ss\")") + private Date olderThan; + + @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "delete by event type") + private String type; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public List getIds() { + return ids; + } + + public Date getOlderThan() { + return olderThan; + } + + public String getType() { + return type; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Account account = UserContext.current().getCaller(); + if (account != null) { + return account.getId(); + } + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute() { + if(ids == null && type == null && olderThan == null) { + throw new InvalidParameterValueException("either ids, type or enddate must be specified"); + } + boolean result = _mgr.deleteEvents(this); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Unable to delete Events, one or more parameters has invalid values"); + } + } +} diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index dd0c3f894fd..5018236e5e2 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -218,9 +218,13 @@ listZones=15 #### events commands listEvents=15 listEventTypes=15 +archiveEvents=15 +deleteEvents=15 #### alerts commands listAlerts=3 +archiveAlerts=1 +deleteAlerts=1 #### system capacity commands listCapacity=3 diff --git a/core/src/com/cloud/alert/AlertVO.java b/core/src/com/cloud/alert/AlertVO.java index f6089d65043..3f014aa2b1f 100755 --- a/core/src/com/cloud/alert/AlertVO.java +++ b/core/src/com/cloud/alert/AlertVO.java @@ -28,9 +28,7 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; -import org.apache.cloudstack.api.Identity; import com.cloud.utils.db.GenericDao; -import org.apache.cloudstack.api.InternalIdentity; @Entity @Table(name="alert") @@ -68,16 +66,19 @@ public class AlertVO implements Alert { @Temporal(TemporalType.TIMESTAMP) @Column(name="resolved", updatable=true, nullable=true) private Date resolved; - + @Column(name="uuid") private String uuid; + @Column(name="archived") + private boolean archived; + public AlertVO() { - this.uuid = UUID.randomUUID().toString(); + this.uuid = UUID.randomUUID().toString(); } public AlertVO(Long id) { this.id = id; - this.uuid = UUID.randomUUID().toString(); + this.uuid = UUID.randomUUID().toString(); } @Override @@ -103,12 +104,12 @@ public class AlertVO implements Alert { } public Long getClusterId() { - return clusterId; - } - public void setClusterId(Long clusterId) { - this.clusterId = clusterId; - } - @Override + return clusterId; + } + public void setClusterId(Long clusterId) { + this.clusterId = clusterId; + } + @Override public Long getPodId() { return podId; } @@ -164,10 +165,19 @@ public class AlertVO implements Alert { @Override public String getUuid() { - return this.uuid; + return this.uuid; } - + public void setUuid(String uuid) { - this.uuid = uuid; + this.uuid = uuid; + } + + @Override + public boolean getArchived() { + return archived; + } + + public void setArchived(Boolean archived) { + this.archived = archived; } } diff --git a/core/src/com/cloud/event/EventVO.java b/core/src/com/cloud/event/EventVO.java index ac46f24b2ee..2c30eadebdc 100644 --- a/core/src/com/cloud/event/EventVO.java +++ b/core/src/com/cloud/event/EventVO.java @@ -29,74 +29,75 @@ import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Transient; -import org.apache.cloudstack.api.Identity; import com.cloud.utils.db.GenericDao; -import org.apache.cloudstack.api.InternalIdentity; @Entity @Table(name="event") public class EventVO implements Event { - @Id + @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") - private long id = -1; + private long id = -1; - @Column(name="type") - private String type; - - @Enumerated(value=EnumType.STRING) - @Column(name="state") + @Column(name="type") + private String type; + + @Enumerated(value=EnumType.STRING) + @Column(name="state") private State state = State.Completed; - @Column(name="description", length=1024) - private String description; + @Column(name="description", length=1024) + private String description; - @Column(name=GenericDao.CREATED_COLUMN) - private Date createDate; + @Column(name=GenericDao.CREATED_COLUMN) + private Date createDate; @Column(name="user_id") private long userId; - @Column(name="account_id") - private long accountId; + @Column(name="account_id") + private long accountId; @Column(name="domain_id") private long domainId; - @Column(name="level") - private String level = LEVEL_INFO; - - @Column(name="start_id") + @Column(name="level") + private String level = LEVEL_INFO; + + @Column(name="start_id") private long startId; - @Column(name="parameters", length=1024) - private String parameters; - - @Column(name="uuid") - private String uuid; + @Column(name="parameters", length=1024) + private String parameters; - @Transient - private int totalSize; + @Column(name="uuid") + private String uuid; - public static final String LEVEL_INFO = "INFO"; - public static final String LEVEL_WARN = "WARN"; - public static final String LEVEL_ERROR = "ERROR"; - - public EventVO() { - this.uuid = UUID.randomUUID().toString(); - } - - public long getId() { - return id; - } - @Override + @Column(name="archived") + private boolean archived; + + @Transient + private int totalSize; + + public static final String LEVEL_INFO = "INFO"; + public static final String LEVEL_WARN = "WARN"; + public static final String LEVEL_ERROR = "ERROR"; + + public EventVO() { + this.uuid = UUID.randomUUID().toString(); + } + + public long getId() { + return id; + } + @Override public String getType() { - return type; - } - public void setType(String type) { - this.type = type; - } - @Override + return type; + } + public void setType(String type) { + this.type = type; + } + @Override public State getState() { return state; } @@ -105,27 +106,27 @@ public class EventVO implements Event { this.state = state; } - @Override + @Override public String getDescription() { - return description; - } - public void setDescription(String description) { - this.description = description; - } - @Override + return description; + } + public void setDescription(String description) { + this.description = description; + } + @Override public Date getCreateDate() { - return createDate; - } - public void setCreatedDate(Date createdDate) { - createDate = createdDate; - } - @Override + return createDate; + } + public void setCreatedDate(Date createdDate) { + createDate = createdDate; + } + @Override public long getUserId() { - return userId; - } - public void setUserId(long userId) { - this.userId = userId; - } + return userId; + } + public void setUserId(long userId) { + this.userId = userId; + } @Override public long getAccountId() { return accountId; @@ -165,21 +166,29 @@ public class EventVO implements Event { this.startId = startId; } - @Override + @Override public String getParameters() { - return parameters; - } - public void setParameters(String parameters) { - this.parameters = parameters; - } - - @Override - public String getUuid() { - return this.uuid; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } + return parameters; + } + public void setParameters(String parameters) { + this.parameters = parameters; + } + @Override + public String getUuid() { + return this.uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + @Override + public boolean getArchived() { + return archived; + } + + public void setArchived(Boolean archived) { + this.archived = archived; + } } diff --git a/core/src/com/cloud/event/dao/EventDao.java b/core/src/com/cloud/event/dao/EventDao.java index bfcb818f20f..da5f47a90b4 100644 --- a/core/src/com/cloud/event/dao/EventDao.java +++ b/core/src/com/cloud/event/dao/EventDao.java @@ -30,4 +30,9 @@ public interface EventDao extends GenericDao { public List listOlderEvents(Date oldTime); EventVO findCompletedEvent(long startId); + + public List listToArchiveOrDeleteEvents(List ids, String type, Date olderThan, Long accountId); + + public void archiveEvents(List events); + } diff --git a/core/src/com/cloud/event/dao/EventDaoImpl.java b/core/src/com/cloud/event/dao/EventDaoImpl.java index 44fbb030dcc..6ba59c56b0a 100644 --- a/core/src/com/cloud/event/dao/EventDaoImpl.java +++ b/core/src/com/cloud/event/dao/EventDaoImpl.java @@ -30,24 +30,34 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.SearchCriteria.Op; @Component @Local(value={EventDao.class}) public class EventDaoImpl extends GenericDaoBase implements EventDao { - public static final Logger s_logger = Logger.getLogger(EventDaoImpl.class.getName()); - protected final SearchBuilder CompletedEventSearch; - - public EventDaoImpl () { - CompletedEventSearch = createSearchBuilder(); - CompletedEventSearch.and("state",CompletedEventSearch.entity().getState(),SearchCriteria.Op.EQ); - CompletedEventSearch.and("startId", CompletedEventSearch.entity().getStartId(), SearchCriteria.Op.EQ); - CompletedEventSearch.done(); - } + public static final Logger s_logger = Logger.getLogger(EventDaoImpl.class.getName()); + protected final SearchBuilder CompletedEventSearch; + protected final SearchBuilder ToArchiveOrDeleteEventSearch; - @Override - public List searchAllEvents(SearchCriteria sc, Filter filter) { - return listIncludingRemovedBy(sc, filter); - } + public EventDaoImpl () { + CompletedEventSearch = createSearchBuilder(); + CompletedEventSearch.and("state",CompletedEventSearch.entity().getState(),SearchCriteria.Op.EQ); + CompletedEventSearch.and("startId", CompletedEventSearch.entity().getStartId(), SearchCriteria.Op.EQ); + CompletedEventSearch.done(); + + ToArchiveOrDeleteEventSearch = createSearchBuilder(); + ToArchiveOrDeleteEventSearch.and("id", ToArchiveOrDeleteEventSearch.entity().getId(), Op.IN); + ToArchiveOrDeleteEventSearch.and("type", ToArchiveOrDeleteEventSearch.entity().getType(), Op.EQ); + ToArchiveOrDeleteEventSearch.and("accountId", ToArchiveOrDeleteEventSearch.entity().getAccountId(), Op.EQ); + ToArchiveOrDeleteEventSearch.and("createDateL", ToArchiveOrDeleteEventSearch.entity().getCreateDate(), Op.LT); + ToArchiveOrDeleteEventSearch.done(); + } + + @Override + public List searchAllEvents(SearchCriteria sc, Filter filter) { + return listIncludingRemovedBy(sc, filter); + } @Override public List listOlderEvents(Date oldTime) { @@ -55,9 +65,8 @@ public class EventDaoImpl extends GenericDaoBase implements Event SearchCriteria sc = createSearchCriteria(); sc.addAnd("createDate", SearchCriteria.Op.LT, oldTime); return listIncludingRemovedBy(sc, null); - } - + @Override public EventVO findCompletedEvent(long startId) { SearchCriteria sc = CompletedEventSearch.create(); @@ -65,4 +74,36 @@ public class EventDaoImpl extends GenericDaoBase implements Event sc.setParameters("startId", startId); return findOneIncludingRemovedBy(sc); } + + @Override + public List listToArchiveOrDeleteEvents(List ids, String type, Date olderThan, Long accountId) { + SearchCriteria sc = ToArchiveOrDeleteEventSearch.create(); + if (ids != null) { + sc.setParameters("id", ids.toArray(new Object[ids.size()])); + } + if (type != null) { + sc.setParameters("type", type); + } + if (olderThan != null) { + sc.setParameters("createDateL", olderThan); + } + if (accountId != null) { + sc.setParameters("accountId", accountId); + } + return search(sc, null); + } + + @Override + public void archiveEvents(List events) { + + Transaction txn = Transaction.currentTxn(); + txn.start(); + for (EventVO event : events) { + event = lockRow(event.getId(), true); + event.setArchived(true); + update(event.getId(), event); + txn.commit(); + } + txn.close(); + } } diff --git a/server/src/com/cloud/alert/dao/AlertDao.java b/server/src/com/cloud/alert/dao/AlertDao.java index eb1faa51a2b..fda814d051d 100755 --- a/server/src/com/cloud/alert/dao/AlertDao.java +++ b/server/src/com/cloud/alert/dao/AlertDao.java @@ -16,6 +16,9 @@ // under the License. package com.cloud.alert.dao; +import java.util.Date; +import java.util.List; + import com.cloud.alert.AlertVO; import com.cloud.utils.db.GenericDao; @@ -23,4 +26,8 @@ public interface AlertDao extends GenericDao { AlertVO getLastAlert(short type, long dataCenterId, Long podId, Long clusterId); // This is for backward compatibility AlertVO getLastAlert(short type, long dataCenterId, Long podId); + + public boolean deleteAlert(List Ids, String type, Date olderThan, Long zoneId); + public boolean archiveAlert(List Ids, String type, Date olderThan, Long zoneId); + public List listOlderAlerts(Date oldTime); } diff --git a/server/src/com/cloud/alert/dao/AlertDaoImpl.java b/server/src/com/cloud/alert/dao/AlertDaoImpl.java index 2f3be882edd..4b9bc6a2988 100755 --- a/server/src/com/cloud/alert/dao/AlertDaoImpl.java +++ b/server/src/com/cloud/alert/dao/AlertDaoImpl.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.alert.dao; +import java.util.Date; import java.util.List; import javax.ejb.Local; @@ -25,11 +26,26 @@ import org.springframework.stereotype.Component; import com.cloud.alert.AlertVO; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.Transaction; @Component @Local(value = { AlertDao.class }) public class AlertDaoImpl extends GenericDaoBase implements AlertDao { + + protected final SearchBuilder AlertSearchByIdsAndType; + + public AlertDaoImpl() { + AlertSearchByIdsAndType = createSearchBuilder(); + AlertSearchByIdsAndType.and("id", AlertSearchByIdsAndType.entity().getId(), Op.IN); + AlertSearchByIdsAndType.and("type", AlertSearchByIdsAndType.entity().getType(), Op.EQ); + AlertSearchByIdsAndType.and("createdDateL", AlertSearchByIdsAndType.entity().getCreatedDate(), Op.LT); + AlertSearchByIdsAndType.and("data_center_id", AlertSearchByIdsAndType.entity().getDataCenterId(), Op.EQ); + AlertSearchByIdsAndType.done(); + } + @Override public AlertVO getLastAlert(short type, long dataCenterId, Long podId, Long clusterId) { Filter searchFilter = new Filter(AlertVO.class, "createdDate", Boolean.FALSE, Long.valueOf(0), Long.valueOf(1)); @@ -68,4 +84,73 @@ public class AlertDaoImpl extends GenericDaoBase implements Alert } return null; } + + @Override + public boolean archiveAlert(List Ids, String type, Date olderThan, Long zoneId) { + SearchCriteria sc = AlertSearchByIdsAndType.create(); + + if (Ids != null) { + sc.setParameters("id", Ids.toArray(new Object[Ids.size()])); + } + if(type != null) { + sc.setParameters("type", type); + } + if(zoneId != null) { + sc.setParameters("data_center_id", zoneId); + } + if(olderThan != null) { + sc.setParameters("createdDateL", olderThan); + } + boolean result = true;; + List alerts = listBy(sc); + if (Ids != null && alerts.size() < Ids.size()) { + result = false; + return result; + } + Transaction txn = Transaction.currentTxn(); + txn.start(); + for (AlertVO alert : alerts) { + alert = lockRow(alert.getId(), true); + alert.setArchived(true); + update(alert.getId(), alert); + txn.commit(); + } + txn.close(); + return result; + } + + @Override + public boolean deleteAlert(List ids, String type, Date olderThan, Long zoneId) { + SearchCriteria sc = AlertSearchByIdsAndType.create(); + + if (ids != null) { + sc.setParameters("id", ids.toArray(new Object[ids.size()])); + } + if(type != null) { + sc.setParameters("type", type); + } + if(zoneId != null) { + sc.setParameters("data_center_id", zoneId); + } + if(olderThan != null) { + sc.setParameters("createdDateL", olderThan); + } + boolean result = true; + List alerts = listBy(sc); + if (ids != null && alerts.size() < ids.size()) { + result = false; + return result; + } + remove(sc); + return result; + } + + @Override + public List listOlderAlerts(Date oldTime) { + if (oldTime == null) return null; + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("createDate", SearchCriteria.Op.LT, oldTime); + return listIncludingRemovedBy(sc, null); + } + } diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java index 764b3aeceaa..f7a32364cf8 100755 --- a/server/src/com/cloud/api/ApiDispatcher.java +++ b/server/src/com/cloud/api/ApiDispatcher.java @@ -50,6 +50,8 @@ import org.apache.cloudstack.api.InternalIdentity; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.Validate; +import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd; +import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd; import org.apache.cloudstack.api.command.user.event.ListEventsCmd; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -391,7 +393,7 @@ public class ApiDispatcher { // This piece of code is for maintaining backward compatibility // and support both the date formats(Bug 9724) // Do the date messaging for ListEventsCmd only - if (cmdObj instanceof ListEventsCmd) { + if (cmdObj instanceof ListEventsCmd || cmdObj instanceof DeleteEventsCmd || cmdObj instanceof ArchiveEventsCmd) { boolean isObjInNewDateFormat = isObjInNewDateFormat(paramObj.toString()); if (isObjInNewDateFormat) { DateFormat newFormat = BaseCmd.NEW_INPUT_FORMAT; @@ -406,6 +408,8 @@ public class ApiDispatcher { date = messageDate(date, 0, 0, 0); } else if (field.getName().equals("endDate")) { date = messageDate(date, 23, 59, 59); + } else if (field.getName().equals("olderThan")) { + date = messageDate(date, 0, 0, 0); } field.set(cmdObj, date); } diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 8d8663a4010..35fe2f35275 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -397,6 +397,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ); sb.and("startId", sb.entity().getStartId(), SearchCriteria.Op.EQ); sb.and("createDate", sb.entity().getCreateDate(), SearchCriteria.Op.BETWEEN); + sb.and("archived", sb.entity().getArchived(), SearchCriteria.Op.EQ); SearchCriteria sc = sb.create(); // building ACL condition @@ -430,6 +431,8 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sc.setParameters("createDateL", endDate); } + sc.setParameters("archived", false); + Pair, Integer> eventPair = null; // event_view will not have duplicate rows for each event, so searchAndCount should be good enough. if ((entryTime != null) && (duration != null)) { diff --git a/server/src/com/cloud/api/query/vo/EventJoinVO.java b/server/src/com/cloud/api/query/vo/EventJoinVO.java index f29a942a59f..12d7e5ae4d0 100644 --- a/server/src/com/cloud/api/query/vo/EventJoinVO.java +++ b/server/src/com/cloud/api/query/vo/EventJoinVO.java @@ -104,6 +104,8 @@ public class EventJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name="project_name") private String projectName; + @Column(name="archived") + private boolean archived; public EventJoinVO() { @@ -313,5 +315,12 @@ public class EventJoinVO extends BaseViewVO implements ControlledViewEntity { this.parameters = parameters; } + public boolean getArchived() { + return archived; + } + + public void setArchived(Boolean archived) { + this.archived = archived; + } } diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 418f97d8c71..64465a2034c 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -204,9 +204,10 @@ public enum Config { SecStorageSessionMax("Advanced", AgentManager.class, Integer.class, "secstorage.session.max", "50", "The max number of command execution sessions that a SSVM can handle", null), SecStorageCmdExecutionTimeMax("Advanced", AgentManager.class, Integer.class, "secstorage.cmd.execution.time.max", "30", "The max command execution time in minute", null), SecStorageProxy("Advanced", AgentManager.class, String.class, "secstorage.proxy", null, "http proxy used by ssvm, in http://username:password@proxyserver:port format", null), + AlertPurgeInterval("Advanced", ManagementServer.class, Integer.class, "alert.purge.interval", "86400", "The interval (in seconds) to wait before running the alert purge thread", null), + AlertPurgeDelay("Advanced", ManagementServer.class, Integer.class, "alert.purge.delay", "0", "Alerts older than specified number days will be purged. Set this value to 0 to never delete alerts", null), - - DirectAttachNetworkEnabled("Advanced", ManagementServer.class, Boolean.class, "direct.attach.network.externalIpAllocator.enabled", "false", "Direct-attach VMs using external DHCP server", "true,false"), + DirectAttachNetworkEnabled("Advanced", ManagementServer.class, Boolean.class, "direct.attach.network.externalIpAllocator.enabled", "false", "Direct-attach VMs using external DHCP server", "true,false"), DirectAttachNetworkExternalAPIURL("Advanced", ManagementServer.class, String.class, "direct.attach.network.externalIpAllocator.url", null, "Direct-attach VMs using external DHCP server (API url)", null), CheckPodCIDRs("Advanced", ManagementServer.class, String.class, "check.pod.cidrs", "true", "If true, different pods must belong to different CIDR subnets.", "true,false"), NetworkGcWait("Advanced", ManagementServer.class, Integer.class, "network.gc.wait", "600", "Time (in seconds) to wait before shutting down a network that's not in used", null), diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 11400de7328..d70c45f1f8a 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -47,6 +47,7 @@ import javax.management.MalformedObjectNameException; import javax.management.NotCompliantMBeanException; import javax.naming.ConfigurationException; +import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ApiConstants; @@ -125,6 +126,7 @@ import com.cloud.alert.AlertManager; import com.cloud.alert.AlertVO; import com.cloud.alert.dao.AlertDao; import com.cloud.api.ApiDBUtils; +import com.cloud.api.query.vo.EventJoinVO; import com.cloud.async.AsyncJobExecutor; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobResult; @@ -188,6 +190,7 @@ import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import com.cloud.info.ConsoleProxyInfo; import com.cloud.keystore.KeystoreManager; import com.cloud.network.IpAddress; +import com.cloud.network.as.ConditionVO; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.IPAddressVO; import com.cloud.network.dao.LoadBalancerDao; @@ -262,6 +265,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.JoinBuilder.JoinType; +import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; @@ -295,7 +299,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe public static final Logger s_logger = Logger.getLogger(ManagementServerImpl.class.getName()); @Inject - private AccountManager _accountMgr; + public AccountManager _accountMgr; @Inject private AgentManager _agentMgr; @Inject @@ -311,7 +315,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Inject private SecondaryStorageVmDao _secStorageVmDao; @Inject - private EventDao _eventDao; + public EventDao _eventDao; @Inject private DataCenterDao _dcDao; @Inject @@ -347,7 +351,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Inject private AccountDao _accountDao; @Inject - private AlertDao _alertDao; + public AlertDao _alertDao; @Inject private CapacityDao _capacityDao; @Inject @@ -371,6 +375,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Inject private AsyncJobManager _asyncMgr; private int _purgeDelay; + private int _alertPurgeDelay; @Inject private InstanceGroupDao _vmGroupDao; @Inject @@ -417,6 +422,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe EventUtils _forceEventUtilsRef; */ private final ScheduledExecutorService _eventExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker")); + private final ScheduledExecutorService _alertExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AlertChecker")); private KeystoreManager _ksMgr; private Map _configs; @@ -446,6 +452,15 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe _eventExecutor.scheduleAtFixedRate(new EventPurgeTask(), cleanup, cleanup, TimeUnit.SECONDS); } + //Alerts purge configurations + int alertPurgeInterval = NumbersUtil.parseInt(_configDao.getValue(Config.AlertPurgeInterval.key()), + 60 * 60 * 24); // 1 day. + _alertPurgeDelay = NumbersUtil.parseInt(_configDao.getValue(Config.AlertPurgeDelay.key()), 0); + if (_alertPurgeDelay != 0) { + _alertExecutor.scheduleAtFixedRate(new AlertPurgeTask(), alertPurgeInterval, alertPurgeInterval, + TimeUnit.SECONDS); + } + String[] availableIds = TimeZone.getAvailableIDs(); _availableIdsMap = new HashMap(availableIds.length); for (String id : availableIds) { @@ -538,6 +553,42 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return _eventDao.search(sc, null); } + @Override + public boolean archiveEvents(ArchiveEventsCmd cmd) { + List ids = cmd.getIds(); + boolean result =true; + + List events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getOlderThan(), cmd.getEntityOwnerId()); + ControlledEntity[] sameOwnerEvents = events.toArray(new ControlledEntity[events.size()]); + _accountMgr.checkAccess(UserContext.current().getCaller(), null, true, sameOwnerEvents); + + if (ids != null && events.size() < ids.size()) { + result = false; + return result; + } + _eventDao.archiveEvents(events); + return result; + } + + @Override + public boolean deleteEvents(DeleteEventsCmd cmd) { + List ids = cmd.getIds(); + boolean result =true; + + List events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getOlderThan(), cmd.getEntityOwnerId()); + ControlledEntity[] sameOwnerEvents = events.toArray(new ControlledEntity[events.size()]); + _accountMgr.checkAccess(UserContext.current().getCaller(), null, true, sameOwnerEvents); + + if (ids != null && events.size() < ids.size()) { + result = false; + return result; + } + for (EventVO event : events) { + _eventDao.remove(event.getId()); + } + return result; + } + private Date massageDate(Date date, int hourOfDay, int minute, int second) { Calendar cal = Calendar.getInstance(); cal.setTime(date); @@ -1663,10 +1714,25 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe sc.addAnd("type", SearchCriteria.Op.EQ, type); } + sc.addAnd("archived", SearchCriteria.Op.EQ, false); Pair, Integer> result = _alertDao.searchAndCount(sc, searchFilter); return new Pair, Integer>(result.first(), result.second()); } + @Override + public boolean archiveAlerts(ArchiveAlertsCmd cmd) { + Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), null); + boolean result = _alertDao.archiveAlert(cmd.getIds(), cmd.getType(), cmd.getOlderThan(), zoneId); + return result; + } + + @Override + public boolean deleteAlerts(DeleteAlertsCmd cmd) { + Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), null); + boolean result = _alertDao.deleteAlert(cmd.getIds(), cmd.getType(), cmd.getOlderThan(), zoneId); + return result; + } + @Override public List listTopConsumedResources(ListCapacityCmd cmd) { @@ -2168,6 +2234,10 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe cmdList.add(AddIpToVmNicCmd.class); cmdList.add(RemoveIpFromVmNicCmd.class); cmdList.add(ListNicsCmd.class); + cmdList.add(ArchiveAlertsCmd.class); + cmdList.add(DeleteAlertsCmd.class); + cmdList.add(ArchiveEventsCmd.class); + cmdList.add(DeleteEventsCmd.class); return cmdList; } @@ -2205,6 +2275,39 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe } } + protected class AlertPurgeTask implements Runnable { + @Override + public void run() { + try { + GlobalLock lock = GlobalLock.getInternLock("AlertPurge"); + if (lock == null) { + s_logger.debug("Couldn't get the global lock"); + return; + } + if (!lock.lock(30)) { + s_logger.debug("Couldn't lock the db"); + return; + } + try { + final Calendar purgeCal = Calendar.getInstance(); + purgeCal.add(Calendar.DAY_OF_YEAR, - _alertPurgeDelay); + Date purgeTime = purgeCal.getTime(); + s_logger.debug("Deleting alerts older than: " + purgeTime.toString()); + List oldAlerts = _alertDao.listOlderAlerts(purgeTime); + s_logger.debug("Found " + oldAlerts.size() + " events to be purged"); + for (AlertVO alert : oldAlerts) { + _alertDao.expunge(alert.getId()); + } + } catch (Exception e) { + s_logger.error("Exception ", e); + } finally { + lock.unlock(); + } + } catch (Exception e) { + s_logger.error("Exception ", e); + } + } + } @Override public Pair, Integer> searchForStoragePools(Criteria c) { diff --git a/server/test/com/cloud/alert/AlertControlsUnitTest.java b/server/test/com/cloud/alert/AlertControlsUnitTest.java new file mode 100644 index 00000000000..412a2619840 --- /dev/null +++ b/server/test/com/cloud/alert/AlertControlsUnitTest.java @@ -0,0 +1,67 @@ +package com.cloud.alert; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyList; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; + +import java.util.Date; + +import junit.framework.TestCase; + +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; + +import com.cloud.alert.dao.AlertDao; +import com.cloud.server.ManagementServerImpl; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; + +public class AlertControlsUnitTest extends TestCase { + private static final Logger s_logger = Logger.getLogger(AlertControlsUnitTest.class); + + @Spy ManagementServerImpl _mgmtServer = new ManagementServerImpl(); + @Mock AccountManager _accountMgr; + @Mock AlertDao _alertDao; + @Override + @Before + protected void setUp() { + MockitoAnnotations.initMocks(this); + _mgmtServer._alertDao = _alertDao; + _mgmtServer._accountMgr = _accountMgr; + doReturn(3L).when(_accountMgr).checkAccessAndSpecifyAuthority(any(Account.class), anyLong()); + when(_alertDao.archiveAlert(anyList(), anyString(), any(Date.class), anyLong())).thenReturn(true); + when(_alertDao.deleteAlert(anyList(), anyString(), any(Date.class), anyLong())).thenReturn(true); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testInjected() throws Exception { + s_logger.info("Starting test to archive and delete alerts"); + archiveAlerts(); + deleteAlerts(); + s_logger.info("archive/delete alerts: TEST PASSED"); + } + + protected void archiveAlerts() { + // archive alerts + String msg = "Archive Alerts: TEST FAILED"; + assertNotNull(msg, _mgmtServer._alertDao.archiveAlert(null, "system alert",null, 2L)); + } + + protected void deleteAlerts() { + // delete alerts + String msg = "Delete Alerts: TEST FAILED"; + assertNotNull(msg, _mgmtServer._alertDao.deleteAlert(null, "system alert",null, 2L)); + } +} diff --git a/server/test/com/cloud/event/EventControlsUnitTest.java b/server/test/com/cloud/event/EventControlsUnitTest.java new file mode 100644 index 00000000000..3fe47471e14 --- /dev/null +++ b/server/test/com/cloud/event/EventControlsUnitTest.java @@ -0,0 +1,68 @@ +package com.cloud.event; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyList; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.when; + +import java.util.Date; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; + +import com.cloud.event.dao.EventDao; +import com.cloud.server.ManagementServerImpl; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; + +public class EventControlsUnitTest extends TestCase{ + private static final Logger s_logger = Logger.getLogger(EventControlsUnitTest.class); + + @Spy ManagementServerImpl _mgmtServer = new ManagementServerImpl(); + @Mock AccountManager _accountMgr; + @Mock EventDao _eventDao; + List _events = null; + + @Override + @Before + protected void setUp() { + MockitoAnnotations.initMocks(this); + _mgmtServer._eventDao = _eventDao; + _mgmtServer._accountMgr = _accountMgr; + doNothing().when(_accountMgr).checkAccess(any(Account.class), any(AccessType.class), any(Boolean.class), any(ControlledEntity.class)); + when(_eventDao.listToArchiveOrDeleteEvents(anyList(), anyString(), any(Date.class), anyLong())).thenReturn(_events); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testInjected() throws Exception { + s_logger.info("Starting test to archive and delete events"); + archiveEvents(); + deleteEvents(); + s_logger.info("archive/delete events: TEST PASSED"); + } + + protected void archiveEvents() { + // archive alerts + doNothing().when(_eventDao).archiveEvents(_events); + } + + protected void deleteEvents() { + // delete alerts + } +} diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index f3112a1da27..ca15bdaf781 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -140,3 +140,48 @@ CREATE TABLE nic_secondary_ips ( ALTER TABLE `cloud`.`nics` ADD COLUMN secondary_ip SMALLINT DEFAULT '0' COMMENT 'secondary ips configured for the nic'; ALTER TABLE `cloud`.`user_ip_address` ADD COLUMN dnat_vmip VARCHAR(40); + +ALTER TABLE `cloud`.`alert` ADD COLUMN `archived` tinyint(1) unsigned NOT NULL DEFAULT 0; +ALTER TABLE `cloud`.`event` ADD COLUMN `archived` tinyint(1) unsigned NOT NULL DEFAULT 0; +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'alert.purge.interval', '86400', 'The interval (in seconds) to wait before running the alert purge thread'); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'alert.purge.delay', '0', 'Alerts older than specified number days will be purged. Set this value to 0 to never delete alerts'); + +DROP VIEW IF EXISTS `cloud`.`event_view`; +CREATE VIEW `cloud`.`event_view` AS + select + event.id, + event.uuid, + event.type, + event.state, + event.description, + event.created, + event.level, + event.parameters, + event.start_id, + eve.uuid start_uuid, + event.user_id, + event.archived, + user.username user_name, + account.id account_id, + account.uuid account_uuid, + account.account_name account_name, + account.type account_type, + domain.id domain_id, + domain.uuid domain_uuid, + domain.name domain_name, + domain.path domain_path, + projects.id project_id, + projects.uuid project_uuid, + projects.name project_name + from + `cloud`.`event` + inner join + `cloud`.`account` ON event.account_id = account.id + inner join + `cloud`.`domain` ON event.domain_id = domain.id + inner join + `cloud`.`user` ON event.user_id = user.id + left join + `cloud`.`projects` ON projects.project_account_id = event.account_id + left join + `cloud`.`event` eve ON event.start_id = eve.id; From c129c4e02e5925d92ecbe434d3e31a2fbaef6b7e Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 8 Mar 2013 14:38:35 -0800 Subject: [PATCH 03/16] Add missing Apache license header. --- .../com/cloud/alert/AlertControlsUnitTest.java | 16 ++++++++++++++++ .../com/cloud/event/EventControlsUnitTest.java | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/server/test/com/cloud/alert/AlertControlsUnitTest.java b/server/test/com/cloud/alert/AlertControlsUnitTest.java index 412a2619840..c1e4c5487f1 100644 --- a/server/test/com/cloud/alert/AlertControlsUnitTest.java +++ b/server/test/com/cloud/alert/AlertControlsUnitTest.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.alert; import static org.mockito.Matchers.any; diff --git a/server/test/com/cloud/event/EventControlsUnitTest.java b/server/test/com/cloud/event/EventControlsUnitTest.java index 3fe47471e14..3c2527565c9 100644 --- a/server/test/com/cloud/event/EventControlsUnitTest.java +++ b/server/test/com/cloud/event/EventControlsUnitTest.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.event; import static org.mockito.Matchers.any; From 860ea5c0dd2583ee9704b61489ec7108d4f502f1 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Thu, 7 Mar 2013 11:21:59 -0800 Subject: [PATCH 04/16] CLOUDSTACK-1451 Pass randomly generated UUID instead of empty string when create internal account as a part of project creation. Otherwise entityexistsexception would happen when attempt to create more than 1 project in the system --- server/src/com/cloud/projects/ProjectManagerImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java index 45a9a242147..33feb5dd57e 100755 --- a/server/src/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/com/cloud/projects/ProjectManagerImpl.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Properties; import java.util.Random; import java.util.TimeZone; +import java.util.UUID; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -204,7 +205,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { StringBuilder acctNm = new StringBuilder("PrjAcct-"); acctNm.append(name).append("-").append(owner.getDomainId()); - Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, "", 0); + Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, UUID.randomUUID().toString(), 0); Project project = _projectDao.persist(new ProjectVO(name, displayText, owner.getDomainId(), projectAccount.getId())); From e40ebcce8f73c76186a49778af3d7f096403aaec Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 8 Mar 2013 16:24:54 -0800 Subject: [PATCH 05/16] CLOUDSTACK-1179: API searches for names should not be fuzzy. fuzzy search should be done through keyword. --- server/src/com/cloud/api/query/QueryManagerImpl.java | 4 ++-- server/src/com/cloud/user/DomainManagerImpl.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 35fe2f35275..951d09ed185 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -1518,7 +1518,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { // pagination _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); - sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); + sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("volumeType", sb.entity().getVolumeType(), SearchCriteria.Op.LIKE); sb.and("instanceId", sb.entity().getVmId(), SearchCriteria.Op.EQ); @@ -1555,7 +1555,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } if (name != null) { - sc.setParameters("name", "%" + name + "%"); + sc.setParameters("name", name); } sc.setParameters("systemUse", 1); diff --git a/server/src/com/cloud/user/DomainManagerImpl.java b/server/src/com/cloud/user/DomainManagerImpl.java index 9f0ad53c94b..babaed37494 100644 --- a/server/src/com/cloud/user/DomainManagerImpl.java +++ b/server/src/com/cloud/user/DomainManagerImpl.java @@ -365,7 +365,7 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom SearchBuilder sb = _domainDao.createSearchBuilder(); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); - sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); + sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); sb.and("level", sb.entity().getLevel(), SearchCriteria.Op.EQ); sb.and("path", sb.entity().getPath(), SearchCriteria.Op.LIKE); sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ); @@ -379,7 +379,7 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom } if (domainName != null) { - sc.setParameters("name", "%" + domainName + "%"); + sc.setParameters("name", domainName); } if (level != null) { @@ -492,7 +492,7 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom if (!domains.isEmpty() && !sameDomain) { InvalidParameterValueException ex = new InvalidParameterValueException("Failed to update specified domain id with name '" + domainName + "' since it already exists in the system"); - ex.addProxyObject(domain, domainId, "domainId"); + ex.addProxyObject(domain, domainId, "domainId"); throw ex; } } From e35ce6587a2519fdbc56e8859ad6aa7dac00dd47 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Fri, 8 Mar 2013 17:42:06 -0800 Subject: [PATCH 06/16] CLOUDSTACK-1461: Don't set dns server for non-default ipv6 network The non-default parameter can be used by ipv4 as well in the future. --- .../agent/api/routing/DhcpEntryCommand.java | 10 ++++++++++ .../virtualnetwork/VirtualRoutingResource.java | 4 ++++ .../debian/config/etc/init.d/cloud-early-config | 4 +++- patches/systemvm/debian/config/root/edithosts.sh | 16 ++++++++++++---- .../vmware/resource/VmwareResource.java | 6 +++++- .../xen/resource/CitrixResourceBase.java | 4 ++++ scripts/network/domr/dhcp_entry.sh | 6 ++++-- .../VirtualNetworkApplianceManagerImpl.java | 3 ++- 8 files changed, 44 insertions(+), 9 deletions(-) diff --git a/api/src/com/cloud/agent/api/routing/DhcpEntryCommand.java b/api/src/com/cloud/agent/api/routing/DhcpEntryCommand.java index f0ce70e9a80..fd8d84c8c3a 100644 --- a/api/src/com/cloud/agent/api/routing/DhcpEntryCommand.java +++ b/api/src/com/cloud/agent/api/routing/DhcpEntryCommand.java @@ -31,6 +31,7 @@ public class DhcpEntryCommand extends NetworkElementCommand { String vmIp6Address; String ip6Gateway; String duid; + private boolean isDefault; protected DhcpEntryCommand() { @@ -46,6 +47,7 @@ public class DhcpEntryCommand extends NetworkElementCommand { this.vmIpAddress = vmIpAddress; this.vmName = vmName; this.vmIp6Address = vmIp6Address; + this.setDefault(true); } public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address, String dns, String gateway, String ip6Gateway) { @@ -129,4 +131,12 @@ public class DhcpEntryCommand extends NetworkElementCommand { public void setVmIp6Address(String ip6Address) { this.vmIp6Address = ip6Address; } + + public boolean isDefault() { + return isDefault; + } + + public void setDefault(boolean isDefault) { + this.isDefault = isDefault; + } } diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index 9dd471d6efa..7148e0710ca 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -600,6 +600,10 @@ public class VirtualRoutingResource implements Manager { command.add("-6", cmd.getVmIp6Address()); command.add("-u", cmd.getDuid()); } + + if (!cmd.isDefault()) { + command.add("-z"); + } final String result = command.execute(); return new Answer(cmd, result==null, result); diff --git a/patches/systemvm/debian/config/etc/init.d/cloud-early-config b/patches/systemvm/debian/config/etc/init.d/cloud-early-config index 4fb0a9bcde6..877ab06009d 100755 --- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config +++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config @@ -425,7 +425,6 @@ setup_dnsmasq() { sed -r -i s/^[#]?domain=.*$/domain=$DOMAIN/ /etc/dnsmasq.conf #answer all local domain queries sed -i -e "s/^[#]*local=.*$/local=\/$DOMAIN\//" /etc/dnsmasq.conf - fi if [ -n "$DNS_SEARCH_ORDER" ] @@ -447,6 +446,9 @@ setup_dnsmasq() { if [ $DHCP_RANGE_IP6 ] then sed -i -e "s/^dhcp-range_ip6=.*$/dhcp-range=$DHCP_RANGE_IP6,static/" /etc/dnsmasq.conf + # For nondefault6 tagged host, don't send dns-server information + sed -i /nondefault6/d /etc/dnsmasq.conf + echo "dhcp-option=nondefault6,option6:dns-server" >> /etc/dnsmasq.conf else sed -i -e "s/^dhcp-range_ip6=.*$//" /etc/dnsmasq.conf fi diff --git a/patches/systemvm/debian/config/root/edithosts.sh b/patches/systemvm/debian/config/root/edithosts.sh index 257de926724..9f21f206172 100755 --- a/patches/systemvm/debian/config/root/edithosts.sh +++ b/patches/systemvm/debian/config/root/edithosts.sh @@ -27,7 +27,7 @@ # $6 : comma separated static routes usage() { - printf "Usage: %s: -m -4 -6 -h -d -n -s -u \n" $(basename $0) >&2 + printf "Usage: %s: -m -4 -6 -h -d -n -s -u [-N]\n" $(basename $0) >&2 } mac= @@ -38,8 +38,9 @@ dflt= dns= routes= duid= +nondefault= -while getopts 'm:4:h:d:n:s:6:u:' OPTION +while getopts 'm:4:h:d:n:s:6:u:N' OPTION do case $OPTION in m) mac="$OPTARG" @@ -58,6 +59,8 @@ do ;; s) routes="$OPTARG" ;; + N) nondefault=1 + ;; ?) usage exit 2 ;; @@ -120,7 +123,12 @@ then fi if [ $ipv6 ] then - echo "id:$duid,[$ipv6],$host,infinite" >>$DHCP_HOSTS + if [ $nondefault ] + then + echo "id:$duid,set:nondefault6,[$ipv6],$host,infinite" >>$DHCP_HOSTS + else + echo "id:$duid,[$ipv6],$host,infinite" >>$DHCP_HOSTS + fi fi #delete leases to supplied mac and ip addresses @@ -176,8 +184,8 @@ then if [ "$dflt" == "0.0.0.0" ] then logger -t cloud "$0: unset default router for $ipv4" + logger -t cloud "$0: unset dns server for $ipv4" echo "$tag,3" >> $DHCP_OPTS - logger -t cloud "$0: setting dns server for $ipv4 to $dns" echo "$tag,6" >> $DHCP_OPTS echo "$tag,15" >> $DHCP_OPTS fi diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 83226a41db4..155d6d9718f 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -1755,7 +1755,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += " -6 " + cmd.getVmIp6Address(); args += " -u " + cmd.getDuid(); } - + + if (!cmd.isDefault()) { + args += " -N"; + } + if (s_logger.isDebugEnabled()) { s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/edithosts.sh " + args); } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 4a89806a49f..886fc6f04fa 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -1890,6 +1890,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe args += " -u " + cmd.getDuid(); } + if (!cmd.isDefault()) { + args += " -z"; + } + String result = callHostPlugin(conn, "vmops", "saveDhcpEntry", "args", args); if (result == null || result.isEmpty()) { return new Answer(cmd, false, "DhcpEntry failed"); diff --git a/scripts/network/domr/dhcp_entry.sh b/scripts/network/domr/dhcp_entry.sh index e417f7273a2..fb5a1669e72 100755 --- a/scripts/network/domr/dhcp_entry.sh +++ b/scripts/network/domr/dhcp_entry.sh @@ -22,7 +22,7 @@ # @VERSION@ usage() { - printf "Usage: %s: -r -m -v -n -s -d -N -6 -u \n" $(basename $0) >&2 + printf "Usage: %s: -r -m -v -n -s -d -N -6 -u [-z]\n" $(basename $0) >&2 exit 2 } @@ -40,7 +40,7 @@ duid= opts= -while getopts 'r:m:v:n:d:s:N:6:u:' OPTION +while getopts 'r:m:v:n:d:s:N:6:u:z' OPTION do case $OPTION in r) domrIp="$OPTARG" @@ -69,6 +69,8 @@ do u) duid="$OPTARG" opts="$opts -u $duid" ;; + z) opts="$opts -N" + ;; ?) usage exit 1 ;; diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index b387ab5934c..3cbd51d4cc4 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -3116,9 +3116,9 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V if (guestOS.getDisplayName().startsWith(name)) { needGateway = true; break; + } } } - } if (!needGateway) { gatewayIp = "0.0.0.0"; } @@ -3126,6 +3126,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V dhcpCommand.setIp6Gateway(nic.getIp6Gateway()); dhcpCommand.setDefaultDns(findDefaultDnsIp(vm.getId())); dhcpCommand.setDuid(NetUtils.getDuidLL(nic.getMacAddress())); + dhcpCommand.setDefault(nic.isDefaultNic()); dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); From ebafcf826b2506e779c8de8887d867ca4e0306bf Mon Sep 17 00:00:00 2001 From: Marcus Sorensen Date: Fri, 8 Mar 2013 23:14:08 -0700 Subject: [PATCH 07/16] CLOUDSTACK-1201 - Fix update to cloud user's home dir on mgmt server. It was printing a meaningless failure if the cloud user's home dir didn't need to be updated. Signed-off-by: Marcus Sorensen 1362809648 -0700 --- packaging/centos63/cloud.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packaging/centos63/cloud.spec b/packaging/centos63/cloud.spec index 002fbbb4d56..e340dd08c60 100644 --- a/packaging/centos63/cloud.spec +++ b/packaging/centos63/cloud.spec @@ -323,7 +323,10 @@ fi # change cloud user's home to 4.1+ version if needed. Would do this via 'usermod', but it # requires that cloud user not be in use, so RPM could not be installed while management is running -getent passwd cloud | grep -q /var/lib/cloud && sed -i 's/\/var\/lib\/cloud\/management/\/var\/cloudstack\/management/g' /etc/passwd +if getent passwd cloud | grep -q /var/lib/cloud; then + sed -i 's/\/var\/lib\/cloud\/management/\/var\/cloudstack\/management/g' /etc/passwd +fi + %post awsapi if [ -d "%{_datadir}/%{name}-management" ] ; then From 603b5ad985e2d952891be880699e8e8973f9007d Mon Sep 17 00:00:00 2001 From: Kishan Kavala Date: Fri, 8 Mar 2013 18:26:02 +0530 Subject: [PATCH 08/16] CLOUDSTACK-1569: Only forward API to source region and check for succcess. Do not convert the response to user/account/domain object since it is not updated locaaly. --- .../cloudstack/region/RegionManagerImpl.java | 46 +++++++------------ 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/server/src/org/apache/cloudstack/region/RegionManagerImpl.java b/server/src/org/apache/cloudstack/region/RegionManagerImpl.java index b4b55fd5a90..cb0b1a69ad8 100755 --- a/server/src/org/apache/cloudstack/region/RegionManagerImpl.java +++ b/server/src/org/apache/cloudstack/region/RegionManagerImpl.java @@ -29,11 +29,11 @@ import com.cloud.user.DomainManager; import com.cloud.user.UserAccount; import com.cloud.user.UserVO; import com.cloud.user.dao.AccountDao; +import com.cloud.user.dao.UserAccountDao; import com.cloud.user.dao.UserDao; import com.cloud.utils.component.Manager; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.uuididentity.dao.IdentityDao; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd; import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd; @@ -69,7 +69,7 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man @Inject private DomainManager _domainMgr; @Inject - private IdentityDao _identityDao; + private UserAccountDao _userAccountDao; private String _name; private int _id; @@ -251,7 +251,6 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man String command = "updateAccount"; List params = new ArrayList(); - params.add(new NameValuePair(ApiConstants.NEW_NAME, newAccountName)); params.add(new NameValuePair(ApiConstants.ID, account.getUuid())); params.add(new NameValuePair(ApiConstants.ACCOUNT, accountName)); params.add(new NameValuePair(ApiConstants.DOMAIN_ID, domain.getUuid())); @@ -266,14 +265,9 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man } else { //First update in the Region where account is created Region region = _regionDao.findById(regionId); - RegionAccount updatedAccount = RegionsApiUtil.makeAccountAPICall(region, command, params); - if (updatedAccount != null) { - Long id = _identityDao.getIdentityId("account", updatedAccount.getUuid()); - updatedAccount.setId(id); - Long domainID = _identityDao.getIdentityId("domain", updatedAccount.getDomainUuid()); - updatedAccount.setDomainId(domainID); + if (RegionsApiUtil.makeAPICall(region, command, params)) { s_logger.debug("Successfully updated account :"+account.getUuid()+" in source Region: "+region.getId()); - return updatedAccount; + return account; } else { throw new CloudRuntimeException("Error while updating account :"+account.getUuid()+" in source Region: "+region.getId()); } @@ -319,10 +313,9 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man } else { //First disable account in the Region where account is created Region region = _regionDao.findById(regionId); - Account retAccount = RegionsApiUtil.makeAccountAPICall(region, command, params); - if (retAccount != null) { + if (RegionsApiUtil.makeAPICall(region, command, params)) { s_logger.debug("Successfully disabled account :"+accountUUID+" in source Region: "+region.getId()); - return retAccount; + return account; } else { throw new CloudRuntimeException("Error while disabling account :"+accountUUID+" in source Region: "+region.getId()); } @@ -363,10 +356,9 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man } else { //First disable account in the Region where account is created Region region = _regionDao.findById(regionId); - Account retAccount = RegionsApiUtil.makeAccountAPICall(region, command, params); - if (retAccount != null) { + if (RegionsApiUtil.makeAPICall(region, command, params)) { s_logger.debug("Successfully enabled account :"+accountUUID+" in source Region: "+region.getId()); - return retAccount; + return account; } else { throw new CloudRuntimeException("Error while enabling account :"+accountUUID+" in source Region: "+region.getId()); } @@ -433,12 +425,9 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man } else { //First update in the Region where domain was created Region region = _regionDao.findById(regionId); - RegionDomain updatedDomain = RegionsApiUtil.makeDomainAPICall(region, command, params); - if (updatedDomain != null) { - Long parentId = _identityDao.getIdentityId("domain", updatedDomain.getParentUuid()); - updatedDomain.setParent(parentId); + if (RegionsApiUtil.makeAPICall(region, command, params)) { s_logger.debug("Successfully updated user :"+domainUUID+" in source Region: "+region.getId()); - return (DomainVO)updatedDomain; + return domain; } else { throw new CloudRuntimeException("Error while updating user :"+domainUUID+" in source Region: "+region.getId()); } @@ -510,10 +499,9 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man } else { //First update in the Region where user was created Region region = _regionDao.findById(regionId); - UserAccount updateUser = RegionsApiUtil.makeUserAccountAPICall(region, command, params); - if (updateUser != null) { + if (RegionsApiUtil.makeAPICall(region, command, params)) { s_logger.debug("Successfully updated user :"+userUUID+" in source Region: "+region.getId()); - return updateUser; + return _userAccountDao.findById(id); } else { throw new CloudRuntimeException("Error while updating user :"+userUUID+" in source Region: "+region.getId()); } @@ -541,10 +529,9 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man } else { //First disable in the Region where user was created Region region = _regionDao.findById(regionId); - UserAccount disabledUser = RegionsApiUtil.makeUserAccountAPICall(region, command, params); - if (disabledUser != null) { + if (RegionsApiUtil.makeAPICall(region, command, params)) { s_logger.debug("Successfully disabled user :"+user.getUuid()+" in source Region: "+region.getId()); - return disabledUser; + return _userAccountDao.findById(userId); } else { throw new CloudRuntimeException("Error while disabling user :"+user.getUuid()+" in source Region: "+region.getId()); } @@ -572,10 +559,9 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man } else { //First enable in the Region where user was created Region region = _regionDao.findById(regionId); - UserAccount enabledUser = RegionsApiUtil.makeUserAccountAPICall(region, command, params); - if (enabledUser != null) { + if (RegionsApiUtil.makeAPICall(region, command, params)) { s_logger.debug("Successfully enabled user :"+user.getUuid()+" in source Region: "+region.getId()); - return enabledUser; + return _userAccountDao.findById(userId); } else { throw new CloudRuntimeException("Error while enabling user :"+user.getUuid()+" in source Region: "+region.getId()); } From 9f4444c9e41ab5dbd6e2603533b9a47af759bbd3 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Mon, 11 Mar 2013 14:10:44 +0530 Subject: [PATCH 09/16] appliance: Add veewee definition for 64bit systemvm template Signed-off-by: Rohit Yadav --- .../definitions/systemvmtemplate64/base.sh | 25 ++ .../definitions/systemvmtemplate64/cleanup.sh | 21 ++ .../systemvmtemplate64/definition.rb | 45 +++ .../systemvmtemplate64/postinstall.sh | 220 +++++++++++ .../systemvmtemplate64/preseed.cfg | 357 ++++++++++++++++++ .../systemvmtemplate64/zerodisk.sh | 15 + 6 files changed, 683 insertions(+) create mode 100644 tools/appliance/definitions/systemvmtemplate64/base.sh create mode 100644 tools/appliance/definitions/systemvmtemplate64/cleanup.sh create mode 100644 tools/appliance/definitions/systemvmtemplate64/definition.rb create mode 100644 tools/appliance/definitions/systemvmtemplate64/postinstall.sh create mode 100644 tools/appliance/definitions/systemvmtemplate64/preseed.cfg create mode 100644 tools/appliance/definitions/systemvmtemplate64/zerodisk.sh diff --git a/tools/appliance/definitions/systemvmtemplate64/base.sh b/tools/appliance/definitions/systemvmtemplate64/base.sh new file mode 100644 index 00000000000..d6faea04b41 --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/base.sh @@ -0,0 +1,25 @@ +# Update the box +apt-get -y update +#apt-get -y install linux-headers-$(uname -r) build-essential +#apt-get -y install zlib1g-dev libssl-dev libreadline-gplv2-dev +apt-get -y install curl unzip + +# Set up sudo +echo 'vagrant ALL=NOPASSWD:ALL' > /etc/sudoers.d/vagrant + +# Tweak sshd to prevent DNS resolution (speed up logins) +echo 'UseDNS no' >> /etc/ssh/sshd_config + +# Remove 5s grub timeout to speed up booting +cat < /etc/default/grub +# If you change this file, run 'update-grub' afterwards to update +# /boot/grub/grub.cfg. + +GRUB_DEFAULT=0 +GRUB_TIMEOUT=0 +GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` +GRUB_CMDLINE_LINUX_DEFAULT="quiet" +GRUB_CMDLINE_LINUX="debian-installer=en_US" +EOF + +update-grub diff --git a/tools/appliance/definitions/systemvmtemplate64/cleanup.sh b/tools/appliance/definitions/systemvmtemplate64/cleanup.sh new file mode 100644 index 00000000000..9e98ab03531 --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/cleanup.sh @@ -0,0 +1,21 @@ +# Clean up +#apt-get -y remove linux-headers-$(uname -r) build-essential +apt-get -y remove dictionaries-common busybox +apt-get -y autoremove +apt-get autoclean +apt-get clean + +# Removing leftover leases and persistent rules +echo "cleaning up dhcp leases" +rm /var/lib/dhcp/* + +# Make sure Udev doesn't block our network +echo "cleaning up udev rules" +rm /etc/udev/rules.d/70-persistent-net.rules +mkdir /etc/udev/rules.d/70-persistent-net.rules +rm -rf /dev/.udev/ +rm /lib/udev/rules.d/75-persistent-net-generator.rules + +echo "Adding a 2 sec delay to the interface up, to make the dhclient happy" +echo "pre-up sleep 2" >> /etc/network/interfaces + diff --git a/tools/appliance/definitions/systemvmtemplate64/definition.rb b/tools/appliance/definitions/systemvmtemplate64/definition.rb new file mode 100644 index 00000000000..35ef878d35a --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/definition.rb @@ -0,0 +1,45 @@ +Veewee::Definition.declare({ + :cpu_count => '1', + :memory_size=> '256', + :disk_size => '2000', :disk_format => 'VDI', :hostiocache => 'off', + :os_type_id => 'Debian_64', + :iso_file => "debian-wheezy-DI-rc1-amd64-netinst.iso", + :iso_src => "http://cdimage.debian.org/cdimage/wheezy_di_rc1/amd64/iso-cd/debian-wheezy-DI-rc1-amd64-netinst.iso", + :iso_md5 => "412f77d4b98adf2a7d575745fd282d78", + :iso_download_timeout => "1000", + :boot_wait => "10", :boot_cmd_sequence => [ + '', + 'install ', + 'preseed/url=http://%IP%:%PORT%/preseed.cfg ', + 'debian-installer=en_US ', + 'auto ', + 'locale=en_US ', + 'kbd-chooser/method=us ', + 'netcfg/get_hostname=systemvm ', + 'netcfg/get_domain=apache.org ', + 'fb=false ', + 'debconf/frontend=noninteractive ', + 'console-setup/ask_detect=false ', + 'console-keymaps-at/keymap=us ', + 'keyboard-configuration/xkb-keymap=us ', + '' + ], + :kickstart_port => "7122", + :kickstart_timeout => "10000", + :kickstart_file => "preseed.cfg", + :ssh_login_timeout => "10000", + :ssh_user => "root", + :ssh_password => "password", + :ssh_key => "", + :ssh_host_port => "7222", + :ssh_guest_port => "22", + :sudo_cmd => "echo '%p'|sudo -S sh '%f'", + :shutdown_cmd => "halt -p", + :postinstall_files => [ + "base.sh", + "postinstall.sh", + "cleanup.sh", + "zerodisk.sh" + ], + :postinstall_timeout => "10000" +}) diff --git a/tools/appliance/definitions/systemvmtemplate64/postinstall.sh b/tools/appliance/definitions/systemvmtemplate64/postinstall.sh new file mode 100644 index 00000000000..8e745eb1ba9 --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/postinstall.sh @@ -0,0 +1,220 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +set -x + +ROOTPW=password +HOSTNAME=systemvm +CLOUDSTACK_RELEASE=4.2.0 + +install_packages() { + DEBIAN_FRONTEND=noninteractive + DEBIAN_PRIORITY=critical + + # Basic packages + apt-get --no-install-recommends -q -y --force-yes install rsyslog logrotate cron chkconfig insserv net-tools ifupdown vim-tiny netbase iptables + apt-get --no-install-recommends -q -y --force-yes install openssh-server openssl e2fsprogs dhcp3-client tcpdump socat wget + # apt-get --no-install-recommends -q -y --force-yes install grub-legacy + apt-get --no-install-recommends -q -y --force-yes install python bzip2 sed gawk diffutils grep gzip less tar telnet ftp rsync traceroute psmisc lsof procps monit inetutils-ping iputils-arping httping + apt-get --no-install-recommends -q -y --force-yes install dnsutils zip unzip ethtool uuid file iproute acpid virt-what sudo + + # sysstat + echo 'sysstat sysstat/enable boolean true' | debconf-set-selections + apt-get --no-install-recommends -q -y --force-yes install sysstat + # apache + apt-get --no-install-recommends -q -y --force-yes install apache2 ssl-cert + # haproxy + apt-get --no-install-recommends -q -y --force-yes install haproxy + # dnsmasq + apt-get --no-install-recommends -q -y --force-yes install dnsmasq + # nfs client + apt-get --no-install-recommends -q -y --force-yes install nfs-common + + # vpn stuff + apt-get --no-install-recommends -q -y --force-yes install xl2tpd bcrelay ppp ipsec-tools tdb-tools + echo "openswan openswan/install_x509_certificate boolean false" | debconf-set-selections + echo "openswan openswan/install_x509_certificate seen true" | debconf-set-selections + apt-get --no-install-recommends -q -y --force-yes install openswan + + # vmware tools + apt-get --no-install-recommends -q -y --force-yes install open-vm-tools + # xenstore utils + apt-get --no-install-recommends -q -y --force-yes install xenstore-utils libxenstore3.0 + # keepalived and conntrackd for redundant router + apt-get --no-install-recommends -q -y --force-yes install keepalived conntrackd ipvsadm libnetfilter-conntrack3 libnl1 + # ipcalc + apt-get --no-install-recommends -q -y --force-yes install ipcalc + # java + apt-get --no-install-recommends -q -y --force-yes install default-jre-headless + + echo "iptables-persistent iptables-persistent/autosave_v4 boolean true" | debconf-set-selections + echo "iptables-persistent iptables-persistent/autosave_v6 boolean true" | debconf-set-selections + apt-get --no-install-recommends -q -y --force-yes install iptables-persistent +} + +setup_accounts() { + # Setup sudo to allow no-password sudo for "admin" + groupadd -r admin + # Create a 'cloud' user if it's not there + id cloud + if [[ $? -ne 0 ]] + then + useradd -G admin cloud + else + usermod -a -G admin cloud + fi + echo "root:$ROOTPW" | chpasswd + echo "cloud:`openssl rand -base64 32`" | chpasswd + sed -i -e '/Defaults\s\+env_reset/a Defaults\texempt_group=admin' /etc/sudoers + sed -i -e 's/%admin ALL=(ALL) ALL/%admin ALL=NOPASSWD:ALL/g' /etc/sudoers + # Disable password based authentication via ssh, this will take effect on next reboot + sed -i -e 's/^.*PasswordAuthentication .*$/PasswordAuthentication no/g' /etc/ssh/sshd_config + # Secure ~/.ssh + mkdir -p /home/cloud/.ssh + chmod 700 /home/cloud/.ssh +} + +fix_nameserver() { + # Replace /etc/resolv.conf also + cat > /etc/resolv.conf << EOF +nameserver 8.8.8.8 +nameserver 4.4.4.4 +EOF +} + +fix_inittab() { + # Fix inittab + cat >> /etc/inittab << EOF + +vc:2345:respawn:/sbin/getty 38400 hvc0 +EOF +} + +fix_acpid() { + # Fix acpid + mkdir -p /etc/acpi/events + cat >> /etc/acpi/events/power << EOF +event=button/power.* +action=/usr/local/sbin/power.sh "%e" +EOF + cat >> /usr/local/sbin/power.sh << EOF +#!/bin/bash +/sbin/poweroff +EOF + chmod a+x /usr/local/sbin/power.sh +} + +fix_hostname() { + # Fix hostname in openssh-server generated keys + sed -i "s/root@\(.*\)$/root@$HOSTNAME/g" /etc/ssh/ssh_host_*.pub + # Fix hostname to override one provided by dhcp during vm build + echo "$HOSTNAME" > /etc/hostname + hostname $HOSTNAME + # Delete entry in /etc/hosts derived from dhcp + sed -i '/127.0.1.1/d' /etc/hosts +} + +fix_locale() { + cat >> /etc/default/locale << EOF +LANG=en_US.UTF-8 +LC_ALL=en_US.UTF-8 +EOF + cat >> /etc/locale.gen << EOF +en_US.UTF-8 UTF-8 +EOF + + locale-gen en_US.UTF-8 +} + +do_fixes() { + fix_nameserver + fix_inittab + fix_acpid + fix_hostname + fix_locale +} + +configure_apache2() { + # Enable ssl, rewrite and auth + a2enmod ssl rewrite auth_basic auth_digest + a2ensite default-ssl + # Backup stock apache configuration since we may modify it in Secondary Storage VM + cp /etc/apache2/sites-available/default /etc/apache2/sites-available/default.orig + cp /etc/apache2/sites-available/default-ssl /etc/apache2/sites-available/default-ssl.orig +} + +configure_services() { + mkdir -p /var/www/html + mkdir -p /opt/cloud/bin + mkdir -p /var/cache/cloud + mkdir -p /usr/share/cloud + mkdir -p /usr/local/cloud + mkdir -p /root/.ssh + # Fix haproxy directory issue + mkdir -p /var/lib/haproxy + + # Get config files from master + snapshot_url="https://git-wip-us.apache.org/repos/asf?p=incubator-cloudstack.git;a=snapshot;h=HEAD;sf=tgz" + snapshot_dir="/opt/incubator-cloudstack*" + cd /opt + wget $snapshot_url -O cloudstack.tar.gz + tar -zxvf cloudstack.tar.gz + cp -rv $snapshot_dir/patches/systemvm/debian/config/* / + cp -rv $snapshot_dir/patches/systemvm/debian/vpn/* / + mkdir -p /usr/share/cloud/ + cd $snapshot_dir/patches/systemvm/debian/config + tar -cvf /usr/share/cloud/cloud-scripts.tar * + cd $snapshot_dir/patches/systemvm/debian/vpn + tar -rvf /usr/share/cloud/cloud-scripts.tar * + cd /opt + rm -fr $snapshot_dir cloudstack.tar.gz + + chkconfig --add cloud-early-config + chkconfig cloud-early-config on + chkconfig --add cloud-passwd-srvr + chkconfig cloud-passwd-srvr off + chkconfig --add cloud + chkconfig cloud off + chkconfig monit off + chkconfig xl2tpd off +} + +do_signature() { + mkdir -p /var/cache/cloud/ + gzip -c /usr/share/cloud/cloud-scripts.tar > /usr/share/cloud/cloud-scripts.tgz + md5sum /usr/share/cloud/cloud-scripts.tgz | awk '{print $1}' > /var/cache/cloud/cloud-scripts-signature + echo "Cloudstack Release $CLOUDSTACK_RELEASE $(date)" > /etc/cloudstack-release +} + +begin=$(date +%s) + +echo "*************INSTALLING PACKAGES********************" +install_packages +echo "*************DONE INSTALLING PACKAGES********************" +setup_accounts +echo "*************DONE ACCOUNT SETUP********************" +configure_services +configure_apache2 +echo "*************DONE SETTING UP SERVICES********************" +do_fixes +echo "*************DONE FIXING CONFIGURATION********************" +do_signature + +fin=$(date +%s) +t=$((fin-begin)) + +echo "Signed systemvm build, finished building systemvm appliance in $t seconds" diff --git a/tools/appliance/definitions/systemvmtemplate64/preseed.cfg b/tools/appliance/definitions/systemvmtemplate64/preseed.cfg new file mode 100644 index 00000000000..ac9edd31213 --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/preseed.cfg @@ -0,0 +1,357 @@ +#### Contents of the preconfiguration file (for squeeze) +### Localization +# Locale sets language and country. +d-i debian-installer/locale string en_US + +# Keyboard selection. +#d-i console-tools/archs select at +d-i console-keymaps-at/keymap select us +# Example for a different keyboard architecture +#d-i console-keymaps-usb/keymap select mac-usb-us + +### Network configuration +# netcfg will choose an interface that has link if possible. This makes it +# skip displaying a list if there is more than one interface. +d-i netcfg/choose_interface select auto + +# To pick a particular interface instead: +#d-i netcfg/choose_interface select eth1 + +# If you have a slow dhcp server and the installer times out waiting for +# it, this might be useful. +#d-i netcfg/dhcp_timeout string 60 + +# If you prefer to configure the network manually, uncomment this line and +# the static network configuration below. +#d-i netcfg/disable_dhcp boolean true + +# If you want the preconfiguration file to work on systems both with and +# without a dhcp server, uncomment these lines and the static network +# configuration below. +#d-i netcfg/dhcp_failed note +#d-i netcfg/dhcp_options select Configure network manually + +# Static network configuration. +#d-i netcfg/get_nameservers string 192.168.1.1 +#d-i netcfg/get_ipaddress string 192.168.1.42 +#d-i netcfg/get_netmask string 255.255.255.0 +#d-i netcfg/get_gateway string 192.168.1.1 +#d-i netcfg/confirm_static boolean true + +# Any hostname and domain names assigned from dhcp take precedence over +# values set here. However, setting the values still prevents the questions +# from being shown, even if values come from dhcp. +d-i netcfg/get_hostname string systemvm +d-i netcfg/get_domain string cloudstack.org + +# Disable that annoying WEP key dialog. +d-i netcfg/wireless_wep string +# The wacky dhcp hostname that some ISPs use as a password of sorts. +#d-i netcfg/dhcp_hostname string radish + +# If non-free firmware is needed for the network or other hardware, you can +# configure the installer to always try to load it, without prompting. Or +# change to false to disable asking. +#d-i hw-detect/load_firmware boolean true + +### Network console +# Use the following settings if you wish to make use of the network-console +# component for remote installation over SSH. This only makes sense if you +# intend to perform the remainder of the installation manually. +#d-i anna/choose_modules string network-console +#d-i network-console/password password r00tme +#d-i network-console/password-again password r00tme + +### Mirror settings +# If you select ftp, the mirror/country string does not need to be set. +#d-i mirror/protocol string ftp +d-i mirror/country string manual +d-i mirror/http/hostname string http.us.debian.org +d-i mirror/http/directory string /debian +d-i mirror/http/proxy string + +# Suite to install. +#d-i mirror/suite string testing +# Suite to use for loading installer components (optional). +#d-i mirror/udeb/suite string testing + +### Clock and time zone setup +# Controls whether or not the hardware clock is set to UTC. +d-i clock-setup/utc boolean true + +# You may set this to any valid setting for $TZ; see the contents of +# /usr/share/zoneinfo/ for valid values. +d-i time/zone string UTC + +# Controls whether to use NTP to set the clock during the install +d-i clock-setup/ntp boolean true +# NTP server to use. The default is almost always fine here. +#d-i clock-setup/ntp-server string ntp.example.com + +### Partitioning +# If the system has free space you can choose to only partition that space. +#d-i partman-auto/init_automatically_partition select biggest_free + +# Alternatively, you can specify a disk to partition. The device name must +# be given in traditional non-devfs format. +# Note: A disk must be specified, unless the system has only one disk. +# For example, to use the first SCSI/SATA hard disk: +d-i partman-auto/disk string /dev/sda +# In addition, you'll need to specify the method to use. +# The presently available methods are: "regular", "lvm" and "crypto" +d-i partman-auto/method string regular + +# If one of the disks that are going to be automatically partitioned +# contains an old LVM configuration, the user will normally receive a +# warning. This can be preseeded away... +#d-i partman-lvm/device_remove_lvm boolean true +# The same applies to pre-existing software RAID array: +#d-i partman-md/device_remove_md boolean true + +# And the same goes for the confirmation to write the lvm partitions. +#d-i partman-lvm/confirm boolean true +#d-i partman-lvm/confirm_nooverwrite boolean true + +#d-i partman/choose_partition select finish +#d-i partman-auto-lvm/guided_size string max + +# You can choose one of the three predefined partitioning recipes: +# - atomic: all files in one partition +# - home: separate /home partition +# - multi: separate /home, /usr, /var, and /tmp partitions +d-i partman-auto/choose_recipe select atomic +#d-i partman/default_filesystem string ext3 + +# Or provide a recipe of your own... +# The recipe format is documented in the file devel/partman-auto-recipe.txt. +# If you have a way to get a recipe file into the d-i environment, you can +# just point at it. +#d-i partman-auto/expert_recipe_file string /hd-media/recipe + +d-i partman-auto/expert_recipe string \ + boot-root :: \ + 40 50 100 ext4 \ + $primary{ } $bootable{ } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /boot } \ + . \ + 400 40 500 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ / } \ + . \ + 60 100 200 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /home } \ + . \ + 500 30 1000 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /usr } \ + . \ + 400 40 500 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /opt } \ + . \ + 500 60 1000 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /var } \ + . \ + 100 70 400 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /tmp } \ + . \ + 64 512 300% linux-swap \ + method{ swap } format{ } \ + . + +# If not, you can put an entire recipe into the preconfiguration file in one +# (logical) line. This example creates a small /boot partition, suitable +# swap, and uses the rest of the space for the root partition: +#d-i partman-auto/expert_recipe string \ +# boot-root :: \ +# 40 50 100 ext3 \ +# $primary{ } $bootable{ } \ +# method{ format } format{ } \ +# use_filesystem{ } filesystem{ ext3 } \ +# mountpoint{ /boot } \ +# . \ +# 500 10000 1000000000 ext3 \ +# method{ format } format{ } \ +# use_filesystem{ } filesystem{ ext3 } \ +# mountpoint{ / } \ +# . \ +# 64 512 300% linux-swap \ +# method{ swap } format{ } \ +# . + +#The preseed line that "selects finish" needs to be in a certain order in your preseed, the example-preseed does not follow this. +#http://ubuntuforums.org/archive/index.php/t-1504045.html + +# This makes partman automatically partition without confirmation, provided +# that you told it what to do using one of the methods above. +#d-i partman-partitioning/confirm_write_new_label boolean true +d-i partman/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true + +### Base system installation +# Select the initramfs generator used to generate the initrd for 2.6 kernels. +#d-i base-installer/kernel/linux/initramfs-generators string yaird + +# The kernel image (meta) package to be installed; "none" can be used if no +# kernel is to be installed. +#d-i base-installer/kernel/image string linux-image-2.6-486 + +### Account setup +# Skip creation of a root account (normal user account will be able to +# use sudo). +d-i passwd/root-login boolean true +# Alternatively, to skip creation of a normal user account. +#d-i passwd/make-user boolean false + +# Root password, either in clear text +d-i passwd/root-password password password +d-i passwd/root-password-again password password +# or encrypted using an MD5 hash. +#d-i passwd/root-password-crypted password [MD5 hash] + +# To create a normal user account. +d-i passwd/user-fullname string Cloud Stack +d-i passwd/username string cloud +# Normal user's password, either in clear text +d-i passwd/user-password password cloud +d-i passwd/user-password-again password cloud +# or encrypted using an MD5 hash. +#d-i passwd/user-password-crypted password [MD5 hash] +# Create the first user with the specified UID instead of the default. +#d-i passwd/user-uid string 1010 +d-i user-setup/encrypt-home boolean false +d-i user-setup/allow-password-weak boolean true + +# The user account will be added to some standard initial groups. To +# override that, use this. +d-i passwd/user-default-groups string audio cdrom video admin + +### Apt setup +# You can choose to install non-free and contrib software. +#d-i apt-setup/non-free boolean true +#d-i apt-setup/contrib boolean true +# Uncomment this if you don't want to use a network mirror. +#d-i apt-setup/use_mirror boolean false +# Select which update services to use; define the mirrors to be used. +# Values shown below are the normal defaults. +#d-i apt-setup/services-select multiselect security, volatile +#d-i apt-setup/security_host string security.debian.org +#d-i apt-setup/volatile_host string volatile.debian.org + + +# By default the installer requires that repositories be authenticated +# using a known gpg key. This setting can be used to disable that +# authentication. Warning: Insecure, not recommended. +#d-i debian-installer/allow_unauthenticated string true + +### Package selection +tasksel tasksel/first multiselect ssh-server +# If the desktop task is selected, install the kde and xfce desktops +# instead of the default gnome desktop. +#tasksel tasksel/desktop multiselect kde, xfce + +# Individual additional packages to install +d-i pkgsel/include string openssh-server ntp acpid sudo bzip2 + +# Whether to upgrade packages after debootstrap. +# Allowed values: none, safe-upgrade, full-upgrade +d-i pkgsel/upgrade select none + +# Some versions of the installer can report back on what software you have +# installed, and what software you use. The default is not to report back, +# but sending reports helps the project determine what software is most +# popular and include it on CDs. +popularity-contest popularity-contest/participate boolean false + +### Boot loader installation +# Grub is the default boot loader (for x86). If you want lilo installed +# instead, uncomment this: +#d-i grub-installer/skip boolean true +# To also skip installing lilo, and install no bootloader, uncomment this +# too: +#d-i lilo-installer/skip boolean true + +# This is fairly safe to set, it makes grub install automatically to the MBR +# if no other operating system is detected on the machine. +d-i grub-installer/only_debian boolean true + +# This one makes grub-installer install to the MBR if it also finds some other +# OS, which is less safe as it might not be able to boot that other OS. +#d-i grub-installer/with_other_os boolean true + +# Alternatively, if you want to install to a location other than the mbr, +# uncomment and edit these lines: +#d-i grub-installer/only_debian boolean false +#d-i grub-installer/with_other_os boolean false +#d-i grub-installer/bootdev string (hd0,0) +# To install grub to multiple disks: +#d-i grub-installer/bootdev string (hd0,0) (hd1,0) (hd2,0) + +# Optional password for grub, either in clear text +#d-i grub-installer/password password r00tme +#d-i grub-installer/password-again password r00tme +# or encrypted using an MD5 hash, see grub-md5-crypt(8). +#d-i grub-installer/password-crypted password [MD5 hash] + +### Finishing up the installation +# During installations from serial console, the regular virtual consoles +# (VT1-VT6) are normally disabled in /etc/inittab. Uncomment the next +# line to prevent this. +#d-i finish-install/keep-consoles boolean true + +# Avoid that last message about the install being complete. +d-i finish-install/reboot_in_progress note + +# This will prevent the installer from ejecting the CD during the reboot, +# which is useful in some situations. +#d-i cdrom-detect/eject boolean false + +# This is how to make the installer shutdown when finished, but not +# reboot into the installed system. +#d-i debian-installer/exit/halt boolean true +# This will power off the machine instead of just halting it. +#d-i debian-installer/exit/poweroff boolean true + +### Preseeding other packages +# Depending on what software you choose to install, or if things go wrong +# during the installation process, it's possible that other questions may +# be asked. You can preseed those too, of course. To get a list of every +# possible question that could be asked during an install, do an +# installation, and then run these commands: +# debconf-get-selections --installer > file +# debconf-get-selections >> file + + +#### Advanced options +### Running custom commands during the installation +# d-i preseeding is inherently not secure. Nothing in the installer checks +# for attempts at buffer overflows or other exploits of the values of a +# preconfiguration file like this one. Only use preconfiguration files from +# trusted locations! To drive that home, and because it's generally useful, +# here's a way to run any shell command you'd like inside the installer, +# automatically. + +# This first command is run as early as possible, just after +# preseeding is read. +# Prevent packaged version of VirtualBox Guest Additions being installed: +d-i preseed/early_command string sed -i \ + '/in-target/idiscover(){/sbin/discover|grep -v VirtualBox;}' \ + /usr/lib/pre-pkgsel.d/20install-hwpackages + +# This command is run just before the install finishes, but when there is +# still a usable /target directory. You can chroot to /target and use it +# directly, or use the apt-install and in-target commands to easily install +# packages and run commands in the target system. diff --git a/tools/appliance/definitions/systemvmtemplate64/zerodisk.sh b/tools/appliance/definitions/systemvmtemplate64/zerodisk.sh new file mode 100644 index 00000000000..25bd8c4af2d --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/zerodisk.sh @@ -0,0 +1,15 @@ +# Clean up stuff copied in by veewee +rm -fv /root/*.iso +rm -fv /root/base.sh /root/cleanup.sh /root/postinstall.sh /root/zerodisk.sh +rm -fv .veewee_version .veewee_params .vbox_version + +echo "Cleaning up" + +# Zero out the free space to save space in the final image: +for path in / /boot /usr /var /opt /tmp +do + dd if=/dev/zero of=$path/zero bs=1M + sync + rm -f $path/zero + echo "Completed zero-ing out disk on $path" +done From 41e39dd9fe24d05b8942a9b18897492a37f1a58e Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Mon, 11 Mar 2013 14:12:20 +0530 Subject: [PATCH 10/16] LICENSE: Fix attribution for 64bit template Signed-off-by: Rohit Yadav --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 5e29e2b12bc..00afdb41fd6 100644 --- a/LICENSE +++ b/LICENSE @@ -370,7 +370,7 @@ Within the scripts/vm/hypervisor/xenserver directory from OpenStack, LLC http://www.openstack.org swift -Within the tools/appliance/definitions/systemvmtemplate directory +Within the tools/appliance/definitions/systemvmtemplate and tools/appliance/definitions/systemvmtemplate64 directory licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows) Copyright (c) 2010-2012 Patrick Debois From 72c1a888ebd73977182432b9f0c9bd1a579a6adc Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Mon, 11 Mar 2013 14:19:30 +0530 Subject: [PATCH 11/16] appliance: Fix build.sh to build 64bit systemvm appliance as well TODO: Make it general like boxer.sh in tools/devcloud/src Signed-off-by: Rohit Yadav --- tools/appliance/README.md | 4 ++-- tools/appliance/build.sh | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tools/appliance/README.md b/tools/appliance/README.md index 2f6f656212d..559f79c6adb 100644 --- a/tools/appliance/README.md +++ b/tools/appliance/README.md @@ -43,7 +43,7 @@ Note, gem may require gcc-4.2, make sure link exists: Just run build.sh, it will export archived appliances for KVM, Xen, VMWare and HyperV in `dist`: - sh build.sh + sh build.sh [systemvmtemplate|systemvmtemplate64] # Building SystemVM template appliance manually @@ -51,7 +51,7 @@ List available appliances one can build: veewee vbox list -Modify scripts in definitions/systemvmtemplate/ as per needs. +Modify scripts in definitions/*appliance*/ as per needs. Build systemvm template appliance: veewee vbox build 'systemvmtemplate' diff --git a/tools/appliance/build.sh b/tools/appliance/build.sh index 69e15d88ca7..74307a06fc3 100644 --- a/tools/appliance/build.sh +++ b/tools/appliance/build.sh @@ -18,7 +18,13 @@ set -x -appliance="systemvmtemplate" +if [ "$1"!="" ] +then + appliance="$1" +else + appliance="systemvmtemplate" +fi + build_date=`date +%Y-%m-%d` branch="master" rootdir=$PWD From 7e7ceba83bb71b9fb00f10643b90794d21c868ba Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Mon, 11 Mar 2013 14:56:20 +0530 Subject: [PATCH 12/16] appliance: Fix hardcoded appliance name while checking and removing shared folders Signed-off-by: Rohit Yadav --- tools/appliance/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/appliance/build.sh b/tools/appliance/build.sh index 74307a06fc3..d18faaf7ce6 100644 --- a/tools/appliance/build.sh +++ b/tools/appliance/build.sh @@ -52,7 +52,7 @@ hdd_path=`vboxmanage list hdds | grep $appliance | grep vdi | cut -c 14-` shared_folders=`vboxmanage showvminfo $appliance | grep Name | grep Host` while [ "$shared_folders" != "" ] do - vboxmanage sharedfolder remove systemvmtemplate --name "`echo $shared_folders | head -1 | cut -c 8- | cut -d \' -f 1`" + vboxmanage sharedfolder remove $appliance --name "`echo $shared_folders | head -1 | cut -c 8- | cut -d \' -f 1`" shared_folders=`vboxmanage showvminfo $appliance | grep Name | grep Host` done From cccdbe630904e4a9d62c0ee616159b6e984ec844 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Mon, 11 Mar 2013 14:59:11 +0530 Subject: [PATCH 13/16] pom: Exclude systemvmtemplate64 during rat checking, attr already fixed in LICENSE Signed-off-by: Rohit Yadav --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index 6b0a9ccfeac..86482d7a77b 100644 --- a/pom.xml +++ b/pom.xml @@ -381,6 +381,11 @@ tools/appliance/definitions/systemvmtemplate/definition.rb tools/appliance/definitions/systemvmtemplate/preseed.cfg tools/appliance/definitions/systemvmtemplate/zerodisk.sh + tools/appliance/definitions/systemvmtemplate64/base.sh + tools/appliance/definitions/systemvmtemplate64/cleanup.sh + tools/appliance/definitions/systemvmtemplate64/definition.rb + tools/appliance/definitions/systemvmtemplate64/preseed.cfg + tools/appliance/definitions/systemvmtemplate64/zerodisk.sh tools/cli/cloudmonkey.egg-info/* tools/devcloud/src/deps/boxes/basebox-build/definition.rb tools/devcloud/src/deps/boxes/basebox-build/preseed.cfg From 75261eb317a763114a6054664f4adf3f7a2c2709 Mon Sep 17 00:00:00 2001 From: Saksham Srivastava Date: Mon, 11 Mar 2013 16:38:02 +0530 Subject: [PATCH 14/16] CLOUDSTACK-924 : Volumes created from snapshots misses the source template information.Fixed the issue with volumes now getting the template id. Signed Off by : - Nitin Mehta --- server/src/com/cloud/storage/VolumeManagerImpl.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index f0e60283067..4951975786f 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -813,6 +813,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { Long diskOfferingId = null; DiskOfferingVO diskOffering = null; Long size = null; + // Volume VO used for extracting the source template id + VolumeVO parentVolume = null; // validate input parameters before creating the volume if ((cmd.getSnapshotId() == null && cmd.getDiskOfferingId() == null) @@ -891,6 +893,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { + snapshotId + " is not in " + Snapshot.State.BackedUp + " state yet and can't be used for volume creation"); } + parentVolume = _volsDao.findByIdIncludingRemoved(snapshotCheck.getVolumeId()); diskOfferingId = snapshotCheck.getDiskOfferingId(); diskOffering = _diskOfferingDao.findById(diskOfferingId); @@ -947,6 +950,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { volume.setUpdated(new Date()); volume.setDomainId((caller == null) ? Domain.ROOT_DOMAIN : caller .getDomainId()); + if (parentVolume != null) { + volume.setTemplateId(parentVolume.getTemplateId()); + } else { + volume.setTemplateId(null); + } volume = _volsDao.persist(volume); if (cmd.getSnapshotId() == null) { From e173aa16f6823fe9ed365b397de4774f11bc3862 Mon Sep 17 00:00:00 2001 From: Dennis Lawler Date: Sun, 10 Mar 2013 12:16:37 -0700 Subject: [PATCH 15/16] CLOUDSTACK-1620: getXenServer602GuestOsType -> getXenServer610GuestOsType Fixing XenServer 6.1 OS types incompatible with XS6.0 --- .../hypervisor/xen/resource/CitrixHelper.java | 41 ++++++++++--------- .../xen/resource/XenServer610Resource.java | 2 +- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixHelper.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixHelper.java index 1b8496ff287..828a8279f9a 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixHelper.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixHelper.java @@ -576,13 +576,12 @@ public class CitrixHelper { _xenServer610GuestOsMap.put("CentOS 5.6 (64-bit)", "CentOS 5 (64-bit)"); _xenServer610GuestOsMap.put("CentOS 5.7 (32-bit)", "CentOS 5 (32-bit)"); _xenServer610GuestOsMap.put("CentOS 5.7 (64-bit)", "CentOS 5 (64-bit)"); - _xenServer610GuestOsMap.put("CentOS 6.0 (32-bit)", "CentOS 6.0 (32-bit)"); - _xenServer610GuestOsMap.put("CentOS 6.0 (64-bit)", "CentOS 6.0 (64-bit)"); - _xenServer610GuestOsMap.put("CentOS 6.1 (32-bit)", "CentOS 6.1 (32-bit)"); - _xenServer610GuestOsMap.put("CentOS 6.1 (64-bit)", "CentOS 6.1 (64-bit)"); - _xenServer610GuestOsMap.put("CentOS 6.2 (32-bit)", "CentOS 6.2 (32-bit)"); - _xenServer610GuestOsMap.put("CentOS 6.2 (64-bit)", "CentOS 6.2 (64-bit)"); - _xenServer610GuestOsMap.put("Debian GNU/Linux 5.0 (32-bit)", "Debian Lenny 5.0 (32-bit)"); + _xenServer610GuestOsMap.put("CentOS 6.0 (32-bit)", "CentOS 6 (32-bit)"); + _xenServer610GuestOsMap.put("CentOS 6.0 (64-bit)", "CentOS 6 (64-bit)"); + _xenServer610GuestOsMap.put("CentOS 6.1 (32-bit)", "CentOS 6 (32-bit)"); + _xenServer610GuestOsMap.put("CentOS 6.1 (64-bit)", "CentOS 6 (64-bit)"); + _xenServer610GuestOsMap.put("CentOS 6.2 (32-bit)", "CentOS 6 (32-bit)"); + _xenServer610GuestOsMap.put("CentOS 6.2 (64-bit)", "CentOS 6 (64-bit)"); _xenServer610GuestOsMap.put("Debian GNU/Linux 6(32-bit)", "Debian Squeeze 6.0 (32-bit)"); _xenServer610GuestOsMap.put("Debian GNU/Linux 6(64-bit)", "Debian Squeeze 6.0 (64-bit)"); _xenServer610GuestOsMap.put("Oracle Enterprise Linux 5.0 (32-bit)", "Oracle Enterprise Linux 5 (32-bit)"); @@ -601,12 +600,12 @@ public class CitrixHelper { _xenServer610GuestOsMap.put("Oracle Enterprise Linux 5.6 (64-bit)", "Oracle Enterprise Linux 5 (64-bit)"); _xenServer610GuestOsMap.put("Oracle Enterprise Linux 5.7 (32-bit)", "Oracle Enterprise Linux 5 (32-bit)"); _xenServer610GuestOsMap.put("Oracle Enterprise Linux 5.7 (64-bit)", "Oracle Enterprise Linux 5 (64-bit)"); - _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.0 (32-bit)", "Oracle Enterprise Linux 6.0 (32-bit)"); - _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.0 (64-bit)", "Oracle Enterprise Linux 6.0 (64-bit)"); - _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.1 (32-bit)", "Oracle Enterprise Linux 6.1 (32-bit)"); - _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.1 (64-bit)", "Oracle Enterprise Linux 6.1 (64-bit)"); - _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.2 (32-bit)", "Oracle Enterprise Linux 6.2 (32-bit)"); - _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.2 (64-bit)", "Oracle Enterprise Linux 6.2 (64-bit)"); + _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.0 (32-bit)", "Oracle Enterprise Linux 6 (32-bit)"); + _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.0 (64-bit)", "Oracle Enterprise Linux 6 (64-bit)"); + _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.1 (32-bit)", "Oracle Enterprise Linux 6 (32-bit)"); + _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.1 (64-bit)", "Oracle Enterprise Linux 6 (64-bit)"); + _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.2 (32-bit)", "Oracle Enterprise Linux 6 (32-bit)"); + _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.2 (64-bit)", "Oracle Enterprise Linux 6 (64-bit)"); _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 4.5 (32-bit)", "Red Hat Enterprise Linux 4.5 (32-bit)"); _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 4.6 (32-bit)", "Red Hat Enterprise Linux 4.6 (32-bit)"); _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 4.7 (32-bit)", "Red Hat Enterprise Linux 4.7 (32-bit)"); @@ -627,12 +626,12 @@ public class CitrixHelper { _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 5.6 (64-bit)", "Red Hat Enterprise Linux 5 (64-bit)"); _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 5.7 (32-bit)", "Red Hat Enterprise Linux 5 (32-bit)"); _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 5.7 (64-bit)", "Red Hat Enterprise Linux 5 (64-bit)"); - _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.0 (32-bit)", "Red Hat Enterprise Linux 6.0 (32-bit)"); - _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.0 (64-bit)", "Red Hat Enterprise Linux 6.0 (64-bit)"); - _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.1 (32-bit)", "Red Hat Enterprise Linux 6.1 (32-bit)"); - _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.1 (64-bit)", "Red Hat Enterprise Linux 6.1 (64-bit)"); - _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.2 (32-bit)", "Red Hat Enterprise Linux 6.2 (32-bit)"); - _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.2 (64-bit)", "Red Hat Enterprise Linux 6.2 (64-bit)"); + _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.0 (32-bit)", "Red Hat Enterprise Linux 6 (32-bit)"); + _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.0 (64-bit)", "Red Hat Enterprise Linux 6 (64-bit)"); + _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.1 (32-bit)", "Red Hat Enterprise Linux 6 (32-bit)"); + _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.1 (64-bit)", "Red Hat Enterprise Linux 6 (64-bit)"); + _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.2 (32-bit)", "Red Hat Enterprise Linux 6 (32-bit)"); + _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.2 (64-bit)", "Red Hat Enterprise Linux 6 (64-bit)"); _xenServer610GuestOsMap.put("SUSE Linux Enterprise Server 9 SP4 (32-bit)", "SUSE Linux Enterprise Server 10 SP1 (32-bit)"); _xenServer610GuestOsMap.put("SUSE Linux Enterprise Server 10 SP1 (32-bit)", "SUSE Linux Enterprise Server 10 SP1 (32-bit)"); _xenServer610GuestOsMap.put("SUSE Linux Enterprise Server 10 SP1 (64-bit)", "SUSE Linux Enterprise Server 10 SP1 (64-bit)"); @@ -662,13 +661,15 @@ public class CitrixHelper { _xenServer610GuestOsMap.put("Windows Server 2008 (32-bit)", "Windows Server 2008 (32-bit)"); _xenServer610GuestOsMap.put("Windows Server 2008 (64-bit)", "Windows Server 2008 (64-bit)"); _xenServer610GuestOsMap.put("Windows Server 2008 R2 (64-bit)", "Windows Server 2008 R2 (64-bit)"); - _xenServer610GuestOsMap.put("Windows Server 8 (64-bit)", "Windows Server 8 (64-bit) (experimental)"); + _xenServer610GuestOsMap.put("Windows Server 8 (64-bit)", "Windows Server 2012 (64-bit) (experimental)"); _xenServer610GuestOsMap.put("Windows Vista (32-bit)", "Windows Vista (32-bit)"); _xenServer610GuestOsMap.put("Windows XP SP3 (32-bit)", "Windows XP SP3 (32-bit)"); _xenServer610GuestOsMap.put("Ubuntu 10.04 (32-bit)", "Ubuntu Lucid Lynx 10.04 (32-bit)"); _xenServer610GuestOsMap.put("Ubuntu 10.04 (64-bit)", "Ubuntu Lucid Lynx 10.04 (64-bit)"); _xenServer610GuestOsMap.put("Ubuntu 10.10 (32-bit)", "Ubuntu Maverick Meerkat 10.10 (32-bit) (experimental)"); _xenServer610GuestOsMap.put("Ubuntu 10.10 (64-bit)", "Ubuntu Maverick Meerkat 10.10 (64-bit) (experimental)"); + _xenServer610GuestOsMap.put("Ubuntu 12.04 (32-bit)", "Ubuntu Precise Pangolin 12.04 (32-bit)"); + _xenServer610GuestOsMap.put("Ubuntu 12.04 (64-bit)", "Ubuntu Precise Pangolin 12.04 (64-bit)"); _xenServer610GuestOsMap.put("Other Linux (32-bit)", "Other install media"); _xenServer610GuestOsMap.put("Other Linux (64-bit)", "Other install media"); _xenServer610GuestOsMap.put("Other (32-bit)", "Other install media"); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java index 17ad3e62383..8d267b114fa 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java @@ -40,7 +40,7 @@ public class XenServer610Resource extends XenServer56FP1Resource { @Override protected String getGuestOsType(String stdType, boolean bootFromCD) { - return CitrixHelper.getXenServer602GuestOsType(stdType, bootFromCD); + return CitrixHelper.getXenServer610GuestOsType(stdType, bootFromCD); } @Override From 85e9d63be4d7c275dedd773c63a6aca0cde03356 Mon Sep 17 00:00:00 2001 From: David Grizzanti Date: Mon, 11 Mar 2013 12:24:32 -0400 Subject: [PATCH 16/16] CLOUDSTACK-94: API command, listIsos documentation clarity Updated API documentation for listIsos command. Descriptions for id and isofilter descriptions clarified: - Updated isofilter description with all options and verbiage taken from VirtualMachineTemplate class - Updated id description Signed-off-by: Chip Childers --- .../api/command/user/iso/ListIsosCmd.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java index 1824612ebb0..3219601156e 100644 --- a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java @@ -52,7 +52,7 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd { private String hypervisor; @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = TemplateResponse.class, - description="list all isos by id") + description="list ISO by id") private Long id; @Parameter(name=ApiConstants.IS_PUBLIC, type=CommandType.BOOLEAN, description="true if the ISO is publicly available to all users, false otherwise.") @@ -61,11 +61,14 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd { @Parameter(name=ApiConstants.IS_READY, type=CommandType.BOOLEAN, description="true if this ISO is ready to be deployed") private Boolean ready; - @Parameter(name=ApiConstants.ISO_FILTER, type=CommandType.STRING, description="possible values are \"featured\", \"self\", \"self-executable\",\"executable\", and \"community\". " + - "* featured-ISOs that are featured and are publicself-ISOs that have been registered/created by the owner. " + - "* selfexecutable-ISOs that have been registered/created by the owner that can be used to deploy a new VM. " + - "* executable-all ISOs that can be used to deploy a new VM " + - "* community-ISOs that are public.") + @Parameter(name=ApiConstants.ISO_FILTER, type=CommandType.STRING, description="possible values are \"featured\", \"self\", \"selfexecutable\",\"sharedexecutable\",\"executable\", and \"community\". " + + "* featured : templates that have been marked as featured and public. " + + "* self : templates that have been registered or created by the calling user. " + + "* selfexecutable : same as self, but only returns templates that can be used to deploy a new VM. " + + "* sharedexecutable : templates ready to be deployed that have been granted to the calling user by another user. " + + "* executable : templates that are owned by the calling user, or public templates, that can be used to deploy a VM. " + + "* community : templates that have been marked as public but not featured. " + + "* all : all templates (only usable by admins).") private String isoFilter = TemplateFilter.selfexecutable.toString(); @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="list all isos by name")