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/network/Network.java b/api/src/com/cloud/network/Network.java index e584e8de925..efed5cd4f8b 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -138,7 +138,6 @@ public interface Network extends ControlledEntity, StateObject, I // NiciraNvp is not an "External" provider, otherwise we get in trouble with NetworkServiceImpl.providersConfiguredForExternalNetworking public static final Provider NiciraNvp = new Provider("NiciraNvp", false); public static final Provider MidokuraMidonet = new Provider("MidokuraMidonet", true); - public static final Provider VPCNetscaler = new Provider("VPCNetscaler", true); private String name; private boolean isExternal; 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/account/CreateAccountCmd.java b/api/src/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java index 57789c97db9..4121651d499 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java @@ -78,6 +78,7 @@ public class CreateAccountCmd extends BaseCmd { @Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "details for account used to store specific parameters") private Map details; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -149,7 +150,8 @@ public class CreateAccountCmd extends BaseCmd { @Override public void execute(){ UserContext.current().setEventDetails("Account Name: "+getAccountName()+", Domain Id:"+getDomainId()); - UserAccount userAccount = _accountService.createUserAccount(getUsername(), getPassword(), getFirstName(), getLastName(), getEmail(), getTimeZone(), getAccountName(), getAccountType(), getDomainId(), getNetworkDomain(), getDetails()); + UserAccount userAccount = _accountService.createUserAccount(getUsername(), getPassword(), getFirstName(), getLastName(), getEmail(), getTimeZone(), getAccountName(), getAccountType(), + getDomainId(), getNetworkDomain(), getDetails()); if (userAccount != null) { AccountResponse response = _responseGenerator.createUserAccountResponse(userAccount); response.setResponseName(getCommandName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/DeleteAccountCmd.java b/api/src/org/apache/cloudstack/api/command/admin/account/DeleteAccountCmd.java index ff6d0d20dc1..9895da113f1 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/account/DeleteAccountCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/account/DeleteAccountCmd.java @@ -49,7 +49,7 @@ public class DeleteAccountCmd extends BaseAsyncCmd { private Long id; @Inject RegionService _regionService; - + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -96,7 +96,7 @@ public class DeleteAccountCmd extends BaseAsyncCmd { @Override public void execute(){ UserContext.current().setEventDetails("Account Id: "+getId()); - + boolean result = _regionService.deleteUserAccount(this); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java b/api/src/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java index fceb192ab7f..1f9b8217dd3 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java @@ -59,7 +59,7 @@ public class DisableAccountCmd extends BaseAsyncCmd { private Boolean lockRequested; @Inject RegionService _regionService; - + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/EnableAccountCmd.java b/api/src/org/apache/cloudstack/api/command/admin/account/EnableAccountCmd.java index d07ea79a91f..b9a9f6d70ba 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/account/EnableAccountCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/account/EnableAccountCmd.java @@ -51,7 +51,7 @@ public class EnableAccountCmd extends BaseCmd { private Long domainId; @Inject RegionService _regionService; - + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -68,7 +68,6 @@ public class EnableAccountCmd extends BaseCmd { return domainId; } - ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java b/api/src/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java index 6aa853f6bb4..60d1a97ffac 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java @@ -64,7 +64,7 @@ public class UpdateAccountCmd extends BaseCmd{ private Map details; @Inject RegionService _regionService; - + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -99,7 +99,6 @@ public class UpdateAccountCmd extends BaseCmd{ return params; } - ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java b/api/src/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java index 97e7afa59bf..488a758caec 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java @@ -51,7 +51,7 @@ public class DeleteDomainCmd extends BaseAsyncCmd { private Boolean cleanup; @Inject RegionService _regionService; - + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java b/api/src/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java index 91c83460ab2..e658f49ada1 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java @@ -53,7 +53,7 @@ public class UpdateDomainCmd extends BaseCmd { private String networkDomain; @Inject RegionService _regionService; - + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -88,7 +88,7 @@ public class UpdateDomainCmd extends BaseCmd { public void execute(){ UserContext.current().setEventDetails("Domain Id: "+getId()); Domain domain = _regionService.updateDomain(this); - + if (domain != null) { DomainResponse response = _responseGenerator.createDomainResponse(domain); response.setResponseName(getCommandName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java index 68ddbe7af13..bb37d085c8e 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java @@ -46,7 +46,7 @@ public class DeleteUserCmd extends BaseCmd { private Long id; @Inject RegionService _regionService; - + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java index a7008afd480..6eaa46bed30 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java @@ -50,7 +50,7 @@ public class DisableUserCmd extends BaseAsyncCmd { private Long id; @Inject RegionService _regionService; - + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -93,7 +93,7 @@ public class DisableUserCmd extends BaseAsyncCmd { public void execute(){ UserContext.current().setEventDetails("UserId: "+getId()); UserAccount user = _regionService.disableUser(this); - + if (user != null){ UserResponse response = _responseGenerator.createUserResponse(user); response.setResponseName(getCommandName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java index c51b31087bc..382f67c98de 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java @@ -47,7 +47,7 @@ public class EnableUserCmd extends BaseCmd { private Long id; @Inject RegionService _regionService; - + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -79,7 +79,7 @@ public class EnableUserCmd extends BaseCmd { public void execute(){ UserContext.current().setEventDetails("UserId: "+getId()); UserAccount user = _regionService.enableUser(this); - + if (user != null){ UserResponse response = _responseGenerator.createUserResponse(user); response.setResponseName(getCommandName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java index 1212cd9f75b..1f31662e8ca 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java @@ -72,7 +72,7 @@ public class UpdateUserCmd extends BaseCmd { private String username; @Inject RegionService _regionService; - + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -136,7 +136,7 @@ public class UpdateUserCmd extends BaseCmd { public void execute(){ UserContext.current().setEventDetails("UserId: "+getId()); UserAccount user = _regionService.updateUser(this); - + if (user != null){ UserResponse response = _responseGenerator.createUserResponse(user); response.setResponseName(getCommandName()); diff --git a/api/src/org/apache/cloudstack/region/RegionService.java b/api/src/org/apache/cloudstack/region/RegionService.java index ec7876efe8e..8679ca92b10 100644 --- a/api/src/org/apache/cloudstack/region/RegionService.java +++ b/api/src/org/apache/cloudstack/region/RegionService.java @@ -38,41 +38,41 @@ import com.cloud.user.UserAccount; public interface RegionService { - /** - * Adds a Region to the local Region - * @param id - * @param name - * @param endPoint - * @param apiKey - * @param secretKey - * @return Return added Region object - */ - public Region addRegion(int id, String name, String endPoint, String apiKey, String secretKey); - - /** - * Update details of the Region with specified Id - * @param id - * @param name - * @param endPoint - * @param apiKey - * @param secretKey - * @return Return updated Region object - */ - public Region updateRegion(int id, String name, String endPoint, String apiKey, String secretKey); - - /** - * @param id - * @return True if region is successfully removed - */ - public boolean removeRegion(int id); - - /** List all Regions or by Id/Name - * @param id - * @param name - * @return List of Regions - */ - public List listRegions(ListRegionsCmd cmd); - + /** + * Adds a Region to the local Region + * @param id + * @param name + * @param endPoint + * @param apiKey + * @param secretKey + * @return Return added Region object + */ + public Region addRegion(int id, String name, String endPoint, String apiKey, String secretKey); + + /** + * Update details of the Region with specified Id + * @param id + * @param name + * @param endPoint + * @param apiKey + * @param secretKey + * @return Return updated Region object + */ + public Region updateRegion(int id, String name, String endPoint, String apiKey, String secretKey); + + /** + * @param id + * @return True if region is successfully removed + */ + public boolean removeRegion(int id); + + /** List all Regions or by Id/Name + * @param id + * @param name + * @return List of Regions + */ + public List listRegions(ListRegionsCmd cmd); + /** * Deletes a user by userId * isPopagate flag is set to true if sent from peer Region @@ -80,8 +80,8 @@ public interface RegionService { * * @return true if delete was successful, false otherwise */ - boolean deleteUserAccount(DeleteAccountCmd cmd); - + boolean deleteUserAccount(DeleteAccountCmd cmd); + /** * Updates an account * isPopagate falg is set to true if sent from peer Region @@ -91,22 +91,22 @@ public interface RegionService { * @return updated account object */ Account updateAccount(UpdateAccountCmd cmd); - - /** - * Disables an account by accountName and domainId or accountId - * @param cmd - * @return - * @throws ResourceUnavailableException - * @throws ConcurrentOperationException - */ - Account disableAccount(DisableAccountCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException; - - /** - * Enables an account by accountId - * @param cmd - * @return - */ - Account enableAccount(EnableAccountCmd cmd); + + /** + * Disables an account by accountName and domainId or accountId + * @param cmd + * @return + * @throws ResourceUnavailableException + * @throws ConcurrentOperationException + */ + Account disableAccount(DisableAccountCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException; + + /** + * Enables an account by accountId + * @param cmd + * @return + */ + Account enableAccount(EnableAccountCmd cmd); /** * Deletes user by Id @@ -114,7 +114,7 @@ public interface RegionService { * @return true if delete was successful, false otherwise */ boolean deleteUser(DeleteUserCmd deleteUserCmd); - + /** * update an existing domain * @@ -122,36 +122,36 @@ public interface RegionService { * - the command containing domainId and new domainName * @return Domain object if the command succeeded */ - public Domain updateDomain(UpdateDomainCmd updateDomainCmd); - - /** - * Deletes domain - * @param cmd - * @return true if delete was successful, false otherwise - */ - public boolean deleteDomain(DeleteDomainCmd cmd); - + public Domain updateDomain(UpdateDomainCmd updateDomainCmd); + + /** + * Deletes domain + * @param cmd + * @return true if delete was successful, false otherwise + */ + public boolean deleteDomain(DeleteDomainCmd cmd); + /** * Update a user by userId * * @param userId * @return UserAccount object */ - public UserAccount updateUser(UpdateUserCmd updateUserCmd); - + public UserAccount updateUser(UpdateUserCmd updateUserCmd); + /** * Disables a user by userId * * @param cmd * @return UserAccount object */ - public UserAccount disableUser(DisableUserCmd cmd); - + public UserAccount disableUser(DisableUserCmd cmd); + /** * Enables a user * * @param cmd * @return UserAccount object */ - public UserAccount enableUser(EnableUserCmd cmd); + public UserAccount enableUser(EnableUserCmd cmd); } 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/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index fc7f08f76a2..9dd471d6efa 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -859,35 +859,29 @@ public class VirtualRoutingResource implements Manager { } public void assignVpcIpToRouter(final String routerIP, final boolean add, final String pubIP, - final String nicname, final String gateway, final String netmask, final String subnet) throws Exception { - try { - String args = ""; + final String nicname, final String gateway, final String netmask, final String subnet) throws InternalErrorException { + String args = ""; - if (add) { - args += " -A "; - } else { - args += " -D "; - } + if (add) { + args += " -A "; + } else { + args += " -D "; + } - args += " -l "; - args += pubIP; - args += " -c "; - args += nicname; - args += " -g "; - args += gateway; - args += " -m "; - args += netmask; - args += " -n "; - args += subnet; + args += " -l "; + args += pubIP; + args += " -c "; + args += nicname; + args += " -g "; + args += gateway; + args += " -m "; + args += netmask; + args += " -n "; + args += subnet; - String result = routerProxy("vpc_ipassoc.sh", routerIP, args); - if (result != null) { - throw new InternalErrorException("KVM plugin \"vpc_ipassoc\" failed:"+result); - } - } catch (Exception e) { - String msg = "Unable to assign public IP address due to " + e.toString(); - s_logger.warn(msg, e); - throw new Exception(msg); + String result = routerProxy("vpc_ipassoc.sh", routerIP, args); + if (result != null) { + throw new InternalErrorException("KVM plugin \"vpc_ipassoc\" failed:"+result); } } 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/core/src/com/cloud/user/AccountVO.java b/core/src/com/cloud/user/AccountVO.java index 37111799c74..fd37c772d11 100644 --- a/core/src/com/cloud/user/AccountVO.java +++ b/core/src/com/cloud/user/AccountVO.java @@ -68,32 +68,32 @@ public class AccountVO implements Account { @Column(name="region_id") private int regionId; - + public AccountVO() { - this.uuid = UUID.randomUUID().toString(); + this.uuid = UUID.randomUUID().toString(); } public AccountVO(long id) { this.id = id; - this.uuid = UUID.randomUUID().toString(); + this.uuid = UUID.randomUUID().toString(); } - - public AccountVO(String accountName, long domainId, String networkDomain, short type, int regionId) { + + public AccountVO(String accountName, long domainId, String networkDomain, short type, String uuid, int regionId) { this.accountName = accountName; this.domainId = domainId; this.networkDomain = networkDomain; this.type = type; this.state = State.enabled; - this.uuid = UUID.randomUUID().toString(); + this.uuid = uuid; this.regionId = regionId; } public void setNeedsCleanup(boolean value) { - needsCleanup = value; + needsCleanup = value; } public boolean getNeedsCleanup() { - return needsCleanup; + return needsCleanup; } @Override @@ -102,10 +102,10 @@ public class AccountVO implements Account { } public void setId(long id) { - this.id = id; - } + this.id = id; + } - @Override + @Override public String getAccountName() { return accountName; } @@ -134,11 +134,11 @@ public class AccountVO implements Account { @Override public Long getDefaultZoneId() { - return defaultZoneId; + return defaultZoneId; } public void setDefaultZoneId(Long defaultZoneId) { - this.defaultZoneId = defaultZoneId; + this.defaultZoneId = defaultZoneId; } @Override @@ -176,14 +176,18 @@ public class AccountVO implements Account { @Override public String getUuid() { - return this.uuid; + return this.uuid; } public void setUuid(String uuid) { - this.uuid = uuid; + this.uuid = uuid; } - public int getRegionId() { - return regionId; - } + public int getRegionId() { + return regionId; + } + + public void setRegionId(int regionId) { + this.regionId = regionId; + } } diff --git a/core/src/com/cloud/user/UserVO.java b/core/src/com/cloud/user/UserVO.java index 1780db439d2..de7f31bd2be 100644 --- a/core/src/com/cloud/user/UserVO.java +++ b/core/src/com/cloud/user/UserVO.java @@ -95,7 +95,7 @@ public class UserVO implements User, Identity, InternalIdentity { @Column(name="region_id") private int regionId; - + public UserVO() { this.uuid = UUID.randomUUID().toString(); } @@ -104,8 +104,8 @@ public class UserVO implements User, Identity, InternalIdentity { this.id = id; this.uuid = UUID.randomUUID().toString(); } - - public UserVO(long accountId, String username, String password, String firstName, String lastName, String email, String timezone, int regionId) { + + public UserVO(long accountId, String username, String password, String firstName, String lastName, String email, String timezone, String uuid, int regionId) { this.accountId = accountId; this.username = username; this.password = password; @@ -114,10 +114,10 @@ public class UserVO implements User, Identity, InternalIdentity { this.email = email; this.timezone = timezone; this.state = State.enabled; - this.uuid = UUID.randomUUID().toString(); - this.regionId = regionId; + this.uuid = uuid; + this.regionId = regionId; } - + @Override public long getId() { return id; @@ -265,9 +265,12 @@ public class UserVO implements User, Identity, InternalIdentity { public void setUuid(String uuid) { this.uuid = uuid; } + + public int getRegionId() { + return regionId; + } - public int getRegionId() { - return regionId; - } - + public void setRegionId(int regionId) { + this.regionId = regionId; + } } diff --git a/debian/cloudstack-agent.install b/debian/cloudstack-agent.install index cf57bfe39b4..b1425717584 100644 --- a/debian/cloudstack-agent.install +++ b/debian/cloudstack-agent.install @@ -23,3 +23,4 @@ /usr/bin/cloud-ssh /var/log/cloudstack/agent /usr/share/cloudstack-agent/lib/* +/usr/share/cloudstack-agent/plugins \ No newline at end of file diff --git a/debian/control b/debian/control index 17e62b7cacc..8f82fc3ab2f 100644 --- a/debian/control +++ b/debian/control @@ -22,7 +22,7 @@ Description: CloudStack server library Package: cloudstack-agent Architecture: all -Depends: openjdk-6-jre | openjdk-7-jre, cloudstack-common (= ${source:Version}), lsb-base (>= 3.2), libcommons-daemon-java, libjna-java, openssh-client, libvirt0, sysvinit-utils, chkconfig, qemu-kvm, libvirt-bin, uuid-runtime, rsync, grep, iproute, ebtables, vlan, wget, jsvc +Depends: openjdk-6-jre | openjdk-7-jre, cloudstack-common (= ${source:Version}), lsb-base (>= 3.2), libcommons-daemon-java, libjna-java, openssh-client, libvirt0, sysvinit-utils, chkconfig, qemu-kvm, libvirt-bin, uuid-runtime, rsync, grep, iproute, perl-base, perl-modules, ebtables, vlan, wget, jsvc Conflicts: cloud-agent, cloud-agent-libs, cloud-agent-deps, cloud-agent-scripts Description: CloudStack agent The CloudStack agent is in charge of managing shared computing resources in diff --git a/debian/rules b/debian/rules index cf950d1bd04..f0cb67f276a 100755 --- a/debian/rules +++ b/debian/rules @@ -14,6 +14,7 @@ DEBVERS := $(shell dpkg-parsechangelog | sed -n -e 's/^Version: //p') VERSION := $(shell echo '$(DEBVERS)' | sed -e 's/^[[:digit:]]*://' -e 's/[~-].*//') PACKAGE = $(shell dh_listpackages|head -n 1|cut -d '-' -f 1) SYSCONFDIR = "/etc" +DESTDIR = "debian/tmp" # Uncomment this to turn on verbose mode. export DH_VERBOSE=1 @@ -50,83 +51,86 @@ install: dh_prep -s # Common packages - mkdir -p debian/tmp$(SYSCONFDIR)/$(PACKAGE) - mkdir -p debian/tmp$(SYSCONFDIR)/init.d - mkdir -p debian/tmp/var/cache/$(PACKAGE) - mkdir -p debian/tmp/var/log/$(PACKAGE) - mkdir -p debian/tmp/var/lib/$(PACKAGE) - mkdir -p debian/tmp/usr/bin + mkdir -p $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE) + mkdir -p $(DESTDIR)/$(SYSCONFDIR)/init.d + mkdir -p $(DESTDIR)/var/cache/$(PACKAGE) + mkdir -p $(DESTDIR)/var/log/$(PACKAGE) + mkdir -p $(DESTDIR)/var/lib/$(PACKAGE) + mkdir -p $(DESTDIR)/usr/bin + mkdir -p $(DESTDIR)/usr/share # cloudstack-agent - mkdir debian/tmp$(SYSCONFDIR)/$(PACKAGE)/agent - mkdir debian/tmp/var/log/$(PACKAGE)/agent - install -D agent/target/cloud-agent-4.2.0-SNAPSHOT.jar debian/tmp/usr/share/$(PACKAGE)-agent/lib/$(PACKAGE)-agent.jar - install -D plugins/hypervisors/kvm/target/cloud-plugin-hypervisor-kvm-4.2.0-SNAPSHOT.jar debian/tmp/usr/share/$(PACKAGE)-agent/lib/ - install -D plugins/hypervisors/kvm/target/dependencies/* debian/tmp/usr/share/$(PACKAGE)-agent/lib/ - install -D packaging/debian/init/cloud-agent debian/tmp$(SYSCONFDIR)/init.d/$(PACKAGE)-agent - install -D agent/bindir/cloud-setup-agent.in debian/tmp/usr/bin/cloud-setup-agent - install -D agent/bindir/cloud-ssh.in debian/tmp/usr/bin/cloud-ssh - install -D agent/target/transformed/* debian/tmp$(SYSCONFDIR)/$(PACKAGE)/agent + mkdir $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/agent + mkdir $(DESTDIR)/var/log/$(PACKAGE)/agent + mkdir $(DESTDIR)/usr/share/$(PACKAGE)-agent + mkdir $(DESTDIR)/usr/share/$(PACKAGE)-agent/plugins + install -D agent/target/cloud-agent-4.2.0-SNAPSHOT.jar $(DESTDIR)/usr/share/$(PACKAGE)-agent/lib/$(PACKAGE)-agent.jar + install -D plugins/hypervisors/kvm/target/cloud-plugin-hypervisor-kvm-4.2.0-SNAPSHOT.jar $(DESTDIR)/usr/share/$(PACKAGE)-agent/lib/ + install -D plugins/hypervisors/kvm/target/dependencies/* $(DESTDIR)/usr/share/$(PACKAGE)-agent/lib/ + install -D packaging/debian/init/cloud-agent $(DESTDIR)/$(SYSCONFDIR)/init.d/$(PACKAGE)-agent + install -D agent/bindir/cloud-setup-agent.in $(DESTDIR)/usr/bin/cloud-setup-agent + install -D agent/bindir/cloud-ssh.in $(DESTDIR)/usr/bin/cloud-ssh + install -D agent/target/transformed/* $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/agent # cloudstack-management - mkdir debian/tmp$(SYSCONFDIR)/$(PACKAGE)/server - mkdir debian/tmp$(SYSCONFDIR)/$(PACKAGE)/management - mkdir -p debian/tmp/usr/share/$(PACKAGE)-management - mkdir -p debian/tmp/usr/share/$(PACKAGE)-management/webapps/client - mkdir debian/tmp/usr/share/$(PACKAGE)-management/setup - mkdir debian/tmp/var/log/$(PACKAGE)/management - mkdir debian/tmp/var/cache/$(PACKAGE)/management - mkdir debian/tmp/var/cache/$(PACKAGE)/management/work - mkdir debian/tmp/var/cache/$(PACKAGE)/management/temp - mkdir debian/tmp/var/log/$(PACKAGE)/ipallocator - mkdir debian/tmp/var/lib/$(PACKAGE)/management - mkdir debian/tmp/var/lib/$(PACKAGE)/mnt - cp -r client/target/utilities/scripts/db/* debian/tmp/usr/share/$(PACKAGE)-management/setup/ - cp -r client/target/cloud-client-ui-4.2.0-SNAPSHOT/* debian/tmp/usr/share/$(PACKAGE)-management/webapps/client/ - cp server/target/conf/* debian/tmp$(SYSCONFDIR)/$(PACKAGE)/server/ - cp client/target/conf/* debian/tmp$(SYSCONFDIR)/$(PACKAGE)/management/ - ln -s tomcat6-nonssl.conf debian/tmp$(SYSCONFDIR)/$(PACKAGE)/management/tomcat6.conf - mkdir -p debian/tmp$(SYSCONFDIR)/$(PACKAGE)/management/Catalina/localhost/client - install -D packaging/debian/init/cloud-management debian/tmp$(SYSCONFDIR)/init.d/$(PACKAGE)-management - install -D client/bindir/cloud-update-xenserver-licenses.in debian/tmp/usr/bin/cloud-update-xenserver-licenses - install -D server/target/cloud-server-4.2.0-SNAPSHOT.jar debian/tmp/usr/share/$(PACKAGE)-management/lib/$(PACKAGE)-server.jar - ln -s /usr/share/tomcat6/bin debian/tmp/usr/share/$(PACKAGE)-management/bin - ln -s ../../..$(SYSCONFDIR)/$(PACKAGE)/management debian/tmp/usr/share/$(PACKAGE)-management/conf - ln -s /usr/share/tomcat6/lib debian/tmp/usr/share/$(PACKAGE)-management/lib - ln -s ../../../var/log/$(PACKAGE)/management debian/tmp/usr/share/$(PACKAGE)-management/logs - ln -s ../../../var/cache/$(PACKAGE)/management/temp debian/tmp/usr/share/$(PACKAGE)-management/temp - ln -s ../../../var/cache/$(PACKAGE)/management/work debian/tmp/usr/share/$(PACKAGE)-management/work + mkdir $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/server + mkdir $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/management + mkdir -p $(DESTDIR)/usr/share/$(PACKAGE)-management + mkdir -p $(DESTDIR)/usr/share/$(PACKAGE)-management/webapps/client + mkdir $(DESTDIR)/usr/share/$(PACKAGE)-management/setup + mkdir $(DESTDIR)/var/log/$(PACKAGE)/management + mkdir $(DESTDIR)/var/cache/$(PACKAGE)/management + mkdir $(DESTDIR)/var/cache/$(PACKAGE)/management/work + mkdir $(DESTDIR)/var/cache/$(PACKAGE)/management/temp + mkdir $(DESTDIR)/var/log/$(PACKAGE)/ipallocator + mkdir $(DESTDIR)/var/lib/$(PACKAGE)/management + mkdir $(DESTDIR)/var/lib/$(PACKAGE)/mnt + cp -r client/target/utilities/scripts/db/* $(DESTDIR)/usr/share/$(PACKAGE)-management/setup/ + cp -r client/target/cloud-client-ui-4.2.0-SNAPSHOT/* $(DESTDIR)/usr/share/$(PACKAGE)-management/webapps/client/ + cp server/target/conf/* $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/server/ + cp client/target/conf/* $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/management/ + ln -s tomcat6-nonssl.conf $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/management/tomcat6.conf + mkdir -p $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/management/Catalina/localhost/client + install -D packaging/debian/init/cloud-management $(DESTDIR)/$(SYSCONFDIR)/init.d/$(PACKAGE)-management + install -D client/bindir/cloud-update-xenserver-licenses.in $(DESTDIR)/usr/bin/cloud-update-xenserver-licenses + install -D server/target/cloud-server-4.2.0-SNAPSHOT.jar $(DESTDIR)/usr/share/$(PACKAGE)-management/lib/$(PACKAGE)-server.jar + ln -s /usr/share/tomcat6/bin $(DESTDIR)/usr/share/$(PACKAGE)-management/bin + ln -s ../../..$(SYSCONFDIR)/$(PACKAGE)/management $(DESTDIR)/usr/share/$(PACKAGE)-management/conf + ln -s /usr/share/tomcat6/lib $(DESTDIR)/usr/share/$(PACKAGE)-management/lib + ln -s ../../../var/log/$(PACKAGE)/management $(DESTDIR)/usr/share/$(PACKAGE)-management/logs + ln -s ../../../var/cache/$(PACKAGE)/management/temp $(DESTDIR)/usr/share/$(PACKAGE)-management/temp + ln -s ../../../var/cache/$(PACKAGE)/management/work $(DESTDIR)/usr/share/$(PACKAGE)-management/work # cloudstack-common - mkdir -p debian/tmp/usr/share/$(PACKAGE)-common - mkdir debian/tmp/usr/share/$(PACKAGE)-common/scripts - mkdir debian/tmp/usr/share/$(PACKAGE)-common/setup - cp -r scripts/installer debian/tmp/usr/share/$(PACKAGE)-common/scripts - cp -r scripts/network debian/tmp/usr/share/$(PACKAGE)-common/scripts - cp -r scripts/storage debian/tmp/usr/share/$(PACKAGE)-common/scripts - cp -r scripts/util debian/tmp/usr/share/$(PACKAGE)-common/scripts - cp -r scripts/vm debian/tmp/usr/share/$(PACKAGE)-common/scripts - install -D client/target/utilities/bin/cloud-migrate-databases debian/tmp/usr/bin - install -D client/target/utilities/bin/cloud-set-guest-password debian/tmp/usr/bin - install -D client/target/utilities/bin/cloud-set-guest-sshkey debian/tmp/usr/bin - install -D client/target/utilities/bin/cloud-setup-databases debian/tmp/usr/bin - install -D client/target/utilities/bin/cloud-setup-management debian/tmp/usr/bin - install -D services/console-proxy/server/dist/systemvm.iso debian/tmp/usr/share/$(PACKAGE)-common/vms/systemvm.iso + mkdir -p $(DESTDIR)/usr/share/$(PACKAGE)-common + mkdir $(DESTDIR)/usr/share/$(PACKAGE)-common/scripts + mkdir $(DESTDIR)/usr/share/$(PACKAGE)-common/setup + cp -r scripts/installer $(DESTDIR)/usr/share/$(PACKAGE)-common/scripts + cp -r scripts/network $(DESTDIR)/usr/share/$(PACKAGE)-common/scripts + cp -r scripts/storage $(DESTDIR)/usr/share/$(PACKAGE)-common/scripts + cp -r scripts/util $(DESTDIR)/usr/share/$(PACKAGE)-common/scripts + cp -r scripts/vm $(DESTDIR)/usr/share/$(PACKAGE)-common/scripts + install -D client/target/utilities/bin/cloud-migrate-databases $(DESTDIR)/usr/bin + install -D client/target/utilities/bin/cloud-set-guest-password $(DESTDIR)/usr/bin + install -D client/target/utilities/bin/cloud-set-guest-sshkey $(DESTDIR)/usr/bin + install -D client/target/utilities/bin/cloud-setup-databases $(DESTDIR)/usr/bin + install -D client/target/utilities/bin/cloud-setup-management $(DESTDIR)/usr/bin + install -D services/console-proxy/server/dist/systemvm.iso $(DESTDIR)/usr/share/$(PACKAGE)-common/vms/systemvm.iso # cloudstack-python - mkdir -p debian/tmp/usr/lib/python2.7/dist-packages - cp -r python/lib/cloud* debian/tmp/usr/lib/python2.7/dist-packages + mkdir -p $(DESTDIR)/usr/lib/python2.7/dist-packages + cp -r python/lib/cloud* $(DESTDIR)/usr/lib/python2.7/dist-packages # cloudstack-usage - mkdir debian/tmp$(SYSCONFDIR)/$(PACKAGE)/usage - mkdir debian/tmp/var/log/$(PACKAGE)/usage - install -D usage/target/cloud-usage-4.2.0-SNAPSHOT.jar debian/tmp/usr/share/$(PACKAGE)-usage/lib/$(PACKAGE)-usage.jar - cp usage/target/transformed/* debian/tmp$(SYSCONFDIR)/$(PACKAGE)/usage/ - ln -s ../management/db.properties debian/tmp$(SYSCONFDIR)/$(PACKAGE)/usage/db.properties - install -D packaging/debian/init/cloud-usage debian/tmp$(SYSCONFDIR)/init.d/$(PACKAGE)-usage + mkdir $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/usage + mkdir $(DESTDIR)/var/log/$(PACKAGE)/usage + install -D usage/target/cloud-usage-4.2.0-SNAPSHOT.jar $(DESTDIR)/usr/share/$(PACKAGE)-usage/lib/$(PACKAGE)-usage.jar + cp usage/target/transformed/* $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/usage/ + ln -s ../management/db.properties $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/usage/db.properties + install -D packaging/debian/init/cloud-usage $(DESTDIR)/$(SYSCONFDIR)/init.d/$(PACKAGE)-usage # cloudstack-awsapi - mkdir debian/tmp/var/log/$(PACKAGE)/awsapi + mkdir $(DESTDIR)/var/log/$(PACKAGE)/awsapi dh_installdirs dh_install diff --git a/docs/en-US/advanced-zone-guest-ip-addresses.xml b/docs/en-US/advanced-zone-guest-ip-addresses.xml index fbc6144bec1..66bc0826683 100644 --- a/docs/en-US/advanced-zone-guest-ip-addresses.xml +++ b/docs/en-US/advanced-zone-guest-ip-addresses.xml @@ -11,9 +11,7 @@ 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 @@ -22,6 +20,12 @@ under the License. -->
- Advanced Zone Guest IP Addresses - When advanced networking is used, the administrator can create additional networks for use by the guests. These networks can span the zone and be available to all accounts, or they can be scoped to a single account, in which case only the named account may create guests that attach to these networks. The networks are defined by a VLAN ID, IP range, and gateway. The administrator may provision thousands of these networks if desired. + Advanced Zone Guest IP Addresses + When advanced networking is used, the administrator can create additional networks for use + by the guests. These networks can span the zone and be available to all accounts, or they can be + scoped to a single account, in which case only the named account may create guests that attach + to these networks. The networks are defined by a VLAN ID, IP range, and gateway. The + administrator may provision thousands of these networks if desired. Additionally, the + administrator can reserve a part of the IP address space for non-&PRODUCT; VMs and + servers.
diff --git a/docs/en-US/build-deb.xml b/docs/en-US/build-deb.xml index 37e5a7d7474..dca31d23a28 100644 --- a/docs/en-US/build-deb.xml +++ b/docs/en-US/build-deb.xml @@ -51,7 +51,7 @@ and packaging them into DEBs by issuing the following command. -$ dpkg-buildpackge -uc -us +$ dpkg-buildpackage -uc -us diff --git a/docs/en-US/build-rpm.xml b/docs/en-US/build-rpm.xml index e983aba8fe5..ba32ef568ab 100644 --- a/docs/en-US/build-rpm.xml +++ b/docs/en-US/build-rpm.xml @@ -5,78 +5,82 @@ ]>
- Building RPMs - - While we have defined, and you have presumably already installed the - bootstrap prerequisites, there are a number of build time prerequisites - that need to be resolved. &PRODUCT; uses maven for dependency resolution. - You can resolve the buildtime depdencies for CloudStack by running the - following command: - $ mvn -P deps - - - Now that we have resolved the dependencies we can move on to building &PRODUCT; - and packaging them into RPMs by issuing the following command. - $ ./waf rpm - - - Once this completes, you should find assembled RPMs in - artifacts/rpmbuild/RPMS/x86_64 - -
- Creating a yum repo - - While RPMs is an ideal packaging format - it's most easily consumed from - yum repositories over a network. We'll move into the directory with the - newly created RPMs by issuing the following command: - $ cd artifacts/rpmbuild/RPMS/x86_64 - - - Next we'll issue a command to create the repository metadata by - issuing the following command: - $ createrepo ./ - - - The files and directories within our current working directory can now - be uploaded to a web server and serve as a yum repository - + Building RPMs from Source + As mentioned previously in , you will need to install several prerequisites before you can build packages for &PRODUCT;. Here we'll assume you're working with a 64-bit build of CentOS or Red Hat Enterprise Linux. + # yum groupinstall "Development Tools" + # yum install java-1.6.0-openjdk-devel.x86_64 genisoimage mysql mysql-server ws-common-utils MySQL-python tomcat6 createrepo + Next, you'll need to install build-time dependencies for CloudStack with + Maven. We're using Maven 3, so you'll want to + grab a Maven 3 tarball + and uncompress it in your home directory (or whatever location you prefer): + $ tar zxvf apache-maven-3.0.4-bin.tar.gz + $ export PATH=/usr/local/apache-maven-3.0.4//bin:$PATH + Maven also needs to know where Java is, and expects the JAVA_HOME environment + variable to be set: + $ export JAVA_HOME=/usr/lib/jvm/jre-1.6.0-openjdk.x86_64/ + Verify that Maven is installed correctly: + $ mvn --version + You probably want to ensure that your environment variables will survive a logout/reboot. + Be sure to update ~/.bashrc with the PATH and JAVA_HOME variables. + + Building RPMs for $PRODUCT; is fairly simple. Assuming you already have the source downloaded and have uncompressed the tarball into a local directory, you're going to be able to generate packages in just a few minutes. + Packaging has Changed + If you've created packages for $PRODUCT; previously, you should be aware that the process has changed considerably since the project has moved to using Apache Maven. Please be sure to follow the steps in this section closely. + +
+ Generating RPMS + Now that we have the prerequisites and source, you will cd to the packaging/centos63/ directory. + Generating RPMs is done using the package.sh script: + $./package.sh + + That will run for a bit and then place the finished packages in dist/rpmbuild/RPMS/x86_64/. + You should see seven RPMs in that directory: cloudstack-agent-4.1.0-SNAPSHOT.el6.x86_64.rpm, cloudstack-awsapi-4.1.0-SNAPSHOT.el6.x86_64.rpm, cloudstack-cli-4.1.0-SNAPSHOT.el6.x86_64.rpm, cloudstack-common-4.1.0-SNAPSHOT.el6.x86_64.rpm, cloudstack-docs-4.1.0-SNAPSHOT.el6.x86_64.rpm, cloudstack-management-4.1.0-SNAPSHOT.el6.x86_64.rpm, and cloudstack-usage-4.1.0-SNAPSHOT.el6.x86_64.rpm. +
+ Creating a yum repo + + While RPMs is a useful packaging format - it's most easily consumed from Yum repositories over a network. The next step is to create a Yum Repo with the finished packages: + $ mkdir -p ~/tmp/repo + $ cp dist/rpmbuild/RPMS/x86_64/*rpm ~/tmp/repo/ + $ createrepo ~/tmp/repo + + + The files and directories within ~/tmp/repo can now be uploaded to a web server and serve as a yum repository. + +
+
+ Configuring your systems to use your new yum repository + + Now that your yum repository is populated with RPMs and metadata + we need to configure the machines that need to install $PRODUCT;. + Create a file named /etc/yum.repos.d/cloudstack.repo with this information: + + [apache-cloudstack] + name=Apache CloudStack + baseurl=http://webserver.tld/path/to/repo + enabled=1 + gpgcheck=0 + + + Completing this step will allow you to easily install $PRODUCT; on a number of machines across the network. + +
+
-
- Configuring your systems to use your new yum repository - - Now that your yum repository is populated with RPMs and metadata - we need to configure our machines that need to install CloudStack. - We will create a file at /etc/yum.repos.d/cloudstack.repo - with the following content: - -[apache-cloudstack] -name=Apache CloudStack -baseurl=http://webserver.tld/path/to/repo -enabled=1 -gpgcheck=0 - - - - Completing this step will allow you to easily install CloudStack on a number of - machines across the network. - -
-
diff --git a/docs/en-US/getting-release.xml b/docs/en-US/getting-release.xml index 09f0a7b08fe..b9e97c9b03d 100644 --- a/docs/en-US/getting-release.xml +++ b/docs/en-US/getting-release.xml @@ -29,35 +29,13 @@ Apache CloudStack project download page.
- - You'll notice several links under the 'Latest release' section. - - - - - - apache-cloudstack-4.0.0-incubating-src.tar.bz2 - - This is the link to the release itself. - - - - - PGP - - This is a detached cryptographic signature that can be used to help - verify the authenticity of the release. - - - - - MD5 - - An MD5 hash of the release to aid in verify the validity of the release download. - - - - - SHA512 - - A SHA512 hash of the release to aid in verify the validity of the release download. - - - + Prior releases are available via archive.apache.org at http://archive.apache.org/dist/incubator/cloudstack/releases/. + + You'll notice several links under the 'Latest release' section. A link to a file ending in tar.bz2, as well as a PGP/GPG signature, MD5, and SHA512 file. + + The tar.bz2 file contains the Bzip2-compressed tarball with the source code. + The .asc file is a detached cryptographic signature that can be used to help verify the authenticity of the release. + The .md5 file is an MD5 hash of the release to aid in verify the validity of the release download. + The .sha file is a SHA512 hash of the release to aid in verify the validity of the release download. + diff --git a/docs/en-US/globally-configured-limits.xml b/docs/en-US/globally-configured-limits.xml index 48a91f1b01e..ac71112b310 100644 --- a/docs/en-US/globally-configured-limits.xml +++ b/docs/en-US/globally-configured-limits.xml @@ -22,7 +22,7 @@ under the License. --> -
+
Globally Configured Limits In a zone, the guest virtual network has a 24 bit CIDR by default. This limits the guest virtual network to 254 running instances. It can be adjusted as needed, but this must be done before any instances are created in the zone. For example, 10.1.1.0/22 would provide for ~1000 addresses. The following table lists limits set in the Global Configuration: diff --git a/docs/en-US/guest-traffic.xml b/docs/en-US/guest-traffic.xml index 16dfa41cf7b..bca635582a8 100644 --- a/docs/en-US/guest-traffic.xml +++ b/docs/en-US/guest-traffic.xml @@ -23,7 +23,14 @@ -->
Guest Traffic - A network can carry guest traffic only between VMs within one zone. Virtual machines in different zones cannot communicate with each other using their IP addresses; they must communicate with each other by routing through a public IP address. + A network can carry guest traffic only between VMs within one zone. Virtual machines in different zones cannot communicate with each other using their IP addresses; they must communicate with each other by routing through a public IP address. + This figure illustrates a typical guest traffic setup: + + + + + Depicts a guest traffic setup. + The Management Server automatically creates a virtual router for each network. A virtual router is a special virtual machine that runs on the hosts. Each virtual router has three network interfaces. Its eth0 interface serves as the gateway for the guest traffic and has the IP address of 10.1.1.1. Its eth1 interface is used by the system to configure the virtual router. Its eth2 interface is assigned a public IP address for public traffic. The virtual router provides DHCP and will automatically assign an IP address for each guest VM within the IP range assigned for the network. The user can manually reconfigure guest VMs to assume different IP addresses. Source NAT is automatically configured in the virtual router to forward outbound traffic for all guest VMs diff --git a/docs/en-US/networks.xml b/docs/en-US/networks.xml index 830576902b1..f877aa55584 100644 --- a/docs/en-US/networks.xml +++ b/docs/en-US/networks.xml @@ -31,6 +31,7 @@ + diff --git a/docs/en-US/reserved-ip-addresses-non-csvms.xml b/docs/en-US/reserved-ip-addresses-non-csvms.xml new file mode 100644 index 00000000000..18ba3ca0e42 --- /dev/null +++ b/docs/en-US/reserved-ip-addresses-non-csvms.xml @@ -0,0 +1,163 @@ + + +%BOOK_ENTITIES; +]> + + +
+ IP Reservation in Isolated Guest Networks + In isolated guest networks, a part of the guest IP address space can be reserved for + non-&PRODUCT; VMs or physical servers. To do so, you configure a range of Reserved IP addresses + by specifying the CIDR when a guest network is in Implemented state. If your customers wish to + have non-&PRODUCT; controlled VMs or physical servers on the same network, they can share a part + of the IP address space that is primarily provided to the guest network. + In an Advanced zone, an IP address range or a CIDR is assigned to a network when the network + is defined. The &PRODUCT; virtual router acts as the DHCP server and uses CIDR for assigning IP + addresses to the guest VMs. If you decide to reserve IP ranges for non-&PRODUCT; purposes, you + can specify a part of the IP address range or the CIDR that should only be allocated by the DHCP + service of the virtual router to the guest VMs created in &PRODUCT;. The remaining IPs in that + network are called Reserved IP Range. When IP reservation is configured, the administrator can + add additional VMs or physical servers that are not part of &PRODUCT; to the same network and + assign them the Reserved IP addresses. &PRODUCT; guest VMs cannot acquire IPs from the Reserved + IP Range. +
+ IP Reservation Considerations + Consider the following before you reserve an IP range for non-&PRODUCT; machines: + + + IP Reservation can be applied only when the network is in Implemented state. + + + No IP Reservation is done by default. + + + Guest VM CIDR you specify must be a subset of the network CIDR. + + + Specify a valid Guest VM CIDR. IP Reservation is applied only if no active IPs exist + outside the Guest VM CIDR. + You cannot apply IP Reservation if any VM is alloted with an IP address that is + outside the Guest VM CIDR. + + + To reset an existing IP Reservation, apply IP reservation by specifying the value of + network CIDR in the CIDR field. + For example, the following table describes three scenarios of guest network + creation: + + + + + + + + + + Case + CIDR + Network CIDR + Reserved IP Range for Non-&PRODUCT; VMs + Description + + + + + 1 + 10.1.1.0/24 + None + None + No IP Reservation. + + + 2 + 10.1.1.0/26 + 10.1.1.0/24 + 10.1.1.64 to 10.1.1.254 + IP Reservation configured by the UpdateNetwork API with + guestvmcidr=10.1.1.0/26 or enter 10.1.1.0/26 in the CIDR field in the + UI. + + + 3 + 10.1.1.0/24 + None + None + Removing IP Reservation by the UpdateNetwork API with + guestvmcidr=10.1.1.0/24 or enter 10.1.1.0/24 in the CIDR field in the UI. + + + + + + + +
+
+ Limitations + + + The IP Reservation is not supported if active IPs that are found outside the Guest VM + CIDR. + + + Upgrading network offering which causes a change in CIDR (such as upgrading an + offering with no external devices to one with external devices) IP Reservation becomes + void if any. Reconfigure IP Reservation in the new re-implemeted network. + + +
+
+ Best Practices + Apply IP Reservation to the guest network as soon as the network state changes to + Implemented. If you apply reservation soon after the first guest VM is deployed, lesser + conflicts occurs while applying reservation. +
+
+ Reserving an IP Range + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + Click the name of the network you want to modify. + + + In the Details tab, click Edit. + + + + + edit-icon.png: button to edit a network + + + The CIDR field changes to editable one. + + + In CIDR, specify the Guest VM CIDR. + + + Click Apply. + Wait for the update to complete. The Network CIDR and the Reserved IP Range are + displayed on the Details page. + + +
+
diff --git a/docs/en-US/source-prereqs.xml b/docs/en-US/source-prereqs.xml index 6c2bc2a3cb8..2e40a58c59a 100644 --- a/docs/en-US/source-prereqs.xml +++ b/docs/en-US/source-prereqs.xml @@ -30,12 +30,15 @@ for package management. - The minimum bootstrapped prerequisites for building &PRODUCT; includes - the following: + You will need, at a minimum, the following to compile &PRODUCT;: - ant - maven (version 3) - Java (Java 6/OpenJDK 1.6) + Maven (version 3) + Java (OpenJDK 1.6 or Java 7/OpenJDK 1.7) + Apache Web Services Common Utilities (ws-commons-util) + MySQL + MySQLdb (provides Python database API) + Tomcat 6 (not 6.0.35) + genisoimage rpmbuild or dpkg-dev diff --git a/docs/en-US/source.xml b/docs/en-US/source.xml index 3cb4af2321f..5d911c23050 100644 --- a/docs/en-US/source.xml +++ b/docs/en-US/source.xml @@ -24,20 +24,10 @@ Building from Source - The official &PRODUCT; release is always in source code form. While there may - exist convenience binaries in various forms from a number of places, the - source is the canonical release will be source. In this document we'll cover - acquiring the source release, building that into binary, deployable packages. - - - While building and deploying directly from source is certainly possible, the reality - of Infrastructure-as-a-Service cloud computing implies a need to deploy packages on - a potentially large number of systems, which RPMs and DEBs fill nicely. - - - Building and deploying directly from source is thus outside the scope of this - document, but is documented in the INSTALL.md file in the release. - + The official &PRODUCT; release is always in source code form. You will likely be able to find "convenience binaries," the source is the canonical release. In this section, we'll cover acquiring the source release and building that so that you can deploy it using Maven or create Debian packages or RPMs. + Note that building and deploying directly from source is typically not the most efficient way to deploy an IaaS. However, we will cover that method as well as building RPMs or Debian packages for deploying &PRODUCT;. + The instructions here are likely version-specific. That is, the method for building from source for the 4.0.x series is different from the 4.1.x series. + If you are working with a unreleased version of &PRODUCT;, see the INSTALL.md file in the top-level directory of the release. diff --git a/docs/en-US/verifying-source.xml b/docs/en-US/verifying-source.xml index b445aa4bd67..b20b9bbacf9 100644 --- a/docs/en-US/verifying-source.xml +++ b/docs/en-US/verifying-source.xml @@ -36,7 +36,7 @@ file. - You next need to import those keys, which you can do by running the following command: + You next need to import those keys, which you can do by running: # gpg --import KEYS
diff --git a/docs/en-US/working-with-snapshots.xml b/docs/en-US/working-with-snapshots.xml index a381707e8f0..b984439203c 100644 --- a/docs/en-US/working-with-snapshots.xml +++ b/docs/en-US/working-with-snapshots.xml @@ -29,4 +29,8 @@ Users can create snapshots manually or by setting up automatic recurring snapshot policies. Users can also create disk volumes from snapshots, which may be attached to a VM like any other disk volume. Snapshots of both root disks and data disks are supported. However, &PRODUCT; does not currently support booting a VM from a recovered root disk. A disk recovered from snapshot of a root disk is treated as a regular data disk; the data on recovered disk can be accessed by attaching the disk to a VM. A completed snapshot is copied from primary storage to secondary storage, where it is stored until deleted or purged by newer snapshot. + + + +
diff --git a/docs/en-US/working-with-usage-data.xml b/docs/en-US/working-with-usage-data.xml index 56a929fd6c1..5324617ab23 100644 --- a/docs/en-US/working-with-usage-data.xml +++ b/docs/en-US/working-with-usage-data.xml @@ -31,4 +31,5 @@ + diff --git a/docs/pot/build-deb.pot b/docs/pot/build-deb.pot index ca2bb9f54c0..995b086af5b 100644 --- a/docs/pot/build-deb.pot +++ b/docs/pot/build-deb.pot @@ -62,7 +62,7 @@ msgstr "" #. Tag: screen #, no-c-format msgid "\n" -"$ dpkg-buildpackge -uc -us\n" +"$ dpkg-buildpackage -uc -us\n" "" msgstr "" diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java index 1530ced30fd..4d845252f57 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java @@ -1,116 +1,112 @@ -/* - * 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. - */ +// 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.storage.datastore.db; +import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreStatus; +import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; +import com.cloud.storage.StoragePoolStatus; import com.cloud.utils.db.GenericDao; - +/** + * Data Access Object for storage_pool table + */ public interface PrimaryDataStoreDao extends GenericDao { - /** - * @param datacenterId - * -- the id of the datacenter (availability zone) - */ - List listByDataCenterId(long datacenterId); - - /** - * @param datacenterId - * -- the id of the datacenter (availability zone) - */ - List listBy(long datacenterId, long podId, Long clusterId); - - /** - * Set capacity of storage pool in bytes - * - * @param id - * pool id. - * @param capacity - * capacity in bytes - */ + /** + * @param datacenterId -- the id of the datacenter (availability zone) + */ + List listByDataCenterId(long datacenterId); + + /** + * @param datacenterId -- the id of the datacenter (availability zone) + */ + List listBy(long datacenterId, long podId, Long clusterId, ScopeType scope); + + /** + * Set capacity of storage pool in bytes + * @param id pool id. + * @param capacity capacity in bytes + */ void updateCapacity(long id, long capacity); - - /** - * Set available bytes of storage pool in bytes - * - * @param id - * pool id. - * @param available - * available capacity in bytes - */ + + /** + * Set available bytes of storage pool in bytes + * @param id pool id. + * @param available available capacity in bytes + */ void updateAvailable(long id, long available); - + + StoragePoolVO persist(StoragePoolVO pool, Map details); - + /** * Find pool by name. * - * @param name - * name of pool. - * @return the single StoragePoolVO + * @param name name of pool. + * @return the single StoragePoolVO */ List findPoolByName(String name); - + /** * Find pools by the pod that matches the details. * - * @param podId - * pod id to find the pools in. - * @param details - * details to match. All must match for the pool to be returned. + * @param podId pod id to find the pools in. + * @param details details to match. All must match for the pool to be returned. * @return List of StoragePoolVO */ - List findPoolsByDetails(long dcId, long podId, Long clusterId, Map details); - - List findPoolsByTags(long dcId, long podId, Long clusterId, String[] tags, Boolean shared); - + List findPoolsByDetails(long dcId, long podId, Long clusterId, Map details, ScopeType scope); + + List findPoolsByTags(long dcId, long podId, Long clusterId, String[] tags); + /** * Find pool by UUID. * - * @param uuid - * uuid of pool. - * @return the single StoragePoolVO + * @param uuid uuid of pool. + * @return the single StoragePoolVO */ StoragePoolVO findPoolByUUID(String uuid); List listByStorageHost(String hostFqdnOrIp); StoragePoolVO findPoolByHostPath(long dcId, Long podId, String host, String path, String uuid); - + List listPoolByHostPath(String host, String path); - + void updateDetails(long poolId, Map details); - + Map getDetails(long poolId); - List searchForStoragePoolDetails(long poolId, String value); + List searchForStoragePoolDetails(long poolId, String value); + + List findIfDuplicatePoolsExistByUUID(String uuid); - List findIfDuplicatePoolsExistByUUID(String uuid); + List listByStatus(StoragePoolStatus status); - List listByStatus(DataStoreStatus status); - - long countPoolsByStatus(DataStoreStatus... statuses); - - List listByStatusInZone(long dcId, DataStoreStatus status); + long countPoolsByStatus(StoragePoolStatus... statuses); + List listByStatusInZone(long dcId, StoragePoolStatus status); + List listPoolsByCluster(long clusterId); -} \ No newline at end of file + + List findLocalStoragePoolsByTags(long dcId, long podId, + Long clusterId, String[] tags); + + List findZoneWideStoragePoolsByTags(long dcId, String[] tags); +} diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java index 023b42bda9d..7fcddf1940f 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java @@ -1,21 +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 - * 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. - */ +// 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.storage.datastore.db; import java.sql.PreparedStatement; @@ -26,12 +24,17 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreStatus; +import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.springframework.stereotype.Component; +import com.cloud.host.Status; + +import com.cloud.storage.StoragePoolStatus; + import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; @@ -39,128 +42,147 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.SearchCriteria2; +import com.cloud.utils.db.SearchCriteriaService; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; @Component -public class PrimaryDataStoreDaoImpl extends GenericDaoBase implements PrimaryDataStoreDao { +@Local(value={PrimaryDataStoreDao.class}) @DB(txn=false) +public class PrimaryDataStoreDaoImpl extends GenericDaoBase implements PrimaryDataStoreDao { protected final SearchBuilder AllFieldSearch; - protected final SearchBuilder DcPodSearch; + protected final SearchBuilder DcPodSearch; protected final SearchBuilder DcPodAnyClusterSearch; protected final SearchBuilder DeleteLvmSearch; protected final GenericSearchBuilder StatusCountSearch; - - @Inject protected PrimaryDataStoreDetailsDao _detailsDao; - - private final String DetailsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_details ON storage_pool.id = storage_pool_details.pool_id WHERE storage_pool.removed is null and storage_pool.data_center_id = ? and (storage_pool.pod_id = ? or storage_pool.pod_id is null) and ("; - private final String DetailsSqlSuffix = ") GROUP BY storage_pool_details.pool_id HAVING COUNT(storage_pool_details.name) >= ?"; - private final String FindPoolTagDetails = "SELECT storage_pool_details.name FROM storage_pool_details WHERE pool_id = ? and value = ?"; - + + @Inject protected StoragePoolDetailsDao _detailsDao; + + private final String DetailsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_details ON storage_pool.id = storage_pool_details.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and (storage_pool.pod_id = ? or storage_pool.pod_id is null) and storage_pool.scope = ? and ("; + private final String DetailsSqlSuffix = ") GROUP BY storage_pool_details.pool_id HAVING COUNT(storage_pool_details.name) >= ?"; + private final String ZoneWideDetailsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_details ON storage_pool.id = storage_pool_details.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and storage_pool.scope = ? and ("; + private final String ZoneWideDetailsSqlSuffix = ") GROUP BY storage_pool_details.pool_id HAVING COUNT(storage_pool_details.name) >= ?"; + + private final String FindPoolTagDetails = "SELECT storage_pool_details.name FROM storage_pool_details WHERE pool_id = ? and value = ?"; + public PrimaryDataStoreDaoImpl() { AllFieldSearch = createSearchBuilder(); AllFieldSearch.and("name", AllFieldSearch.entity().getName(), SearchCriteria.Op.EQ); AllFieldSearch.and("uuid", AllFieldSearch.entity().getUuid(), SearchCriteria.Op.EQ); AllFieldSearch.and("datacenterId", AllFieldSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); AllFieldSearch.and("hostAddress", AllFieldSearch.entity().getHostAddress(), SearchCriteria.Op.EQ); - AllFieldSearch.and("status", AllFieldSearch.entity().getStatus(), SearchCriteria.Op.EQ); + AllFieldSearch.and("status",AllFieldSearch.entity().getStatus(),SearchCriteria.Op.EQ); AllFieldSearch.and("path", AllFieldSearch.entity().getPath(), SearchCriteria.Op.EQ); AllFieldSearch.and("podId", AllFieldSearch.entity().getPodId(), Op.EQ); AllFieldSearch.and("clusterId", AllFieldSearch.entity().getClusterId(), Op.EQ); - AllFieldSearch.done(); - - DcPodSearch = createSearchBuilder(); - DcPodSearch.and("datacenterId", DcPodSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); - DcPodSearch.and().op("nullpod", DcPodSearch.entity().getPodId(), SearchCriteria.Op.NULL); - DcPodSearch.or("podId", DcPodSearch.entity().getPodId(), SearchCriteria.Op.EQ); - DcPodSearch.cp(); - DcPodSearch.and().op("nullcluster", DcPodSearch.entity().getClusterId(), SearchCriteria.Op.NULL); - DcPodSearch.or("cluster", DcPodSearch.entity().getClusterId(), SearchCriteria.Op.EQ); - DcPodSearch.cp(); - DcPodSearch.done(); - - DcPodAnyClusterSearch = createSearchBuilder(); + AllFieldSearch.done(); + + DcPodSearch = createSearchBuilder(); + DcPodSearch.and("datacenterId", DcPodSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + DcPodSearch.and("status", DcPodSearch.entity().getStatus(), SearchCriteria.Op.EQ); + DcPodSearch.and("scope", DcPodSearch.entity().getScope(), SearchCriteria.Op.EQ); + DcPodSearch.and().op("nullpod", DcPodSearch.entity().getPodId(), SearchCriteria.Op.NULL); + DcPodSearch.or("podId", DcPodSearch.entity().getPodId(), SearchCriteria.Op.EQ); + DcPodSearch.cp(); + DcPodSearch.and().op("nullcluster", DcPodSearch.entity().getClusterId(), SearchCriteria.Op.NULL); + DcPodSearch.or("cluster", DcPodSearch.entity().getClusterId(), SearchCriteria.Op.EQ); + DcPodSearch.cp(); + DcPodSearch.done(); + + DcPodAnyClusterSearch = createSearchBuilder(); DcPodAnyClusterSearch.and("datacenterId", DcPodAnyClusterSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + DcPodAnyClusterSearch.and("status", DcPodAnyClusterSearch.entity().getStatus(), SearchCriteria.Op.EQ); + DcPodAnyClusterSearch.and("scope", DcPodAnyClusterSearch.entity().getScope(), SearchCriteria.Op.EQ); DcPodAnyClusterSearch.and().op("nullpod", DcPodAnyClusterSearch.entity().getPodId(), SearchCriteria.Op.NULL); DcPodAnyClusterSearch.or("podId", DcPodAnyClusterSearch.entity().getPodId(), SearchCriteria.Op.EQ); DcPodAnyClusterSearch.cp(); DcPodAnyClusterSearch.done(); - + DeleteLvmSearch = createSearchBuilder(); DeleteLvmSearch.and("ids", DeleteLvmSearch.entity().getId(), SearchCriteria.Op.IN); DeleteLvmSearch.and().op("LVM", DeleteLvmSearch.entity().getPoolType(), SearchCriteria.Op.EQ); DeleteLvmSearch.or("Filesystem", DeleteLvmSearch.entity().getPoolType(), SearchCriteria.Op.EQ); DeleteLvmSearch.cp(); - DeleteLvmSearch.done(); + DeleteLvmSearch.done(); + + StatusCountSearch = createSearchBuilder(Long.class); StatusCountSearch.and("status", StatusCountSearch.entity().getStatus(), SearchCriteria.Op.IN); StatusCountSearch.select(null, Func.COUNT, null); StatusCountSearch.done(); - } - @Override - public List findPoolByName(String name) { - SearchCriteria sc = AllFieldSearch.create(); + } + + @Override + public List findPoolByName(String name) { + SearchCriteria sc = AllFieldSearch.create(); sc.setParameters("name", name); return listIncludingRemovedBy(sc); - } + } - @Override - public StoragePoolVO findPoolByUUID(String uuid) { - SearchCriteria sc = AllFieldSearch.create(); + + @Override + public StoragePoolVO findPoolByUUID(String uuid) { + SearchCriteria sc = AllFieldSearch.create(); sc.setParameters("uuid", uuid); return findOneIncludingRemovedBy(sc); - } + } + + - @Override - public List findIfDuplicatePoolsExistByUUID(String uuid) { - SearchCriteria sc = AllFieldSearch.create(); + @Override + public List findIfDuplicatePoolsExistByUUID(String uuid) { + SearchCriteria sc = AllFieldSearch.create(); sc.setParameters("uuid", uuid); return listBy(sc); - } + } - @Override - public List listByDataCenterId(long datacenterId) { - SearchCriteria sc = AllFieldSearch.create(); + + @Override + public List listByDataCenterId(long datacenterId) { + SearchCriteria sc = AllFieldSearch.create(); sc.setParameters("datacenterId", datacenterId); return listBy(sc); - } + } - @Override - public void updateAvailable(long id, long available) { - StoragePoolVO pool = createForUpdate(id); - pool.setAvailableBytes(available); - update(id, pool); - } - @Override - public void updateCapacity(long id, long capacity) { - StoragePoolVO pool = createForUpdate(id); - pool.setCapacityBytes(capacity); - update(id, pool); + @Override + public void updateAvailable(long id, long available) { + StoragePoolVO pool = createForUpdate(id); + pool.setAvailableBytes(available); + update(id, pool); + } - } + @Override + public void updateCapacity(long id, long capacity) { + StoragePoolVO pool = createForUpdate(id); + pool.setCapacityBytes(capacity); + update(id, pool); + + } + @Override public List listByStorageHost(String hostFqdnOrIp) { SearchCriteria sc = AllFieldSearch.create(); sc.setParameters("hostAddress", hostFqdnOrIp); return listIncludingRemovedBy(sc); } - + @Override - public List listByStatus(DataStoreStatus status) { + public List listByStatus(StoragePoolStatus status){ SearchCriteria sc = AllFieldSearch.create(); - sc.setParameters("status", status); - return listBy(sc); + sc.setParameters("status", status); + return listBy(sc); } - + @Override - public List listByStatusInZone(long dcId, DataStoreStatus status) { + public List listByStatusInZone(long dcId, StoragePoolStatus status){ SearchCriteria sc = AllFieldSearch.create(); - sc.setParameters("status", status); - sc.setParameters("datacenterId", dcId); - return listBy(sc); + sc.setParameters("status", status); + sc.setParameters("datacenterId", dcId); + return listBy(sc); } @Override @@ -171,190 +193,238 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase sc.setParameters("datacenterId", datacenterId); sc.setParameters("podId", podId); sc.setParameters("uuid", uuid); - + return findOneBy(sc); } - @Override - public List listBy(long datacenterId, long podId, Long clusterId) { - if (clusterId != null) { - SearchCriteria sc = DcPodSearch.create(); + @Override + public List listBy(long datacenterId, long podId, Long clusterId, ScopeType scope) { + if (clusterId != null) { + SearchCriteria sc = DcPodSearch.create(); sc.setParameters("datacenterId", datacenterId); sc.setParameters("podId", podId); - + sc.setParameters("status", Status.Up); + sc.setParameters("scope", scope); + sc.setParameters("cluster", clusterId); return listBy(sc); - } else { - SearchCriteria sc = DcPodAnyClusterSearch.create(); - sc.setParameters("datacenterId", datacenterId); - sc.setParameters("podId", podId); - return listBy(sc); - } - } + } else { + SearchCriteria sc = DcPodAnyClusterSearch.create(); + sc.setParameters("datacenterId", datacenterId); + sc.setParameters("podId", podId); + sc.setParameters("status", Status.Up); + sc.setParameters("scope", scope); + return listBy(sc); + } + } - @Override - public List listPoolByHostPath(String host, String path) { + @Override + public List listPoolByHostPath(String host, String path) { SearchCriteria sc = AllFieldSearch.create(); sc.setParameters("hostAddress", host); sc.setParameters("path", path); - + return listBy(sc); - } - - public StoragePoolVO listById(Integer id) { + } + + public StoragePoolVO listById(Integer id) + { SearchCriteria sc = AllFieldSearch.create(); sc.setParameters("id", id); - + return findOneIncludingRemovedBy(sc); + } + + @Override @DB + public StoragePoolVO persist(StoragePoolVO pool, Map details) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + pool = super.persist(pool); + if (details != null) { + for (Map.Entry detail : details.entrySet()) { + StoragePoolDetailVO vo = new StoragePoolDetailVO(pool.getId(), detail.getKey(), detail.getValue()); + _detailsDao.persist(vo); + } + } + txn.commit(); + return pool; + } + + @DB + @Override + public List findPoolsByDetails(long dcId, long podId, Long clusterId, Map details, ScopeType scope) { + StringBuilder sql = new StringBuilder(DetailsSqlPrefix); + if (clusterId != null) { + sql.append("storage_pool.cluster_id = ? OR storage_pool.cluster_id IS NULL) AND ("); + } + + for (Map.Entry detail : details.entrySet()) { + sql.append("((storage_pool_details.name='").append(detail.getKey()).append("') AND (storage_pool_details.value='").append(detail.getValue()).append("')) OR "); + } + sql.delete(sql.length() - 4, sql.length()); + sql.append(DetailsSqlSuffix); + Transaction txn = Transaction.currentTxn(); + PreparedStatement pstmt = null; + try { + pstmt = txn.prepareAutoCloseStatement(sql.toString()); + int i = 1; + pstmt.setLong(i++, dcId); + pstmt.setLong(i++, podId); + pstmt.setString(i++, scope.toString()); + if (clusterId != null) { + pstmt.setLong(i++, clusterId); + } + pstmt.setInt(i++, details.size()); + ResultSet rs = pstmt.executeQuery(); + List pools = new ArrayList(); + while (rs.next()) { + pools.add(toEntityBean(rs, false)); + } + return pools; + } catch (SQLException e) { + throw new CloudRuntimeException("Unable to execute " + pstmt, e); + } + } + + protected Map tagsToDetails(String[] tags) { + Map details = new HashMap(tags.length); + for (String tag: tags) { + details.put(tag, "true"); + } + return details; + } + + @Override + public List findPoolsByTags(long dcId, long podId, Long clusterId, String[] tags) { + List storagePools = null; + if (tags == null || tags.length == 0) { + storagePools = listBy(dcId, podId, clusterId, ScopeType.CLUSTER); + } else { + Map details = tagsToDetails(tags); + storagePools = findPoolsByDetails(dcId, podId, clusterId, details, ScopeType.CLUSTER); + } + + return storagePools; + } + + @Override + public List findLocalStoragePoolsByTags(long dcId, long podId, Long clusterId, String[] tags) { + List storagePools = null; + if (tags == null || tags.length == 0) { + storagePools = listBy(dcId, podId, clusterId, ScopeType.HOST); + } else { + Map details = tagsToDetails(tags); + storagePools = findPoolsByDetails(dcId, podId, clusterId, details, ScopeType.HOST); + } + + return storagePools; + } + + @Override + public List findZoneWideStoragePoolsByTags(long dcId, String[] tags) { + List storagePools = null; + if (tags == null || tags.length == 0) { + SearchCriteriaService sc = SearchCriteria2.create(StoragePoolVO.class); + sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dcId); + sc.addAnd(sc.getEntity().getStatus(), Op.EQ, Status.Up); + sc.addAnd(sc.getEntity().getScope(), Op.EQ, ScopeType.ZONE); + return sc.list(); + } else { + Map details = tagsToDetails(tags); + + StringBuilder sql = new StringBuilder(ZoneWideDetailsSqlPrefix); + + for (Map.Entry detail : details.entrySet()) { + sql.append("((storage_pool_details.name='").append(detail.getKey()).append("') AND (storage_pool_details.value='").append(detail.getValue()).append("')) OR "); + } + sql.delete(sql.length() - 4, sql.length()); + sql.append(ZoneWideDetailsSqlSuffix); + Transaction txn = Transaction.currentTxn(); + PreparedStatement pstmt = null; + try { + pstmt = txn.prepareAutoCloseStatement(sql.toString()); + int i = 1; + pstmt.setLong(i++, dcId); + pstmt.setString(i++, ScopeType.ZONE.toString()); + pstmt.setInt(i++, details.size()); + ResultSet rs = pstmt.executeQuery(); + List pools = new ArrayList(); + while (rs.next()) { + pools.add(toEntityBean(rs, false)); + } + return pools; + } catch (SQLException e) { + throw new CloudRuntimeException("Unable to execute " + pstmt, e); + } + } + } + + @Override + @DB + public List searchForStoragePoolDetails(long poolId, String value){ + + StringBuilder sql = new StringBuilder(FindPoolTagDetails); + + Transaction txn = Transaction.currentTxn(); + PreparedStatement pstmt = null; + try { + pstmt = txn.prepareAutoCloseStatement(sql.toString()); + pstmt.setLong(1, poolId); + pstmt.setString(2, value); + + ResultSet rs = pstmt.executeQuery(); + List tags = new ArrayList(); + + while (rs.next()) { + tags.add(rs.getString("name")); + } + return tags; + } catch (SQLException e) { + throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e); + } + + } + + @Override + public void updateDetails(long poolId, Map details) { + if (details != null) { + _detailsDao.update(poolId, details); + } } - - @Override - @DB - public StoragePoolVO persist(StoragePoolVO pool, Map details) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - pool = super.persist(pool); - if (details != null) { - for (Map.Entry detail : details.entrySet()) { - PrimaryDataStoreDetailVO vo = new PrimaryDataStoreDetailVO(pool.getId(), detail.getKey(), detail.getValue()); - _detailsDao.persist(vo); - } - } - txn.commit(); - return pool; - } - - @DB - @Override - public List findPoolsByDetails(long dcId, long podId, Long clusterId, Map details) { - StringBuilder sql = new StringBuilder(DetailsSqlPrefix); - if (clusterId != null) { - sql.append("storage_pool.cluster_id = ? OR storage_pool.cluster_id IS NULL) AND ("); - } - for (Map.Entry detail : details.entrySet()) { - sql.append("((storage_pool_details.name='").append(detail.getKey()).append("') AND (storage_pool_details.value='").append(detail.getValue()).append("')) OR "); - } - sql.delete(sql.length() - 4, sql.length()); - sql.append(DetailsSqlSuffix); - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql.toString()); - int i = 1; - pstmt.setLong(i++, dcId); - pstmt.setLong(i++, podId); - if (clusterId != null) { - pstmt.setLong(i++, clusterId); - } - pstmt.setInt(i++, details.size()); - ResultSet rs = pstmt.executeQuery(); - List pools = new ArrayList(); - while (rs.next()) { - pools.add(toEntityBean(rs, false)); - } - return pools; - } catch (SQLException e) { - throw new CloudRuntimeException("Unable to execute " + pstmt, e); - } - } - - protected Map tagsToDetails(String[] tags) { - Map details = new HashMap(tags.length); - for (String tag : tags) { - details.put(tag, "true"); - } - return details; - } - - @Override - public List findPoolsByTags(long dcId, long podId, Long clusterId, String[] tags, Boolean shared) { - List storagePools = null; - if (tags == null || tags.length == 0) { - storagePools = listBy(dcId, podId, clusterId); - } else { - Map details = tagsToDetails(tags); - storagePools = findPoolsByDetails(dcId, podId, clusterId, details); - } - - if (shared == null) { - return storagePools; - } else { - List filteredStoragePools = new ArrayList(storagePools); - for (StoragePoolVO pool : storagePools) { - /* - * if (shared != pool.isShared()) { - * filteredStoragePools.remove(pool); } - */ - } - - return filteredStoragePools; - } - } - - @Override - @DB - public List searchForStoragePoolDetails(long poolId, String value) { - - StringBuilder sql = new StringBuilder(FindPoolTagDetails); - - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql.toString()); - pstmt.setLong(1, poolId); - pstmt.setString(2, value); - - ResultSet rs = pstmt.executeQuery(); - List tags = new ArrayList(); - - while (rs.next()) { - tags.add(rs.getString("name")); - } - return tags; - } catch (SQLException e) { - throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e); - } - - } - - @Override - public void updateDetails(long poolId, Map details) { - if (details != null) { - _detailsDao.update(poolId, details); - } - } - - @Override - public Map getDetails(long poolId) { - return _detailsDao.getDetails(poolId); - } - - @Override + + @Override + public Map getDetails(long poolId) { + return _detailsDao.getDetails(poolId); + } + + @Override public boolean configure(String name, Map params) throws ConfigurationException { - super.configure(name, params); - _detailsDao.configure("DetailsDao", params); - return true; - } - + super.configure(name, params); + _detailsDao.configure("DetailsDao", params); + return true; + } + + + @Override - public long countPoolsByStatus(DataStoreStatus... statuses) { + public long countPoolsByStatus( StoragePoolStatus... statuses) { SearchCriteria sc = StatusCountSearch.create(); - - sc.setParameters("status", (Object[]) statuses); - + + sc.setParameters("status", (Object[])statuses); + List rs = customSearchIncludingRemoved(sc, null); if (rs.size() == 0) { return 0; } - + return rs.get(0); } - + @Override public List listPoolsByCluster(long clusterId) { SearchCriteria sc = AllFieldSearch.create(); sc.setParameters("clusterId", clusterId); - + return listBy(sc); } } diff --git a/core/src/com/cloud/storage/StoragePoolDetailVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailVO.java similarity index 97% rename from core/src/com/cloud/storage/StoragePoolDetailVO.java rename to engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailVO.java index 48487e566ac..699beef90c2 100644 --- a/core/src/com/cloud/storage/StoragePoolDetailVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailVO.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.storage; +package org.apache.cloudstack.storage.datastore.db; import org.apache.cloudstack.api.InternalIdentity; diff --git a/server/src/com/cloud/storage/dao/StoragePoolDetailsDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailsDao.java similarity index 93% rename from server/src/com/cloud/storage/dao/StoragePoolDetailsDao.java rename to engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailsDao.java index 34aa87f5882..be71670e992 100644 --- a/server/src/com/cloud/storage/dao/StoragePoolDetailsDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailsDao.java @@ -14,11 +14,11 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.storage.dao; +package org.apache.cloudstack.storage.datastore.db; import java.util.Map; -import com.cloud.storage.StoragePoolDetailVO; + import com.cloud.utils.db.GenericDao; public interface StoragePoolDetailsDao extends GenericDao { diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java index 1782f16a4c1..579eaefe329 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java @@ -32,12 +32,13 @@ import javax.persistence.TemporalType; import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolStatus; import com.cloud.utils.db.GenericDao; @Entity @Table(name="storage_pool") -public class StoragePoolVO { +public class StoragePoolVO implements StoragePool{ @Id @TableGenerator(name = "storage_pool_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "storage_pool_seq", allocationSize = 1) @Column(name = "id", updatable = false, nullable = false) @@ -301,4 +302,10 @@ public class StoragePoolVO { public boolean isLocal() { return !isShared(); } + + @Override + public boolean isInMaintenance() { + // TODO Auto-generated method stub + return false; + } } diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java index d7bab4a7889..8b9b100c243 100755 --- a/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java @@ -28,6 +28,7 @@ import org.apache.cloudstack.engine.cloud.entity.api.db.VMReservationVO; import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMEntityDao; import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMReservationDao; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.springframework.stereotype.Component; import com.cloud.dc.DataCenter; @@ -50,7 +51,6 @@ import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.user.dao.AccountDao; @@ -101,7 +101,7 @@ public class VMEntityManagerImpl implements VMEntityManager { protected VolumeDao _volsDao; @Inject - protected StoragePoolDao _storagePoolDao; + protected PrimaryDataStoreDao _storagePoolDao; @Inject DataStoreManager dataStoreMgr; diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java index 81dfb6217d6..414e2319465 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java @@ -30,6 +30,9 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager; import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO; +import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.junit.Before; import org.junit.Test; @@ -54,14 +57,11 @@ import com.cloud.org.Managed.ManagedState; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolDetailVO; import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.dao.DiskOfferingDao; -import com.cloud.storage.dao.StoragePoolDao; -import com.cloud.storage.dao.StoragePoolDetailsDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.component.ComponentContext; import com.cloud.vm.DiskProfile; @@ -71,7 +71,7 @@ import com.cloud.vm.VirtualMachineProfile; @ContextConfiguration(locations = "classpath:/storageContext.xml") public class StorageAllocatorTest { @Inject - StoragePoolDao storagePoolDao; + PrimaryDataStoreDao storagePoolDao; @Inject StorageManager storageMgr; @Inject diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTestConfiguration.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTestConfiguration.java index 16017021246..b815fc13446 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTestConfiguration.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTestConfiguration.java @@ -19,6 +19,7 @@ package org.apache.cloudstack.storage.allocator; import java.io.IOException; import org.apache.cloudstack.storage.allocator.StorageAllocatorTestConfiguration.Library; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl; import org.mockito.Mockito; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -33,7 +34,6 @@ import com.cloud.dc.dao.DataCenterDaoImpl; import com.cloud.domain.dao.DomainDaoImpl; import com.cloud.host.dao.HostDaoImpl; import com.cloud.storage.StorageManager; -import com.cloud.storage.dao.StoragePoolDaoImpl; import com.cloud.storage.dao.StoragePoolDetailsDaoImpl; import com.cloud.storage.dao.VMTemplateDaoImpl; import com.cloud.utils.component.SpringComponentScanUtils; @@ -43,7 +43,7 @@ import com.cloud.vm.UserVmManager; @Configuration @ComponentScan(basePackageClasses={ StoragePoolDetailsDaoImpl.class, - StoragePoolDaoImpl.class, + PrimaryDataStoreDaoImpl.class, VMTemplateDaoImpl.class, HostDaoImpl.class, DomainDaoImpl.class, diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnasphotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnasphotStrategy.java index 5cbe2243faa..ea3b0afd09d 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnasphotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnasphotStrategy.java @@ -44,6 +44,7 @@ import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.motion.DataMotionService; import org.apache.cloudstack.storage.snapshot.SnapshotObject; import org.apache.cloudstack.storage.snapshot.SnapshotStateMachineManager; @@ -71,7 +72,6 @@ import com.cloud.storage.StoragePool; import com.cloud.storage.VolumeManager; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.s3.S3Manager; import com.cloud.storage.snapshot.SnapshotManager; @@ -96,7 +96,7 @@ public class AncientSnasphotStrategy implements SnapshotStrategy { @Inject protected UserVmDao _vmDao; @Inject - protected StoragePoolDao _storagePoolDao; + protected PrimaryDataStoreDao _storagePoolDao; @Inject protected ClusterDao _clusterDao; @Inject diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java index 4c5f0e6cccf..6334ca7f2dc 100755 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java @@ -29,6 +29,7 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.log4j.Logger; import com.cloud.configuration.dao.ConfigurationDao; @@ -43,7 +44,6 @@ import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; import com.cloud.storage.Volume.Type; import com.cloud.storage.dao.DiskOfferingDao; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.user.Account; import com.cloud.utils.NumbersUtil; @@ -55,7 +55,7 @@ import com.cloud.vm.VirtualMachineProfile; public abstract class AbstractStoragePoolAllocator extends AdapterBase implements StoragePoolAllocator { private static final Logger s_logger = Logger.getLogger(AbstractStoragePoolAllocator.class); @Inject StorageManager storageMgr; - protected @Inject StoragePoolDao _storagePoolDao; + protected @Inject PrimaryDataStoreDao _storagePoolDao; @Inject VolumeDao _volumeDao; @Inject ConfigurationDao _configDao; @Inject ClusterDao _clusterDao; diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java index 6f7849737f4..c45f8a822a9 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java @@ -22,6 +22,7 @@ import java.util.List; import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -31,7 +32,6 @@ import com.cloud.deploy.DeploymentPlanner.ExcludeList; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; @@ -39,7 +39,7 @@ import com.cloud.vm.VirtualMachineProfile; @Component public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator { private static final Logger s_logger = Logger.getLogger(ZoneWideStoragePoolAllocator.class); - @Inject StoragePoolDao _storagePoolDao; + @Inject PrimaryDataStoreDao _storagePoolDao; @Inject DataStoreManager dataStoreMgr; @Override diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/AncientPrimaryDataStoreLifeCycleImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/AncientPrimaryDataStoreLifeCycleImpl.java index 7a5b0d06020..6154a666b24 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/AncientPrimaryDataStoreLifeCycleImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/AncientPrimaryDataStoreLifeCycleImpl.java @@ -532,7 +532,7 @@ public class AncientPrimaryDataStoreLifeCycleImpl implements // if they dont, then just stop all vms on this one List upPools = primaryDataStoreDao .listByStatusInZone(pool.getDataCenterId(), - DataStoreStatus.Up); + StoragePoolStatus.Up); boolean restart = true; if (upPools == null || upPools.size() == 0) { restart = false; diff --git a/packaging/centos63/cloud-agent.rc b/packaging/centos63/cloud-agent.rc index 58611f299ba..6d534732528 100755 --- a/packaging/centos63/cloud-agent.rc +++ b/packaging/centos63/cloud-agent.rc @@ -57,11 +57,12 @@ done export JAVA_HOME ACP=`ls /usr/share/cloudstack-agent/lib/*.jar | tr '\n' ':' | sed s'/.$//'` +PCP=`ls /usr/share/cloudstack-agent/plugins/*.jar 2>/dev/null | tr '\n' ':' | sed s'/.$//'` # We need to append the JSVC daemon JAR to the classpath # AgentShell implements the JSVC daemon methods # We also need JNA in the classpath (from the distribution) for the Libvirt Java bindings -export CLASSPATH="/usr/share/java/commons-daemon.jar:/usr/share/java/jna.jar:$ACP:/etc/cloudstack/agent:/usr/share/cloudstack-common/scripts" +export CLASSPATH="/usr/share/java/commons-daemon.jar:/usr/share/java/jna.jar:$ACP:$PCP:/etc/cloudstack/agent:/usr/share/cloudstack-common/scripts" start() { echo -n $"Starting $PROGNAME: " diff --git a/packaging/centos63/cloud.spec b/packaging/centos63/cloud.spec index 369ff7f11de..002fbbb4d56 100644 --- a/packaging/centos63/cloud.spec +++ b/packaging/centos63/cloud.spec @@ -116,6 +116,7 @@ Requires: ebtables Requires: jsvc Requires: jakarta-commons-daemon Requires: jakarta-commons-daemon-jsvc +Requires: perl Provides: cloud-agent Obsoletes: cloud-agent < 4.1.0 Obsoletes: cloud-test < 4.1.0 @@ -256,6 +257,7 @@ chmod 770 ${RPM_BUILD_ROOT}%{_localstatedir}/log/%{name}/agent mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/agent mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/log/%{name}/agent mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-agent/lib +mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-agent/plugins install -D packaging/centos63/cloud-agent.rc ${RPM_BUILD_ROOT}%{_sysconfdir}/init.d/%{name}-agent install -D agent/target/transformed/agent.properties ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/agent/agent.properties install -D agent/target/transformed/environment.properties ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/agent/environment.properties @@ -395,6 +397,7 @@ fi %config(noreplace) %{_sysconfdir}/%{name}/agent %dir %{_localstatedir}/log/%{name}/agent %attr(0644,root,root) %{_datadir}/%{name}-agent/lib/*.jar +%dir %{_datadir}/%{name}-agent/plugins %doc LICENSE %doc NOTICE diff --git a/packaging/debian/init/cloud-agent b/packaging/debian/init/cloud-agent index 3d9d3db4400..c87a5c09f81 100755 --- a/packaging/debian/init/cloud-agent +++ b/packaging/debian/init/cloud-agent @@ -55,12 +55,13 @@ for jdir in $JDK_DIRS; do done export JAVA_HOME -ACP=`ls /usr/share/cloudstack-agent/lib/* | tr '\n' ':' | sed s'/.$//'` +ACP=`ls /usr/share/cloudstack-agent/lib/*.jar | tr '\n' ':' | sed s'/.$//'` +PCP=`ls /usr/share/cloudstack-agent/plugins/*.jar 2>/dev/null | tr '\n' ':' | sed s'/.$//'` # We need to append the JSVC daemon JAR to the classpath # AgentShell implements the JSVC daemon methods # We also need JNA in the classpath (from the distribution) for the Libvirt Java bindings -export CLASSPATH="/usr/share/java/commons-daemon.jar:/usr/share/java/jna.jar:$ACP:/etc/cloudstack/agent" +export CLASSPATH="/usr/share/java/commons-daemon.jar:/usr/share/java/jna.jar:$ACP:$PCP:/etc/cloudstack/agent" wait_for_network() { i=1 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 8ddccd582f7..4fb0a9bcde6 100755 --- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config +++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config @@ -108,14 +108,17 @@ get_boot_params() { sed -i "s/%/ /g" /var/cache/cloud/cmdline ;; kvm) - # KVM needs to mount another disk, to get cmdline - mkdir -p $EXTRA_MOUNT - mount /dev/vdb $EXTRA_MOUNT - cp -f $EXTRA_MOUNT/cmdline /var/cache/cloud/cmdline - cp -f $EXTRA_MOUNT/authorized_keys /var/cache/cloud/authorized_keys - privkey=/var/cache/cloud/authorized_keys - umount $EXTRA_MOUNT - cp -f $privkey /root/.ssh/ && chmod go-rwx /root/.ssh/authorized_keys + while read line; do + if [[ $line == cmdline:* ]]; then + cmd=${line//cmdline:/} + echo $cmd > /var/cache/cloud/cmdline + elif [[ $line == pubkey:* ]]; then + pubkey=${line//pubkey:/} + echo $pubkey > /var/cache/cloud/authorized_keys + echo $pubkey > /root/.ssh/authorized_keys + fi + done < /dev/vport0p1 + chmod go-rwx /root/.ssh/authorized_keys ;; vmware) vmtoolsd --cmd 'machine.id.get' > /var/cache/cloud/cmdline diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMHABase.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMHABase.java index af89d9b18a9..d067b35902f 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMHABase.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMHABase.java @@ -23,6 +23,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import org.apache.log4j.Logger; import org.libvirt.LibvirtException; import org.libvirt.StoragePool; import org.libvirt.StoragePoolInfo; @@ -33,6 +34,7 @@ import com.cloud.utils.script.OutputInterpreter.AllLinesParser; import com.cloud.utils.script.Script; public class KVMHABase { + private static final Logger s_logger = Logger.getLogger(KVMHABase.class); private long _timeout = 60000; /* 1 minutes */ protected static String _heartBeatPath; protected long _heartBeatUpdateTimeout = 60000; @@ -124,14 +126,14 @@ public class KVMHABase { } poolName = pool.getName(); } catch (LibvirtException e) { - + s_logger.debug("Ignoring libvirt error.", e); } finally { try { if (pool != null) { pool.free(); } } catch (LibvirtException e) { - + s_logger.debug("Ignoring libvirt error.", e); } } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 3c848dead1e..0a25bab2a10 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -255,7 +255,7 @@ ServerResource { private String _modifyVlanPath; private String _versionstringpath; - private String _patchdomrPath; + private String _patchViaSocketPath; private String _createvmPath; private String _manageSnapshotPath; private String _resizeVolumePath; @@ -521,10 +521,10 @@ ServerResource { throw new ConfigurationException("Unable to find versions.sh"); } - _patchdomrPath = Script.findScript(kvmScriptsDir + "/patch/", - "rundomrpre.sh"); - if (_patchdomrPath == null) { - throw new ConfigurationException("Unable to find rundomrpre.sh"); + _patchViaSocketPath = Script.findScript(kvmScriptsDir + "/patch/", + "patchviasocket.pl"); + if (_patchViaSocketPath == null) { + throw new ConfigurationException("Unable to find patchviasocket.pl"); } _heartBeatPath = Script.findScript(kvmScriptsDir, "kvmheartbeat.sh"); @@ -692,7 +692,7 @@ ServerResource { _hvVersion = conn.getVersion(); _hvVersion = (_hvVersion % 1000000) / 1000; } catch (LibvirtException e) { - + s_logger.trace("Ignoring libvirt error.", e); } String[] info = NetUtils.getNetworkParams(_privateNic); @@ -764,8 +764,8 @@ ServerResource { if (tokens.length == 2) { try { _migrateSpeed = Integer.parseInt(tokens[0]); - } catch (Exception e) { - + } catch (NumberFormatException e) { + s_logger.trace("Ignoring migrateSpeed extraction error.", e); } s_logger.debug("device " + _pifs.get("public") + " has speed: " + String.valueOf(_migrateSpeed)); } @@ -846,8 +846,8 @@ ServerResource { throw new ConfigurationException("Unable to find class for libvirt.vif.driver " + e); } catch (InstantiationException e) { throw new ConfigurationException("Unable to instantiate class for libvirt.vif.driver " + e); - } catch (Exception e) { - throw new ConfigurationException("Failed to initialize libvirt.vif.driver " + e); + } catch (IllegalAccessException e) { + throw new ConfigurationException("Unable to instantiate class for libvirt.vif.driver " + e); } return vifDriver; } @@ -1014,13 +1014,11 @@ ServerResource { return vnetId; } - private void patchSystemVm(String cmdLine, String dataDiskPath, - String vmName) throws InternalErrorException { + private void passCmdLine(String vmName, String cmdLine) + throws InternalErrorException { + final Script command = new Script(_patchViaSocketPath, _timeout, s_logger); String result; - final Script command = new Script(_patchdomrPath, _timeout, s_logger); - command.add("-l", vmName); - command.add("-t", "all"); - command.add("-d", dataDiskPath); + command.add("-n",vmName); command.add("-p", cmdLine.replaceAll(" ", "%")); result = command.execute(); if (result != null) { @@ -1043,7 +1041,6 @@ ServerResource { protected String startVM(Connect conn, String vmName, String domainXML) throws LibvirtException, InternalErrorException { - Domain dm = null; try { /* We create a transient domain here. When this method gets @@ -1053,12 +1050,11 @@ ServerResource { This also makes sure we never have any old "garbage" defined in libvirt which might haunt us. */ - dm = conn.domainCreateXML(domainXML, 0); + conn.domainCreateXML(domainXML, 0); } catch (final LibvirtException e) { s_logger.warn("Failed to start domain " + vmName + ": " - + e.getMessage()); + + e.getMessage(), e); } - return null; } @@ -1068,6 +1064,7 @@ ServerResource { Connect conn = LibvirtConnection.getConnection(); conn.close(); } catch (LibvirtException e) { + s_logger.trace("Ignoring libvirt error.", e); } return true; @@ -1461,24 +1458,6 @@ ServerResource { pool.deletePhysicalDisk(vol.getPath()); String vmName = cmd.getVmName(); String poolPath = pool.getLocalPath(); - - /* if vol is a root disk for a system vm, try to remove accompanying patch disk as well - this is a bit tricky since the patchdisk is only a LibvirtComputingResource construct - and not tracked anywhere in cloudstack */ - if (vol.getType() == Volume.Type.ROOT && vmName.matches("^[rsv]-\\d+-.+$")) { - File patchVbd = new File(poolPath + File.separator + vmName + "-patchdisk"); - if(patchVbd.exists()){ - try { - _storagePoolMgr.deleteVbdByPath(vol.getPoolType(),patchVbd.getAbsolutePath()); - } catch(CloudRuntimeException e) { - s_logger.warn("unable to destroy patch disk '" + patchVbd.getAbsolutePath() + - "' while removing root disk for " + vmName + " : " + e); - } - } else { - s_logger.debug("file '" +patchVbd.getAbsolutePath()+ "' not found"); - } - } - return new Answer(cmd, true, "Success"); } catch (CloudRuntimeException e) { s_logger.debug("Failed to delete volume: " + e.toString()); @@ -1516,11 +1495,10 @@ ServerResource { } private PlugNicAnswer execute(PlugNicCommand cmd) { - Connect conn; NicTO nic = cmd.getNic(); String vmName = cmd.getVmName(); try { - conn = LibvirtConnection.getConnection(); + Connect conn = LibvirtConnection.getConnection(); Domain vm = getDomain(conn, vmName); List pluggedNics = getInterfaces(conn, vmName); Integer nicnum = 0; @@ -1533,7 +1511,11 @@ ServerResource { } vm.attachDevice(getVifDriver(nic.getType()).plug(nic, "Other PV (32-bit)").toString()); return new PlugNicAnswer(cmd, true, "success"); - } catch (Exception e) { + } catch (LibvirtException e) { + String msg = " Plug Nic failed due to " + e.toString(); + s_logger.warn(msg, e); + return new PlugNicAnswer(cmd, false, msg); + } catch (InternalErrorException e) { String msg = " Plug Nic failed due to " + e.toString(); s_logger.warn(msg, e); return new PlugNicAnswer(cmd, false, msg); @@ -1555,7 +1537,7 @@ ServerResource { } } return new UnPlugNicAnswer(cmd, true, "success"); - } catch (Exception e) { + } catch (LibvirtException e) { String msg = " Unplug Nic failed due to " + e.toString(); s_logger.warn(msg, e); return new UnPlugNicAnswer(cmd, false, msg); @@ -1609,7 +1591,7 @@ ServerResource { return new SetupGuestNetworkAnswer(cmd, false, "Creating guest network failed due to " + result); } return new SetupGuestNetworkAnswer(cmd, true, "success"); - } catch (Exception e) { + } catch (LibvirtException e) { String msg = "Creating guest network failed due to " + e.toString(); s_logger.warn(msg, e); return new SetupGuestNetworkAnswer(cmd, false, msg); @@ -1649,7 +1631,7 @@ ServerResource { } return new SetNetworkACLAnswer(cmd, true, results); - } catch (Exception e) { + } catch (LibvirtException e) { String msg = "SetNetworkACL failed due to " + e.toString(); s_logger.error(msg, e); return new SetNetworkACLAnswer(cmd, false, results); @@ -1694,7 +1676,7 @@ ServerResource { return new SetSourceNatAnswer(cmd, false, "KVM plugin \"vpc_snat\" failed:"+result); } return new SetSourceNatAnswer(cmd, true, "success"); - } catch (Exception e) { + } catch (LibvirtException e) { String msg = "Ip SNAT failure due to " + e.toString(); s_logger.error(msg, e); return new SetSourceNatAnswer(cmd, false, msg); @@ -1739,7 +1721,10 @@ ServerResource { results[i++] = ip.getPublicIp() + " - success"; } - } catch (Exception e) { + } catch (LibvirtException e) { + s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); + results[i++] = IpAssocAnswer.errorResult; + } catch (InternalErrorException e) { s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); results[i++] = IpAssocAnswer.errorResult; } @@ -1819,7 +1804,7 @@ ServerResource { vm = getDomain(conn, cmd.getVmName()); state = vm.getInfo().state; } catch (LibvirtException e) { - + s_logger.trace("Ignoring libvirt error.", e); } } @@ -1938,7 +1923,7 @@ ServerResource { vm = getDomain(conn, cmd.getVmName()); state = vm.getInfo().state; } catch (LibvirtException e) { - + s_logger.trace("Ignoring libvirt error.", e); } } @@ -2380,7 +2365,7 @@ ServerResource { Connect conn = LibvirtConnection.getConnection(); Integer vncPort = getVncPort(conn, cmd.getName()); return new GetVncPortAnswer(cmd, _privateIp, 5900 + vncPort); - } catch (Exception e) { + } catch (LibvirtException e) { return new GetVncPortAnswer(cmd, e.toString()); } } @@ -2501,16 +2486,13 @@ ServerResource { } catch (final LibvirtException e) { s_logger.warn("Can't get vm state " + vmName + e.getMessage() + "retry:" + retry); - } catch (Exception e) { - s_logger.warn("Can't get vm state " + vmName + e.getMessage() - + "retry:" + retry); } finally { try { if (vms != null) { vms.free(); } - } catch (final LibvirtException e) { - + } catch (final LibvirtException l) { + s_logger.trace("Ignoring libvirt error.", l); } } } @@ -2603,9 +2585,6 @@ ServerResource { } catch (LibvirtException e) { s_logger.debug("Can't migrate domain: " + e.getMessage()); result = e.getMessage(); - } catch (Exception e) { - s_logger.debug("Can't migrate domain: " + e.getMessage()); - result = e.getMessage(); } finally { try { if (dm != null) { @@ -2618,7 +2597,7 @@ ServerResource { destDomain.free(); } } catch (final LibvirtException e) { - + s_logger.trace("Ignoring libvirt error.", e); } } @@ -2795,8 +2774,8 @@ ServerResource { Integer vncPort = null; try { vncPort = getVncPort(conn, cmd.getVmName()); - } catch (Exception e) { - + } catch (LibvirtException e) { + s_logger.trace("Ignoring libvirt error.", e); } get_rule_logs_for_vms(); return new RebootAnswer(cmd, null, vncPort); @@ -3122,10 +3101,27 @@ ServerResource { } } + // pass cmdline info to system vms + if (vmSpec.getType() != VirtualMachine.Type.User) { + passCmdLine(vmName, vmSpec.getBootArgs() ); + } + state = State.Running; return new StartAnswer(cmd); - } catch (Exception e) { - s_logger.warn("Exception ", e); + } catch (LibvirtException e) { + s_logger.warn("LibvirtException ", e); + if (conn != null) { + handleVmStartFailure(conn, vmName, vm); + } + return new StartAnswer(cmd, e.getMessage()); + } catch (InternalErrorException e) { + s_logger.warn("InternalErrorException ", e); + if (conn != null) { + handleVmStartFailure(conn, vmName, vm); + } + return new StartAnswer(cmd, e.getMessage()); + } catch (URISyntaxException e) { + s_logger.warn("URISyntaxException ", e); if (conn != null) { handleVmStartFailure(conn, vmName, vm); } @@ -3237,8 +3233,6 @@ ServerResource { iso.defISODisk(_sysvmISOPath); vm.getDevices().addDevice(iso); } - - createPatchVbd(conn, vmName, vm, vmSpec); } } @@ -3252,64 +3246,6 @@ ServerResource { return null; } - private void createPatchVbd(Connect conn, String vmName, LibvirtVMDef vm, - VirtualMachineTO vmSpec) throws LibvirtException, - InternalErrorException { - - List disks = vm.getDevices().getDisks(); - DiskDef rootDisk = disks.get(0); - VolumeTO rootVol = getVolume(vmSpec, Volume.Type.ROOT); - String patchName = vmName + "-patchdisk"; - KVMStoragePool pool = _storagePoolMgr.getStoragePool( - rootVol.getPoolType(), - rootVol.getPoolUuid()); - String patchDiskPath = pool.getLocalPath() + "/" + patchName; - - List phyDisks = pool.listPhysicalDisks(); - boolean foundDisk = false; - - for (KVMPhysicalDisk phyDisk : phyDisks) { - if (phyDisk.getPath().equals(patchDiskPath)) { - foundDisk = true; - break; - } - } - - if (!foundDisk) { - s_logger.debug("generating new patch disk for " + vmName + " since none was found"); - KVMPhysicalDisk disk = pool.createPhysicalDisk(patchName, KVMPhysicalDisk.PhysicalDiskFormat.RAW, - 10L * 1024 * 1024); - } else { - s_logger.debug("found existing patch disk at " + patchDiskPath + " using it for " + vmName); - } - - /* Format/create fs on this disk */ - final Script command = new Script(_createvmPath, _timeout, s_logger); - command.add("-f", patchDiskPath); - String result = command.execute(); - if (result != null) { - s_logger.debug("Failed to create data disk: " + result); - throw new InternalErrorException("Failed to create data disk: " - + result); - } - - /* add patch disk */ - DiskDef patchDisk = new DiskDef(); - - if (pool.getType() == StoragePoolType.CLVM) { - patchDisk.defBlockBasedDisk(patchDiskPath, 1, rootDisk.getBusType()); - } else { - patchDisk.defFileBasedDisk(patchDiskPath, 1, rootDisk.getBusType(), - DiskDef.diskFmtType.RAW); - } - - disks.add(patchDisk); - - String bootArgs = vmSpec.getBootArgs(); - - patchSystemVm(bootArgs, patchDiskPath, vmName); - } - private void createVif(LibvirtVMDef vm, NicTO nic) throws InternalErrorException, LibvirtException { vm.getDevices().addDevice( @@ -3325,14 +3261,10 @@ ServerResource { s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort); } - try { - String result = _virtRouterResource.connect(privateIp, cmdPort); - if (result != null) { - return new CheckSshAnswer(cmd, "Can not ping System vm " - + vmName + "due to:" + result); - } - } catch (Exception e) { - return new CheckSshAnswer(cmd, e); + String result = _virtRouterResource.connect(privateIp, cmdPort); + if (result != null) { + return new CheckSshAnswer(cmd, "Can not ping System vm " + + vmName + "due to:" + result); } if (s_logger.isDebugEnabled()) { @@ -3479,14 +3411,12 @@ ServerResource { + e.getMessage()); } throw e; - } catch (Exception e) { - throw new InternalErrorException(e.toString()); } finally { if (dm != null) { try { dm.free(); } catch (LibvirtException l) { - + s_logger.trace("Ignoring libvirt error.", l); } } } @@ -3704,22 +3634,21 @@ ServerResource { return convertToState(vps); } } catch (final LibvirtException e) { - s_logger.trace(e.getMessage()); - } catch (Exception e) { - s_logger.trace(e.getMessage()); + s_logger.trace("Ignoring libvirt error.", e); } finally { try { if (dm != null) { dm.free(); } - } catch (final LibvirtException e) { - + } catch (final LibvirtException l) { + s_logger.trace("Ignoring libvirt error.", l); } } try { Thread.sleep(1000); } catch (InterruptedException e) { + s_logger.trace("Ignoring InterruptedException.", e); } } return State.Stopped; @@ -3757,7 +3686,7 @@ ServerResource { dm.free(); } } catch (final LibvirtException e) { - + s_logger.trace("Ignoring libvirt error.", e); } } } @@ -3812,7 +3741,7 @@ ServerResource { dm.free(); } } catch (LibvirtException e) { - + s_logger.trace("Ignoring libvirt error.", e); } } } @@ -3832,15 +3761,13 @@ ServerResource { vmStates.put(vmName, state); } catch (final LibvirtException e) { s_logger.warn("Unable to get vms", e); - } catch (Exception e) { - s_logger.warn("Unable to get vms", e); } finally { try { if (dm != null) { dm.free(); } } catch (LibvirtException e) { - + s_logger.trace("Ignoring libvirt error.", e); } } } @@ -3891,7 +3818,7 @@ ServerResource { } } } catch (LibvirtException e) { - + s_logger.trace("Ignoring libvirt error.", e); } if (isSnapshotSupported()) { @@ -3938,7 +3865,7 @@ ServerResource { } catch (LibvirtException e) { s_logger.warn("Failed to create vm", e); msg = e.getMessage(); - } catch (Exception e) { + } catch (InternalErrorException e) { s_logger.warn("Failed to create vm", e); msg = e.getMessage(); } finally { @@ -3947,7 +3874,7 @@ ServerResource { dm.free(); } } catch (LibvirtException e) { - + s_logger.trace("Ignoring libvirt error.", e); } } @@ -3977,15 +3904,13 @@ ServerResource { break; } catch (LibvirtException e) { s_logger.debug("Failed to get vm status:" + e.getMessage()); - } catch (Exception e) { - s_logger.debug("Failed to get vm status:" + e.getMessage()); } finally { try { if (dm != null) { dm.free(); } } catch (LibvirtException l) { - + s_logger.trace("Ignoring libvirt error.", l); } } } @@ -4040,15 +3965,13 @@ ServerResource { } catch (InterruptedException ie) { s_logger.debug("Interrupted sleep"); return ie.getMessage(); - } catch (Exception e) { - s_logger.debug("Failed to stop VM :" + vmName + " :", e); - return e.getMessage(); } finally { try { if (dm != null) { dm.free(); } } catch (LibvirtException e) { + s_logger.trace("Ignoring libvirt error.", e); } } @@ -4094,7 +4017,7 @@ ServerResource { dm.free(); } } catch (LibvirtException l) { - + s_logger.trace("Ignoring libvirt error.", l); } } } @@ -4110,7 +4033,7 @@ ServerResource { } } } catch (LibvirtException e) { - + s_logger.trace("Ignoring libvirt error.", e); } return false; } @@ -4135,8 +4058,7 @@ ServerResource { parser.parseDomainXML(xmlDesc); return parser.getDescription(); } catch (LibvirtException e) { - return null; - } catch (Exception e) { + s_logger.trace("Ignoring libvirt error.", e); return null; } finally { try { @@ -4144,7 +4066,7 @@ ServerResource { dm.free(); } } catch (LibvirtException l) { - + s_logger.trace("Ignoring libvirt error.", l); } } } @@ -4242,16 +4164,13 @@ ServerResource { } catch (LibvirtException e) { s_logger.debug("Failed to get dom xml: " + e.toString()); return new ArrayList(); - } catch (Exception e) { - s_logger.debug("Failed to get dom xml: " + e.toString()); - return new ArrayList(); } finally { try { if (dm != null) { dm.free(); } } catch (LibvirtException e) { - + s_logger.trace("Ignoring libvirt error.", e); } } } @@ -4268,16 +4187,13 @@ ServerResource { } catch (LibvirtException e) { s_logger.debug("Failed to get dom xml: " + e.toString()); return new ArrayList(); - } catch (Exception e) { - s_logger.debug("Failed to get dom xml: " + e.toString()); - return new ArrayList(); } finally { try { if (dm != null) { dm.free(); } } catch (LibvirtException e) { - + s_logger.trace("Ignoring libvirt error.", e); } } } @@ -4625,8 +4541,7 @@ ServerResource { conn = LibvirtConnection.getConnection(); success = default_network_rules_for_systemvm(conn, cmd.getVmName()); } catch (LibvirtException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + s_logger.trace("Ignoring libvirt error.", e); } return new Answer(cmd, success, ""); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java index fc3b5f6da00..c93aeeb2dd6 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java @@ -864,8 +864,8 @@ public class LibvirtVMDef { virtioSerialBuilder.append("\n"); virtioSerialBuilder.append("\n"); - virtioSerialBuilder.append("\n"); - virtioSerialBuilder.append("
\n"); + virtioSerialBuilder.append("\n"); + virtioSerialBuilder.append("
\n"); virtioSerialBuilder.append("\n"); return virtioSerialBuilder.toString(); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtXMLParser.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtXMLParser.java index 3a614037d85..dd0d7724c4a 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtXMLParser.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtXMLParser.java @@ -19,6 +19,7 @@ package com.cloud.hypervisor.kvm.resource; import java.io.IOException; import java.io.StringReader; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; @@ -40,13 +41,14 @@ public class LibvirtXMLParser extends DefaultHandler { protected boolean _initialized = false; public LibvirtXMLParser() { - try { _sp = s_spf.newSAXParser(); _initialized = true; - } catch (Exception ex) { + } catch (ParserConfigurationException e) { + s_logger.trace("Ignoring xml parser error.", e); + } catch (SAXException e) { + s_logger.trace("Ignoring xml parser error.", e); } - } public boolean parseDomainXML(String domXML) { diff --git a/pom.xml b/pom.xml index c10297a3e81..6b0a9ccfeac 100644 --- a/pom.xml +++ b/pom.xml @@ -345,6 +345,7 @@ **/*.patch **/.classpath **/.project + **/.idea/** **/*.iml **/.settings/** .metadata/** @@ -362,6 +363,7 @@ **/*.zip **/target/** **/.vagrant + awsapi/overlays/** build/build.number services/console-proxy/server/js/jquery.js debian/compat @@ -436,7 +438,6 @@ patches/systemvm/debian/config/var/www/html/userdata/.htaccess patches/systemvm/debian/config/var/www/html/latest/.htaccess patches/systemvm/debian/vpn/etc/ipsec.d/l2tp.conf - diff --git a/scripts/vm/hypervisor/kvm/patchviasocket.pl b/scripts/vm/hypervisor/kvm/patchviasocket.pl new file mode 100644 index 00000000000..443d6e4277b --- /dev/null +++ b/scripts/vm/hypervisor/kvm/patchviasocket.pl @@ -0,0 +1,58 @@ +#!/usr/bin/perl -w +# 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. + +############################################################# +# This script connects to the system vm socket and writes the +# authorized_keys and cmdline data to it. The system VM then +# reads it from /dev/vport0p1 in cloud_early_config +############################################################# + +use strict; +use Getopt::Std; +use IO::Socket; +$|=1; + +my $opts = {}; +getopt('pn',$opts); +my $name = $opts->{n}; +my $cmdline = $opts->{p}; +my $sockfile = "/var/lib/libvirt/qemu/$name.agent"; +my $pubkeyfile = "/root/.ssh/id_rsa.pub.cloud"; + +if (! -S $sockfile) { + print "ERROR: $sockfile socket not found\n"; + exit 1; +} + +if (! -f $pubkeyfile) { + print "ERROR: ssh public key not found on host at $pubkeyfile\n"; + exit 1; +} + +open(FILE,$pubkeyfile) or die "ERROR: unable to open $pubkeyfile - $^E"; +my $key = ; +close FILE; + +$cmdline =~ s/%/ /g; +my $msg = "pubkey:" . $key . "\ncmdline:" . $cmdline; + +my $socket = IO::Socket::UNIX->new(Peer=>$sockfile,Type=>SOCK_STREAM) + or die "ERROR: unable to connect to $sockfile - $^E\n"; +print $socket "$msg\r\n"; +close $socket; + diff --git a/scripts/vm/hypervisor/kvm/rundomrpre.sh b/scripts/vm/hypervisor/kvm/rundomrpre.sh deleted file mode 100755 index dc783749815..00000000000 --- a/scripts/vm/hypervisor/kvm/rundomrpre.sh +++ /dev/null @@ -1,147 +0,0 @@ -#!/bin/bash -# 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. - - -# $Id: rundomrpre.sh 10427 2010-07-09 03:30:48Z edison $ $HeadURL: svn://svn.lab.vmops.com/repos/vmdev/java/scripts/vm/hypervisor/kvm/rundomrpre.sh $ - -set -x -pubKey="/root/.ssh/id_rsa.pub.cloud" -mntpath() { - local vmname=$1 - if [ ! -d /mnt/$vmname ] - then - mkdir -p /mnt/$vmname - fi - echo "/mnt/$vmname" -} - -mount_raw_disk() { - local vmname=$1 - local datadisk=$2 - local path=$(mntpath $vmname) - if [ ! -f $datadisk -a ! -b $datadisk ] - then - printf "$datadisk doesn't exist" >&2 - return 2 - fi - - retry=10 - while [ $retry -gt 0 ] - do - if [ -b $datadisk ]; then - mount $datadisk $path &>/dev/null - ret=$? - else - mount $datadisk $path -o loop &>/dev/null - ret=$? - fi - sleep 10 - if [ $ret -gt 0 ] - then - sleep 5 - else - break - fi - retry=$(($retry-1)) - done - return 0 -} - -umount_raw_disk() { - local vmname=$1 - local datadisk=$2 - local path=$(mntpath $vmname) - - retry=10 - sync - while [ $retry -gt 0 ] - do - umount -d $path &>/dev/null - if [ $? -gt 0 ] - then - sleep 5 - else - rm -rf $path - break - fi - retry=$(($retry-1)) - done - return $? -} - -patch_all() { - local vmname=$1 - local cmdline=$2 - local datadisk=$3 - local path=$(mntpath $vmname) - - - if [ -f $pubKey ] - then - cp $pubKey $path/authorized_keys - fi - echo $cmdline > $path/cmdline - sed -i "s/%/\ /g" $path/cmdline - return 0 -} - -lflag= -dflag= - -while getopts 't:v:i:m:e:E:a:A:g:l:n:d:b:B:p:I:N:Mx:X:' OPTION -do - case $OPTION in - l) lflag=1 - vmname="$OPTARG" - ;; - t) tflag=1 - vmtype="$OPTARG" - ;; - d) dflag=1 - rootdisk="$OPTARG" - ;; - p) pflag=1 - cmdline="$OPTARG" - ;; - *) ;; - esac -done - -if [ "$lflag$tflag$dflag" != "111" ] -then - printf "Error: No enough parameter\n" >&2 - exit 1 -fi - -if [ "$vmtype" = "all" ] -then - mount_raw_disk $vmname $rootdisk - if [ $? -gt 0 ] - then - printf "Failed to mount $rootdisk" - exit $? - fi - - patch_all $vmname $cmdline $rootdisk - - umount_raw_disk $vmname $rootdisk - exit $? -fi - - -exit $? diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java index 5342a4f71f9..c1bbb588faf 100755 --- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -39,6 +39,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -100,7 +101,6 @@ import com.cloud.resource.ServerResource; import com.cloud.server.ManagementService; import com.cloud.storage.StorageManager; import com.cloud.storage.StorageService; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.resource.DummySecondaryStorageResource; @@ -172,7 +172,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl @Inject protected ConfigurationDao _configDao = null; @Inject - protected StoragePoolDao _storagePoolDao = null; + protected PrimaryDataStoreDao _storagePoolDao = null; @Inject protected StoragePoolHostDao _storagePoolHostDao = null; @Inject diff --git a/server/src/com/cloud/agent/manager/allocator/impl/RecreateHostAllocator.java b/server/src/com/cloud/agent/manager/allocator/impl/RecreateHostAllocator.java index dc2082f4ba6..3b659c02741 100755 --- a/server/src/com/cloud/agent/manager/allocator/impl/RecreateHostAllocator.java +++ b/server/src/com/cloud/agent/manager/allocator/impl/RecreateHostAllocator.java @@ -27,6 +27,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -49,7 +50,6 @@ import com.cloud.host.dao.HostDao; import com.cloud.org.Grouping; import com.cloud.resource.ResourceManager; import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.Pair; import com.cloud.vm.VirtualMachine; @@ -61,7 +61,7 @@ public class RecreateHostAllocator extends FirstFitRoutingAllocator { private final static Logger s_logger = Logger.getLogger(RecreateHostAllocator.class); @Inject HostPodDao _podDao; - @Inject StoragePoolDao _poolDao; + @Inject PrimaryDataStoreDao _poolDao; @Inject ClusterDao _clusterDao; @Inject VolumeDao _volsDao; @Inject DataCenterDao _dcDao; 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/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 95879ee0238..8e6f8062463 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -45,6 +45,7 @@ import org.apache.cloudstack.api.response.UserResponse; import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.api.response.VolumeResponse; import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.springframework.stereotype.Component; @@ -254,7 +255,7 @@ public class ApiDBUtils { static HostPodDao _podDao; static ServiceOfferingDao _serviceOfferingDao; static SnapshotDao _snapshotDao; - static StoragePoolDao _storagePoolDao; + static PrimaryDataStoreDao _storagePoolDao; static VMTemplateDao _templateDao; static VMTemplateDetailsDao _templateDetailsDao; static VMTemplateHostDao _templateHostDao; @@ -357,7 +358,7 @@ public class ApiDBUtils { @Inject private HostPodDao podDao; @Inject private ServiceOfferingDao serviceOfferingDao; @Inject private SnapshotDao snapshotDao; - @Inject private StoragePoolDao storagePoolDao; + @Inject private PrimaryDataStoreDao storagePoolDao; @Inject private VMTemplateDao templateDao; @Inject private VMTemplateDetailsDao templateDetailsDao; @Inject private VMTemplateHostDao templateHostDao; 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/dao/DomainRouterJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java index cdb859e8eb8..488c4e494e1 100644 --- a/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java @@ -170,6 +170,29 @@ public class DomainRouterJoinDaoImpl extends GenericDaoBase 0) { + TrafficType ty = vr.getTrafficType(); + if (ty != null) { + // legacy code, public/control/guest nic info is kept in + // nics response object + if (ty == TrafficType.Public) { + vrData.setPublicIp(vr.getIpAddress()); + vrData.setPublicMacAddress(vr.getMacAddress()); + vrData.setPublicNetmask(vr.getNetmask()); + vrData.setGateway(vr.getGateway()); + vrData.setPublicNetworkId(vr.getNetworkUuid()); + } else if (ty == TrafficType.Control) { + vrData.setLinkLocalIp(vr.getIpAddress()); + vrData.setLinkLocalMacAddress(vr.getMacAddress()); + vrData.setLinkLocalNetmask(vr.getNetmask()); + vrData.setLinkLocalNetworkId(vr.getNetworkUuid()); + } else if (ty == TrafficType.Guest) { + vrData.setGuestIpAddress(vr.getIpAddress()); + vrData.setGuestMacAddress(vr.getMacAddress()); + vrData.setGuestNetmask(vr.getNetmask()); + vrData.setGuestNetworkId(vr.getNetworkUuid()); + vrData.setNetworkDomain(vr.getNetworkDomain()); + } + } NicResponse nicResponse = new NicResponse(); nicResponse.setId(vr.getNicUuid()); nicResponse.setIpaddress(vr.getIpAddress()); 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/capacity/dao/CapacityDaoImpl.java b/server/src/com/cloud/capacity/dao/CapacityDaoImpl.java index 1c23cb8e5e1..c3d98173a5c 100755 --- a/server/src/com/cloud/capacity/dao/CapacityDaoImpl.java +++ b/server/src/com/cloud/capacity/dao/CapacityDaoImpl.java @@ -27,6 +27,7 @@ import java.util.Map; import javax.ejb.Local; import javax.inject.Inject; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -34,7 +35,6 @@ import org.springframework.stereotype.Component; import com.cloud.capacity.Capacity; import com.cloud.capacity.CapacityVO; import com.cloud.storage.Storage; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.utils.Pair; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; @@ -62,7 +62,7 @@ public class CapacityDaoImpl extends GenericDaoBase implements private final SearchBuilder _hostIdTypeSearch; private final SearchBuilder _hostOrPoolIdSearch; private final SearchBuilder _allFieldsSearch; - @Inject protected StoragePoolDao _storagePoolDao; + @Inject protected PrimaryDataStoreDao _storagePoolDao; private static final String LIST_HOSTS_IN_CLUSTER_WITH_ENOUGH_CAPACITY = " SELECT host_capacity.host_id FROM (`cloud`.`host` JOIN `cloud`.`op_host_capacity` host_capacity ON (host.id = host_capacity.host_id AND host.cluster_id = ?) JOIN `cloud`.`cluster_details` cluster_details ON (host_capacity.cluster_id = cluster_details.cluster_id) AND host.type = ? AND cluster_details.name='cpuOvercommitRatio' AND ((host_capacity.total_capacity *cluster_details.value ) - host_capacity.used_capacity) >= ? and host_capacity.capacity_type = '1' " + 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/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 62f4fd5d8dd..7f449dec60e 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -2330,10 +2330,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati Vlan vlan = createVlanAndPublicIpRange(zoneId, networkId, physicalNetworkId, forVirtualNetwork, podId, startIP, endIP, vlanGateway, vlanNetmask, vlanId, vlanOwner, startIPv6, endIPv6, ip6Gateway, ip6Cidr); + txn.commit(); if (associateIpRangeToAccount) { _networkMgr.associateIpAddressListToAccount(userId, vlanOwner.getId(), zoneId, vlan.getId(), null); } - txn.commit(); // Associate ips to the network if (associateIpRangeToAccount) { diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 69f70e521d8..544a803b13f 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -31,6 +31,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; @@ -115,7 +116,6 @@ import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.dao.DiskOfferingDao; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.template.TemplateManager; @@ -221,7 +221,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy @Inject NetworkOfferingDao _networkOfferingDao; @Inject - StoragePoolDao _storagePoolDao; + PrimaryDataStoreDao _storagePoolDao; @Inject UserVmDetailsDao _vmDetailsDao; @Inject diff --git a/server/src/com/cloud/deploy/FirstFitPlanner.java b/server/src/com/cloud/deploy/FirstFitPlanner.java index 187ceab25dc..c219cfccaf2 100755 --- a/server/src/com/cloud/deploy/FirstFitPlanner.java +++ b/server/src/com/cloud/deploy/FirstFitPlanner.java @@ -29,6 +29,7 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.log4j.Logger; import com.cloud.agent.manager.allocator.HostAllocator; @@ -67,7 +68,6 @@ import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSCategoryDao; import com.cloud.storage.dao.GuestOSDao; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.user.AccountManager; @@ -96,7 +96,7 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner { @Inject protected VolumeDao _volsDao; @Inject protected CapacityManager _capacityMgr; @Inject protected ConfigurationDao _configDao; - @Inject protected StoragePoolDao _storagePoolDao; + @Inject protected PrimaryDataStoreDao _storagePoolDao; @Inject protected CapacityDao _capacityDao; @Inject protected AccountManager _accountMgr; @Inject protected StorageManager _storageMgr; diff --git a/server/src/com/cloud/ha/RecreatableFencer.java b/server/src/com/cloud/ha/RecreatableFencer.java index dd3e71c77b9..50aa1b75762 100644 --- a/server/src/com/cloud/ha/RecreatableFencer.java +++ b/server/src/com/cloud/ha/RecreatableFencer.java @@ -21,12 +21,12 @@ import java.util.List; import javax.ejb.Local; import javax.inject.Inject; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.host.HostVO; import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.component.AdapterBase; import com.cloud.vm.VMInstanceVO; @@ -37,7 +37,7 @@ import com.cloud.vm.VirtualMachine; public class RecreatableFencer extends AdapterBase implements FenceBuilder { private static final Logger s_logger = Logger.getLogger(RecreatableFencer.class); @Inject VolumeDao _volsDao; - @Inject StoragePoolDao _poolDao; + @Inject PrimaryDataStoreDao _poolDao; public RecreatableFencer() { super(); diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java index 88568819922..d7b6d78c9bb 100644 --- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java +++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java @@ -819,7 +819,8 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase } } else { s_logger.debug("Revoking a rule for an inline load balancer that has not been programmed yet."); - return null; + nic.setNic(null); + return nic; } } @@ -877,9 +878,9 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase MappingNic nic = getLoadBalancingIpNic(zone, network, rule.getSourceIpAddressId(), revoked, null); mappingStates.add(nic.getState()); NicVO loadBalancingIpNic = nic.getNic(); - if (loadBalancingIpNic == null) { - continue; - } + if (loadBalancingIpNic == null) { + continue; + } // Change the source IP address for the load balancing rule to be the load balancing IP address srcIp = loadBalancingIpNic.getIp4Address(); diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index de6707e86da..fee4ef310f7 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -1164,7 +1164,6 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager{ if (vpcElements == null) { vpcElements = new ArrayList(); vpcElements.add((VpcProvider)_ntwkModel.getElementImplementingProvider(Provider.VPCVirtualRouter.getName())); - vpcElements.add((VpcProvider)_ntwkModel.getElementImplementingProvider(Provider.VPCNetscaler.getName())); } if (vpcElements == null) { diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java index 72ed940804f..45a9a242147 100755 --- a/server/src/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/com/cloud/projects/ProjectManagerImpl.java @@ -204,7 +204,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); + Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, "", 0); Project project = _projectDao.persist(new ProjectVO(name, displayText, owner.getDomainId(), projectAccount.getId())); diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java index a4a08aa4046..47b1d55ddac 100755 --- a/server/src/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/com/cloud/resource/ResourceManagerImpl.java @@ -45,6 +45,7 @@ import org.apache.cloudstack.api.command.admin.storage.AddS3Cmd; import org.apache.cloudstack.api.command.admin.storage.ListS3sCmd; import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd; import org.apache.cloudstack.api.command.admin.swift.ListSwiftsCmd; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -117,7 +118,6 @@ import com.cloud.storage.Swift; import com.cloud.storage.SwiftVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.GuestOSCategoryDao; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.s3.S3Manager; @@ -193,7 +193,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, @Inject protected GuestOSCategoryDao _guestOSCategoryDao; @Inject - protected StoragePoolDao _storagePoolDao; + protected PrimaryDataStoreDao _storagePoolDao; @Inject protected DataCenterIpAddressDao _privateIPAddressDao; @Inject diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index 7ff06af9409..23c079679b1 100755 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -628,7 +628,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim ResourceType resourceType = null; if (typeId != null) { - for (ResourceType type : resourceTypes) { + for (ResourceType type : Resource.ResourceType.values()) { if (type.getOrdinal() == typeId.intValue()) { resourceType = type; } diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index c5ae1e2a436..8c665ad1eee 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -603,8 +603,16 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio throw new CloudRuntimeException("No home directory was detected for the user '" + username + "'. Please check the profile of this user."); } - File privkeyfile = new File(homeDir + "/.ssh/id_rsa"); - File pubkeyfile = new File(homeDir + "/.ssh/id_rsa.pub"); + // Using non-default file names (id_rsa.cloud and id_rsa.cloud.pub) in developer mode. This is to prevent SSH keys overwritten for user running management server + File privkeyfile = null; + File pubkeyfile = null; + if (devel) { + privkeyfile = new File(homeDir + "/.ssh/id_rsa.cloud"); + pubkeyfile = new File(homeDir + "/.ssh/id_rsa.cloud.pub"); + } else { + privkeyfile = new File(homeDir + "/.ssh/id_rsa"); + pubkeyfile = new File(homeDir + "/.ssh/id_rsa.pub"); + } if (already == null || already.isEmpty()) { if (s_logger.isInfoEnabled()) { @@ -661,13 +669,8 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio } } else { - s_logger.info("Keypairs already in database"); - if (username.equalsIgnoreCase("cloud")) { - s_logger.info("Keypairs already in database, updating local copy"); - updateKeyPairsOnDisk(homeDir); - } else { - s_logger.info("Keypairs already in database, skip updating local copy (not running as cloud user)"); - } + s_logger.info("Keypairs already in database, updating local copy"); + updateKeyPairsOnDisk(homeDir); } s_logger.info("Going to update systemvm iso with generated keypairs if needed"); try { @@ -726,14 +729,22 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio private void updateKeyPairsOnDisk(String homeDir) { File keyDir = new File(homeDir + "/.ssh"); + Boolean devel = Boolean.valueOf(_configDao.getValue("developer")); if (!keyDir.isDirectory()) { s_logger.warn("Failed to create " + homeDir + "/.ssh for storing the SSH keypars"); keyDir.mkdir(); } String pubKey = _configDao.getValue("ssh.publickey"); String prvKey = _configDao.getValue("ssh.privatekey"); - writeKeyToDisk(prvKey, homeDir + "/.ssh/id_rsa"); - writeKeyToDisk(pubKey, homeDir + "/.ssh/id_rsa.pub"); + + // Using non-default file names (id_rsa.cloud and id_rsa.cloud.pub) in developer mode. This is to prevent SSH keys overwritten for user running management server + if( devel ) { + writeKeyToDisk(prvKey, homeDir + "/.ssh/id_rsa.cloud"); + writeKeyToDisk(pubKey, homeDir + "/.ssh/id_rsa.cloud.pub"); + } else { + writeKeyToDisk(prvKey, homeDir + "/.ssh/id_rsa"); + writeKeyToDisk(pubKey, homeDir + "/.ssh/id_rsa.pub"); + } } protected void injectSshKeysIntoSystemVmIsoPatch(String publicKeyPath, String privKeyPath) { diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 3c615e1957c..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; @@ -109,6 +110,7 @@ import org.apache.cloudstack.api.command.user.vpn.*; import org.apache.cloudstack.api.command.user.zone.*; import org.apache.cloudstack.api.response.ExtractResponse; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; @@ -124,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; @@ -187,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; @@ -220,7 +224,6 @@ import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSCategoryDao; import com.cloud.storage.dao.GuestOSDao; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.UploadDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; @@ -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 @@ -355,7 +359,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Inject private GuestOSCategoryDao _guestOSCategoryDao; @Inject - private StoragePoolDao _poolDao; + private PrimaryDataStoreDao _poolDao; @Inject private NetworkDao _networkDao; @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/src/com/cloud/storage/LocalStoragePoolListener.java b/server/src/com/cloud/storage/LocalStoragePoolListener.java index a04c79cf435..244f7fbe271 100755 --- a/server/src/com/cloud/storage/LocalStoragePoolListener.java +++ b/server/src/com/cloud/storage/LocalStoragePoolListener.java @@ -18,6 +18,7 @@ package com.cloud.storage; import javax.inject.Inject; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.log4j.Logger; import com.cloud.agent.Listener; @@ -33,13 +34,12 @@ import com.cloud.dc.dao.DataCenterDao; import com.cloud.exception.ConnectionException; import com.cloud.host.HostVO; import com.cloud.host.Status; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.utils.db.DB; public class LocalStoragePoolListener implements Listener { private final static Logger s_logger = Logger.getLogger(LocalStoragePoolListener.class); - @Inject StoragePoolDao _storagePoolDao; + @Inject PrimaryDataStoreDao _storagePoolDao; @Inject StoragePoolHostDao _storagePoolHostDao; @Inject CapacityDao _capacityDao; @Inject StorageManager _storageMgr; diff --git a/server/src/com/cloud/storage/OCFS2ManagerImpl.java b/server/src/com/cloud/storage/OCFS2ManagerImpl.java index 5c526a69e4f..476bf04cae9 100755 --- a/server/src/com/cloud/storage/OCFS2ManagerImpl.java +++ b/server/src/com/cloud/storage/OCFS2ManagerImpl.java @@ -25,6 +25,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -43,7 +44,6 @@ import com.cloud.resource.ResourceListener; import com.cloud.resource.ResourceManager; import com.cloud.resource.ServerResource; import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.utils.Ternary; import com.cloud.utils.component.ManagerBase; @@ -63,7 +63,7 @@ public class OCFS2ManagerImpl extends ManagerBase implements OCFS2Manager, Resou @Inject ClusterDao _clusterDao; @Inject ResourceManager _resourceMgr; @Inject StoragePoolHostDao _poolHostDao; - @Inject StoragePoolDao _poolDao; + @Inject PrimaryDataStoreDao _poolDao; @Override public boolean configure(String name, Map params) throws ConfigurationException { diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index f51079240c9..b0a1da14eb8 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1395,7 +1395,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C List spes = _storagePoolDao.listBy( primaryStorage.getDataCenterId(), primaryStorage.getPodId(), - primaryStorage.getClusterId()); + primaryStorage.getClusterId(), ScopeType.CLUSTER); for (StoragePoolVO sp : spes) { if (sp.getStatus() == StoragePoolStatus.PrepareForMaintenance) { throw new CloudRuntimeException( diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 336dbcbf336..f0e60283067 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -1444,8 +1444,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { List matchingVMPools = _storagePoolDao .findPoolsByTags(vmRootVolumePool.getDataCenterId(), vmRootVolumePool.getPodId(), - vmRootVolumePool.getClusterId(), volumeTags, - isVolumeOnSharedPool); + vmRootVolumePool.getClusterId(), volumeTags + ); boolean moveVolumeNeeded = true; if (matchingVMPools.size() == 0) { diff --git a/server/src/com/cloud/storage/dao/StoragePoolDao.java b/server/src/com/cloud/storage/dao/StoragePoolDao.java deleted file mode 100644 index 28ead9c2945..00000000000 --- a/server/src/com/cloud/storage/dao/StoragePoolDao.java +++ /dev/null @@ -1,113 +0,0 @@ -// 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 com.cloud.storage.dao; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; -import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; - -import com.cloud.storage.StoragePoolStatus; -import com.cloud.utils.db.GenericDao; -/** - * Data Access Object for storage_pool table - */ -public interface StoragePoolDao extends GenericDao { - - /** - * @param datacenterId -- the id of the datacenter (availability zone) - */ - List listByDataCenterId(long datacenterId); - - /** - * @param datacenterId -- the id of the datacenter (availability zone) - */ - List listBy(long datacenterId, long podId, Long clusterId, ScopeType scope); - - /** - * Set capacity of storage pool in bytes - * @param id pool id. - * @param capacity capacity in bytes - */ - void updateCapacity(long id, long capacity); - - /** - * Set available bytes of storage pool in bytes - * @param id pool id. - * @param available available capacity in bytes - */ - void updateAvailable(long id, long available); - - - StoragePoolVO persist(StoragePoolVO pool, Map details); - - /** - * Find pool by name. - * - * @param name name of pool. - * @return the single StoragePoolVO - */ - List findPoolByName(String name); - - /** - * Find pools by the pod that matches the details. - * - * @param podId pod id to find the pools in. - * @param details details to match. All must match for the pool to be returned. - * @return List of StoragePoolVO - */ - List findPoolsByDetails(long dcId, long podId, Long clusterId, Map details, ScopeType scope); - - List findPoolsByTags(long dcId, long podId, Long clusterId, String[] tags); - - /** - * Find pool by UUID. - * - * @param uuid uuid of pool. - * @return the single StoragePoolVO - */ - StoragePoolVO findPoolByUUID(String uuid); - - List listByStorageHost(String hostFqdnOrIp); - - StoragePoolVO findPoolByHostPath(long dcId, Long podId, String host, String path, String uuid); - - List listPoolByHostPath(String host, String path); - - void updateDetails(long poolId, Map details); - - Map getDetails(long poolId); - - List searchForStoragePoolDetails(long poolId, String value); - - List findIfDuplicatePoolsExistByUUID(String uuid); - - List listByStatus(StoragePoolStatus status); - - long countPoolsByStatus(StoragePoolStatus... statuses); - - List listByStatusInZone(long dcId, StoragePoolStatus status); - - List listPoolsByCluster(long clusterId); - - List findLocalStoragePoolsByTags(long dcId, long podId, - Long clusterId, String[] tags); - - List findZoneWideStoragePoolsByTags(long dcId, String[] tags); -} diff --git a/server/src/com/cloud/storage/dao/StoragePoolDaoImpl.java b/server/src/com/cloud/storage/dao/StoragePoolDaoImpl.java deleted file mode 100644 index 28b4dbc5c18..00000000000 --- a/server/src/com/cloud/storage/dao/StoragePoolDaoImpl.java +++ /dev/null @@ -1,432 +0,0 @@ -// 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 com.cloud.storage.dao; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.ejb.Local; -import javax.inject.Inject; -import javax.naming.ConfigurationException; - -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; -import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import org.springframework.stereotype.Component; - -import com.cloud.host.Status; -import com.cloud.storage.StoragePoolDetailVO; -import com.cloud.storage.StoragePoolStatus; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.GenericSearchBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.SearchCriteria.Func; -import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.SearchCriteria2; -import com.cloud.utils.db.SearchCriteriaService; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.exception.CloudRuntimeException; - -@Component -@Local(value={StoragePoolDao.class}) @DB(txn=false) -public class StoragePoolDaoImpl extends GenericDaoBase implements StoragePoolDao { - protected final SearchBuilder AllFieldSearch; - protected final SearchBuilder DcPodSearch; - protected final SearchBuilder DcPodAnyClusterSearch; - protected final SearchBuilder DeleteLvmSearch; - protected final GenericSearchBuilder StatusCountSearch; - - - - @Inject protected StoragePoolDetailsDao _detailsDao; - - private final String DetailsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_details ON storage_pool.id = storage_pool_details.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and (storage_pool.pod_id = ? or storage_pool.pod_id is null) and storage_pool.scope = ? and ("; - private final String DetailsSqlSuffix = ") GROUP BY storage_pool_details.pool_id HAVING COUNT(storage_pool_details.name) >= ?"; - private final String ZoneWideDetailsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_details ON storage_pool.id = storage_pool_details.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and storage_pool.scope = ? and ("; - private final String ZoneWideDetailsSqlSuffix = ") GROUP BY storage_pool_details.pool_id HAVING COUNT(storage_pool_details.name) >= ?"; - - private final String FindPoolTagDetails = "SELECT storage_pool_details.name FROM storage_pool_details WHERE pool_id = ? and value = ?"; - - protected StoragePoolDaoImpl() { - AllFieldSearch = createSearchBuilder(); - AllFieldSearch.and("name", AllFieldSearch.entity().getName(), SearchCriteria.Op.EQ); - AllFieldSearch.and("uuid", AllFieldSearch.entity().getUuid(), SearchCriteria.Op.EQ); - AllFieldSearch.and("datacenterId", AllFieldSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); - AllFieldSearch.and("hostAddress", AllFieldSearch.entity().getHostAddress(), SearchCriteria.Op.EQ); - AllFieldSearch.and("status",AllFieldSearch.entity().getStatus(),SearchCriteria.Op.EQ); - AllFieldSearch.and("path", AllFieldSearch.entity().getPath(), SearchCriteria.Op.EQ); - AllFieldSearch.and("podId", AllFieldSearch.entity().getPodId(), Op.EQ); - AllFieldSearch.and("clusterId", AllFieldSearch.entity().getClusterId(), Op.EQ); - AllFieldSearch.done(); - - DcPodSearch = createSearchBuilder(); - DcPodSearch.and("datacenterId", DcPodSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); - DcPodSearch.and("status", DcPodSearch.entity().getStatus(), SearchCriteria.Op.EQ); - DcPodSearch.and("scope", DcPodSearch.entity().getScope(), SearchCriteria.Op.EQ); - DcPodSearch.and().op("nullpod", DcPodSearch.entity().getPodId(), SearchCriteria.Op.NULL); - DcPodSearch.or("podId", DcPodSearch.entity().getPodId(), SearchCriteria.Op.EQ); - DcPodSearch.cp(); - DcPodSearch.and().op("nullcluster", DcPodSearch.entity().getClusterId(), SearchCriteria.Op.NULL); - DcPodSearch.or("cluster", DcPodSearch.entity().getClusterId(), SearchCriteria.Op.EQ); - DcPodSearch.cp(); - DcPodSearch.done(); - - DcPodAnyClusterSearch = createSearchBuilder(); - DcPodAnyClusterSearch.and("datacenterId", DcPodAnyClusterSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); - DcPodAnyClusterSearch.and("status", DcPodAnyClusterSearch.entity().getStatus(), SearchCriteria.Op.EQ); - DcPodAnyClusterSearch.and("scope", DcPodAnyClusterSearch.entity().getScope(), SearchCriteria.Op.EQ); - DcPodAnyClusterSearch.and().op("nullpod", DcPodAnyClusterSearch.entity().getPodId(), SearchCriteria.Op.NULL); - DcPodAnyClusterSearch.or("podId", DcPodAnyClusterSearch.entity().getPodId(), SearchCriteria.Op.EQ); - DcPodAnyClusterSearch.cp(); - DcPodAnyClusterSearch.done(); - - DeleteLvmSearch = createSearchBuilder(); - DeleteLvmSearch.and("ids", DeleteLvmSearch.entity().getId(), SearchCriteria.Op.IN); - DeleteLvmSearch.and().op("LVM", DeleteLvmSearch.entity().getPoolType(), SearchCriteria.Op.EQ); - DeleteLvmSearch.or("Filesystem", DeleteLvmSearch.entity().getPoolType(), SearchCriteria.Op.EQ); - DeleteLvmSearch.cp(); - DeleteLvmSearch.done(); - - - - StatusCountSearch = createSearchBuilder(Long.class); - StatusCountSearch.and("status", StatusCountSearch.entity().getStatus(), SearchCriteria.Op.IN); - StatusCountSearch.select(null, Func.COUNT, null); - StatusCountSearch.done(); - - } - - @Override - public List findPoolByName(String name) { - SearchCriteria sc = AllFieldSearch.create(); - sc.setParameters("name", name); - return listIncludingRemovedBy(sc); - } - - - @Override - public StoragePoolVO findPoolByUUID(String uuid) { - SearchCriteria sc = AllFieldSearch.create(); - sc.setParameters("uuid", uuid); - return findOneIncludingRemovedBy(sc); - } - - - - @Override - public List findIfDuplicatePoolsExistByUUID(String uuid) { - SearchCriteria sc = AllFieldSearch.create(); - sc.setParameters("uuid", uuid); - return listBy(sc); - } - - - @Override - public List listByDataCenterId(long datacenterId) { - SearchCriteria sc = AllFieldSearch.create(); - sc.setParameters("datacenterId", datacenterId); - return listBy(sc); - } - - - @Override - public void updateAvailable(long id, long available) { - StoragePoolVO pool = createForUpdate(id); - pool.setAvailableBytes(available); - update(id, pool); - } - - - @Override - public void updateCapacity(long id, long capacity) { - StoragePoolVO pool = createForUpdate(id); - pool.setCapacityBytes(capacity); - update(id, pool); - - } - - @Override - public List listByStorageHost(String hostFqdnOrIp) { - SearchCriteria sc = AllFieldSearch.create(); - sc.setParameters("hostAddress", hostFqdnOrIp); - return listIncludingRemovedBy(sc); - } - - @Override - public List listByStatus(StoragePoolStatus status){ - SearchCriteria sc = AllFieldSearch.create(); - sc.setParameters("status", status); - return listBy(sc); - } - - @Override - public List listByStatusInZone(long dcId, StoragePoolStatus status){ - SearchCriteria sc = AllFieldSearch.create(); - sc.setParameters("status", status); - sc.setParameters("datacenterId", dcId); - return listBy(sc); - } - - @Override - public StoragePoolVO findPoolByHostPath(long datacenterId, Long podId, String host, String path, String uuid) { - SearchCriteria sc = AllFieldSearch.create(); - sc.setParameters("hostAddress", host); - sc.setParameters("path", path); - sc.setParameters("datacenterId", datacenterId); - sc.setParameters("podId", podId); - sc.setParameters("uuid", uuid); - - return findOneBy(sc); - } - - @Override - public List listBy(long datacenterId, long podId, Long clusterId, ScopeType scope) { - if (clusterId != null) { - SearchCriteria sc = DcPodSearch.create(); - sc.setParameters("datacenterId", datacenterId); - sc.setParameters("podId", podId); - sc.setParameters("status", Status.Up); - sc.setParameters("scope", scope); - - sc.setParameters("cluster", clusterId); - return listBy(sc); - } else { - SearchCriteria sc = DcPodAnyClusterSearch.create(); - sc.setParameters("datacenterId", datacenterId); - sc.setParameters("podId", podId); - sc.setParameters("status", Status.Up); - sc.setParameters("scope", scope); - return listBy(sc); - } - } - - @Override - public List listPoolByHostPath(String host, String path) { - SearchCriteria sc = AllFieldSearch.create(); - sc.setParameters("hostAddress", host); - sc.setParameters("path", path); - - return listBy(sc); - } - - public StoragePoolVO listById(Integer id) - { - SearchCriteria sc = AllFieldSearch.create(); - sc.setParameters("id", id); - - return findOneIncludingRemovedBy(sc); - } - - @Override @DB - public StoragePoolVO persist(StoragePoolVO pool, Map details) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - pool = super.persist(pool); - if (details != null) { - for (Map.Entry detail : details.entrySet()) { - StoragePoolDetailVO vo = new StoragePoolDetailVO(pool.getId(), detail.getKey(), detail.getValue()); - _detailsDao.persist(vo); - } - } - txn.commit(); - return pool; - } - - @DB - @Override - public List findPoolsByDetails(long dcId, long podId, Long clusterId, Map details, ScopeType scope) { - StringBuilder sql = new StringBuilder(DetailsSqlPrefix); - if (clusterId != null) { - sql.append("storage_pool.cluster_id = ? OR storage_pool.cluster_id IS NULL) AND ("); - } - - for (Map.Entry detail : details.entrySet()) { - sql.append("((storage_pool_details.name='").append(detail.getKey()).append("') AND (storage_pool_details.value='").append(detail.getValue()).append("')) OR "); - } - sql.delete(sql.length() - 4, sql.length()); - sql.append(DetailsSqlSuffix); - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql.toString()); - int i = 1; - pstmt.setLong(i++, dcId); - pstmt.setLong(i++, podId); - pstmt.setString(i++, scope.toString()); - if (clusterId != null) { - pstmt.setLong(i++, clusterId); - } - pstmt.setInt(i++, details.size()); - ResultSet rs = pstmt.executeQuery(); - List pools = new ArrayList(); - while (rs.next()) { - pools.add(toEntityBean(rs, false)); - } - return pools; - } catch (SQLException e) { - throw new CloudRuntimeException("Unable to execute " + pstmt, e); - } - } - - protected Map tagsToDetails(String[] tags) { - Map details = new HashMap(tags.length); - for (String tag: tags) { - details.put(tag, "true"); - } - return details; - } - - @Override - public List findPoolsByTags(long dcId, long podId, Long clusterId, String[] tags) { - List storagePools = null; - if (tags == null || tags.length == 0) { - storagePools = listBy(dcId, podId, clusterId, ScopeType.CLUSTER); - } else { - Map details = tagsToDetails(tags); - storagePools = findPoolsByDetails(dcId, podId, clusterId, details, ScopeType.CLUSTER); - } - - return storagePools; - } - - @Override - public List findLocalStoragePoolsByTags(long dcId, long podId, Long clusterId, String[] tags) { - List storagePools = null; - if (tags == null || tags.length == 0) { - storagePools = listBy(dcId, podId, clusterId, ScopeType.HOST); - } else { - Map details = tagsToDetails(tags); - storagePools = findPoolsByDetails(dcId, podId, clusterId, details, ScopeType.HOST); - } - - return storagePools; - } - - @Override - public List findZoneWideStoragePoolsByTags(long dcId, String[] tags) { - List storagePools = null; - if (tags == null || tags.length == 0) { - SearchCriteriaService sc = SearchCriteria2.create(StoragePoolVO.class); - sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dcId); - sc.addAnd(sc.getEntity().getStatus(), Op.EQ, Status.Up); - sc.addAnd(sc.getEntity().getScope(), Op.EQ, ScopeType.ZONE); - return sc.list(); - } else { - Map details = tagsToDetails(tags); - - StringBuilder sql = new StringBuilder(ZoneWideDetailsSqlPrefix); - - for (Map.Entry detail : details.entrySet()) { - sql.append("((storage_pool_details.name='").append(detail.getKey()).append("') AND (storage_pool_details.value='").append(detail.getValue()).append("')) OR "); - } - sql.delete(sql.length() - 4, sql.length()); - sql.append(ZoneWideDetailsSqlSuffix); - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql.toString()); - int i = 1; - pstmt.setLong(i++, dcId); - pstmt.setString(i++, ScopeType.ZONE.toString()); - pstmt.setInt(i++, details.size()); - ResultSet rs = pstmt.executeQuery(); - List pools = new ArrayList(); - while (rs.next()) { - pools.add(toEntityBean(rs, false)); - } - return pools; - } catch (SQLException e) { - throw new CloudRuntimeException("Unable to execute " + pstmt, e); - } - } - } - - @Override - @DB - public List searchForStoragePoolDetails(long poolId, String value){ - - StringBuilder sql = new StringBuilder(FindPoolTagDetails); - - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql.toString()); - pstmt.setLong(1, poolId); - pstmt.setString(2, value); - - ResultSet rs = pstmt.executeQuery(); - List tags = new ArrayList(); - - while (rs.next()) { - tags.add(rs.getString("name")); - } - return tags; - } catch (SQLException e) { - throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e); - } - - } - - @Override - public void updateDetails(long poolId, Map details) { - if (details != null) { - _detailsDao.update(poolId, details); - } - } - - @Override - public Map getDetails(long poolId) { - return _detailsDao.getDetails(poolId); - } - - @Override - public boolean configure(String name, Map params) throws ConfigurationException { - super.configure(name, params); - _detailsDao.configure("DetailsDao", params); - return true; - } - - - - @Override - public long countPoolsByStatus( StoragePoolStatus... statuses) { - SearchCriteria sc = StatusCountSearch.create(); - - sc.setParameters("status", (Object[])statuses); - - List rs = customSearchIncludingRemoved(sc, null); - if (rs.size() == 0) { - return 0; - } - - return rs.get(0); - } - - @Override - public List listPoolsByCluster(long clusterId) { - SearchCriteria sc = AllFieldSearch.create(); - sc.setParameters("clusterId", clusterId); - - return listBy(sc); - } -} diff --git a/server/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java b/server/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java index 8cc5d7be9d4..0d797ed3545 100644 --- a/server/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java +++ b/server/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java @@ -22,9 +22,10 @@ import java.util.Map; import javax.ejb.Local; +import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO; +import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; import org.springframework.stereotype.Component; -import com.cloud.storage.StoragePoolDetailVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; diff --git a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java index df2df7b5267..f957ca31ada 100755 --- a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java +++ b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java @@ -20,6 +20,7 @@ import java.util.List; import javax.inject.Inject; +import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; @@ -75,7 +76,8 @@ public class StoragePoolMonitor implements Listener { StartupRoutingCommand scCmd = (StartupRoutingCommand)cmd; if (scCmd.getHypervisorType() == HypervisorType.XenServer || scCmd.getHypervisorType() == HypervisorType.KVM || scCmd.getHypervisorType() == HypervisorType.VMware || scCmd.getHypervisorType() == HypervisorType.Simulator || scCmd.getHypervisorType() == HypervisorType.Ovm) { - List pools = _poolDao.listBy(host.getDataCenterId(), host.getPodId(), host.getClusterId()); + List pools = _poolDao.listBy(host.getDataCenterId(), host.getPodId(), host.getClusterId(), ScopeType.CLUSTER); + pools.addAll(_poolDao.findZoneWideStoragePoolsByTags(host.getDataCenterId(), null)); for (StoragePoolVO pool : pools) { if (pool.getStatus() != StoragePoolStatus.Up) { continue; diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index ed48bd1b45b..bacca019294 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -37,6 +37,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -92,7 +93,6 @@ import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.SnapshotPolicyDao; import com.cloud.storage.dao.SnapshotScheduleDao; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.s3.S3Manager; @@ -158,7 +158,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, @Inject protected SnapshotDao _snapshotDao; @Inject - protected StoragePoolDao _storagePoolDao; + protected PrimaryDataStoreDao _storagePoolDao; @Inject protected EventDao _eventDao; @Inject diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 29659d3deee..d843dbc9b8d 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -66,6 +66,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -143,7 +144,6 @@ import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.LaunchPermissionDao; import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.UploadDao; import com.cloud.storage.dao.VMTemplateDao; @@ -197,7 +197,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Inject protected VMTemplateDetailsDao _templateDetailsDao; @Inject VMInstanceDao _vmInstanceDao; - @Inject StoragePoolDao _poolDao; + @Inject PrimaryDataStoreDao _poolDao; @Inject StoragePoolHostDao _poolHostDao; @Inject EventDao _eventDao; @Inject DownloadMonitor _downloadMonitor; diff --git a/server/src/com/cloud/user/AccountManager.java b/server/src/com/cloud/user/AccountManager.java index ff9f1682799..4b3a601b802 100755 --- a/server/src/com/cloud/user/AccountManager.java +++ b/server/src/com/cloud/user/AccountManager.java @@ -47,14 +47,14 @@ public interface AccountManager extends AccountService { boolean deleteAccount(AccountVO account, long callerUserId, Account caller); - boolean cleanupAccount(AccountVO account, long callerUserId, Account caller); - - Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId); - - Account createAccount(String accountName, short accountType, Long domainId, String networkDomain, Map details); - - UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone); + boolean cleanupAccount(AccountVO account, long callerUserId, Account caller); + Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId); + + Account createAccount(String accountName, short accountType, Long domainId, String networkDomain, Map details, String uuid, int regionId); + + UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone); + /** * Logs out a user * @param userId diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index b1f81466250..9b916024cbb 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -763,8 +763,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Override @DB @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account") - public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long domainId, String networkDomain, - Map details) { + public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, + Long domainId, String networkDomain, Map details) { if (accountName == null) { accountName = userName; @@ -806,27 +806,26 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } } + Transaction txn = Transaction.currentTxn(); + txn.start(); - Transaction txn = Transaction.currentTxn(); - txn.start(); + // create account + AccountVO account = createAccount(accountName, accountType, domainId, networkDomain, details, UUID.randomUUID().toString(), _regionMgr.getId()); + long accountId = account.getId(); - // create account - AccountVO account = createAccount(accountName, accountType, domainId, networkDomain, details); - long accountId = account.getId(); + // create the first user for the account + UserVO user = createUser(accountId, userName, password, firstName, lastName, email, timezone); - // create the first user for the account - UserVO user = createUser(accountId, userName, password, firstName, lastName, email, timezone); - - if (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { - // set registration token - byte[] bytes = (domainId + accountName + userName + System.currentTimeMillis()).getBytes(); - String registrationToken = UUID.nameUUIDFromBytes(bytes).toString(); - user.setRegistrationToken(registrationToken); - } - txn.commit(); - //check success - return _userAccountDao.findById(user.getId()); + if (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { + // set registration token + byte[] bytes = (domainId + accountName + userName + System.currentTimeMillis()).getBytes(); + String registrationToken = UUID.nameUUIDFromBytes(bytes).toString(); + user.setRegistrationToken(registrationToken); + } + txn.commit(); + //check success + return _userAccountDao.findById(user.getId()); } @Override @@ -858,8 +857,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M if (!_userAccountDao.validateUsernameInDomain(userName, domainId)) { throw new CloudRuntimeException("The user " + userName + " already exists in domain " + domainId); } - - return createUser(account.getId(), userName, password, firstName, lastName, email, timeZone); + UserVO user = null; + user = createUser(account.getId(), userName, password, firstName, lastName, email, timeZone); + return user; } @Override @@ -1646,7 +1646,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Override @DB - public AccountVO createAccount(String accountName, short accountType, Long domainId, String networkDomain, Map details) { + public AccountVO createAccount(String accountName, short accountType, Long domainId, String networkDomain, Map details, String uuid, int regionId) { // Validate domain Domain domain = _domainMgr.getDomain(domainId); if (domain == null) { @@ -1690,7 +1690,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M Transaction txn = Transaction.currentTxn(); txn.start(); - AccountVO account = _accountDao.persist(new AccountVO(accountName, domainId, networkDomain, accountType, _accountDao.getRegionId())); + AccountVO account = _accountDao.persist(new AccountVO(accountName, domainId, networkDomain, accountType, uuid, regionId)); if (account == null) { throw new CloudRuntimeException("Failed to create account name " + accountName + " in domain id=" + domainId); @@ -1730,7 +1730,30 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M throw new CloudRuntimeException("Failed to encode password"); } - UserVO user = _userDao.persist(new UserVO(accountId, userName, encodedPassword, firstName, lastName, email, timezone, _userDao.getRegionId())); + UserVO user = _userDao.persist(new UserVO(accountId, userName, encodedPassword, firstName, lastName, email, timezone, UUID.randomUUID().toString(), _regionMgr.getId())); + + return user; + } + + //ToDo Add events?? + public UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone, String uuid, int regionId) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating user: " + userName + ", accountId: " + accountId + " timezone:" + timezone); + } + + String encodedPassword = null; + for (Iterator en = _userAuthenticators.iterator(); en.hasNext();) { + UserAuthenticator authenticator = en.next(); + encodedPassword = authenticator.encode(password); + if (encodedPassword != null) { + break; + } + } + if (encodedPassword == null) { + throw new CloudRuntimeException("Failed to encode password"); + } + + UserVO user = _userDao.persist(new UserVO(accountId, userName, encodedPassword, firstName, lastName, email, timezone, uuid, regionId)); return user; } diff --git a/server/src/com/cloud/user/DomainManagerImpl.java b/server/src/com/cloud/user/DomainManagerImpl.java index d7967d5e54c..9f0ad53c94b 100644 --- a/server/src/com/cloud/user/DomainManagerImpl.java +++ b/server/src/com/cloud/user/DomainManagerImpl.java @@ -161,7 +161,6 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom throw new InvalidParameterValueException("Domain with name " + name + " already exists for the parent id=" + parentId); } - Transaction txn = Transaction.currentTxn(); txn.start(); @@ -471,8 +470,8 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom // check if domain exists in the system DomainVO domain = _domainDao.findById(domainId); if (domain == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find domain with specified domain id"); - ex.addProxyObject(domain, domainId, "domainId"); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find domain with specified domain id"); + ex.addProxyObject(domain, domainId, "domainId"); throw ex; } else if (domain.getParent() == null && domainName != null) { // check if domain is ROOT domain - and deny to edit it with the new name @@ -494,7 +493,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"); - throw ex; + throw ex; } } @@ -552,5 +551,5 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom _domainDao.update(dom.getId(), dom); } } - + } diff --git a/server/src/com/cloud/user/dao/AccountDaoImpl.java b/server/src/com/cloud/user/dao/AccountDaoImpl.java index 3ffc1db0497..892fdcd548d 100755 --- a/server/src/com/cloud/user/dao/AccountDaoImpl.java +++ b/server/src/com/cloud/user/dao/AccountDaoImpl.java @@ -44,17 +44,17 @@ import com.cloud.utils.db.Transaction; public class AccountDaoImpl extends GenericDaoBase implements AccountDao { private static final Logger s_logger = Logger.getLogger(AccountDaoImpl.class); private final String FIND_USER_ACCOUNT_BY_API_KEY = "SELECT u.id, u.username, u.account_id, u.secret_key, u.state, " + - "a.id, a.account_name, a.type, a.domain_id, a.state " + - "FROM `cloud`.`user` u, `cloud`.`account` a " + - "WHERE u.account_id = a.id AND u.api_key = ? and u.removed IS NULL"; - + "a.id, a.account_name, a.type, a.domain_id, a.state " + + "FROM `cloud`.`user` u, `cloud`.`account` a " + + "WHERE u.account_id = a.id AND u.api_key = ? and u.removed IS NULL"; + protected final SearchBuilder AllFieldsSearch; protected final SearchBuilder AccountTypeSearch; protected final SearchBuilder DomainAccountsSearch; protected final SearchBuilder CleanupForRemovedAccountsSearch; protected final SearchBuilder CleanupForDisabledAccountsSearch; protected final SearchBuilder NonProjectAccountSearch; - + public AccountDaoImpl() { AllFieldsSearch = createSearchBuilder(); AllFieldsSearch.and("accountName", AllFieldsSearch.entity().getAccountName(), SearchCriteria.Op.EQ); @@ -62,7 +62,7 @@ public class AccountDaoImpl extends GenericDaoBase implements A AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), SearchCriteria.Op.EQ); AllFieldsSearch.and("type", AllFieldsSearch.entity().getType(), SearchCriteria.Op.EQ); AllFieldsSearch.done(); - + AccountTypeSearch = createSearchBuilder(); AccountTypeSearch.and("domainId", AccountTypeSearch.entity().getDomainId(), SearchCriteria.Op.EQ); AccountTypeSearch.and("type", AccountTypeSearch.entity().getType(), SearchCriteria.Op.EQ); @@ -72,19 +72,19 @@ public class AccountDaoImpl extends GenericDaoBase implements A DomainAccountsSearch.and("domainId", DomainAccountsSearch.entity().getDomainId(), SearchCriteria.Op.EQ); DomainAccountsSearch.and("removed", DomainAccountsSearch.entity().getRemoved(), SearchCriteria.Op.NULL); DomainAccountsSearch.done(); - + CleanupForRemovedAccountsSearch = createSearchBuilder(); CleanupForRemovedAccountsSearch.and("cleanup", CleanupForRemovedAccountsSearch.entity().getNeedsCleanup(), SearchCriteria.Op.EQ); CleanupForRemovedAccountsSearch.and("removed", CleanupForRemovedAccountsSearch.entity().getRemoved(), SearchCriteria.Op.NNULL); CleanupForRemovedAccountsSearch.and("domainid", CleanupForRemovedAccountsSearch.entity().getDomainId(), SearchCriteria.Op.EQ); CleanupForRemovedAccountsSearch.done(); - + CleanupForDisabledAccountsSearch = createSearchBuilder(); CleanupForDisabledAccountsSearch.and("cleanup", CleanupForDisabledAccountsSearch.entity().getNeedsCleanup(), SearchCriteria.Op.EQ); CleanupForDisabledAccountsSearch.and("removed", CleanupForDisabledAccountsSearch.entity().getRemoved(), SearchCriteria.Op.NULL); CleanupForDisabledAccountsSearch.and("state", CleanupForDisabledAccountsSearch.entity().getState(), SearchCriteria.Op.EQ); CleanupForDisabledAccountsSearch.done(); - + NonProjectAccountSearch = createSearchBuilder(); NonProjectAccountSearch.and("accountName", NonProjectAccountSearch.entity().getAccountName(), SearchCriteria.Op.EQ); NonProjectAccountSearch.and("domainId", NonProjectAccountSearch.entity().getDomainId(), SearchCriteria.Op.EQ); @@ -92,28 +92,28 @@ public class AccountDaoImpl extends GenericDaoBase implements A NonProjectAccountSearch.and("type", NonProjectAccountSearch.entity().getType(), SearchCriteria.Op.NEQ); NonProjectAccountSearch.done(); } - + @Override public List findCleanupsForRemovedAccounts(Long domainId) { - SearchCriteria sc = CleanupForRemovedAccountsSearch.create(); - sc.setParameters("cleanup", true); - - if (domainId != null) { - sc.setParameters("domainid", domainId); - } - - return searchIncludingRemoved(sc, null, null, false); + SearchCriteria sc = CleanupForRemovedAccountsSearch.create(); + sc.setParameters("cleanup", true); + + if (domainId != null) { + sc.setParameters("domainid", domainId); + } + + return searchIncludingRemoved(sc, null, null, false); } - + @Override public List findCleanupsForDisabledAccounts() { SearchCriteria sc = CleanupForDisabledAccountsSearch.create(); sc.setParameters("cleanup", true); sc.setParameters("state", State.disabled); - + return listBy(sc); } - + @Override public Pair findUserAccountByApiKey(String apiKey) { Transaction txn = Transaction.currentTxn(); @@ -160,7 +160,7 @@ public class AccountDaoImpl extends GenericDaoBase implements A sc.setParameters("state", State.enabled); return findOneBy(sc); } - + @Override public Account findEnabledNonProjectAccount(String accountName, Long domainId) { SearchCriteria sc = NonProjectAccountSearch.create("accountName", accountName); @@ -170,15 +170,15 @@ public class AccountDaoImpl extends GenericDaoBase implements A return findOneBy(sc); } - @Override - public Account findActiveAccount(String accountName, Long domainId) { + @Override + public Account findActiveAccount(String accountName, Long domainId) { SearchCriteria sc = AllFieldsSearch.create("accountName", accountName); sc.setParameters("domainId", domainId); return findOneBy(sc); } - - @Override - public Account findActiveNonProjectAccount(String accountName, Long domainId) { + + @Override + public Account findActiveNonProjectAccount(String accountName, Long domainId) { SearchCriteria sc = NonProjectAccountSearch.create("accountName", accountName); sc.setParameters("domainId", domainId); sc.setParameters("type", Account.ACCOUNT_TYPE_PROJECT); @@ -191,7 +191,7 @@ public class AccountDaoImpl extends GenericDaoBase implements A sc.setParameters("domainId", domainId); return findOneIncludingRemovedBy(sc); } - + @Override public Account findNonProjectAccountIncludingRemoved(String accountName, Long domainId) { SearchCriteria sc = NonProjectAccountSearch.create("accountName", accountName); @@ -199,7 +199,7 @@ public class AccountDaoImpl extends GenericDaoBase implements A sc.setParameters("type", Account.ACCOUNT_TYPE_PROJECT); return findOneIncludingRemovedBy(sc); } - + @Override public List listAccounts(String accountName, Long domainId, Filter filter) { SearchCriteria sc = AllFieldsSearch.create("accountName", accountName); @@ -246,22 +246,22 @@ public class AccountDaoImpl extends GenericDaoBase implements A return listIncludingRemovedBy(sc, filter); } - @Override - public List findActiveAccountsForDomain(Long domain) { + @Override + public List findActiveAccountsForDomain(Long domain) { SearchCriteria sc = DomainAccountsSearch.create(); sc.setParameters("domainId", domain); - return listBy(sc); - } - - @Override - public void markForCleanup(long accountId) { - AccountVO account = findByIdIncludingRemoved(accountId); - if (!account.getNeedsCleanup()) { - account.setNeedsCleanup(true); - if (!update(accountId, account)) { - s_logger.warn("Failed to mark account id=" + accountId + " for cleanup"); - } - } - } - + return listBy(sc); + } + + @Override + public void markForCleanup(long accountId) { + AccountVO account = findByIdIncludingRemoved(accountId); + if (!account.getNeedsCleanup()) { + account.setNeedsCleanup(true); + if (!update(accountId, account)) { + s_logger.warn("Failed to mark account id=" + accountId + " for cleanup"); + } + } + } + } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index ca9c13fd1c4..6b2f762a74d 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -52,6 +52,7 @@ import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd; import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd; import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity; import org.apache.cloudstack.engine.service.api.OrchestrationService; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; @@ -180,7 +181,6 @@ import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSCategoryDao; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateDetailsDao; import com.cloud.storage.dao.VMTemplateHostDao; @@ -317,7 +317,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use @Inject protected ClusterDao _clusterDao; @Inject - protected StoragePoolDao _storagePoolDao; + protected PrimaryDataStoreDao _storagePoolDao; @Inject protected SecurityGroupManager _securityGroupMgr; @Inject diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index f8448c0ac8f..0aeef0e58e1 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -37,6 +37,8 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; + import com.cloud.dc.*; import org.apache.log4j.Logger; @@ -128,7 +130,6 @@ import com.cloud.storage.VolumeManager; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.GuestOSCategoryDao; import com.cloud.storage.dao.GuestOSDao; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.user.Account; @@ -216,7 +217,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Inject protected DataCenterDao _dcDao; @Inject - protected StoragePoolDao _storagePoolDao; + protected PrimaryDataStoreDao _storagePoolDao; @Inject protected HypervisorGuruManager _hvGuruMgr; @Inject diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java index 01f3dd3afe2..12a059727be 100644 --- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java +++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java @@ -29,6 +29,7 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -67,7 +68,6 @@ import com.cloud.storage.StoragePool; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; @@ -114,7 +114,7 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana @Inject HypervisorGuruManager _hvGuruMgr; @Inject AccountManager _accountMgr; @Inject GuestOSDao _guestOSDao; - @Inject StoragePoolDao _storagePoolDao; + @Inject PrimaryDataStoreDao _storagePoolDao; @Inject SnapshotDao _snapshotDao; @Inject VirtualMachineManager _itMgr; @Inject DataStoreManager dataStoreMgr; diff --git a/server/src/org/apache/cloudstack/region/RegionManager.java b/server/src/org/apache/cloudstack/region/RegionManager.java index 40fda7076d7..4cbd664ce5a 100644 --- a/server/src/org/apache/cloudstack/region/RegionManager.java +++ b/server/src/org/apache/cloudstack/region/RegionManager.java @@ -73,4 +73,98 @@ public interface RegionManager { * @return List of Regions */ List listRegions(Integer id, String name); + + /** + * Deletes a user by userId and propagates the change to peer Regions + * + * @param accountId + * - id of the account do delete + * + * @return true if delete was successful, false otherwise + */ + boolean deleteUserAccount(long accountId); + + /** + * Updates an account + * isPopagate falg is set to true if sent from peer Region + * + * @param cmd + * - the parameter containing accountId or account nameand domainId + * @return updated account object + */ + Account updateAccount(UpdateAccountCmd cmd); + + /** + * Disables an account by accountName and domainId or accountId + * @param accountName + * @param domainId + * @param id + * @param lockRequested + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + Account disableAccount(String accountName, Long domainId, Long id, Boolean lockRequested) throws ConcurrentOperationException, ResourceUnavailableException; + + /** + * Enables an account by accountId + * + * @param accountName + * - the enableAccount command defining the accountId to be deleted. + * @param domainId + * TODO + * @param accountId + * @return account object + */ + Account enableAccount(String accountName, Long domainId, Long accountId); + + /** + * Deletes user by Id + * @param deleteUserCmd + * @return + */ + boolean deleteUser(DeleteUserCmd deleteUserCmd); + + /** + * update an existing domain + * + * @param cmd + * - the command containing domainId and new domainName + * @return Domain object if the command succeeded + */ + Domain updateDomain(UpdateDomainCmd updateDomainCmd); + + /** + * Deletes domain by Id + * @param id + * @param cleanup + * @return true if delete was successful, false otherwise + */ + boolean deleteDomain(Long id, Boolean cleanup); + + /** + * Update a user by userId + * + * @param userId + * @return UserAccount object + */ + UserAccount updateUser(UpdateUserCmd updateUserCmd); + + /** + * Disables a user by userId + * + * @param userId + * - the userId + * @return UserAccount object + */ + UserAccount disableUser(Long id); + + /** + * Enables a user + * + * @param userId + * - the userId + * @return UserAccount object + */ + UserAccount enableUser(long userId); } diff --git a/server/src/org/apache/cloudstack/region/RegionManagerImpl.java b/server/src/org/apache/cloudstack/region/RegionManagerImpl.java index c1a0cc577bf..b4b55fd5a90 100755 --- a/server/src/org/apache/cloudstack/region/RegionManagerImpl.java +++ b/server/src/org/apache/cloudstack/region/RegionManagerImpl.java @@ -16,25 +16,6 @@ // under the License. package org.apache.cloudstack.region; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import javax.ejb.Local; -import javax.inject.Inject; -import javax.naming.ConfigurationException; - -import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd; -import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd; -import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd; -import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd; -import org.apache.cloudstack.region.dao.RegionDao; -import org.apache.cloudstack.region.dao.RegionSyncDao; -import org.apache.commons.httpclient.NameValuePair; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; @@ -48,12 +29,27 @@ 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; +import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd; +import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd; +import org.apache.cloudstack.region.dao.RegionDao; +import org.apache.commons.httpclient.NameValuePair; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; @Component @Local(value = { RegionManager.class }) @@ -73,11 +69,7 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man @Inject private DomainManager _domainMgr; @Inject - private UserAccountDao _userAccountDao; - @Inject private IdentityDao _identityDao; - @Inject - private RegionSyncDao _regionSyncDao; private String _name; private int _id; @@ -198,4 +190,396 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man } return _regionDao.listAll(); } + + /** + * {@inheritDoc} + */ + @Override + public boolean deleteUserAccount(long accountId) { + AccountVO account = _accountDao.findById(accountId); + if(account == null){ + throw new InvalidParameterValueException("The specified account does not exist in the system"); + } + String accountUUID = account.getUuid(); + int regionId = account.getRegionId(); + + String command = "deleteAccount"; + List params = new ArrayList(); + params.add(new NameValuePair(ApiConstants.ID, accountUUID)); + + if(getId() == regionId){ + return _accountMgr.deleteUserAccount(accountId); + } else { + //First delete in the Region where account is created + Region region = _regionDao.findById(regionId); + if (RegionsApiUtil.makeAPICall(region, command, params)) { + s_logger.debug("Successfully deleted account :"+accountUUID+" in Region: "+region.getId()); + return true; + } else { + s_logger.error("Error while deleting account :"+accountUUID+" in Region: "+region.getId()); + return false; + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public Account updateAccount(UpdateAccountCmd cmd) { + Long accountId = cmd.getId(); + Long domainId = cmd.getDomainId(); + DomainVO domain = _domainDao.findById(domainId); + String accountName = cmd.getAccountName(); + String newAccountName = cmd.getNewName(); + String networkDomain = cmd.getNetworkDomain(); + //ToDo send details + Map details = cmd.getDetails(); + + Account account = null; + if (accountId != null) { + account = _accountDao.findById(accountId); + } else { + account = _accountDao.findEnabledAccount(accountName, domainId); + } + + // Check if account exists + if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) { + s_logger.error("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId); + throw new InvalidParameterValueException("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId); + } + + 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())); + params.add(new NameValuePair(ApiConstants.NETWORK_DOMAIN, networkDomain)); + params.add(new NameValuePair(ApiConstants.NEW_NAME, newAccountName)); + if(details != null){ + params.add(new NameValuePair(ApiConstants.ACCOUNT_DETAILS, details.toString())); + } + int regionId = account.getRegionId(); + if(getId() == regionId){ + return _accountMgr.updateAccount(cmd); + } 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); + s_logger.debug("Successfully updated account :"+account.getUuid()+" in source Region: "+region.getId()); + return updatedAccount; + } else { + throw new CloudRuntimeException("Error while updating account :"+account.getUuid()+" in source Region: "+region.getId()); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public Account disableAccount(String accountName, Long domainId, Long accountId, Boolean lockRequested) throws ConcurrentOperationException, ResourceUnavailableException { + Account account = null; + if (accountId != null) { + account = _accountDao.findById(accountId); + } else { + account = _accountDao.findActiveAccount(accountName, domainId); + } + + if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) { + throw new InvalidParameterValueException("Unable to find active account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId); + } + + String accountUUID = account.getUuid(); + + String command = "disableAccount"; + List params = new ArrayList(); + params.add(new NameValuePair(ApiConstants.LOCK, lockRequested.toString())); + params.add(new NameValuePair(ApiConstants.ID, accountUUID)); + DomainVO domain = _domainDao.findById(domainId); + if(domain != null){ + params.add(new NameValuePair(ApiConstants.DOMAIN_ID, domain.getUuid())); + } + + int regionId = account.getRegionId(); + if(getId() == regionId){ + Account retAccount = null; + if(lockRequested){ + retAccount = _accountMgr.lockAccount(accountName, domainId, accountId); + } else { + retAccount = _accountMgr.disableAccount(accountName, domainId, accountId); + } + return retAccount; + } 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) { + s_logger.debug("Successfully disabled account :"+accountUUID+" in source Region: "+region.getId()); + return retAccount; + } else { + throw new CloudRuntimeException("Error while disabling account :"+accountUUID+" in source Region: "+region.getId()); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public Account enableAccount(String accountName, Long domainId, Long accountId) { + // Check if account exists + Account account = null; + if (accountId != null) { + account = _accountDao.findById(accountId); + } else { + account = _accountDao.findActiveAccount(accountName, domainId); + } + + if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) { + throw new InvalidParameterValueException("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId); + } + + String accountUUID = account.getUuid(); + + String command = "enableAccount"; + List params = new ArrayList(); + params.add(new NameValuePair(ApiConstants.ID, accountUUID)); + params.add(new NameValuePair(ApiConstants.ACCOUNT, accountName)); + DomainVO domain = _domainDao.findById(domainId); + if(domain != null){ + params.add(new NameValuePair(ApiConstants.DOMAIN_ID, domain.getUuid())); + } + + int regionId = account.getRegionId(); + if(getId() == regionId){ + return _accountMgr.enableAccount(accountName, domainId, accountId); + } 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) { + s_logger.debug("Successfully enabled account :"+accountUUID+" in source Region: "+region.getId()); + return retAccount; + } else { + throw new CloudRuntimeException("Error while enabling account :"+accountUUID+" in source Region: "+region.getId()); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean deleteUser(DeleteUserCmd cmd) { + long id = cmd.getId(); + + UserVO user = _userDao.findById(id); + + if (user == null) { + throw new InvalidParameterValueException("The specified user doesn't exist in the system"); + } + + String userUUID = user.getUuid(); + int regionId = user.getRegionId(); + + String command = "deleteUser"; + List params = new ArrayList(); + params.add(new NameValuePair(ApiConstants.ID, userUUID)); + + if(getId() == regionId){ + return _accountMgr.deleteUser(cmd); + } else { + //First delete in the Region where user is created + Region region = _regionDao.findById(regionId); + if (RegionsApiUtil.makeAPICall(region, command, params)) { + s_logger.debug("Successfully deleted user :"+userUUID+" in source Region: "+region.getId()); + return true; + } else { + s_logger.error("Error while deleting user :"+userUUID+" in source Region: "+region.getId()); + return false; + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public Domain updateDomain(UpdateDomainCmd cmd) { + long id = cmd.getId(); + DomainVO domain = _domainDao.findById(id); + if(domain == null){ + throw new InvalidParameterValueException("The specified domain doesn't exist in the system"); + } + + String domainUUID = domain.getUuid(); + + String command = "updateDomain"; + List params = new ArrayList(); + params.add(new NameValuePair(ApiConstants.ID, domainUUID)); + params.add(new NameValuePair(ApiConstants.NAME, cmd.getDomainName())); + params.add(new NameValuePair(ApiConstants.NETWORK_DOMAIN, cmd.getNetworkDomain())); + + int regionId = domain.getRegionId(); + if(getId() == regionId){ + return _domainMgr.updateDomain(cmd); + } 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); + s_logger.debug("Successfully updated user :"+domainUUID+" in source Region: "+region.getId()); + return (DomainVO)updatedDomain; + } else { + throw new CloudRuntimeException("Error while updating user :"+domainUUID+" in source Region: "+region.getId()); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean deleteDomain(Long id, Boolean cleanup) { + DomainVO domain = _domainDao.findById(id); + if(domain == null){ + throw new InvalidParameterValueException("The specified domain doesn't exist in the system"); + } + + String domainUUID = domain.getUuid(); + + String command = "deleteDomain"; + List params = new ArrayList(); + params.add(new NameValuePair(ApiConstants.ID, domainUUID)); + params.add(new NameValuePair(ApiConstants.CLEANUP, cleanup.toString())); + + int regionId = domain.getRegionId(); + if(getId() == regionId){ + return _domainMgr.deleteDomain(id, cleanup); + } else { + //First delete in the Region where domain is created + Region region = _regionDao.findById(regionId); + if (RegionsApiUtil.makeAPICall(region, command, params)) { + s_logger.debug("Successfully deleted domain :"+domainUUID+" in Region: "+region.getId()); + return true; + } else { + s_logger.error("Error while deleting domain :"+domainUUID+" in Region: "+region.getId()); + return false; + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public UserAccount updateUser(UpdateUserCmd cmd) { + long id = cmd.getId(); + + UserVO user = _userDao.findById(id); + if (user == null) { + throw new InvalidParameterValueException("The specified user doesn't exist in the system"); + } + + String userUUID = user.getUuid(); + + String command = "updateUser"; + List params = new ArrayList(); + params.add(new NameValuePair(ApiConstants.ID, userUUID)); + params.add(new NameValuePair(ApiConstants.API_KEY, cmd.getApiKey())); + params.add(new NameValuePair(ApiConstants.EMAIL, cmd.getEmail())); + params.add(new NameValuePair(ApiConstants.FIRSTNAME, cmd.getFirstname())); + params.add(new NameValuePair(ApiConstants.LASTNAME, cmd.getLastname())); + params.add(new NameValuePair(ApiConstants.PASSWORD, cmd.getPassword())); + params.add(new NameValuePair(ApiConstants.SECRET_KEY, cmd.getSecretKey())); + params.add(new NameValuePair(ApiConstants.TIMEZONE, cmd.getTimezone())); + params.add(new NameValuePair(ApiConstants.USERNAME, cmd.getUsername())); + + int regionId = user.getRegionId(); + if(getId() == regionId){ + return _accountMgr.updateUser(cmd); + } 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) { + s_logger.debug("Successfully updated user :"+userUUID+" in source Region: "+region.getId()); + return updateUser; + } else { + throw new CloudRuntimeException("Error while updating user :"+userUUID+" in source Region: "+region.getId()); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public UserAccount disableUser(Long userId) { + UserVO user = _userDao.findById(userId); + if (user == null || user.getRemoved() != null) { + throw new InvalidParameterValueException("Unable to find active user by id " + userId); + } + + int regionId = user.getRegionId(); + + String command = "disableUser"; + List params = new ArrayList(); + params.add(new NameValuePair(ApiConstants.ID, user.getUuid())); + + if(getId() == regionId){ + return _accountMgr.disableUser(userId); + } 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) { + s_logger.debug("Successfully disabled user :"+user.getUuid()+" in source Region: "+region.getId()); + return disabledUser; + } else { + throw new CloudRuntimeException("Error while disabling user :"+user.getUuid()+" in source Region: "+region.getId()); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public UserAccount enableUser(long userId) { + UserVO user = _userDao.findById(userId); + if (user == null || user.getRemoved() != null) { + throw new InvalidParameterValueException("Unable to find active user by id " + userId); + } + + int regionId = user.getRegionId(); + + String command = "enableUser"; + List params = new ArrayList(); + params.add(new NameValuePair(ApiConstants.ID, user.getUuid())); + + if(getId() == regionId){ + return _accountMgr.enableUser(userId); + } 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) { + s_logger.debug("Successfully enabled user :"+user.getUuid()+" in source Region: "+region.getId()); + return enabledUser; + } else { + throw new CloudRuntimeException("Error while enabling user :"+user.getUuid()+" in source Region: "+region.getId()); + } + } + } + } diff --git a/server/src/org/apache/cloudstack/region/RegionServiceImpl.java b/server/src/org/apache/cloudstack/region/RegionServiceImpl.java index 62bf4232200..0662c320145 100755 --- a/server/src/org/apache/cloudstack/region/RegionServiceImpl.java +++ b/server/src/org/apache/cloudstack/region/RegionServiceImpl.java @@ -16,13 +16,13 @@ // under the License. package org.apache.cloudstack.region; -import java.util.List; -import java.util.Map; - -import javax.ejb.Local; -import javax.inject.Inject; -import javax.naming.ConfigurationException; - +import com.cloud.domain.Domain; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.user.Account; +import com.cloud.user.UserAccount; +import com.cloud.utils.component.Manager; +import com.cloud.utils.component.ManagerBase; import org.apache.cloudstack.api.command.admin.account.DeleteAccountCmd; import org.apache.cloudstack.api.command.admin.account.DisableAccountCmd; import org.apache.cloudstack.api.command.admin.account.EnableAccountCmd; @@ -34,44 +34,22 @@ import org.apache.cloudstack.api.command.admin.user.DisableUserCmd; import org.apache.cloudstack.api.command.admin.user.EnableUserCmd; import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd; import org.apache.cloudstack.api.command.user.region.ListRegionsCmd; -import org.apache.cloudstack.region.dao.RegionDao; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.domain.Domain; -import com.cloud.domain.dao.DomainDao; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.PermissionDeniedException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.DomainManager; -import com.cloud.user.UserAccount; -import com.cloud.user.UserContext; -import com.cloud.user.dao.AccountDao; -import com.cloud.user.dao.UserDao; -import com.cloud.utils.component.Manager; -import com.cloud.utils.component.ManagerBase; +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; +import java.util.List; +import java.util.Map; @Component @Local(value = { RegionService.class }) public class RegionServiceImpl extends ManagerBase implements RegionService, Manager { public static final Logger s_logger = Logger.getLogger(RegionServiceImpl.class); - @Inject - private RegionDao _regionDao; - @Inject - private AccountDao _accountDao; - @Inject - private UserDao _userDao; - @Inject - private DomainDao _domainDao; @Inject private RegionManager _regionMgr; - @Inject - private AccountManager _accountMgr; - @Inject - private DomainManager _domainMgr; private String _name; @@ -137,7 +115,7 @@ public class RegionServiceImpl extends ManagerBase implements RegionService, Man */ @Override public boolean deleteUserAccount(DeleteAccountCmd cmd) { - return _accountMgr.deleteUserAccount(cmd.getId()); + return _regionMgr.deleteUserAccount(cmd.getId()); } /** @@ -145,7 +123,7 @@ public class RegionServiceImpl extends ManagerBase implements RegionService, Man */ @Override public Account updateAccount(UpdateAccountCmd cmd) { - return _accountMgr.updateAccount(cmd); + return _regionMgr.updateAccount(cmd); } /** @@ -153,12 +131,7 @@ public class RegionServiceImpl extends ManagerBase implements RegionService, Man */ @Override public Account disableAccount(DisableAccountCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException { - Account result = null; - if(cmd.getLockRequested()) - result = _accountMgr.lockAccount(cmd.getAccountName(), cmd.getDomainId(), cmd.getId()); - else - result = _accountMgr.disableAccount(cmd.getAccountName(), cmd.getDomainId(), cmd.getId()); - return result; + return _regionMgr.disableAccount(cmd.getAccountName(), cmd.getDomainId(), cmd.getId(), cmd.getLockRequested()); } /** @@ -166,7 +139,7 @@ public class RegionServiceImpl extends ManagerBase implements RegionService, Man */ @Override public Account enableAccount(EnableAccountCmd cmd) { - return _accountMgr.enableAccount(cmd.getAccountName(), cmd.getDomainId(), cmd.getId()); + return _regionMgr.enableAccount(cmd.getAccountName(), cmd.getDomainId(), cmd.getId()); } /** @@ -174,7 +147,7 @@ public class RegionServiceImpl extends ManagerBase implements RegionService, Man */ @Override public boolean deleteUser(DeleteUserCmd cmd) { - return _accountMgr.deleteUser(cmd); + return _regionMgr.deleteUser(cmd); } /** @@ -182,7 +155,7 @@ public class RegionServiceImpl extends ManagerBase implements RegionService, Man */ @Override public Domain updateDomain(UpdateDomainCmd cmd) { - return _domainMgr.updateDomain(cmd); + return _regionMgr.updateDomain(cmd); } /** @@ -190,7 +163,7 @@ public class RegionServiceImpl extends ManagerBase implements RegionService, Man */ @Override public boolean deleteDomain(DeleteDomainCmd cmd) { - return _domainMgr.deleteDomain(cmd.getId(), cmd.getCleanup()); + return _regionMgr.deleteDomain(cmd.getId(), cmd.getCleanup()); } /** @@ -198,7 +171,7 @@ public class RegionServiceImpl extends ManagerBase implements RegionService, Man */ @Override public UserAccount updateUser(UpdateUserCmd cmd){ - return _accountMgr.updateUser(cmd); + return _regionMgr.updateUser(cmd); } /** @@ -206,7 +179,7 @@ public class RegionServiceImpl extends ManagerBase implements RegionService, Man */ @Override public UserAccount disableUser(DisableUserCmd cmd) { - return _accountMgr.disableUser(cmd.getId()); + return _regionMgr.disableUser(cmd.getId()); } /** @@ -214,6 +187,7 @@ public class RegionServiceImpl extends ManagerBase implements RegionService, Man */ @Override public UserAccount enableUser(EnableUserCmd cmd) { - return _accountMgr.enableUser(cmd.getId()); + return _regionMgr.enableUser(cmd.getId()); } + } diff --git a/server/src/org/apache/cloudstack/region/RegionsApiUtil.java b/server/src/org/apache/cloudstack/region/RegionsApiUtil.java new file mode 100644 index 00000000000..2ace4f9295c --- /dev/null +++ b/server/src/org/apache/cloudstack/region/RegionsApiUtil.java @@ -0,0 +1,306 @@ +// 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.region; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpMethod; +import org.apache.commons.httpclient.NameValuePair; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.log4j.Logger; + +import com.cloud.domain.DomainVO; +import com.cloud.user.UserAccount; +import com.cloud.user.UserAccountVO; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.DomDriver; + +/** + * Utility class for making API calls between peer Regions + * + */ +public class RegionsApiUtil { + public static final Logger s_logger = Logger.getLogger(RegionsApiUtil.class); + + /** + * Makes an api call using region service end_point, api command and params + * @param region + * @param command + * @param params + * @return True, if api is successful + */ + protected static boolean makeAPICall(Region region, String command, List params){ + try { + String apiParams = buildParams(command, params); + String url = buildUrl(apiParams, region); + HttpClient client = new HttpClient(); + HttpMethod method = new GetMethod(url); + if( client.executeMethod(method) == 200){ + return true; + } else { + return false; + } + } catch (HttpException e) { + s_logger.error(e.getMessage()); + return false; + } catch (IOException e) { + s_logger.error(e.getMessage()); + return false; + } + } + + /** + * Makes an api call using region service end_point, api command and params + * Returns Account object on success + * @param region + * @param command + * @param params + * @return + */ + protected static RegionAccount makeAccountAPICall(Region region, String command, List params){ + try { + String url = buildUrl(buildParams(command, params), region); + HttpClient client = new HttpClient(); + HttpMethod method = new GetMethod(url); + if( client.executeMethod(method) == 200){ + InputStream is = method.getResponseBodyAsStream(); + //Translate response to Account object + XStream xstream = new XStream(new DomDriver()); + xstream.alias("account", RegionAccount.class); + xstream.alias("user", RegionUser.class); + xstream.aliasField("id", RegionAccount.class, "uuid"); + xstream.aliasField("name", RegionAccount.class, "accountName"); + xstream.aliasField("accounttype", RegionAccount.class, "type"); + xstream.aliasField("domainid", RegionAccount.class, "domainUuid"); + xstream.aliasField("networkdomain", RegionAccount.class, "networkDomain"); + xstream.aliasField("id", RegionUser.class, "uuid"); + xstream.aliasField("accountId", RegionUser.class, "accountUuid"); + ObjectInputStream in = xstream.createObjectInputStream(is); + return (RegionAccount)in.readObject(); + } else { + return null; + } + } catch (HttpException e) { + s_logger.error(e.getMessage()); + return null; + } catch (IOException e) { + s_logger.error(e.getMessage()); + return null; + } catch (ClassNotFoundException e) { + s_logger.error(e.getMessage()); + return null; + } + } + + /** + * Makes an api call using region service end_point, api command and params + * Returns Domain object on success + * @param region + * @param command + * @param params + * @return + */ + protected static RegionDomain makeDomainAPICall(Region region, String command, List params){ + try { + String url = buildUrl(buildParams(command, params), region); + HttpClient client = new HttpClient(); + HttpMethod method = new GetMethod(url); + if( client.executeMethod(method) == 200){ + InputStream is = method.getResponseBodyAsStream(); + XStream xstream = new XStream(new DomDriver()); + //Translate response to Domain object + xstream.alias("domain", RegionDomain.class); + xstream.aliasField("id", RegionDomain.class, "uuid"); + xstream.aliasField("parentdomainid", RegionDomain.class, "parentUuid"); + xstream.aliasField("networkdomain", DomainVO.class, "networkDomain"); + ObjectInputStream in = xstream.createObjectInputStream(is); + return (RegionDomain)in.readObject(); + } else { + return null; + } + } catch (HttpException e) { + s_logger.error(e.getMessage()); + return null; + } catch (IOException e) { + s_logger.error(e.getMessage()); + return null; + } catch (ClassNotFoundException e) { + s_logger.error(e.getMessage()); + return null; + } + } + + /** + * Makes an api call using region service end_point, api command and params + * Returns UserAccount object on success + * @param region + * @param command + * @param params + * @return + */ + protected static UserAccount makeUserAccountAPICall(Region region, String command, List params){ + try { + String url = buildUrl(buildParams(command, params), region); + HttpClient client = new HttpClient(); + HttpMethod method = new GetMethod(url); + if( client.executeMethod(method) == 200){ + InputStream is = method.getResponseBodyAsStream(); + XStream xstream = new XStream(new DomDriver()); + xstream.alias("useraccount", UserAccountVO.class); + xstream.aliasField("id", UserAccountVO.class, "uuid"); + ObjectInputStream in = xstream.createObjectInputStream(is); + return (UserAccountVO)in.readObject(); + } else { + return null; + } + } catch (HttpException e) { + s_logger.error(e.getMessage()); + return null; + } catch (IOException e) { + s_logger.error(e.getMessage()); + return null; + } catch (ClassNotFoundException e) { + s_logger.error(e.getMessage()); + return null; + } + } + + /** + * Builds parameters string with command and encoded param values + * @param command + * @param params + * @return + */ + protected static String buildParams(String command, List params) { + StringBuffer paramString = new StringBuffer("command="+command); + Iterator iter = params.iterator(); + try { + while(iter.hasNext()){ + NameValuePair param = iter.next(); + if(param.getValue() != null && !(param.getValue().isEmpty())){ + paramString.append("&"+param.getName()+"="+URLEncoder.encode(param.getValue(), "UTF-8")); + } + } + } + catch (UnsupportedEncodingException e) { + s_logger.error(e.getMessage()); + return null; + } + return paramString.toString(); + } + + /** + * Build URL for api call using region end_point + * Parameters are sorted and signed using secret_key + * @param apiParams + * @param region + * @return + */ + private static String buildUrl(String apiParams, Region region) { + + String apiKey = region.getApiKey(); + String secretKey = region.getSecretKey(); + + + if (apiKey == null || secretKey == null) { + return region.getEndPoint() +"?"+ apiParams; + } + + String encodedApiKey; + try { + encodedApiKey = URLEncoder.encode(apiKey, "UTF-8"); + + List sortedParams = new ArrayList(); + sortedParams.add("apikey=" + encodedApiKey.toLowerCase()); + StringTokenizer st = new StringTokenizer(apiParams, "&"); + String url = null; + boolean first = true; + while (st.hasMoreTokens()) { + String paramValue = st.nextToken(); + String param = paramValue.substring(0, paramValue.indexOf("=")); + String value = paramValue.substring(paramValue.indexOf("=") + 1, paramValue.length()); + if (first) { + url = param + "=" + value; + first = false; + } else { + url = url + "&" + param + "=" + value; + } + sortedParams.add(param.toLowerCase() + "=" + value.toLowerCase()); + } + Collections.sort(sortedParams); + + + //Construct the sorted URL and sign and URL encode the sorted URL with your secret key + String sortedUrl = null; + first = true; + for (String param : sortedParams) { + if (first) { + sortedUrl = param; + first = false; + } else { + sortedUrl = sortedUrl + "&" + param; + } + } + String encodedSignature = signRequest(sortedUrl, secretKey); + + String finalUrl = region.getEndPoint() +"?"+apiParams+ "&apiKey=" + apiKey + "&signature=" + encodedSignature; + + return finalUrl; + + } catch (UnsupportedEncodingException e) { + s_logger.error(e.getMessage()); + return null; + } + } + + /** + * 1. Signs a string with a secret key using SHA-1 2. Base64 encode the result 3. URL encode the final result + * + * @param request + * @param key + * @return + */ + private static String signRequest(String request, String key) { + try { + Mac mac = Mac.getInstance("HmacSHA1"); + SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacSHA1"); + mac.init(keySpec); + mac.update(request.getBytes()); + byte[] encryptedBytes = mac.doFinal(); + return URLEncoder.encode(Base64.encodeBase64String(encryptedBytes), "UTF-8"); + } catch (Exception ex) { + s_logger.error(ex.getMessage()); + return null; + } + } + +} \ No newline at end of file diff --git a/server/src/org/apache/cloudstack/region/dao/RegionSyncDao.java b/server/src/org/apache/cloudstack/region/dao/RegionSyncDao.java deleted file mode 100644 index df287e51e32..00000000000 --- a/server/src/org/apache/cloudstack/region/dao/RegionSyncDao.java +++ /dev/null @@ -1,24 +0,0 @@ -// 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.region.dao; - -import org.apache.cloudstack.region.RegionSyncVO; - -import com.cloud.utils.db.GenericDao; - -public interface RegionSyncDao extends GenericDao { -} diff --git a/server/src/org/apache/cloudstack/region/dao/RegionSyncDaoImpl.java b/server/src/org/apache/cloudstack/region/dao/RegionSyncDaoImpl.java deleted file mode 100644 index 9cd9b0dd71b..00000000000 --- a/server/src/org/apache/cloudstack/region/dao/RegionSyncDaoImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -// 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.region.dao; - -import javax.ejb.Local; - -import org.apache.cloudstack.region.RegionSyncVO; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import com.cloud.utils.db.GenericDaoBase; - -@Component -@Local(value={RegionSyncDao.class}) -public class RegionSyncDaoImpl extends GenericDaoBase implements RegionSyncDao { - private static final Logger s_logger = Logger.getLogger(RegionSyncDaoImpl.class); - - public RegionSyncDaoImpl(){ - - } -} diff --git a/server/test/com/cloud/storage/dao/StoragePoolDaoTest.java b/server/test/com/cloud/storage/dao/StoragePoolDaoTest.java index e79f582e7ec..eea61a1a129 100644 --- a/server/test/com/cloud/storage/dao/StoragePoolDaoTest.java +++ b/server/test/com/cloud/storage/dao/StoragePoolDaoTest.java @@ -18,6 +18,7 @@ package com.cloud.storage.dao; import javax.inject.Inject; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; @@ -30,7 +31,7 @@ import com.cloud.storage.StoragePoolStatus; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:/StoragePoolDaoTestContext.xml") public class StoragePoolDaoTest extends TestCase { - @Inject StoragePoolDaoImpl dao; + @Inject PrimaryDataStoreDaoImpl dao; @Test public void testCountByStatus() { diff --git a/server/test/com/cloud/storage/dao/StoragePoolDaoTestConfiguration.java b/server/test/com/cloud/storage/dao/StoragePoolDaoTestConfiguration.java index 60161dc31bf..de0a4edb655 100644 --- a/server/test/com/cloud/storage/dao/StoragePoolDaoTestConfiguration.java +++ b/server/test/com/cloud/storage/dao/StoragePoolDaoTestConfiguration.java @@ -19,6 +19,7 @@ package com.cloud.storage.dao; import java.io.IOException; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration; @@ -31,7 +32,7 @@ import com.cloud.utils.component.SpringComponentScanUtils; @Configuration @ComponentScan(basePackageClasses={ - StoragePoolDaoImpl.class, + PrimaryDataStoreDaoImpl.class, StoragePoolDetailsDaoImpl.class}, includeFilters={@Filter(value=StoragePoolDaoTestConfiguration.Library.class, type=FilterType.CUSTOM)}, useDefaultFilters=false diff --git a/server/test/com/cloud/user/MockAccountManagerImpl.java b/server/test/com/cloud/user/MockAccountManagerImpl.java index 8e0bb646b96..b637c2aaf4e 100644 --- a/server/test/com/cloud/user/MockAccountManagerImpl.java +++ b/server/test/com/cloud/user/MockAccountManagerImpl.java @@ -343,7 +343,8 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco @Override public Account createAccount(String accountName, short accountType, - Long domainId, String networkDomain, Map details) { + Long domainId, String networkDomain, Map details, String uuid, + int regionId) { // TODO Auto-generated method stub return null; } diff --git a/server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java b/server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java index 6fc6404e15f..a238e52c5d5 100644 --- a/server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java +++ b/server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java @@ -29,6 +29,7 @@ import java.util.List; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; @@ -53,7 +54,6 @@ import com.cloud.storage.SnapshotVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; @@ -84,7 +84,7 @@ public class VMSnapshotManagerTest { @Mock HypervisorGuruManager _hvGuruMgr; @Mock AccountManager _accountMgr; @Mock GuestOSDao _guestOSDao; - @Mock StoragePoolDao _storagePoolDao; + @Mock PrimaryDataStoreDao _storagePoolDao; @Mock SnapshotDao _snapshotDao; @Mock VirtualMachineManager _itMgr; @Mock ConfigurationDao _configDao; diff --git a/server/test/org/apache/cloudstack/region/RegionManagerTest.java b/server/test/org/apache/cloudstack/region/RegionManagerTest.java index b8bde7dee8b..330f0b49d22 100644 --- a/server/test/org/apache/cloudstack/region/RegionManagerTest.java +++ b/server/test/org/apache/cloudstack/region/RegionManagerTest.java @@ -43,19 +43,32 @@ public class RegionManagerTest extends TestCase { protected void setUp() { } - + @Test public void testUniqueName() { - RegionManagerImpl regionMgr = new RegionManagerImpl(); - RegionDao regionDao = Mockito.mock(RegionDao.class); - RegionVO region = new RegionVO(2, "APAC", "", null, null); - Mockito.when(regionDao.findByName(Mockito.anyString())).thenReturn(region); - regionMgr._regionDao = regionDao; - try { - regionMgr.addRegion(2, "APAC", "", null, null); - } catch (InvalidParameterValueException e){ - Assert.assertEquals("Region with name: APAC already exists", e.getMessage()); - } + RegionManagerImpl regionMgr = new RegionManagerImpl(); + RegionDao regionDao = Mockito.mock(RegionDao.class); + RegionVO region = new RegionVO(2, "APAC", "", null, null); + Mockito.when(regionDao.findByName(Mockito.anyString())).thenReturn(region); + regionMgr._regionDao = regionDao; + try { + regionMgr.addRegion(2, "APAC", "", null, null); + } catch (InvalidParameterValueException e){ + Assert.assertEquals("Region with name: APAC already exists", e.getMessage()); + } + } + + @Test + public void testUserDelete() { + RegionManagerImpl regionMgr = new RegionManagerImpl(); + AccountDao accountDao = Mockito.mock(AccountDao.class); + Mockito.when(accountDao.findById(Mockito.anyLong())).thenReturn(null); + regionMgr._accountDao = accountDao; + try { + regionMgr.deleteUserAccount(5); + } catch (InvalidParameterValueException e){ + Assert.assertEquals("The specified account does not exist in the system", e.getMessage()); + } } } diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java index 7756d01cd7f..7f79bae657f 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java @@ -49,7 +49,9 @@ public class ConsoleProxyHttpHandlerHelper { if(map.get("token") != null) { ConsoleProxyPasswordBasedEncryptor encryptor = new ConsoleProxyPasswordBasedEncryptor( ConsoleProxy.getEncryptorPassword()); - + + // make sure we get information from token only + map.clear(); ConsoleProxyClientParam param = encryptor.decryptObject(ConsoleProxyClientParam.class, map.get("token")); if(param != null) { if(param.getClientHostAddress() != null) @@ -67,6 +69,9 @@ public class ConsoleProxyHttpHandlerHelper { if(param.getTicket() != null) map.put("ticket", param.getTicket()); } + } else { + // we no longer accept information from parameter other than token + map.clear(); } return map; diff --git a/setup/db/db/schema-40to410.sql b/setup/db/db/schema-40to410.sql index 706a1973bee..b9bfe1aae4f 100644 --- a/setup/db/db/schema-40to410.sql +++ b/setup/db/db/schema-40to410.sql @@ -263,6 +263,7 @@ CREATE TABLE `cloud`.`region` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + INSERT INTO `cloud`.`region` values ('1','Local','http://localhost:8080/client/api','',''); ALTER TABLE `cloud`.`account` ADD COLUMN `region_id` int unsigned NOT NULL DEFAULT '1'; 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; diff --git a/tools/appliance/definitions/systemvmtemplate/definition.rb b/tools/appliance/definitions/systemvmtemplate/definition.rb index a6be769deee..27336f17f8b 100644 --- a/tools/appliance/definitions/systemvmtemplate/definition.rb +++ b/tools/appliance/definitions/systemvmtemplate/definition.rb @@ -3,9 +3,9 @@ Veewee::Definition.declare({ :memory_size=> '256', :disk_size => '2000', :disk_format => 'VDI', :hostiocache => 'off', :os_type_id => 'Debian', - :iso_file => "debian-wheezy-DI-b4-i386-netinst.iso", - :iso_src => "http://cdimage.debian.org/cdimage/wheezy_di_beta4/i386/iso-cd/debian-wheezy-DI-b4-i386-netinst.iso", - :iso_md5 => "34d0ae973715c7a31646281c70839809", + :iso_file => "debian-wheezy-DI-rc1-i386-netinst.iso", + :iso_src => "http://cdimage.debian.org/cdimage/wheezy_di_rc1/i386/iso-cd/debian-wheezy-DI-rc1-i386-netinst.iso", + :iso_md5 => "db12ca9554bb8f121c98e268682a55d0", :iso_download_timeout => "1000", :boot_wait => "10", :boot_cmd_sequence => [ '', diff --git a/tools/appliance/definitions/systemvmtemplate/zerodisk.sh b/tools/appliance/definitions/systemvmtemplate/zerodisk.sh index cb793084f73..25bd8c4af2d 100644 --- a/tools/appliance/definitions/systemvmtemplate/zerodisk.sh +++ b/tools/appliance/definitions/systemvmtemplate/zerodisk.sh @@ -1,6 +1,7 @@ # 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" diff --git a/ui/scripts/docs.js b/ui/scripts/docs.js index 3356ecb866e..34835d6fc95 100755 --- a/ui/scripts/docs.js +++ b/ui/scripts/docs.js @@ -16,6 +16,15 @@ // under the License. cloudStack.docs = { + //Ldap + helpLdapQueryFilter: { + + desc:'Query filter is used to find a mapped user in the external LDAP server.Cloudstack provides some wildchars to represent the unique attributes in its database . Example - If Cloudstack account-name is same as the LDAP uid, then following will be a valid filter: Queryfilter : (&(uid=%u) , Queryfilter: .incase of Active Directory , Email _ID :(&(mail=%e)) , displayName :(&(displayName=%u)', + + externalLink:'' + }, + + //IP Reservation tooltips helpIPReservationCidr: { desc:'Edit CIDR when you want to configure IP Reservation in isolated guest Network', diff --git a/ui/scripts/globalSettings.js b/ui/scripts/globalSettings.js index 912dde7d86b..4c96b5feda5 100644 --- a/ui/scripts/globalSettings.js +++ b/ui/scripts/globalSettings.js @@ -137,7 +137,7 @@ name:{label: 'Bind DN' , validation: {required:true} }, password: {label: 'Bind Password', validation: {required: true },isPassword:true }, hostname: {label:'Hostname' , validation:{required:true}}, - queryfilter: {label:'Query Filter' , validation: {required:true}}, + queryfilter: {label:'Query Filter' , validation: {required:true} , docID:'helpLdapQueryFilter'}, searchbase: {label:'SearchBase',validation:{required:true}}, ssl: { label:'SSL' , diff --git a/ui/scripts/system.js b/ui/scripts/system.js index ac8fe3d8870..4d529aeb04e 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -7725,10 +7725,13 @@ var clusterName = args.data.name; - if(args.data.cpuovercommit != "") - array1.push("&cpuovercommitratio=" + todb(args.data.cpuovercommit)); + if(args.data.cpuovercommit != "" && args.data.cpuovercommit > 0 ){ + + array1.push("&cpuovercommitratio=" + todb(args.data.cpuovercommit)); - if(args.data.memoryovercommit != "") + } + + if(args.data.memoryovercommit != "" && args.data.memoryovercommit > 0) array1.push("&memoryovercommitratio=" + todb(args.data.memoryovercommit)); if(args.data.hypervisor == "VMware") { @@ -8989,7 +8992,7 @@ label: 'label.scope', select: function(args) { var scope = [ - { id: 'zone-wide', description: _l('label.zone.wide') }, + { id: 'zone', description: _l('label.zone.wide') }, { id: 'cluster', description: _l('label.cluster') }, { id: 'host', description: _l('label.host') } ]; @@ -9002,7 +9005,7 @@ var $form = $(this).closest('form'); var scope = $(this).val(); - if(scope == 'zone-wide'){ + if(scope == 'zone'){ $form.find('.form-item[rel=podId]').hide(); $form.find('.form-item[rel=clusterId]').hide(); $form.find('.form-item[rel=hostId]').hide(); diff --git a/utils/src/com/cloud/utils/component/ComponentContext.java b/utils/src/com/cloud/utils/component/ComponentContext.java index 407ad7a7529..ca7ad5c7b4b 100644 --- a/utils/src/com/cloud/utils/component/ComponentContext.java +++ b/utils/src/com/cloud/utils/component/ComponentContext.java @@ -28,10 +28,7 @@ import javax.management.NotCompliantMBeanException; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; -import org.springframework.aop.Advisor; import org.springframework.aop.framework.Advised; -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.context.ApplicationContext; @@ -39,7 +36,6 @@ import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; -import com.cloud.utils.db.TransactionContextBuilder; import com.cloud.utils.mgmt.JmxUtil; import com.cloud.utils.mgmt.ManagementBean; diff --git a/utils/src/com/cloud/utils/db/TransactionContextBuilder.java b/utils/src/com/cloud/utils/db/TransactionContextBuilder.java index 2cbaa303f2a..e03b25f912d 100644 --- a/utils/src/com/cloud/utils/db/TransactionContextBuilder.java +++ b/utils/src/com/cloud/utils/db/TransactionContextBuilder.java @@ -32,8 +32,8 @@ public class TransactionContextBuilder implements MethodInterceptor { public Object AroundAnyMethod(ProceedingJoinPoint call) throws Throwable { MethodSignature methodSignature = (MethodSignature)call.getSignature(); - Method targetMethod = methodSignature.getMethod(); - if(true) { // TODO ??? needToIntercept(targetMethod)) { + Method targetMethod = methodSignature.getMethod(); + if(needToIntercept(targetMethod, call.getTarget())) { Transaction txn = Transaction.open(call.getSignature().getName()); Object ret = null; try { @@ -50,7 +50,7 @@ public class TransactionContextBuilder implements MethodInterceptor { public Object invoke(MethodInvocation method) throws Throwable { Method targetMethod = method.getMethod(); - if(needToIntercept(targetMethod)) { + if(needToIntercept(targetMethod, method.getThis())) { Transaction txn = Transaction.open(targetMethod.getName()); Object ret = null; try { @@ -63,13 +63,25 @@ public class TransactionContextBuilder implements MethodInterceptor { return method.proceed(); } - private boolean needToIntercept(Method method) { + private boolean needToIntercept(Method method, Object target) { DB db = method.getAnnotation(DB.class); if (db != null) { return true; } Class clazz = method.getDeclaringClass(); + if(clazz.isInterface()) { + clazz = target.getClass(); + for(Method m : clazz.getMethods()) { + // it is supposed that we need to check against type arguments, + // this can be simplified by just checking method name + if(m.getName().equals(method.getName())) { + if(m.getAnnotation(DB.class) != null) + return true; + } + } + } + do { db = clazz.getAnnotation(DB.class); if (db != null) { diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java index cbae5a95819..e69a3d26c56 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java @@ -17,11 +17,11 @@ package com.cloud.hypervisor.vmware.util; import java.lang.reflect.Method; -import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.StringTokenizer; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; @@ -29,10 +29,6 @@ import javax.net.ssl.HttpsURLConnection; import javax.xml.ws.BindingProvider; import javax.xml.ws.handler.MessageContext; -import org.apache.http.cookie.Cookie; -import org.apache.http.cookie.CookieOrigin; -import org.apache.http.impl.cookie.BrowserCompatSpec; -import org.apache.http.message.BasicHeader; import com.vmware.vim25.DynamicProperty; import com.vmware.vim25.InvalidCollectorVersionFaultMsg; @@ -143,20 +139,15 @@ public class VmwareClient { serviceContent = vimPort.retrieveServiceContent(SVC_INST_REF); // Extract a cookie. See vmware sample program com.vmware.httpfileaccess.GetVMFiles - URL urlUrl = new URL(url); Map> headers = (Map>) ((BindingProvider) vimPort) .getResponseContext().get(MessageContext.HTTP_RESPONSE_HEADERS); - for (String header_raw_value : (List) headers.get("Set-cookie")) { - List cookies = new BrowserCompatSpec().parse( - new BasicHeader("Set-cookie", header_raw_value), - new CookieOrigin(urlUrl.getHost(), urlUrl.getPort(), - urlUrl.getPath(), true)); - if (cookies.size() > 0) { - serviceCookie = cookies.get(0).getValue(); - break; - } - } - + List cookies = (List) headers.get("Set-cookie"); + String cookieValue = cookies.get(0); + StringTokenizer tokenizer = new StringTokenizer(cookieValue, ";"); + cookieValue = tokenizer.nextToken(); + String pathData = "$" + tokenizer.nextToken(); + serviceCookie = "$Version=\"1\"; " + cookieValue + "; " + pathData; + vimPort.login(serviceContent.getSessionManager(), userName, password, null); isConnected = true;