From 602d4ef0cfd7f0f6dd02c0cd060a8b1ea17e03bb Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Thu, 21 Nov 2013 10:15:30 -0800 Subject: [PATCH 001/170] Resource metadata - support for VPC --- api/src/com/cloud/server/ResourceTag.java | 30 +++++-- ...spring-engine-schema-core-daos-context.xml | 2 +- .../resourcedetail/VpcDetailVO.java | 81 +++++++++++++++++++ .../resourcedetail/dao/VpcDetailsDao.java | 26 ++++++ .../resourcedetail/dao/VpcDetailsDaoImpl.java | 33 ++++++++ .../metadata/ResourceMetaDataManagerImpl.java | 8 +- setup/db/db/schema-421to430.sql | 11 +++ 7 files changed, 180 insertions(+), 11 deletions(-) create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/VpcDetailVO.java create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcDetailsDao.java create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcDetailsDaoImpl.java diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java index 000808d9f36..8a9116423ac 100644 --- a/api/src/com/cloud/server/ResourceTag.java +++ b/api/src/com/cloud/server/ResourceTag.java @@ -22,15 +22,29 @@ import org.apache.cloudstack.api.InternalIdentity; public interface ResourceTag extends ControlledEntity, Identity, InternalIdentity { - //FIXME - extract enum to another interface as its used both by resourceTags and resourceMetaData code + // FIXME - extract enum to another interface as its used both by resourceTags and resourceMetaData code public enum ResourceObjectType { - UserVm(true, true), Template(true, true), ISO(true, false), Volume(true, true), Snapshot(true, false), Network(true, true), Nic(false, true), LoadBalancer( - true, - true), PortForwardingRule(true, true), FirewallRule(true, true), SecurityGroup(true, false), PublicIpAddress(true, true), Project(true, false), Vpc( - true, - false), NetworkACL(true, false), StaticRoute(true, false), VMSnapshot(true, false), RemoteAccessVpn(true, true), Zone(false, true), ServiceOffering( - false, - true), Storage(false, true); + UserVm(true, true), + Template(true, true), + ISO(true, false), + Volume(true, true), + Snapshot(true, false), + Network(true, true), + Nic(false, true), + LoadBalancer(true, true), + PortForwardingRule(true, true), + FirewallRule(true, true), + SecurityGroup(true, false), + PublicIpAddress(true, true), + Project(true, false), + Vpc(true, true), + NetworkACL(true, false), + StaticRoute(true, false), + VMSnapshot(true, false), + RemoteAccessVpn(true, true), + Zone(false, true), + ServiceOffering(false, true), + Storage(false, true); ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport) { this.resourceTagsSupport = resourceTagsSupport; diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index a8a1bffdb01..23db19d3b0c 100644 --- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -323,7 +323,7 @@ - + diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/VpcDetailVO.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/VpcDetailVO.java new file mode 100644 index 00000000000..beb38b50d1b --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/VpcDetailVO.java @@ -0,0 +1,81 @@ +// 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.resourcedetail; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.apache.cloudstack.api.ResourceDetail; + +@Entity +@Table(name = "vpc_details") +public class VpcDetailVO implements ResourceDetail { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "vpc_id") + private long resourceId; + + @Column(name = "name") + private String name; + + @Column(name = "value", length = 1024) + private String value; + + @Column(name = "display") + private boolean display; + + public VpcDetailVO() { + } + + public VpcDetailVO(long id, String name, String value) { + this.resourceId = id; + this.name = name; + this.value = value; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getValue() { + return value; + } + + @Override + public long getResourceId() { + return resourceId; + } + + @Override + public boolean isDisplay() { + return display; + } +} diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcDetailsDao.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcDetailsDao.java new file mode 100644 index 00000000000..8ebd5005d61 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcDetailsDao.java @@ -0,0 +1,26 @@ +// 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.resourcedetail.dao; + +import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; +import org.apache.cloudstack.resourcedetail.VpcDetailVO; + +import com.cloud.utils.db.GenericDao; + +public interface VpcDetailsDao extends GenericDao, ResourceDetailsDao { + +} diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcDetailsDaoImpl.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcDetailsDaoImpl.java new file mode 100644 index 00000000000..64597231009 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcDetailsDaoImpl.java @@ -0,0 +1,33 @@ +// 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.resourcedetail.dao; + +import javax.ejb.Local; + +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; +import org.apache.cloudstack.resourcedetail.VpcDetailVO; +import org.springframework.stereotype.Component; + +@Component +@Local(value = { VpcDetailsDao.class }) +public class VpcDetailsDaoImpl extends ResourceDetailsDaoBase implements VpcDetailsDao { + + @Override + public void addDetail(long resourceId, String key, String value) { + super.addDetail(new VpcDetailVO(resourceId, key, value)); + } +} diff --git a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java index 68597840c53..583401a9094 100644 --- a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java +++ b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java @@ -32,6 +32,7 @@ import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; import org.apache.cloudstack.resourcedetail.dao.FirewallRuleDetailsDao; import org.apache.cloudstack.resourcedetail.dao.RemoteAccessVpnDetailsDao; import org.apache.cloudstack.resourcedetail.dao.UserIpAddressDetailsDao; +import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; import com.cloud.dc.dao.DataCenterDetailsDao; @@ -81,9 +82,11 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource UserIpAddressDetailsDao _userIpAddressDetailsDao; @Inject RemoteAccessVpnDetailsDao _vpnDetailsDao; + @Inject + VpcDetailsDao _vpcDetailsDao; private static Map> _daoMap = - new HashMap>(); + new HashMap>(); @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -100,6 +103,7 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource _daoMap.put(ResourceObjectType.PortForwardingRule, _firewallRuleDetailsDao); _daoMap.put(ResourceObjectType.LoadBalancer, _firewallRuleDetailsDao); _daoMap.put(ResourceObjectType.RemoteAccessVpn, _vpnDetailsDao); + _daoMap.put(ResourceObjectType.Vpc, _vpcDetailsDao); return true; } @@ -162,7 +166,7 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource if (dao == null) { throw new UnsupportedOperationException("ResourceType " + resourceType + " doesn't support metadata"); } - this.dao = (ResourceDetailsDao)_daoMap.get(resourceType); + this.dao = (ResourceDetailsDao) _daoMap.get(resourceType); } private void removeDetail(long resourceId, String key) { diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql index 7dc475fa8d3..8be0fb14896 100644 --- a/setup/db/db/schema-421to430.sql +++ b/setup/db/db/schema-421to430.sql @@ -751,6 +751,17 @@ CREATE VIEW `cloud`.`domain_router_view` AS `cloud`.`async_job` ON async_job.instance_id = vm_instance.id and async_job.instance_type = 'DomainRouter' and async_job.job_status = 0; + INSERT IGNORE INTO `cloud`.`configuration` VALUES ("Advanced", 'DEFAULT', 'management-server', "vmware.vcenter.session.timeout", "1200", "VMware client timeout in seconds", "1200", NULL,NULL,0); INSERT IGNORE INTO `cloud`.`configuration` VALUES ("Advanced", 'DEFAULT', 'management-server', "mgt.server.vendor", "ACS", "the vendor of management server", "ACS", NULL,NULL,0); + +CREATE TABLE `cloud`.`vpc_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `vpc_id` bigint unsigned NOT NULL COMMENT 'VPC id', + `name` varchar(255) NOT NULL, + `value` varchar(1024) NOT NULL, + `display` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'True if the detail can be displayed to the end user', + PRIMARY KEY (`id`), + CONSTRAINT `fk_vpc_details__vpc_id` FOREIGN KEY `fk_vpc_details__vpc_id`(`vpc_id`) REFERENCES `vpc`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; From 7df7abf3273e760cb55abb2213ccc5a21fc5f982 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Thu, 21 Nov 2013 12:50:04 -0800 Subject: [PATCH 002/170] Added missing @Inject to the ipAddressManager Conflicts: server/src/com/cloud/user/AccountManagerImpl.java --- .../com/cloud/user/AccountManagerImpl.java | 136 +++++++++--------- 1 file changed, 70 insertions(+), 66 deletions(-) diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index b8646b056c3..43dd622dc8c 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -155,7 +155,7 @@ import com.cloud.vm.dao.InstanceGroupDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; -@Local(value = {AccountManager.class, AccountService.class}) +@Local(value = { AccountManager.class, AccountService.class }) public class AccountManagerImpl extends ManagerBase implements AccountManager, Manager { public static final Logger s_logger = Logger.getLogger(AccountManagerImpl.class); @@ -253,6 +253,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M private List _userAuthenticators; List _userPasswordEncoders; + @Inject protected IpAddressManager _ipAddrMgr; private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AccountChecker")); @@ -343,7 +344,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Override public boolean isAdmin(short accountType) { return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) || - (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)); + (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)); } @Override @@ -400,7 +401,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M domainId = account != null ? account.getDomainId() : -1; } if (entity.getAccountId() != -1 && domainId != -1 && !(entity instanceof VirtualMachineTemplate) && - !(accessType != null && accessType == AccessType.UseNetwork) && !(entity instanceof AffinityGroup)) { + !(accessType != null && accessType == AccessType.UseNetwork) && !(entity instanceof AffinityGroup)) { List toBeChecked = domains.get(entity.getDomainId()); // for templates, we don't have to do cross domains check if (toBeChecked == null) { @@ -542,7 +543,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M public boolean deleteAccount(AccountVO account, long callerUserId, Account caller) { long accountId = account.getId(); - //delete the account record + // delete the account record if (!_accountDao.remove(accountId)) { s_logger.error("Unable to delete account " + accountId); return false; @@ -560,7 +561,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M boolean accountCleanupNeeded = false; try { - //cleanup the users from the account + // cleanup the users from the account List users = _userDao.listByAccount(accountId); for (UserVO user : users) { if (!_userDao.remove(user.getId())) { @@ -575,7 +576,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M _gslbService.revokeAllGslbRulesForAccount(caller, accountId); } - //delete the account from project accounts + // delete the account from project accounts _projectAccountDao.removeAccountFromProjects(accountId); // delete all vm groups belonging to accont @@ -683,7 +684,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } } - //Delete all VPCs + // Delete all VPCs boolean vpcsDeleted = true; s_logger.debug("Deleting vpcs for account " + account.getId()); List vpcs = _vpcMgr.getVpcsForAccount(account.getId()); @@ -749,7 +750,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M s_logger.debug("Releasing portable ip " + ip + " as a part of account id=" + accountId + " cleanup"); _ipAddrMgr.releasePortableIpAddress(ip.getId()); } - //release dedication if any + // release dedication if any List dedicatedResources = _dedicatedDao.listByAccountId(accountId); if (dedicatedResources != null && !dedicatedResources.isEmpty()) { s_logger.debug("Releasing dedicated resources for account " + accountId); @@ -760,7 +761,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } } - // Updating and deleting the resourceLimit and resourceCount should be the last step in cleanupAccount process. + // Updating and deleting the resourceLimit and resourceCount should be the last step in cleanupAccount +// process. // Update resource count for this account and for parent domains. List resourceCounts = _resourceCountDao.listByOwnerId(accountId, ResourceOwnerType.Account); for (ResourceCountVO resourceCount : resourceCounts) { @@ -855,11 +857,13 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Override @DB - @ActionEvents({@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account"), - @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")}) - public UserAccount createUserAccount(final String userName, final String password, final String firstName, final String lastName, final String email, - final String timezone, String accountName, final short accountType, Long domainId, final String networkDomain, final Map details, - String accountUUID, final String userUUID) { + @ActionEvents({ + @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account"), + @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User") + }) + public UserAccount createUserAccount(final String userName, final String password, final String firstName, final String lastName, final String email, final String timezone, String accountName, + final short accountType, + Long domainId, final String networkDomain, final Map details, String accountUUID, final String userUUID) { if (accountName == null) { accountName = userName; @@ -896,8 +900,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M if (networkDomain != null) { if (!NetUtils.verifyDomainName(networkDomain)) { throw new InvalidParameterValueException( - "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', " - + "and the hyphen ('-'); can't start or end with \"-\""); + "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', " + + "and the hyphen ('-'); can't start or end with \"-\""); } } @@ -933,14 +937,14 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M CallContext.current().putContextParameter(Account.class, account.getUuid()); - //check success + // check success return _userAccountDao.findById(userId); } @Override @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User") public UserVO createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, - String userUUID) { + String userUUID) { // default domain to ROOT if not specified if (domainId == null) { @@ -1005,7 +1009,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M throw new InvalidParameterValueException("unable to find user by id"); } - //don't allow updating system account + // don't allow updating system account if (account != null && (account.getId() == Account.ACCOUNT_ID_SYSTEM)) { throw new PermissionDeniedException("user id : " + id + " is system account, update is not allowed"); } @@ -1255,8 +1259,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Override @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_DELETE, eventDescription = "deleting account", async = true) // This method deletes the account - public - boolean deleteUserAccount(long accountId) { + public boolean deleteUserAccount(long accountId) { CallContext ctx = CallContext.current(); long callerUserId = ctx.getCallingUserId(); @@ -1277,7 +1280,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M checkAccess(caller, null, true, account); - //don't allow to delete default account (system and admin) + // don't allow to delete default account (system and admin) if (account.isDefault()) { throw new InvalidParameterValueException("The account is default and can't be removed"); } @@ -1347,7 +1350,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M 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); + domainId); } if (account.getId() == Account.ACCOUNT_ID_SYSTEM) { @@ -1436,14 +1439,14 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M // update // itself throw new InvalidParameterValueException("There already exists an account with the name:" + newAccountName + " in the domain:" + domainId + - " with existing account id:" + duplicateAcccount.getId()); + " with existing account id:" + duplicateAcccount.getId()); } if (networkDomain != null && !networkDomain.isEmpty()) { if (!NetUtils.verifyDomainName(networkDomain)) { throw new InvalidParameterValueException( - "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', " - + "and the hyphen ('-'); can't start or end with \"-\""); + "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', " + + "and the hyphen ('-'); can't start or end with \"-\""); } } @@ -1498,7 +1501,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M throw new InvalidParameterValueException("The specified user doesn't exist in the system"); } - //don't allow to delete default user (system and admin users) + // don't allow to delete default user (system and admin users) if (user.isDefault()) { throw new InvalidParameterValueException("The user is default and can't be removed"); } @@ -1552,7 +1555,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M try { List accountsForCleanupInDomain = _accountDao.findCleanupsForRemovedAccounts(domainId); if (accountsForCleanupInDomain.isEmpty()) { - //release dedication if any, before deleting the domain + // release dedication if any, before deleting the domain List dedicatedResources = _dedicatedDao.listByDomainId(domainId); if (dedicatedResources != null && !dedicatedResources.isEmpty()) { s_logger.debug("Releasing dedicated resources for domain" + domainId); @@ -1681,18 +1684,18 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M // Account type to role type translation switch (accountType) { - case Account.ACCOUNT_TYPE_ADMIN: - roleType = RoleType.Admin; - break; - case Account.ACCOUNT_TYPE_DOMAIN_ADMIN: - roleType = RoleType.DomainAdmin; - break; - case Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN: - roleType = RoleType.ResourceAdmin; - break; - case Account.ACCOUNT_TYPE_NORMAL: - roleType = RoleType.User; - break; + case Account.ACCOUNT_TYPE_ADMIN: + roleType = RoleType.Admin; + break; + case Account.ACCOUNT_TYPE_DOMAIN_ADMIN: + roleType = RoleType.DomainAdmin; + break; + case Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN: + roleType = RoleType.ResourceAdmin; + break; + case Account.ACCOUNT_TYPE_NORMAL: + roleType = RoleType.User; + break; } return roleType; } @@ -1722,7 +1725,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Override @DB public AccountVO createAccount(final String accountName, final short accountType, final Long domainId, final String networkDomain, final Map details, - final String uuid) { + final String uuid) { // Validate domain Domain domain = _domainMgr.getDomain(domainId); if (domain == null) { @@ -1745,8 +1748,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M if (networkDomain != null) { if (!NetUtils.verifyDomainName(networkDomain)) { throw new InvalidParameterValueException( - "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', " - + "and the hyphen ('-'); can't start or end with \"-\""); + "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', " + + "and the hyphen ('-'); can't start or end with \"-\""); } } @@ -1851,7 +1854,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M List parameterNames = new ArrayList(); for (Object paramNameObj : requestParameters.keySet()) { - parameterNames.add((String)paramNameObj); // put the name in a list that we'll sort later + parameterNames.add((String) paramNameObj); // put the name in a list that we'll sort later } Collections.sort(parameterNames); @@ -1859,7 +1862,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M try { for (String paramName : parameterNames) { // parameters come as name/value pairs in the form String/String[] - String paramValue = ((String[])requestParameters.get(paramName))[0]; + String paramValue = ((String[]) requestParameters.get(paramName))[0]; if ("signature".equalsIgnoreCase(paramName)) { signature = paramValue; @@ -1921,7 +1924,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } if (user != null) { - //don't allow to authenticate system user + // don't allow to authenticate system user if (user.getId() == User.UID_SYSTEM) { s_logger.error("Failed to authenticate user: " + username + " in domain " + domainId); return null; @@ -1932,10 +1935,10 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } if (NetUtils.isValidIp(loginIpAddress)) { ActionEventUtils.onActionEvent(user.getId(), user.getAccountId(), user.getDomainId(), EventTypes.EVENT_USER_LOGIN, "user has logged in from IP Address " + - loginIpAddress); + loginIpAddress); } else { ActionEventUtils.onActionEvent(user.getId(), user.getAccountId(), user.getDomainId(), EventTypes.EVENT_USER_LOGIN, - "user has logged in. The IP Address cannot be determined"); + "user has logged in. The IP Address cannot be determined"); } return user; } else { @@ -1973,7 +1976,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } if (!userAccount.getState().equalsIgnoreCase(Account.State.enabled.toString()) || - !userAccount.getAccountState().equalsIgnoreCase(Account.State.enabled.toString())) { + !userAccount.getAccountState().equalsIgnoreCase(Account.State.enabled.toString())) { if (s_logger.isInfoEnabled()) { s_logger.info("User " + username + " in domain " + domainName + " is disabled/locked (or account is disabled/locked)"); } @@ -1994,7 +1997,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M if (userAccount != null) { if (userAccount.getState().equalsIgnoreCase(Account.State.enabled.toString())) { if (!isInternalAccount(userAccount.getType())) { - //Internal accounts are not disabled + // Internal accounts are not disabled int attemptsMade = userAccount.getLoginAttempts() + 1; if (attemptsMade < _allowedLoginAttempts) { updateLoginAttempts(userAccount.getId(), attemptsMade, false); @@ -2030,7 +2033,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M throw new InvalidParameterValueException("unable to find user by id"); } - //don't allow updating system user + // don't allow updating system user if (user.getId() == User.UID_SYSTEM) { throw new PermissionDeniedException("user id : " + user.getId() + " is system account, update is not allowed"); } @@ -2105,14 +2108,14 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Override public void buildACLSearchBuilder(SearchBuilder sb, Long domainId, boolean isRecursive, List permittedAccounts, - ListProjectResourcesCriteria listProjectResourcesCriteria) { + ListProjectResourcesCriteria listProjectResourcesCriteria) { if (sb.entity() instanceof IPAddressVO) { - sb.and("accountIdIN", ((IPAddressVO)sb.entity()).getAllocatedToAccountId(), SearchCriteria.Op.IN); - sb.and("domainId", ((IPAddressVO)sb.entity()).getAllocatedInDomainId(), SearchCriteria.Op.EQ); + sb.and("accountIdIN", ((IPAddressVO) sb.entity()).getAllocatedToAccountId(), SearchCriteria.Op.IN); + sb.and("domainId", ((IPAddressVO) sb.entity()).getAllocatedInDomainId(), SearchCriteria.Op.EQ); } else if (sb.entity() instanceof ProjectInvitationVO) { - sb.and("accountIdIN", ((ProjectInvitationVO)sb.entity()).getForAccountId(), SearchCriteria.Op.IN); - sb.and("domainId", ((ProjectInvitationVO)sb.entity()).getInDomainId(), SearchCriteria.Op.EQ); + sb.and("accountIdIN", ((ProjectInvitationVO) sb.entity()).getForAccountId(), SearchCriteria.Op.IN); + sb.and("domainId", ((ProjectInvitationVO) sb.entity()).getInDomainId(), SearchCriteria.Op.EQ); } else { sb.and("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN); sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ); @@ -2124,9 +2127,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE); if (sb.entity() instanceof IPAddressVO) { - sb.join("domainSearch", domainSearch, ((IPAddressVO)sb.entity()).getAllocatedInDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER); + sb.join("domainSearch", domainSearch, ((IPAddressVO) sb.entity()).getAllocatedInDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER); } else if (sb.entity() instanceof ProjectInvitationVO) { - sb.join("domainSearch", domainSearch, ((ProjectInvitationVO)sb.entity()).getInDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER); + sb.join("domainSearch", domainSearch, ((ProjectInvitationVO) sb.entity()).getInDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER); } else { sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER); } @@ -2141,9 +2144,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } if (sb.entity() instanceof IPAddressVO) { - sb.join("accountSearch", accountSearch, ((IPAddressVO)sb.entity()).getAllocatedToAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER); + sb.join("accountSearch", accountSearch, ((IPAddressVO) sb.entity()).getAllocatedToAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER); } else if (sb.entity() instanceof ProjectInvitationVO) { - sb.join("accountSearch", accountSearch, ((ProjectInvitationVO)sb.entity()).getForAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER); + sb.join("accountSearch", accountSearch, ((ProjectInvitationVO) sb.entity()).getForAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER); } else { sb.join("accountSearch", accountSearch, sb.entity().getAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER); } @@ -2152,7 +2155,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Override public void buildACLSearchCriteria(SearchCriteria sc, Long domainId, boolean isRecursive, List permittedAccounts, - ListProjectResourcesCriteria listProjectResourcesCriteria) { + ListProjectResourcesCriteria listProjectResourcesCriteria) { if (listProjectResourcesCriteria != null) { sc.setJoinParameters("accountSearch", "type", Account.ACCOUNT_TYPE_PROJECT); @@ -2171,8 +2174,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } @Override - public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List permittedAccounts, - Ternary domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation) { + public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List + permittedAccounts, Ternary domainIdRecursiveListProject, + boolean listAll, boolean forProjectInvitation) { Long domainId = domainIdRecursiveListProject.first(); if (domainId != null) { Domain domain = _domainDao.findById(domainId); @@ -2200,7 +2204,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M if (userAccount != null) { checkAccess(caller, null, false, userAccount); - //check permissions + // check permissions permittedAccounts.add(userAccount.getId()); } else { throw new InvalidParameterValueException("could not find account " + accountName + " in domain " + domain.getUuid()); @@ -2258,7 +2262,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Override public void buildACLViewSearchBuilder(SearchBuilder sb, Long domainId, boolean isRecursive, List permittedAccounts, - ListProjectResourcesCriteria listProjectResourcesCriteria) { + ListProjectResourcesCriteria listProjectResourcesCriteria) { sb.and("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN); sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ); @@ -2281,7 +2285,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Override public void buildACLViewSearchCriteria(SearchCriteria sc, Long domainId, boolean isRecursive, List permittedAccounts, - ListProjectResourcesCriteria listProjectResourcesCriteria) { + ListProjectResourcesCriteria listProjectResourcesCriteria) { if (listProjectResourcesCriteria != null) { sc.setParameters("accountType", Account.ACCOUNT_TYPE_PROJECT); From e8ec75a2b5d2e2b7db2b794a76d1c3dd1b0e7939 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Thu, 21 Nov 2013 14:11:14 -0800 Subject: [PATCH 003/170] Removed unused agent lb timer --- .../manager/ClusteredAgentManagerImpl.java | 113 +++++++++--------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/engine/orchestration/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java b/engine/orchestration/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java index a73d5a50d9d..d1fd2a7c899 100755 --- a/engine/orchestration/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java +++ b/engine/orchestration/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java @@ -94,7 +94,7 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.nio.Link; import com.cloud.utils.nio.Task; -@Local(value = {AgentManager.class, ClusteredAgentRebalanceService.class}) +@Local(value = { AgentManager.class, ClusteredAgentRebalanceService.class }) public class ClusteredAgentManagerImpl extends AgentManagerImpl implements ClusterManagerListener, ClusteredAgentRebalanceService { final static Logger s_logger = Logger.getLogger(ClusteredAgentManagerImpl.class); private static final ScheduledExecutorService s_transferExecutor = Executors.newScheduledThreadPool(2, new NamedThreadFactory("Cluster-AgentRebalancingExecutor")); @@ -108,7 +108,6 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust protected HashMap _peers; protected HashMap _sslEngines; private final Timer _timer = new Timer("ClusteredAgentManager Timer"); - private final Timer _agentLbTimer = new Timer("ClusteredAgentManager AgentRebalancing Timer"); boolean _agentLbHappened = false; @Inject @@ -129,13 +128,13 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust } protected final ConfigKey EnableLB = new ConfigKey(Boolean.class, "agent.lb.enabled", "Advanced", "false", - "Enable agent load balancing between management server nodes", true); + "Enable agent load balancing between management server nodes", true); protected final ConfigKey ConnectedAgentThreshold = new ConfigKey(Double.class, "agent.load.threshold", "Advanced", "0.7", - "What percentage of the agents can be held by one management server before load balancing happens", true); + "What percentage of the agents can be held by one management server before load balancing happens", true); protected final ConfigKey LoadSize = new ConfigKey(Integer.class, "direct.agent.load.size", "Advanced", "16", - "How many agents to connect to in each round", true); + "How many agents to connect to in each round", true); protected final ConfigKey ScanInterval = new ConfigKey(Integer.class, "direct.agent.scan.interval", "Advanced", "90", - "Interval between scans to load agents", false, ConfigKey.Scope.Global, 1000); + "Interval between scans to load agents", false, ConfigKey.Scope.Global, 1000); @Override public boolean configure(String name, Map xmlParams) throws ConfigurationException { @@ -277,9 +276,9 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust @Override protected AgentAttache createAttacheForDirectConnect(Host host, ServerResource resource) { -// if (resource instanceof DummySecondaryStorageResource) { -// return new DummyAttache(this, host.getId(), false); -// } +// if (resource instanceof DummySecondaryStorageResource) { +// return new DummyAttache(this, host.getId(), false); +// } s_logger.debug("create ClusteredDirectAgentAttache for " + host.getId()); final DirectAgentAttache attache = new ClusteredDirectAgentAttache(this, host.getId(), host.getName(), _nodeId, resource, host.isInMaintenanceStates(), this); AgentAttache old = null; @@ -329,23 +328,23 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust } AgentAttache attache = findAttache(hostId); if (attache != null) { - //don't process disconnect if the host is being rebalanced + // don't process disconnect if the host is being rebalanced if (isAgentRebalanceEnabled()) { HostTransferMapVO transferVO = _hostTransferDao.findById(hostId); if (transferVO != null) { if (transferVO.getFutureOwner() == _nodeId && transferVO.getState() == HostTransferState.TransferStarted) { s_logger.debug("Not processing " + Event.AgentDisconnected + " event for the host id=" + hostId + " as the host is being connected to " + - _nodeId); + _nodeId); return true; } } } - //don't process disconnect if the disconnect came for the host via delayed cluster notification, - //but the host has already reconnected to the current management server + // don't process disconnect if the disconnect came for the host via delayed cluster notification, + // but the host has already reconnected to the current management server if (!attache.forForward()) { s_logger.debug("Not processing " + Event.AgentDisconnected + " event for the host id=" + hostId + - " as the host is directly connected to the current management server " + _nodeId); + " as the host is directly connected to the current management server " + _nodeId); return true; } @@ -376,7 +375,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust public void notifyNodesInCluster(AgentAttache attache) { s_logger.debug("Notifying other nodes of to disconnect"); - Command[] cmds = new Command[] {new ChangeAgentCommand(attache.getId(), Event.AgentDisconnected)}; + Command[] cmds = new Command[] { new ChangeAgentCommand(attache.getId(), Event.AgentDisconnected) }; _clusterMgr.broadcast(attache.getId(), _gson.toJson(cmds)); } @@ -385,23 +384,23 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust if (s_logger.isDebugEnabled()) { s_logger.debug("Notifying other MS nodes to run host scan task"); } - Command[] cmds = new Command[] {new ScheduleHostScanTaskCommand()}; + Command[] cmds = new Command[] { new ScheduleHostScanTaskCommand() }; _clusterMgr.broadcast(0, _gson.toJson(cmds)); } protected static void logT(byte[] bytes, final String msg) { s_logger.trace("Seq " + Request.getAgentId(bytes) + "-" + Request.getSequence(bytes) + ": MgmtId " + Request.getManagementServerId(bytes) + ": " + - (Request.isRequest(bytes) ? "Req: " : "Resp: ") + msg); + (Request.isRequest(bytes) ? "Req: " : "Resp: ") + msg); } protected static void logD(byte[] bytes, final String msg) { s_logger.debug("Seq " + Request.getAgentId(bytes) + "-" + Request.getSequence(bytes) + ": MgmtId " + Request.getManagementServerId(bytes) + ": " + - (Request.isRequest(bytes) ? "Req: " : "Resp: ") + msg); + (Request.isRequest(bytes) ? "Req: " : "Resp: ") + msg); } protected static void logI(byte[] bytes, final String msg) { s_logger.info("Seq " + Request.getAgentId(bytes) + "-" + Request.getSequence(bytes) + ": MgmtId " + Request.getManagementServerId(bytes) + ": " + - (Request.isRequest(bytes) ? "Req: " : "Resp: ") + msg); + (Request.isRequest(bytes) ? "Req: " : "Resp: ") + msg); } public boolean routeToPeer(String peer, byte[] bytes) { @@ -426,7 +425,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust if (s_logger.isDebugEnabled()) { logD(bytes, "Routing to peer"); } - Link.write(ch, new ByteBuffer[] {ByteBuffer.wrap(bytes)}, sslEngine); + Link.write(ch, new ByteBuffer[] { ByteBuffer.wrap(bytes) }, sslEngine); return true; } catch (IOException e) { try { @@ -568,9 +567,8 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust } } _timer.cancel(); - _agentLbTimer.cancel(); - //cancel all transfer tasks + // cancel all transfer tasks s_transferExecutor.shutdownNow(); cleanupTransferMap(_nodeId); @@ -620,14 +618,15 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust } Request req = Request.parse(data); Command[] cmds = req.getCommands(); - CancelCommand cancel = (CancelCommand)cmds[0]; + CancelCommand cancel = (CancelCommand) cmds[0]; if (s_logger.isDebugEnabled()) { logD(data, "Cancel request received"); } agent.cancel(cancel.getSequence()); final Long current = agent._currentSequence; - //if the request is the current request, always have to trigger sending next request in sequence, - //otherwise the agent queue will be blocked + // if the request is the current request, always have to trigger sending next request in +// sequence, + // otherwise the agent queue will be blocked if (req.executeInSequence() && (current != null && current == Request.getSequence(data))) { agent.sendNext(Request.getSequence(data)); } @@ -648,7 +647,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust return; } else { if (agent instanceof Routable) { - Routable cluster = (Routable)agent; + Routable cluster = (Routable) agent; cluster.routeToAgent(data); } else { agent.send(Request.parse(data)); @@ -665,7 +664,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust if (mgmtId != -1 && mgmtId != _nodeId) { routeToPeer(Long.toString(mgmtId), data); if (Request.requiresSequentialExecution(data)) { - AgentAttache attache = (AgentAttache)link.attachment(); + AgentAttache attache = (AgentAttache) link.attachment(); if (attache != null) { attache.sendNext(Request.getSequence(data)); } else if (s_logger.isDebugEnabled()) { @@ -727,7 +726,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust @Override public boolean executeRebalanceRequest(long agentId, long currentOwnerId, long futureOwnerId, Event event) throws AgentUnavailableException, - OperationTimedoutException { + OperationTimedoutException { boolean result = false; if (event == Event.RequestAgentRebalance) { return setToWaitForRebalance(agentId, currentOwnerId, futureOwnerId); @@ -794,7 +793,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust } else { if (s_logger.isDebugEnabled()) { s_logger.debug("There are no hosts to rebalance in the system. Current number of active management server nodes in the system is " + allMS.size() + - "; number of managed agents is " + allManagedAgents.size()); + "; number of managed agents is " + allManagedAgents.size()); } return; } @@ -849,7 +848,8 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust if (s_logger.isDebugEnabled()) { s_logger.debug("Removing mapping from op_host_transfer as it failed to be set to transfer mode"); } - //just remove the mapping (if exists) as nothing was done on the peer management server yet + // just remove the mapping (if exists) as nothing was done on the peer management +// server yet _hostTransferDao.remove(transfer.getId()); } } @@ -934,7 +934,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust synchronized (_agentToTransferIds) { if (_agentToTransferIds.size() > 0) { s_logger.debug("Found " + _agentToTransferIds.size() + " agents to transfer"); - //for (Long hostId : _agentToTransferIds) { + // for (Long hostId : _agentToTransferIds) { for (Iterator iterator = _agentToTransferIds.iterator(); iterator.hasNext();) { Long hostId = iterator.next(); AgentAttache attache = findAttache(hostId); @@ -947,7 +947,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust // no need to do anything with the real attache as we haven't modified it yet Date cutTime = DateUtil.currentGMTTime(); HostTransferMapVO transferMap = - _hostTransferDao.findActiveHostTransferMapByHostId(hostId, new Date(cutTime.getTime() - rebalanceTimeOut)); + _hostTransferDao.findActiveHostTransferMapByHostId(hostId, new Date(cutTime.getTime() - rebalanceTimeOut)); if (transferMap == null) { s_logger.debug("Timed out waiting for the host id=" + hostId + " to be ready to transfer, skipping rebalance for the host"); @@ -966,7 +966,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust ManagementServerHostVO ms = _mshostDao.findByMsid(transferMap.getFutureOwner()); if (ms != null && ms.getState() != ManagementServerHost.State.Up) { s_logger.debug("Can't transfer host " + hostId + " as it's future owner is not in UP state: " + ms + - ", skipping rebalance for the host"); + ", skipping rebalance for the host"); iterator.remove(); _hostTransferDao.completeAgentTransfer(hostId); continue; @@ -983,7 +983,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust } else { s_logger.debug("Agent " + hostId + " can't be transfered yet as its request queue size is " + attache.getQueueSize() + - " and listener queue size is " + attache.getNonRecurringListenersSize()); + " and listener queue size is " + attache.getNonRecurringListenersSize()); } } } else { @@ -1050,7 +1050,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust if (result) { if (s_logger.isDebugEnabled()) { s_logger.debug("Loading directly connected host " + host.getId() + "(" + host.getName() + ") to the management server " + _nodeId + - " as a part of rebalance process"); + " as a part of rebalance process"); } result = loadDirectlyConnectedHost(host, true); } else { @@ -1059,16 +1059,16 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust } catch (Exception ex) { s_logger.warn("Failed to load directly connected host " + host.getId() + "(" + host.getName() + ") to the management server " + _nodeId + - " as a part of rebalance process due to:", ex); + " as a part of rebalance process due to:", ex); result = false; } if (result) { s_logger.debug("Successfully loaded directly connected host " + host.getId() + "(" + host.getName() + ") to the management server " + _nodeId + - " as a part of rebalance process"); + " as a part of rebalance process"); } else { s_logger.warn("Failed to load directly connected host " + host.getId() + "(" + host.getName() + ") to the management server " + _nodeId + - " as a part of rebalance process"); + " as a part of rebalance process"); } } @@ -1089,18 +1089,18 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust return; } - ClusteredAgentAttache forwardAttache = (ClusteredAgentAttache)attache; + ClusteredAgentAttache forwardAttache = (ClusteredAgentAttache) attache; if (success) { - //1) Set transfer mode to false - so the agent can start processing requests normally + // 1) Set transfer mode to false - so the agent can start processing requests normally forwardAttache.setTransferMode(false); - //2) Get all transfer requests and route them to peer + // 2) Get all transfer requests and route them to peer Request requestToTransfer = forwardAttache.getRequestToTransfer(); while (requestToTransfer != null) { s_logger.debug("Forwarding request " + requestToTransfer.getSequence() + " held in transfer attache " + hostId + " from the management server " + - _nodeId + " to " + futureOwnerId); + _nodeId + " to " + futureOwnerId); boolean routeResult = routeToPeer(Long.toString(futureOwnerId), requestToTransfer.getBytes()); if (!routeResult) { logD(requestToTransfer.getBytes(), "Failed to route request to peer"); @@ -1138,10 +1138,10 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust } synchronized (_agents) { - ClusteredDirectAgentAttache attache = (ClusteredDirectAgentAttache)_agents.get(hostId); + ClusteredDirectAgentAttache attache = (ClusteredDirectAgentAttache) _agents.get(hostId); if (attache != null && attache.getQueueSize() == 0 && attache.getNonRecurringListenersSize() == 0) { handleDisconnectWithoutInvestigation(attache, Event.StartAgentRebalance, true, true); - ClusteredAgentAttache forwardAttache = (ClusteredAgentAttache)createAttache(hostId); + ClusteredAgentAttache forwardAttache = (ClusteredAgentAttache) createAttache(hostId); if (forwardAttache == null) { s_logger.warn("Unable to create a forward attache for the host " + hostId + " as a part of rebalance process"); return false; @@ -1154,7 +1154,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust s_logger.warn("Attache for the agent " + hostId + " no longer exists on management server " + _nodeId + ", can't start host rebalancing"); } else { s_logger.warn("Attache for the agent " + hostId + " has request queue size= " + attache.getQueueSize() + " and listener queue size " + - attache.getNonRecurringListenersSize() + ", can't start host rebalancing"); + attache.getNonRecurringListenersSize() + ", can't start host rebalancing"); } return false; } @@ -1211,7 +1211,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust // Scheduling host scan task in peer MS is a best effort operation during host add, regular host scan // happens at fixed intervals anyways. So handling any exceptions that may be thrown s_logger.warn("Exception happened while trying to schedule host scan task on mgmt server " + _clusterMgr.getSelfPeerName() + - ", ignoring as regular host scan happens at fixed interval anyways", e); + ", ignoring as regular host scan happens at fixed interval anyways", e); return null; } @@ -1249,8 +1249,8 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust s_logger.error("Excection in gson decoding : ", e); } - if (cmds.length == 1 && cmds[0] instanceof ChangeAgentCommand) { //intercepted - ChangeAgentCommand cmd = (ChangeAgentCommand)cmds[0]; + if (cmds.length == 1 && cmds[0] instanceof ChangeAgentCommand) { // intercepted + ChangeAgentCommand cmd = (ChangeAgentCommand) cmds[0]; if (s_logger.isDebugEnabled()) { s_logger.debug("Intercepting command for agent change: agent " + cmd.getAgentId() + " event: " + cmd.getEvent()); @@ -1271,7 +1271,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust answers[0] = new ChangeAgentAnswer(cmd, result); return _gson.toJson(answers); } else if (cmds.length == 1 && cmds[0] instanceof TransferAgentCommand) { - TransferAgentCommand cmd = (TransferAgentCommand)cmds[0]; + TransferAgentCommand cmd = (TransferAgentCommand) cmds[0]; if (s_logger.isDebugEnabled()) { s_logger.debug("Intercepting command for agent rebalancing: agent " + cmd.getAgentId() + " event: " + cmd.getEvent()); @@ -1294,7 +1294,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust answers[0] = new Answer(cmd, result, null); return _gson.toJson(answers); } else if (cmds.length == 1 && cmds[0] instanceof PropagateResourceEventCommand) { - PropagateResourceEventCommand cmd = (PropagateResourceEventCommand)cmds[0]; + PropagateResourceEventCommand cmd = (PropagateResourceEventCommand) cmds[0]; s_logger.debug("Intercepting command to propagate event " + cmd.getEvent().name() + " for host " + cmd.getHostId()); @@ -1311,7 +1311,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust answers[0] = new Answer(cmd, result, null); return _gson.toJson(answers); } else if (cmds.length == 1 && cmds[0] instanceof ScheduleHostScanTaskCommand) { - ScheduleHostScanTaskCommand cmd = (ScheduleHostScanTaskCommand)cmds[0]; + ScheduleHostScanTaskCommand cmd = (ScheduleHostScanTaskCommand) cmds[0]; String response = handleScheduleHostScanTaskCommand(cmd); return response; } @@ -1328,14 +1328,14 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust if (s_logger.isDebugEnabled()) { s_logger.debug("Completed dispatching -> " + pdu.getAgentId() + ", json: " + pdu.getJsonPackage() + " in " + - (System.currentTimeMillis() - startTick) + " ms, return result: " + jsonReturn); + (System.currentTimeMillis() - startTick) + " ms, return result: " + jsonReturn); } return jsonReturn; } else { if (s_logger.isDebugEnabled()) { s_logger.debug("Completed dispatching -> " + pdu.getAgentId() + ", json: " + pdu.getJsonPackage() + " in " + - (System.currentTimeMillis() - startTick) + " ms, return null result"); + (System.currentTimeMillis() - startTick) + " ms, return null result"); } } } catch (AgentUnavailableException e) { @@ -1369,7 +1369,8 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust if (s_logger.isTraceEnabled()) { s_logger.trace("Agent rebalance task check, management server id:" + _nodeId); } - //initiate agent lb task will be scheduled and executed only once, and only when number of agents loaded exceeds _connectedAgentsThreshold + // initiate agent lb task will be scheduled and executed only once, and only when number of agents +// loaded exceeds _connectedAgentsThreshold if (!_agentLbHappened) { QueryBuilder sc = QueryBuilder.create(HostVO.class); sc.and(sc.entity().getManagementServerId(), Op.NNULL); @@ -1385,12 +1386,12 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust double load = managedHostsCount / allHostsCount; if (load >= ConnectedAgentThreshold.value()) { s_logger.debug("Scheduling agent rebalancing task as the average agent load " + load + " is more than the threshold " + - ConnectedAgentThreshold.value()); + ConnectedAgentThreshold.value()); scheduleRebalanceAgents(); _agentLbHappened = true; } else { s_logger.debug("Not scheduling agent rebalancing task as the averages load " + load + " is less than the threshold " + - ConnectedAgentThreshold.value()); + ConnectedAgentThreshold.value()); } } } From 7b0cae602151b56ad80b3e70df0d9a9ed2ba00ef Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 21 Nov 2013 16:03:03 -0800 Subject: [PATCH 004/170] CLOUDSTACK-4793: UI > Virtual Routers > add "Select View" dropdown on top of listView. --- ui/scripts/system.js | 761 +++---------------------------------------- 1 file changed, 38 insertions(+), 723 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 63e0c904f24..91674eb28c1 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -7391,8 +7391,7 @@ return listView; }, virtualRouters: function() { - var listView = $.extend(true, {}, cloudStack.sections.system.subsections.virtualRouters, { - //??????? + var listView = $.extend(true, {}, cloudStack.sections.system.subsections.virtualRouters, { sections: { virtualRouterNoGrouping: { listView: { @@ -7808,8 +7807,7 @@ } } } - } - //??????? + } }); return listView; @@ -8636,160 +8634,20 @@ } } } - }, - routerByZone: { - id: 'routers', + }, + routerGroupByZone: { + id: 'routerGroupByZone', type: 'select', - title: 'By zone', + title: 'group by zone', listView: { + id: 'routerGroupByZone', label: 'label.virtual.appliances', - id: 'routers', fields: { name: { - label: 'label.name' - }, - zonename: { label: 'label.zone' }, - routerType: { - label: 'label.type' - }, - state: { - converter: function(str) { - // For localization - return str; - }, - label: 'label.status', - indicator: { - 'Running': 'on', - 'Stopped': 'off', - 'Error': 'off' - } - } - }, - - advSearchFields: { - name: { - label: 'Name' - }, - zoneid: { - label: 'Zone', - select: function(args) { - $.ajax({ - url: createURL('listZones'), - data: { - listAll: true - }, - success: function(json) { - var zones = json.listzonesresponse.zone ? json.listzonesresponse.zone : []; - - args.response.success({ - data: $.map(zones, function(zone) { - return { - id: zone.id, - description: zone.name - }; - }) - }); - } - }); - } - }, - podid: { - label: 'Pod', - dependsOn: 'zoneid', - select: function (args) { - $.ajax({ - url: createURL("listPods&zoneid=" + args.zoneid), - dataType: "json", - async: true, - success: function (json) { - var pods = json.listpodsresponse.pod ? json.listpodsresponse.pod : []; - args.response.success({ - data: $.map(pods, function(pod) { - return { - id: pod.id, - description: pod.name - }; - }) - }); - } - }); - } - }, - clusterid: { - label: 'label.cluster', - dependsOn: 'podid', - select: function(args) { - $.ajax({ - url: createURL("listClusters&podid=" + args.podid), - dataType: "json", - async: false, - success: function(json) { - var clusters = json.listclustersresponse.cluster ? json.listclustersresponse.cluster : []; - args.response.success({ - data: $.map(clusters, function(cluster) { - return { - id: cluster.id, - description: cluster.name - }; - }) - }); - } - }); - } - }, - domainid: { - label: 'Domain', - select: function(args) { - if (isAdmin() || isDomainAdmin()) { - $.ajax({ - url: createURL('listDomains'), - data: { - listAll: true, - details: 'min' - }, - success: function(json) { - var array1 = [{ - id: '', - description: '' - }]; - var domains = json.listdomainsresponse.domain; - if (domains != null && domains.length > 0) { - for (var i = 0; i < domains.length; i++) { - array1.push({ - id: domains[i].id, - description: domains[i].path - }); - } - } - args.response.success({ - data: array1 - }); - } - }); - } else { - args.response.success({ - data: null - }); - } - }, - isHidden: function(args) { - if (isAdmin() || isDomainAdmin()) - return false; - else - return true; - } - }, - - account: { - label: 'Account', - isHidden: function(args) { - if (isAdmin() || isDomainAdmin()) - return false; - else - return true; - } + routerCount: { + label: 'Total of Virtual Routers' } }, @@ -8798,588 +8656,45 @@ if (args.filterBy != null) { if (args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { switch (args.filterBy.search.by) { - case "name": - if (args.filterBy.search.value.length > 0) - array1.push("&keyword=" + args.filterBy.search.value); - break; + case "name": + if (args.filterBy.search.value.length > 0) + array1.push("&keyword=" + args.filterBy.search.value); + break; } } } - - var data2 = { - forvpc: false - }; - - var routers = []; $.ajax({ - url: createURL("listRouters&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), - data: data2, + url: createURL("listZones&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), + dataType: "json", + async: true, success: function(json) { - var items = json.listroutersresponse.router ? - json.listroutersresponse.router : []; - - $(items).map(function(index, item) { - routers.push(item); - }); - // Get project routers - $.ajax({ - url: createURL("listRouters&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("") + "&projectid=-1"), - data: data2, - success: function(json) { - var items = json.listroutersresponse.router ? - json.listroutersresponse.router : []; - - $(items).map(function(index, item) { - routers.push(item); - }); - args.response.success({ - actionFilter: routerActionfilter, - data: $(routers).map(mapRouterType) - }); - } + var zoneObjs = json.listzonesresponse.zone; + if (zoneObjs != null) { + for (var i = 0; i < zoneObjs.length; i++) { + $.ajax({ + url: createURL('listRouters'), + data: { + zoneid: zoneObjs[i].id + }, + async: false, + success: function(json) { + if (json.listroutersresponse.count != undefined) { + zoneObjs[i].routerCount = json.listroutersresponse.count; + } else { + zoneObjs[i].routerCount = 0; + } + } + }); + } + } + args.response.success({ + data: zoneObjs }); } }); - }, - detailView: { - name: 'Virtual applicance details', - actions: { - start: { - label: 'label.action.start.router', - messages: { - confirm: function(args) { - return 'message.action.start.router'; - }, - notification: function(args) { - return 'label.action.start.router'; - } - }, - action: function(args) { - $.ajax({ - url: createURL('startRouter&id=' + args.context.routers[0].id), - dataType: 'json', - async: true, - success: function(json) { - var jid = json.startrouterresponse.jobid; - args.response.success({ - _custom: { - jobId: jid, - getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.domainrouter; - }, - getActionFilter: function() { - return routerActionfilter; - } - } - }); - } - }); - }, - notification: { - poll: pollAsyncJobResult - } - }, - - stop: { - label: 'label.action.stop.router', - createForm: { - title: 'label.action.stop.router', - desc: 'message.action.stop.router', - fields: { - forced: { - label: 'force.stop', - isBoolean: true, - isChecked: false - } - } - }, - messages: { - notification: function(args) { - return 'label.action.stop.router'; - } - }, - action: function(args) { - var array1 = []; - array1.push("&forced=" + (args.data.forced == "on")); - $.ajax({ - url: createURL('stopRouter&id=' + args.context.routers[0].id + array1.join("")), - dataType: 'json', - async: true, - success: function(json) { - var jid = json.stoprouterresponse.jobid; - args.response.success({ - _custom: { - jobId: jid, - getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.domainrouter; - }, - getActionFilter: function() { - return routerActionfilter; - } - } - }); - } - }); - }, - notification: { - poll: pollAsyncJobResult - } - }, - - upgradeRouterToUseNewerTemplate: { - label: 'Upgrade Router to Use Newer Template', - messages: { - confirm: function(args) { - return 'Please confirm that you want to upgrade router to use newer template'; - }, - notification: function (args) { - return 'Upgrade Router to Use Newer Template'; - } - }, - action: function (args) { - $.ajax({ - url: createURL('upgradeRouterTemplate'), - data: { - id: args.context.routers[0].id - }, - success: function (json) { - var jobs = json.upgraderoutertemplateresponse.asyncjobs; - if (jobs != undefined) { - args.response.success({ - _custom: { - jobId: jobs[0].jobid - } - }); - } - } - }); - }, - notification: { - poll: pollAsyncJobResult - } - }, - - 'remove': { - label: 'label.destroy.router', - messages: { - confirm: function(args) { - return 'message.confirm.destroy.router'; - }, - notification: function(args) { - return 'label.destroy.router'; - } - }, - action: function(args) { - $.ajax({ - url: createURL("destroyRouter&id=" + args.context.routers[0].id), - dataType: "json", - async: true, - success: function(json) { - var jid = json.destroyrouterresponse.jobid; - args.response.success({ - _custom: { - jobId: jid - } - }); - } - }); - }, - notification: { - poll: pollAsyncJobResult - } - }, - - restart: { - label: 'label.action.reboot.router', - messages: { - confirm: function(args) { - return 'message.action.reboot.router'; - }, - notification: function(args) { - return 'label.action.reboot.router'; - } - }, - action: function(args) { - $.ajax({ - url: createURL('rebootRouter&id=' + args.context.routers[0].id), - dataType: 'json', - async: true, - success: function(json) { - var jid = json.rebootrouterresponse.jobid; - args.response.success({ - _custom: { - jobId: jid, - getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.domainrouter; - }, - getActionFilter: function() { - return routerActionfilter; - } - } - }); - } - }); - }, - notification: { - poll: pollAsyncJobResult - } - }, - - migrate: { - label: 'label.action.migrate.router', - createForm: { - title: 'label.action.migrate.router', - desc: '', - fields: { - hostId: { - label: 'label.host', - validation: { - required: true - }, - select: function(args) { - $.ajax({ - url: createURL("findHostsForMigration&VirtualMachineId=" + args.context.routers[0].id), - dataType: "json", - async: true, - success: function(json) { - var hostObjs = json.findhostsformigrationresponse.host; - var items = []; - $(hostObjs).each(function() { - items.push({ - id: this.id, - description: (this.name + " (" + (this.suitableformigration ? "Suitable" : "Not Suitable") + ")") - }); - }); - args.response.success({ - data: items - }); - } - }); - }, - error: function(XMLHttpResponse) { - var errorMsg = parseXMLHttpResponse(XMLHttpResponse); - args.response.error(errorMsg); - } - } - } - }, - messages: { - notification: function(args) { - return 'label.action.migrate.router'; - } - }, - action: function(args) { - $.ajax({ - url: createURL("migrateSystemVm&hostid=" + args.data.hostId + "&virtualmachineid=" + args.context.routers[0].id), - dataType: "json", - async: true, - success: function(json) { - var jid = json.migratesystemvmresponse.jobid; - args.response.success({ - _custom: { - jobId: jid, - getUpdatedItem: function(json) { - //return json.queryasyncjobresultresponse.jobresult.systemvminstance; //not all properties returned in systemvminstance - $.ajax({ - url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvminstance.id), - dataType: "json", - async: false, - success: function(json) { - var items = json.listroutersresponse.router; - if (items != null && items.length > 0) { - return items[0]; - } - } - }); - }, - getActionFilter: function() { - return routerActionfilter; - } - } - }); - } - }); - }, - notification: { - poll: pollAsyncJobResult - } - }, - - scaleUp: { - label: 'label.change.service.offering', - createForm: { - title: 'label.change.service.offering', - desc: function(args) { - var description = ''; - var vmObj = args.jsonObj; - //if (vmObj.state == 'Running' && vmObj.hypervisor == 'VMware') { //needs to wait for API fix that will return hypervisor property - if (vmObj.state == 'Running') { - description = 'Please read the dynamic scaling section in the admin guide before scaling up.'; - } - return description; - }, - fields: { - serviceOfferingId: { - label: 'label.compute.offering', - select: function(args) { - $.ajax({ - url: createURL('listServiceOfferings'), - data: { - issystem: true, - systemvmtype: 'domainrouter' - }, - success: function(json) { - var serviceofferings = json.listserviceofferingsresponse.serviceoffering; - var items = []; - $(serviceofferings).each(function() { - // if(this.id != args.context.routers[0].serviceofferingid) { - items.push({ - id: this.id, - description: this.name - }); //default one (i.e. "System Offering For Software Router") doesn't have displaytext property. So, got to use name property instead. - - }); - args.response.success({ - data: items - }); - } - }); - } - } - } - }, - - action: function(args) { - $.ajax({ - url: createURL("scaleSystemVm&id=" + args.context.routers[0].id + "&serviceofferingid=" + args.data.serviceOfferingId), - dataType: "json", - async: true, - success: function(json) { - var jid = json.changeserviceforsystemvmresponse.jobid; - args.response.success({ - _custom: { - jobId: jid, - getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.systemvm; - }, - getActionFilter: function() { - return routerActionfilter; - } - } - }); - - }, - error: function(json) { - args.response.error(parseXMLHttpResponse(json)); - } - - }); - }, - messages: { - confirm: function(args) { - return 'Do you really want to scale up the Router VM ?'; - }, - notification: function(args) { - - return 'Router VM Scaled Up'; - } - }, - notification: { - poll: pollAsyncJobResult - } - - }, - - - viewConsole: { - label: 'label.view.console', - action: { - externalLink: { - url: function(args) { - return clientConsoleUrl + '?cmd=access&vm=' + args.context.routers[0].id; - }, - title: function(args) { - return args.context.routers[0].id.substr(0, 8); //title in window.open() can't have space nor longer than 8 characters. Otherwise, IE browser will have error. - }, - width: 820, - height: 640 - } - } - } - }, - tabs: { - details: { - title: 'label.details', - preFilter: function(args) { - var hiddenFields = []; - if (!args.context.routers[0].project) { - hiddenFields.push('project'); - hiddenFields.push('projectid'); - } - $.ajax({ - url: createURL('listZones'), - data: { - id: args.context.routers[0].zoneid - }, - async: false, - success: function(json) { - if (json.listzonesresponse.zone != undefined) { - var zoneObj = json.listzonesresponse.zone[0]; - if (zoneObj.networktype == 'Basic') { - hiddenFields.push('publicip'); //In Basic zone, guest IP is public IP. So, publicip is not returned by listRouters API. Only guestipaddress is returned by listRouters API. - } - } - } - }); - - return hiddenFields; - }, - fields: [{ - name: { - label: 'label.name' - }, - project: { - label: 'label.project' - } - }, { - id: { - label: 'label.id' - }, - projectid: { - label: 'label.project.id' - }, - state: { - label: 'label.state' - }, - version: { - label: 'label.version' - }, - requiresupgrade: { - label: 'Requires Upgrade', - converter: cloudStack.converters.toBooleanText - }, - guestnetworkid: { - label: 'label.network.id' - }, - publicip: { - label: 'label.public.ip' - }, - guestipaddress: { - label: 'label.guest.ip' - }, - linklocalip: { - label: 'label.linklocal.ip' - }, - hostname: { - label: 'label.host' - }, - serviceofferingname: { - label: 'label.compute.offering' - }, - networkdomain: { - label: 'label.network.domain' - }, - domain: { - label: 'label.domain' - }, - account: { - label: 'label.account' - }, - created: { - label: 'label.created', - converter: cloudStack.converters.toLocalDate - }, - isredundantrouter: { - label: 'label.redundant.router', - converter: cloudStack.converters.toBooleanText - }, - redundantRouterState: { - label: 'label.redundant.state' - }, - vpcid: { - label: 'VPC ID' - } - }], - dataProvider: function(args) { - $.ajax({ - url: createURL("listRouters&id=" + args.context.routers[0].id), - dataType: 'json', - async: true, - success: function(json) { - var jsonObj = json.listroutersresponse.router[0]; - addExtraPropertiesToRouterInstanceObject(jsonObj); - args.response.success({ - actionFilter: routerActionfilter, - data: jsonObj - }); - } - }); - } - }, - nics: { - title: 'label.nics', - multiple: true, - fields: [{ - name: { - label: 'label.name', - header: true - }, - type: { - label: 'label.type' - }, - traffictype: { - label: 'label.traffic.type' - }, - networkname: { - label: 'label.network.name' - }, - netmask: { - label: 'label.netmask' - }, - ipaddress: { - label: 'label.ip.address' - }, - id: { - label: 'label.id' - }, - networkid: { - label: 'label.network.id' - }, - isolationuri: { - label: 'label.isolation.uri' - }, - broadcasturi: { - label: 'label.broadcast.uri' - } - }], - dataProvider: function(args) { - $.ajax({ - url: createURL("listRouters&id=" + args.context.routers[0].id), - dataType: 'json', - async: true, - success: function(json) { - var jsonObj = json.listroutersresponse.router[0].nic; - - args.response.success({ - actionFilter: routerActionfilter, - data: $.map(jsonObj, function(nic, index) { - var name = 'NIC ' + (index + 1); - if (nic.isdefault) { - name += ' (' + _l('label.default') + ')'; - } - return $.extend(nic, { - name: name - }); - }) - }); - } - }); - } - } - } } } - } + } } }, systemVms: { From 386ee6bf344f1cd82260b7319685991c06913ab5 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 21 Nov 2013 16:48:47 -0800 Subject: [PATCH 005/170] CLOUDSTACK-4793: UI > Virtual Routers > Select View > group by zone > listView of Zone, Total of Virtual Routers, Virtual Routers require upgrade. --- ui/scripts/system.js | 45 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 91674eb28c1..d6ced5bd90f 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -387,7 +387,7 @@ async: false, success: function(json) { args.response.success({ - data: $(json.listhypervisorsresponse.hypervisor).map(function(index, hypervisor) { + data: $(json.listhypervisorsresponse.hypervisor).map(function(index, hypervisor) { var totalHostCount = 0; var currentPage = 1; var returnedHostCount = 0; @@ -8648,6 +8648,16 @@ }, routerCount: { label: 'Total of Virtual Routers' + }, + routerRequiresUpgrade: { + label: 'Virtual Routers require upgrade', + converter: function(args) { + if (args > 0) { + return 'Yes'; + } else { + return 'No'; + } + } } }, @@ -8680,8 +8690,41 @@ success: function(json) { if (json.listroutersresponse.count != undefined) { zoneObjs[i].routerCount = json.listroutersresponse.count; + + var routerCountFromAllPages = zoneObjs[i].routerCount; + var currentPage = 1; + var routerCountFromFirstPageToCurrentPage = 0; + var routerRequiresUpgrade = 0; + var callListApiWithPage = function() { + $.ajax({ + url: createURL('listRouters'), + async: false, + data: { + zoneid: zoneObjs[i].id, + page: currentPage, + pagesize: pageSize //global variable + }, + success: function(json) { + routerCountFromFirstPageToCurrentPage += json.listroutersresponse.router.length; + var items = json.listroutersresponse.router; + for (var i = 0; i < items.length; i++) { + if (items[i].requiresupgrade) { + routerRequiresUpgrade++; + } + } + if (routerCountFromFirstPageToCurrentPage < routerCountFromAllPages) { + currentPage++; + callListApiWithPage(); + } + } + }); + } + callListApiWithPage(); + zoneObjs[i].routerRequiresUpgrade = routerRequiresUpgrade; + } else { zoneObjs[i].routerCount = 0; + zoneObjs[i].routerRequiresUpgrade = 0; } } }); From 8e580cc41184eac53969267234114d9d8ea23006 Mon Sep 17 00:00:00 2001 From: Yichi Lu Date: Thu, 21 Nov 2013 23:21:42 -0500 Subject: [PATCH 006/170] CLOUDSTACK-5231: add helper messages for DynamicallyScalable and Routing --- ui/scripts/docs.js | 8 ++++++++ ui/scripts/templates.js | 2 ++ 2 files changed, 10 insertions(+) diff --git a/ui/scripts/docs.js b/ui/scripts/docs.js index e898a969ebe..32237f318ea 100755 --- a/ui/scripts/docs.js +++ b/ui/scripts/docs.js @@ -1167,6 +1167,10 @@ cloudStack.docs = { desc: 'Whether the template is extractable or not', externalLink: '' }, + helpRegisterTemplateDynamicallyScalable: { + desc: 'Check this if the template contains XS/VMWare tools to support dynamic scaling of VM cpu/memory.', + externalLink: '' + }, helpRegisterTemplatePasswordEnabled: { desc: 'Check this if the template has the password change script installed.', externalLink: '' @@ -1179,6 +1183,10 @@ cloudStack.docs = { desc: 'Check this to make the template more prominent for users. The template will appear in the Featured Templates list.', externalLink: '' }, + helpRegisterTemplateRouting: { + desc: 'Check this if the template is used for deploying router.', + externalLink: '' + }, // Upload volume helpUploadVolumeName: { desc: 'A unique name for the volume. This will be visible to users, so choose something descriptive.', diff --git a/ui/scripts/templates.js b/ui/scripts/templates.js index f45c2d26927..1100646e4b3 100644 --- a/ui/scripts/templates.js +++ b/ui/scripts/templates.js @@ -423,6 +423,7 @@ isdynamicallyscalable: { label: "Dynamically Scalable", + docID: 'helpRegisterTemplateDynamicallyScalable', isBoolean: true }, @@ -441,6 +442,7 @@ }, isrouting: { label: 'label.routing', + docID: 'helpRegisterTemplateRouting', isBoolean: true, isHidden: true } From 4517b9277b4b6299b36a45844052882d856561e6 Mon Sep 17 00:00:00 2001 From: Jijun Date: Fri, 22 Nov 2013 17:54:39 +0100 Subject: [PATCH 007/170] rhel 6.x os mapping for vmware --- .../vmware/util/VmwareGuestOsMapper.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) mode change 100755 => 100644 vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareGuestOsMapper.java diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareGuestOsMapper.java b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareGuestOsMapper.java old mode 100755 new mode 100644 index d703adadac4..1f3d28b7ca1 --- a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareGuestOsMapper.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareGuestOsMapper.java @@ -121,14 +121,6 @@ public class VmwareGuestOsMapper { s_mapper.put("CentOS 5.6 (64-bit)", VirtualMachineGuestOsIdentifier.CENTOS_64_GUEST); s_mapper.put("CentOS 6.0 (32-bit)", VirtualMachineGuestOsIdentifier.CENTOS_GUEST); s_mapper.put("CentOS 6.0 (64-bit)", VirtualMachineGuestOsIdentifier.CENTOS_64_GUEST); - s_mapper.put("CentOS 6.1 (32-bit)", VirtualMachineGuestOsIdentifier.CENTOS_GUEST); - s_mapper.put("CentOS 6.1 (64-bit)", VirtualMachineGuestOsIdentifier.CENTOS_64_GUEST); - s_mapper.put("CentOS 6.2 (32-bit)", VirtualMachineGuestOsIdentifier.CENTOS_GUEST); - s_mapper.put("CentOS 6.2 (64-bit)", VirtualMachineGuestOsIdentifier.CENTOS_64_GUEST); - s_mapper.put("CentOS 6.3 (32-bit)", VirtualMachineGuestOsIdentifier.CENTOS_GUEST); - s_mapper.put("CentOS 6.3 (64-bit)", VirtualMachineGuestOsIdentifier.CENTOS_64_GUEST); - s_mapper.put("CentOS 6.4 (32-bit)", VirtualMachineGuestOsIdentifier.CENTOS_GUEST); - s_mapper.put("CentOS 6.4 (64-bit)", VirtualMachineGuestOsIdentifier.CENTOS_64_GUEST); s_mapper.put("Other CentOS (32-bit)", VirtualMachineGuestOsIdentifier.CENTOS_GUEST); s_mapper.put("Other CentOS (64-bit)", VirtualMachineGuestOsIdentifier.CENTOS_64_GUEST); @@ -156,6 +148,15 @@ public class VmwareGuestOsMapper { s_mapper.put("Red Hat Enterprise Linux 5.3 (64-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_64_GUEST); s_mapper.put("Red Hat Enterprise Linux 5.4 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_GUEST); s_mapper.put("Red Hat Enterprise Linux 5.4 (64-bit)", VirtualMachineGuestOsIdentifier.RHEL_5_64_GUEST); + s_mapper.put("Red Hat Enterprise Linux 6.0 (64-bit)", VirtualMachineGuestOsIdentifier.RHEL_6_64_GUEST); + s_mapper.put("Red Hat Enterprise Linux 6.1 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_6_GUEST); + s_mapper.put("Red Hat Enterprise Linux 6.1 (64-bit)", VirtualMachineGuestOsIdentifier.RHEL_6_64_GUEST); + s_mapper.put("Red Hat Enterprise Linux 6.2 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_6_GUEST); + s_mapper.put("Red Hat Enterprise Linux 6.2 (64-bit)", VirtualMachineGuestOsIdentifier.RHEL_6_64_GUEST); + s_mapper.put("Red Hat Enterprise Linux 6.3 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_6_GUEST); + s_mapper.put("Red Hat Enterprise Linux 6.3 (64-bit)", VirtualMachineGuestOsIdentifier.RHEL_6_64_GUEST); + s_mapper.put("Red Hat Enterprise Linux 6.4 (32-bit)", VirtualMachineGuestOsIdentifier.RHEL_6_GUEST); + s_mapper.put("Red Hat Enterprise Linux 6.4 (64-bit)", VirtualMachineGuestOsIdentifier.RHEL_6_64_GUEST); s_mapper.put("Ubuntu 8.04 (32-bit)", VirtualMachineGuestOsIdentifier.UBUNTU_GUEST); s_mapper.put("Ubuntu 8.04 (64-bit)", VirtualMachineGuestOsIdentifier.UBUNTU_64_GUEST); From fad0cfcc182d14d95b5d1dc2bcbac75ebf51bc4e Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Thu, 21 Nov 2013 15:01:01 -0800 Subject: [PATCH 008/170] Added new paramerer "start" to createVPC command. When false is passed in, VPC won't be started (its VPC VR won't get implemented) till the point when the first netwotrk gets implemented in the VPC. The parameter is optional and true by default to preserve the original behavior Conflicts: api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java --- .../apache/cloudstack/api/ApiConstants.java | 4 +- .../api/command/user/vpc/CreateVPCCmd.java | 69 ++++++++++++------- .../orchestration/NetworkOrchestrator.java | 18 ++--- 3 files changed, 56 insertions(+), 35 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 523bb6024db..6f919c170a2 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -410,7 +410,8 @@ public class ApiConstants { public static final String EXTERNAL_SWITCH_MGMT_DEVICE_ID = "vsmdeviceid"; public static final String EXTERNAL_SWITCH_MGMT_DEVICE_NAME = "vsmdevicename"; public static final String EXTERNAL_SWITCH_MGMT_DEVICE_STATE = "vsmdevicestate"; - // Would we need to have a capacity field for Cisco N1KV VSM? Max hosts managed by it perhaps? May remove this later. + // Would we need to have a capacity field for Cisco N1KV VSM? Max hosts managed by it perhaps? May remove this +// later. public static final String EXTERNAL_SWITCH_MGMT_DEVICE_CAPACITY = "vsmdevicecapacity"; public static final String CISCO_NEXUS_VSM_NAME = "vsmname"; public static final String VSM_USERNAME = "vsmusername"; @@ -534,6 +535,7 @@ public class ApiConstants { public static final String FOR_DISPLAY = "fordisplay"; public static final String PASSIVE = "passive"; public static final String VERSION = "version"; + public static final String START = "start"; public enum HostDetails { all, capacity, events, stats, min; diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java index 0aafa399d08..f12d15b5f0e 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java @@ -16,8 +16,6 @@ // under the License. package org.apache.cloudstack.api.command.user.vpc; -import org.apache.log4j.Logger; - import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -30,6 +28,7 @@ import org.apache.cloudstack.api.response.VpcOfferingResponse; import org.apache.cloudstack.api.response.VpcResponse; import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.context.CallContext; +import org.apache.log4j.Logger; import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; @@ -43,47 +42,54 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(CreateVPCCmd.class.getName()); private static final String s_name = "createvpcresponse"; - ///////////////////////////////////////////////////// - //////////////// API parameters ///////////////////// - ///////////////////////////////////////////////////// + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// - @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "the account associated with the VPC. " - + "Must be used with the domainId parameter.") + @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "the account associated with the VPC. " + + "Must be used with the domainId parameter.") private String accountName; - @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "the domain ID associated with the VPC. " - + "If used with the account parameter returns the VPC associated with the account for the specified domain.") + @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, + description = "the domain ID associated with the VPC. " + + "If used with the account parameter returns the VPC associated with the account for the specified domain.") private Long domainId; - @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "create VPC for the project") + @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, + description = "create VPC for the project") private Long projectId; - @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "the ID of the availability zone") + @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, + required = true, description = "the ID of the availability zone") private Long zoneId; @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the VPC") private String vpcName; - @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, required = true, description = "the display text of " + "the VPC") + @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, required = true, description = "the display text of " + + "the VPC") private String displayText; - @Parameter(name = ApiConstants.CIDR, type = CommandType.STRING, required = true, description = "the cidr of the VPC. All VPC " - + "guest networks' cidrs should be within this CIDR") + @Parameter(name = ApiConstants.CIDR, type = CommandType.STRING, required = true, description = "the cidr of the VPC. All VPC " + + "guest networks' cidrs should be within this CIDR") private String cidr; - @Parameter(name = ApiConstants.VPC_OFF_ID, - type = CommandType.UUID, - entityType = VpcOfferingResponse.class, - required = true, - description = "the ID of the VPC offering") + @Parameter(name = ApiConstants.VPC_OFF_ID, type = CommandType.UUID, entityType = VpcOfferingResponse.class, + required = true, description = "the ID of the VPC offering") private Long vpcOffering; - @Parameter(name = ApiConstants.NETWORK_DOMAIN, type = CommandType.STRING, description = "VPC network domain. All networks inside the VPC will belong to this domain") + @Parameter(name = ApiConstants.NETWORK_DOMAIN, type = CommandType.STRING, + description = "VPC network domain. All networks inside the VPC will belong to this domain") private String networkDomain; - ///////////////////////////////////////////////////// - /////////////////// Accessors /////////////////////// - ///////////////////////////////////////////////////// + @Parameter(name = ApiConstants.START, type = CommandType.BOOLEAN, + description = "If set to false, the VPC won't start (VPC VR will not get allocated) until its first network gets implemented. " + + "True by default.", since = "4.3") + private Boolean start; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// public String getAccountName() { return accountName; @@ -117,6 +123,13 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd { return networkDomain; } + public boolean isStart() { + if (start != null) { + return start; + } + return true; + } + @Override public void create() throws ResourceAllocationException { Vpc vpc = _vpcService.createVpc(getZoneId(), getVpcOffering(), getEntityOwnerId(), getVpcName(), getDisplayText(), getCidr(), getNetworkDomain()); @@ -131,10 +144,14 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd { @Override public void execute() { Vpc vpc = null; + boolean success = true; try { - if (_vpcService.startVpc(getEntityId(), true)) { - vpc = _entityMgr.findById(Vpc.class, getEntityId()); + if (isStart()) { + success = _vpcService.startVpc(getEntityId(), true); + } else { + s_logger.debug("Not starting VPC as " + ApiConstants.START + "=false was passed to the API"); } + vpc = _entityMgr.findById(Vpc.class, getEntityId()); } catch (ResourceUnavailableException ex) { s_logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); @@ -147,7 +164,7 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd { throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage()); } - if (vpc != null) { + if (vpc != null && success) { VpcResponse response = _responseGenerator.createVpcResponse(vpc); response.setResponseName(getCommandName()); setResponseObject(response); diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 7179944f7ba..75caabe12d3 100755 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -47,6 +47,7 @@ import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.region.PortableIpDao; +import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; @@ -147,6 +148,7 @@ import com.cloud.network.rules.StaticNatRule; import com.cloud.network.rules.StaticNatRuleImpl; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.network.vpc.NetworkACLManager; +import com.cloud.network.vpc.Vpc; import com.cloud.network.vpc.VpcManager; import com.cloud.network.vpc.dao.PrivateIpDao; import com.cloud.network.vpn.RemoteAccessVpnService; @@ -1031,22 +1033,22 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra (network.getGuestType() == Network.GuestType.Isolated || (network.getGuestType() == Network.GuestType.Shared && zone.getNetworkType() == NetworkType.Advanced))) { List ips = null; + Account owner = _entityMgr.findById(Account.class, network.getAccountId()); if (network.getVpcId() != null) { ips = _ipAddressDao.listByAssociatedVpc(network.getVpcId(), true); if (ips.isEmpty()) { - throw new CloudRuntimeException("Vpc is not implemented; there is no source nat ip"); + Vpc vpc = _vpcMgr.getActiveVpc(network.getVpcId()); + s_logger.debug("Creating a source nat ip for vpc " + vpc); + _vpcMgr.assignSourceNatIpAddressToVpc(owner, vpc); } } else { ips = _ipAddressDao.listByAssociatedNetwork(network.getId(), true); - } - - if (ips.isEmpty()) { - s_logger.debug("Creating a source nat ip for network " + network); - Account owner = _entityMgr.findById(Account.class, network.getAccountId()); - _ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, network); + if (ips.isEmpty()) { + s_logger.debug("Creating a source nat ip for network " + network); + _ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, network); + } } } - // get providers to implement List providersToImplement = getNetworkProviders(network.getId()); for (NetworkElement element : _networkElements) { From 6227ba6356cf9e68b2c62dc3e96d83b2719f4218 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 22 Nov 2013 10:56:27 -0800 Subject: [PATCH 009/170] CLOUDSTACK-5246:Xenserver - Hourly Snapshots - Creating snapshot from ROOT volume fails with NullPointer Exception due to new jobs framework merge. --- .../src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java index 2b9e1e2ad13..8cb76d29ccd 100644 --- a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java @@ -34,6 +34,7 @@ import org.springframework.stereotype.Component; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotCmd; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher; import org.apache.cloudstack.framework.jobs.AsyncJobManager; import org.apache.cloudstack.framework.jobs.dao.AsyncJobDao; import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO; @@ -82,6 +83,8 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu protected VolumeDao _volsDao; @Inject protected ConfigurationDao _configDao; + @Inject + protected AsyncJobDispatcher _asyncDispatcher; private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 5; // 5 seconds private int _snapshotPollInterval; @@ -254,6 +257,7 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu new AsyncJobVO(UUID.randomUUID().toString(), User.UID_SYSTEM, volume.getAccountId(), CreateSnapshotCmd.class.getName(), ApiGsonHelper.getBuilder() .create() .toJson(params), cmd.getEntityId(), cmd.getInstanceType() != null ? cmd.getInstanceType().toString() : null); + job.setDispatcher(_asyncDispatcher.getName()); long jobId = _asyncMgr.submitAsyncJob(job); From 2ba27db0cea55665acc3344bc31d3931c7545f35 Mon Sep 17 00:00:00 2001 From: Gaurav Aradhye Date: Mon, 25 Nov 2013 13:15:49 +0530 Subject: [PATCH 010/170] CLOUDSTACK 2233: Automation test cases for Add Remove Networks to VM Signed-off-by: Girish Shilamkar --- tools/marvin/marvin/integration/lib/base.py | 6 +++++- tools/marvin/setup.py | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/marvin/marvin/integration/lib/base.py b/tools/marvin/marvin/integration/lib/base.py index b03c552427f..bce13272afe 100755 --- a/tools/marvin/marvin/integration/lib/base.py +++ b/tools/marvin/marvin/integration/lib/base.py @@ -530,11 +530,15 @@ class VirtualMachine: cmd.id = volume.id return apiclient.detachVolume(cmd) - def add_nic(self, apiclient, networkId): + def add_nic(self, apiclient, networkId, ipaddress=None): """Add a NIC to a VM""" cmd = addNicToVirtualMachine.addNicToVirtualMachineCmd() cmd.virtualmachineid = self.id cmd.networkid = networkId + + if ipaddress: + cmd.ipaddress = ipaddress + return apiclient.addNicToVirtualMachine(cmd) def remove_nic(self, apiclient, nicId): diff --git a/tools/marvin/setup.py b/tools/marvin/setup.py index eeed3bfa8fd..9ce3951fdeb 100644 --- a/tools/marvin/setup.py +++ b/tools/marvin/setup.py @@ -51,7 +51,8 @@ setup(name="Marvin", "mysql-connector-python", "requests", "paramiko", - "nose" + "nose", + "ddt >= 0.4.0" ], py_modules=['marvin.marvinPlugin'], zip_safe=False, From ab2c38c05040e1473b7d9e95736ee90548d84a65 Mon Sep 17 00:00:00 2001 From: Girish Shilamkar Date: Mon, 25 Nov 2013 13:43:18 +0530 Subject: [PATCH 011/170] Add test/integration/component/test_add_remove_network.py --- .../component/test_add_remove_network.py | 1785 +++++++++++++++++ 1 file changed, 1785 insertions(+) create mode 100644 test/integration/component/test_add_remove_network.py diff --git a/test/integration/component/test_add_remove_network.py b/test/integration/component/test_add_remove_network.py new file mode 100644 index 00000000000..f1508e1f1cb --- /dev/null +++ b/test/integration/component/test_add_remove_network.py @@ -0,0 +1,1785 @@ +# 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. + +""" + P1 tests for Add Remove Network to VM + + Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Add+Remove+networks+to+VM+Test+cases + + Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-645 + + Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Add+Remove+Networks+to+VMs +""" + +# Import Local Modules +from nose.plugins.attrib import attr +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from ddt import ddt, data +from marvin.integration.lib.base import ( + Account, + Domain, + ServiceOffering, + VirtualMachine, + NetworkOffering, + Network, + VpcOffering, + VPC + ) +from marvin.integration.lib.common import (get_domain, + get_zone, + get_template, + cleanup_resources, + list_virtual_machines, + list_events, + list_zones, + get_free_vlan, + get_hypervisor_type, + update_resource_limit + ) + +from marvin.integration.lib.utils import (validateList, + random_gen) + +from marvin.cloudstackAPI import (addNicToVirtualMachine, + removeNicFromVirtualMachine, + updateDefaultNicForVirtualMachine) + +from marvin.codes import PASS +import random + +class Services: + """Test Add Remove Network Services + """ + + def __init__(self): + self.services = { + + "ostype": "CentOS 5.3 (64-bit)", + # Cent OS 5.3 (64 bit) + + "isolated_network_offering": { + "name": 'Test Isolated Network offering', + "displaytext": 'Test Isolated Network offering', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList" : { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + }, + }, + + "shared_network_offering": { + "name": 'Test Shared Network Offering', + "displaytext": 'Test Shared Network Offering', + "guestiptype": 'Shared', + "supportedservices": 'Dhcp,Dns,UserData', + "specifyVlan" : "True", + "specifyIpRanges" : "True", + "traffictype": 'GUEST', + "serviceProviderList" : { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "UserData": 'VirtualRouter' + }, + }, + + "shared_network": { + "name": "Test Shared Network", + "displaytext": "Test Shared Network", + "gateway" :"172.16.17.1", + "netmask" :"255.255.255.0", + "startip" :"172.16.17.2", + "endip" :"172.16.17.20", + }, + + "shared_network_2": { + "name": "Test Shared Network", + "displaytext": "Test Shared Network", + "gateway" :"172.16.18.1", + "netmask" :"255.255.255.0", + "startip" :"172.16.18.2", + "endip" :"172.16.18.20", + }, + + "isolated_network": { + "name": "Test Isolated Network", + "displaytext": "Test Isolated Network", + }, + + "service_offering": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, + # in MHz + "memory": 256, + # In MBs + }, + + "account": { + "email": "test@test.com", + "firstname": "Test_add_remove_network_vm", + "lastname": "User", + "username": "test_add_remove_network_vm", + "password": "password", + }, + "domain": { + "name": "Domain_add_nw_to_vm", + }, + "virtual_machine": { + "displayname": "testserver", + "username": "root", # VM creds for SSH + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + + "vpc_offering": { + "name": 'VPC off add remove network', + "displaytext": 'VPC off add remove network', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat,NetworkACL', + }, + + "vpc": { + "name": "TestVPC add remove network", + "displaytext": "TestVPC add remove network", + "cidr": '10.0.0.1/24' + }, + } + +@ddt +class TestAddNetworkToVirtualMachine(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super(TestAddNetworkToVirtualMachine, cls).getClsTestClient().getApiClient() + + hypervisor = get_hypervisor_type(cls.api_client) + if hypervisor.lower() not in ["xenserver","kvm"]: + raise unittest.SkipTest("This feature is supported only on XenServer and KVM") + + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + + template = get_template(cls.api_client, cls.zone.id, cls.services["ostype"]) + # Set Zones and disk offerings + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = template.id + + # Create Accounts & networks + cls.services["isolated_network"]["zoneid"] = cls.zone.id + cls.services["shared_network"]["zoneid"] = cls.zone.id + + cls.account = Account.create(cls.api_client, cls.services["account"], domainid = cls.domain.id) + + cls.service_offering = ServiceOffering.create(cls.api_client,cls.services["service_offering"]) + + cls.virtual_machine = VirtualMachine.create(cls.api_client, cls.services["virtual_machine"],accountid=cls.account.name, + domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id, + mode=cls.zone.networktype) + + # Create Shared Network Offering + cls.isolated_network_offering = NetworkOffering.create(cls.api_client, cls.services["isolated_network_offering"]) + # Enable Isolated Network offering + cls.isolated_network_offering.update(cls.api_client, state='Enabled') + + # Create Shared Network Offering + cls.shared_network_offering = NetworkOffering.create(cls.api_client,cls.services["shared_network_offering"]) + # Enable shared Network offering + cls.shared_network_offering.update(cls.api_client, state='Enabled') + + cls.isolated_network = Network.create(cls.api_client,cls.services["isolated_network"],cls.account.name, + cls.account.domainid,networkofferingid=cls.isolated_network_offering.id) + + cls.services["shared_network"]["vlan"] = get_free_vlan(cls.api_client, cls.zone.id)[1] + + shared_network_subnet_number = random.randrange(1,254) + + cls.services["shared_network"]["gateway"] = "172.16."+str(shared_network_subnet_number)+".1" + cls.services["shared_network"]["startip"] = "172.16."+str(shared_network_subnet_number)+".2" + cls.services["shared_network"]["endip"] = "172.16."+str(shared_network_subnet_number)+".20" + + cls.shared_nw_endip = cls.services["shared_network"]["endip"] + + cls.shared_network = Network.create(cls.api_client,cls.services["shared_network"],cls.account.name, + cls.account.domainid,networkofferingid=cls.shared_network_offering.id) + + cls._cleanup = [cls.account,cls.service_offering,cls.shared_network,cls.isolated_network_offering, + cls.shared_network_offering] + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.addednics = [] + + shared_network_subnet_number = random.randrange(1,254) + + self.services["shared_network"]["gateway"] = "172.16."+str(shared_network_subnet_number)+".1" + self.services["shared_network"]["startip"] = "172.16."+str(shared_network_subnet_number)+".2" + self.services["shared_network"]["endip"] = "172.16."+str(shared_network_subnet_number)+".20" + + self.services["shared_network_2"]["gateway"] = "172.16."+str(shared_network_subnet_number + 1)+".1" + self.services["shared_network_2"]["startip"] = "172.16."+str(shared_network_subnet_number + 1)+".2" + self.services["shared_network_2"]["endip"] = "172.16."+str(shared_network_subnet_number + 1)+".20" + self.cleanup = [] + + def tearDown(self): + try: + for nic in self.addednics: + self.virtual_machine.remove_nic(self.apiclient, nic.id) + #Clean up, terminate the created accounts, domains etc + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @classmethod + def tearDownClass(cls): + try: + # Disable Network Offerings + cls.isolated_network_offering.update(cls.api_client, state='Disabled') + cls.shared_network_offering.update(cls.api_client, state='Disabled') + + # Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def addNetworkToVm(self, network, vm, ipaddress=None): + """Add network to VM and check if new nic added in the VM""" + + self.debug("Adding %s Network: %s to virtual machine %s" % + (network.type, network.id, vm.id)) + vm.add_nic(self.apiclient, network.id, ipaddress=ipaddress) + + vm_list = list_virtual_machines(self.apiclient, id=vm.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + + self.debug("virtual machine nics: %s" % vm_list[0].nic) + nics = [x for x in vm_list[0].nic if x.networkid == network.id] + self.debug("Filtered nics list: %s:" % nics) + self.addednics.append(nics[-1]) + + self.assertTrue(len(nics) == 1, "nics list should contain the nic of added isolated network,\ + the number of nics for the network should be 1, instead they are %s" % + len(nics)) + + if ipaddress is not None: + self.assertEqual(nics[0].ipaddress, ipaddress, "The ip address of nic does not match with \ + the ip address passed while adding network to vm. ip address of nic is %s \ + while passed ip address is %s" % (nics[0].ipaddress, ipaddress)) + + return + + @attr(tags = ["advanced"]) + @data("isolated","shared") + def test_01_add_nw_running_vm(self, value): + """Add network to running VM""" + + # 1. Deploy VM in an account + # 2. Add isolated/shared network to the VM which is in running state + + # Validate the following: + # 1. New nic is generated for the added network + # 2. Event NIC.CREATE is generated + + network = None #The network which we are adding to the vm + + if value == "isolated": + network = self.isolated_network + elif value == "shared": + network = self.shared_network + if network is None: + self.skipTest("Network should not be none. Case not handled for Network of type %s" % value) + + self.addNetworkToVm(network, self.virtual_machine) + self.debug("Retrieving the list of events matching 'NIC.CREATE' in account: %s" % self.account.name) + events = list_events(self.apiclient, account=self.account.name, domainid=self.account.domainid, + type='NIC.CREATE') + event_list_validation_result = validateList(events) + self.assertEqual(event_list_validation_result[0], PASS, "event list validation failed due to %s" % + event_list_validation_result[2]) + self.debug("Events list contains event NIC.CREATE") + + return + + @attr(tags = ["advanced"]) + @data("isolated","shared") + def test_02_add_nw_stopped_vm(self, value): + """Add network to stopped VM""" + + # 1. Deploy VM in an account + # 2. Stop the VM + # 3. Add isolated/shared network to the stopped VM + + # Validate the following: + # 1. New nic is generated for the added network + + self.debug("Stopping Virtual Machine: %s" % self.virtual_machine.id) + self.virtual_machine.stop(self.apiclient) + + vm_list = list_virtual_machines(self.apiclient,id=self.virtual_machine.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + self.assertTrue(vm_list[0].state == 'Stopped', "Failed to stop VM, the state is %s" % vm_list[0].state) + + network = None #The network which we are adding to the vm + if value == "isolated": + network = self.isolated_network + elif value == "shared": + network = self.shared_network + if network is None: + self.skipTest("Network should not be none. Case not handled for Network of type %s" % value) + + self.addNetworkToVm(network, self.virtual_machine) + self.debug("Starting Virtual Machine: %s" % self.virtual_machine.id) + self.virtual_machine.start(self.apiclient) + + return + + @attr(tags = ["advanced"]) + @data("isolated","shared") + def test_03_add_nw_multiple_times(self, value): + """Add same network multiple times to running VM""" + + # 1. Deploy VM in an account + # 2. Add isolated/shared network to the VM + # 3. Try Adding same network again to the VM + + # Validate the following: + # 1. Adding same network to vm multiple times fails + + network = None #The network which we are adding to the vm + if value == "isolated": + network = self.isolated_network + elif value == "shared": + network = self.shared_network + if network is None: + self.skipTest("Network should not be none. Case not handled for Network of type %s" % value) + + # Adding network to vm for the first time + self.addNetworkToVm(network, self.virtual_machine) + + # Trying to add same network to vm for the second time + with self.assertRaises(Exception) as e: + self.addNetworkToVm(network, self.virtual_machine) + + self.debug("Adding same network again failed with exception: %s" % e.exception) + + return + + @attr(tags = ["advanced"]) + @data("isolated") + def test_04_vpc_nw_running_vm(self, value): + """Add VPC network to running VM belonging to isolated network""" + + # 1. Deploy VM in an account + # 2. Add isolated network to the VM + # 3. Create VPC + # 4. Try adding VPC to the VM + + # Validate the following: + # 1. Adding VPC to vm should fail + + network = self.isolated_network + self.addNetworkToVm(network, self.virtual_machine) + + self.debug("Creating VPC offering") + vpc_off = VpcOffering.create(self.api_client,self.services["vpc_offering"]) + self.debug("Created VPC offering: %s" % vpc_off.id) + self.debug("Enabling the VPC offering") + vpc_off.update(self.apiclient, state='Enabled') + self.debug("Creating VPC") + vpc = VPC.create(self.apiclient, self.services["vpc"], vpcofferingid=vpc_off.id, zoneid=self.zone.id, + account=self.account.name,domainid=self.account.domainid) + # Appending to cleanup list + self.cleanup.append(vpc) + self.cleanup.append(vpc_off) + + self.debug("Trying to add VPC to vm belonging to isolated network, this should fail") + with self.assertRaises(Exception): + self.virtual_machine.add_nic(self.apiclient, vpc.id) + + self.debug("Disabling vpc offering: %s" % vpc_off.id) + vpc_off.update(self.apiclient, state='Disabled') + + return + + @attr(tags = ["advanced"]) + @data("isolated") + def test_05_add_vpc_nw_stopped_vm(self, value): + """Add VPC network to stopped VM belonging to isolated network""" + + # 1. Deploy VM in an account + # 2. Stop the VM + # 3. Add isolated network to the VM + # 4. Create VPC + # 5. Try adding VPC to the stopped VM + + # Validate the following: + # 1. Adding VPC to vm should fail + + self.debug("Stopping Virtual Machine: %s" % self.virtual_machine.id) + self.virtual_machine.stop(self.apiclient) + + vm_list = list_virtual_machines(self.apiclient,id=self.virtual_machine.id) + #validation vm list + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + + self.assertTrue(vm_list[0].state == 'Stopped', "Failed to stop VM, the state is %s" % vm_list[0].state) + + self.addNetworkToVm(self.isolated_network, self.virtual_machine) + + self.debug("Creating VPC offering") + vpc_off = VpcOffering.create(self.api_client,self.services["vpc_offering"]) + self.debug("Created VPC offering: %s" % vpc_off.id) + self.debug("Enabling the VPC offering") + vpc_off.update(self.apiclient, state='Enabled') + self.debug("Creating VPC") + vpc = VPC.create(self.apiclient,self.services["vpc"],vpcofferingid=vpc_off.id,zoneid=self.zone.id, + account=self.account.name,domainid=self.account.domainid) + # Appending to cleanup list + self.cleanup.append(vpc) + self.cleanup.append(vpc_off) + self.debug("Trying to add VPC to vm belonging to isolated network, this should fail") + with self.assertRaises(Exception): + self.virtual_machine.add_nic(self.apiclient, vpc.id) + self.debug("Starting virtual machine") + self.virtual_machine.start(self.apiclient) + self.debug("Disabling vpc offering: %s" % vpc_off.id) + vpc_off.update(self.apiclient, state='Disabled') + + return + + @attr(tags = ["advanced"]) + def test_06_add_nw_ipaddress_running_vm(self): + """Add network and ip address to running VM""" + + # 1. Deploy VM in an account + # 2. Add shared network and ip address to this VM + + # Validate the following: + # 1. New nic gets added for the shared network + # 2. The newly added nic has the ip address same as + # that passed while adding the network + + ipaddress = self.shared_nw_endip + self.debug("Adding network to vm with ip address %s: " % ipaddress) + self.addNetworkToVm(self.shared_network, self.virtual_machine,ipaddress = ipaddress) + + return + + @attr(tags = ["advanced"]) + def test_10_add_nw_invalid_ipaddress_running_vm(self): + """Add network with invalid ip address to running VM""" + + # 1. Deploy VM in an account + # 2. Add shared network with invalid ip address to this VM + + # Validate the following: + # 1. Adding network to VM should fail because of invalid ip address + + ipaddress = "257.257.257.257" #Invalid ip address + self.debug("Adding network to vm with ip address %s: " % ipaddress) + with self.assertRaises(Exception) as e: + self.addNetworkToVm(self.shared_network, self.virtual_machine, + ipaddress = ipaddress) + self.debug("API failed with exception: %s" % e.exception) + + return + + @attr(tags = ["advanced"]) + @data("isolated","shared") + def test_14_add_nw_different_account(self, value): + """Add network to running VM""" + + # 1. Deploy VM in an account + # 2. Create new account under same domain and create network in that account + # 3. Add isolated/shared network belonging to other account to the VM in first account + + # Validate the following: + # 1. Adding network should fail + + network = None #The network which we are adding to the vm + account = Account.create(self.apiclient,self.services["account"],domainid = self.domain.id) + self.cleanup.append(account) + + if value == "isolated": + network = Network.create(self.api_client,self.services["isolated_network"],account.name, + account.domainid,networkofferingid=self.isolated_network_offering.id) + elif value == "shared": + self.services["shared_network_2"]["zoneid"] = self.zone.id + self.services["shared_network_2"]["vlan"] = get_free_vlan(self.apiclient, self.zone.id)[1] + network = Network.create(self.api_client,self.services["shared_network_2"],account.name, + account.domainid, networkofferingid=self.shared_network_offering.id) + + if network is None: + self.skipTest("Network should not be none. Case not handled for Network of type %s" % value) + + self.debug("Trying to %s network in account %s to a vm in account %s, This should fail" % + (network.type, account.name, self.account.name)) + + with self.assertRaises(Exception) as e: + self.virtual_machine.add_nic(self.apiclient, network.id) + network.delete(self.apiclient) + + self.debug("Operation failed with exception %s" % e.exception) + + return + + @attr(tags = ["advanced"]) + def test_24_add_nw_different_domain(self): + """Add network to running VM""" + + # 1. Create two domains + # 2. Create network in one domain and create virtual machine in other domain + # 3. Ad isolated/shared network belonging to one domain to the vm belonging to other domain + + # Validate the following: + # 1. Adding network should fail + + network = None #The network which we are adding to the vm + + self.child_domain_1 = Domain.create(self.apiclient, + services=self.services["domain"], + parentdomainid=self.domain.id) + + self.child_do_admin_1 = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.child_domain_1.id + ) + + self.debug("Creating a domain under: %s" % self.domain.name) + + self.child_domain_2 = Domain.create(self.apiclient, + services=self.services["domain"], + parentdomainid=self.domain.id) + + self.child_do_admin_2 = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.child_domain_2.id) + + network = Network.create(self.api_client,self.services["isolated_network"],self.child_do_admin_1.name, + self.child_do_admin_1.domainid,networkofferingid=self.isolated_network_offering.id) + + self.cleanup.append(self.child_do_admin_1) + self.cleanup.append(self.child_domain_1) + self.cleanup.append(self.child_do_admin_2) + self.cleanup.append(self.child_domain_2) + + virtual_machine = VirtualMachine.create(self.apiclient, self.services["virtual_machine"],accountid=self.child_do_admin_2.name, + domainid=self.child_do_admin_2.domainid, serviceofferingid=self.service_offering.id, + mode=self.zone.networktype) + + self.debug("Trying to %s network in domain %s to a vm in domain %s, This should fail" % + (network.type, self.child_domain_1.name, self.child_domain_2.name)) + + with self.assertRaises(Exception) as e: + virtual_machine.add_nic(self.apiclient, network.id) + self.debug("Operation failed with exception %s" % e.exception) + + network.delete(self.apiclient) + + return + + @attr(tags = ["advanced"]) + def test_25_add_nw_above_account_limit(self): + """Add network to VM with maximum network limit reached""" + + # 1. Create an account and create maximum allowed networks in the account + # 2. Deploy VM in this account + # 3. Create a network in other account and add to this VM + + # Validate the following: + # 1. Adding network should fail + + self.debug("Creating account 1") + account_1 = Account.create( + self.apiclient, + self.services["account"], + domainid=self.domain.id + ) + self.debug("create account %s" % account_1.name) + + self.cleanup.append(account_1) + + self.debug("setting network limit of account: %s as 1" % account_1.name) + + update_resource_limit( + self.apiclient, + 6, # Network + max=1, + account=account_1.name, + domainid=account_1.domainid + ) + + self.debug("Creating isolated network in account: %s" % account_1.name) + + network_1 = Network.create(self.api_client,self.services["isolated_network"],account_1.name, + account_1.domainid,networkofferingid=self.isolated_network_offering.id) + + self.debug("created network %s" % network_1.name) + + self.debug("Deploying virtual machine in account: %s" % account_1.name) + + virtual_machine = VirtualMachine.create(self.apiclient, self.services["virtual_machine"],accountid=account_1.name, + domainid=account_1.domainid, serviceofferingid=self.service_offering.id, + mode=self.zone.networktype) + + self.debug("Deployed virtual machine : %s" % virtual_machine.id) + + self.debug("Creating another account") + + account_2 = Account.create( + self.apiclient, + self.services["account"], + domainid=self.domain.id + ) + + self.debug("Created account %s" % account_2.name) + + self.cleanup.append(account_2) + + self.debug("Creating network in account %s" % account_2.name) + network_2 = Network.create(self.api_client,self.services["isolated_network"],account_2.name, + account_2.domainid,networkofferingid=self.isolated_network_offering.id) + + self.debug("Created network %s" % network_2.name) + + self.debug("Trying to add netwrok %s to VM %s, this should fail" % + (network_2.name, virtual_machine.id)) + + with self.assertRaises(Exception) as e: + virtual_machine.add_nic(self.apiclient, network_2.id) + self.debug("Operation failed with exception %s" % e.exception) + + return + +class TestRemoveNetworkFromVirtualMachine(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super(TestRemoveNetworkFromVirtualMachine, cls).getClsTestClient().getApiClient() + + hypervisor = get_hypervisor_type(cls.api_client) + if hypervisor.lower() not in ["xenserver","kvm"]: + raise unittest.SkipTest("This feature is supported only on XenServer and KVM") + + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + + template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"]) + # Set Zones and disk offerings + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = template.id + + # Create Accounts & networks + cls.services["isolated_network"]["zoneid"] = cls.zone.id + cls.services["shared_network"]["zoneid"] = cls.zone.id + + cls.account = Account.create(cls.api_client,cls.services["account"],domainid = cls.domain.id) + + cls.service_offering = ServiceOffering.create(cls.api_client,cls.services["service_offering"]) + + cls.virtual_machine = VirtualMachine.create(cls.api_client,cls.services["virtual_machine"],accountid=cls.account.name, + domainid=cls.account.domainid,serviceofferingid=cls.service_offering.id, + mode=cls.zone.networktype) + # Create Shared Network Offering + cls.isolated_network_offering = NetworkOffering.create(cls.api_client,cls.services["isolated_network_offering"]) + # Enable Isolated Network offering + cls.isolated_network_offering.update(cls.api_client, state='Enabled') + cls.isolated_network = Network.create(cls.api_client,cls.services["isolated_network"],cls.account.name, + cls.account.domainid,networkofferingid=cls.isolated_network_offering.id) + + cls._cleanup = [cls.account,cls.service_offering,cls.isolated_network_offering,] + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + + def tearDown(self): + try: + #Clean up, terminate the created accounts, domains etc + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @classmethod + def tearDownClass(cls): + try: + # Disable Network Offerings + cls.isolated_network_offering.update(cls.api_client, state='Disabled') + # Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def addNetworkToVm(self, network, vm): + """Add network to VM and check if new nic added in the VM""" + + self.debug("Adding %s Network: %s to virtual machine %s" % + (network.type, network.id, vm.id)) + vm.add_nic(self.apiclient, network.id) + vm_list = list_virtual_machines(self.apiclient, id=vm.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + self.debug("virtual machine nics: %s" % vm_list[0].nic) + # Add nic of network to list so that it can be deleted later accessing its id from this list + self.nics = [x for x in vm_list[0].nic if x.networkid == network.id] + self.debug("Filtered nics list: %s:" % self.nics) + self.assertTrue(len(self.nics) == 1, "nics list should contain the nic of added isolated network,\ + the number of nics for the network should be 1, instead they are %s" % + len(self.nics)) + return + + @attr(tags = ["advanced"]) + def test_07_remove_nic_running_vm(self): + """Remove nic from running VM""" + + # 1. Deploy Vm in account + # 2. Add network to VM + # 3. Remove the nic added by the newly added network + + # Validate the following: + # 1. Newly added nic is removed + # 2. Event NIC.DELETE is generated + + self.addNetworkToVm(self.isolated_network, self.virtual_machine) + # Access the nic of the added network from self.nics object which is fillled + # in addNetworkToVm function + self.debug("Removing added nic %s from vm %s" % + (self.nics[0].id, self.virtual_machine.id)) + self.virtual_machine.remove_nic(self.apiclient, self.nics[0].id) + vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + self.debug("virtual machine nics: %s" % vm_list[0].nic) + # Verify the nic is removed from the virtual machine + self.debug("Verifying the nic is removed from the virtual machine") + self.assertFalse(any(x.networkid == self.isolated_network.id for x in vm_list[0].nic), + "nic still present in the virtual machine nic list") + self.debug("nic removed successfully") + self.debug("Retrieving events list matching events 'NIC.DELETE'") + events = list_events( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid, + type='NIC.DELETE' + ) + event_list_validation_result = validateList(events) + self.assertEqual(event_list_validation_result[0], PASS, "vm list validation failed due to %s" % + event_list_validation_result[2]) + self.debug("Events list contains event NIC.DELETE") + self.debug("events: %s" % events) + return + + @attr(tags = ["advanced"]) + def test_08_remove_default_nic(self): + """Test Remove default nic of running VM""" + + # 1. Deploy Vm in account + # 2. Try to remove the default nic of the VM + + # Validate the following: + # 1. Default nic of vm is not removed + + vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + self.debug("virtual machine nics: %s" % vm_list[0].nic) + self.assertEqual(len(vm_list[0].nic), 1, "There should only be default nic present in the vm") + self.debug("Trying to remove the default nic of vm : %s, this should fail" % + self.virtual_machine.id) + with self.assertRaises(Exception): + self.virtual_machine.remove_nic(self.apiclient, vm_list[0].nic[0].id) + self.debug("Removing default nic of vm failed") + return + + @attr(tags = ["advanced"]) + def test_09_remove_foreign_nic(self): + """Remove nic which does not belong to VM""" + + # 1. Add VM in an account + # 1. Add new account and deploy vm in it + # 2. Try to remove nic of the new vm from first vm + + # Validate the following: + # 1. Nic remove operation should fail + + self.debug("Creating new account") + account = Account.create( + self.api_client, + self.services["account"], + domainid = self.domain.id + ) + self.cleanup.append(account) + self.debug("created new account : %s" % account.name) + self.debug("Deploying virtual machine in this account") + virtual_machine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"],accountid=account.name, + domainid=account.domainid,serviceofferingid=self.service_offering.id, + mode=self.zone.networktype) + self.debug("Deployed virtual machine: %s" % virtual_machine.id) + self.debug("Trying to remove nic of new virtual machine from existing virtual machine, This \ + operation should fail") + with self.assertRaises(Exception) as e: + self.virtual_machine.remove_nic(self.apiclient, virtual_machine.nic[0].id) + self.debug("Operation failed with exception: %s" % e.exception) + return + +class TestUpdateVirtualMachineNIC(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super(TestUpdateVirtualMachineNIC, cls).getClsTestClient().getApiClient() + + hypervisor = get_hypervisor_type(cls.api_client) + if hypervisor.lower() not in ["xenserver","kvm"]: + raise unittest.SkipTest("This feature is supported only on XenServer and KVM") + + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + + template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"]) + # Set Zones and disk offerings + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = template.id + + # Create Accounts & networks + cls.services["isolated_network"]["zoneid"] = cls.zone.id + cls.services["shared_network"]["zoneid"] = cls.zone.id + + cls.account = Account.create(cls.api_client,cls.services["account"],domainid = cls.domain.id) + + cls.service_offering = ServiceOffering.create(cls.api_client,cls.services["service_offering"]) + + cls.virtual_machine = VirtualMachine.create(cls.api_client,cls.services["virtual_machine"], + accountid=cls.account.name,domainid=cls.account.domainid, + serviceofferingid=cls.service_offering.id, + mode=cls.zone.networktype) + # Create Shared Network Offering + cls.isolated_network_offering = NetworkOffering.create(cls.api_client,cls.services["isolated_network_offering"],) + # Enable Isolated Network offering + cls.isolated_network_offering.update(cls.api_client, state='Enabled') + cls.isolated_network = Network.create(cls.api_client,cls.services["isolated_network"],cls.account.name, + cls.account.domainid,networkofferingid=cls.isolated_network_offering.id) + cls._cleanup = [cls.account,cls.service_offering,cls.isolated_network_offering,] + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + + def tearDown(self): + try: + #Clean up, terminate the created accounts, domains etc + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @classmethod + def tearDownClass(cls): + try: + # Disable Network Offerings + cls.isolated_network_offering.update(cls.api_client, state='Disabled') + # Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def addNetworkToVm(self, network, vm): + """Add network to VM and check if new nic added in the VM""" + + self.debug("Adding %s Network: %s to virtual machine %s" % + (network.type, network.id, vm.id)) + vm.add_nic(self.apiclient, network.id) + vm_list = list_virtual_machines(self.apiclient, id=vm.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + self.debug("virtual machine nics: %s" % vm_list[0].nic) + # Add nic of network to list so that it can be deleted later accessing its id from this list + self.nics = [x for x in vm_list[0].nic if x.networkid == network.id] + self.debug("Filtered nics list: %s:" % self.nics) + self.assertTrue(len(self.nics) == 1, "nics list should contain the nic of added isolated network,\ + the number of nics for the network should be 1, instead they are %s" % + len(self.nics)) + return + + @attr(tags = ["advanced"]) + def test_11_update_nic_running_vm(self): + """update default nic of running VM""" + + # 1. Deploy Vm in account + # 2. Add network to VM + # 3. Update default nic of VM (Make the newly added NIC as default) + + # Validate the following: + # 1. Default nic is updated + # 2. Previous default nic is now non-default + # 3. Event NIC.UPDATE is generated + + self.addNetworkToVm(self.isolated_network, self.virtual_machine) + self.debug("Listing virtual machine so that to retrive the list of non-default and default nic") + vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + if len(vm_list[0].nic) != 2: + self.fail("VM should have exactly two NICs") + + defaultNicIdBeforeUpdate = None + nonDefaultNicIdBeforeUpdate = None + + for nic in vm_list[0].nic: + if nic.isdefault: + defaultNicIdBeforeUpdate = nic.id + else: + nonDefaultNicIdBeforeUpdate = nic.id + + self.debug("Default nic of VM is %s and non default nic of VM is %s" + % (defaultNicIdBeforeUpdate, nonDefaultNicIdBeforeUpdate)) + + self.debug("Making non default nic as default nic") + self.virtual_machine.update_default_nic(self.apiclient, nicId = nonDefaultNicIdBeforeUpdate) + self.debug("Again listing the NIC list of VM to verify the update operation was successful") + vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + + if len(vm_list[0].nic) != 2: + self.fail("VM should have exactly two NICs") + + for nic in vm_list[0].nic: + if nic.isdefault: + defaultNicIdAfterUpdate = nic.id + + self.assertEqual(nonDefaultNicIdBeforeUpdate, defaultNicIdAfterUpdate, "old non default NIC not made\ + default one, update_default_nic API failed") + self.debug("Retrieving events list matching events 'NIC.UPDATE'") + events = list_events( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid, + type='NIC.UPDATE' + ) + event_list_validation_result = validateList(events) + self.assertEqual(event_list_validation_result[0], PASS, "event list validation failed due to %s" % + event_list_validation_result[2]) + self.debug("Events list contains event NIC.UPDATE") + self.debug("events: %s" % events) + return + + @attr(tags = ["advanced"]) + def test_12_make_default_nic_as_default(self): + """Try to set default nic of vm again as default""" + + # 1. Deploy Vm in account + # 2. Set default nic of vm again as default + + # Validate the following: + # 1. updateDefaultNic API fails + + self.debug("Listing virtual machine to get default nic") + vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + + defaultNicId = None + + for nic in vm_list[0].nic: + if nic.isdefault: + defaultNicId = nic.id + + self.debug("Trying to set default nic again as default nic, This should fail") + with self.assertRaises(Exception) as e: + self.virtual_machine.update_default_nic(self.apiclient, nicId = defaultNicId) + self.debug("updateDefaultNic operation failed as expected with exception: %s" % + e.exception) + + return + + @attr(tags = ["advanced"]) + def test_13_set_foreign_nic_as_default(self): + """set nic which does not belong to VM as its default one""" + + # 1. Add VM in an account + # 1. Add new account and deploy vm in it + # 2. Try to set nic of the new vm as default nic of first vm + + # Validate the following: + # 1. updateDefaultNic operation should fail + + self.debug("Creating new account") + + account = Account.create(self.api_client,self.services["account"],domainid = self.domain.id) + self.cleanup.append(account) + self.debug("created new account : %s" % account.name) + self.debug("Deploying virtual machine in this account") + virtual_machine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + accountid=account.name,domainid=account.domainid, + serviceofferingid=self.service_offering.id,mode=self.zone.networktype) + self.debug("Deployed virtual machine: %s" % virtual_machine.id) + + foreignNicId = virtual_machine.nic[0].id + + self.debug("Trying to set nic of new virtual machine as default nic of existing virtual machine, This \ + operation should fail") + with self.assertRaises(Exception) as e: + self.virtual_machine.update_default_nic(self.apiclient, nicId = foreignNicId) + self.debug("updateDefaultNic operation failed as expected with exception: %s" % + e.exception) + + return + +class TestFailureScenariosAddNetworkToVM(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super(TestFailureScenariosAddNetworkToVM, cls).getClsTestClient().getApiClient() + + hypervisor = get_hypervisor_type(cls.api_client) + if hypervisor.lower() not in ["xenserver","kvm"]: + raise unittest.SkipTest("This feature is supported only on XenServer and KVM") + + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"]) + # Set Zones and disk offerings + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = template.id + # Create Accounts & networks + cls.services["isolated_network"]["zoneid"] = cls.zone.id + cls.account = Account.create(cls.api_client,cls.services["account"],domainid = cls.domain.id) + cls.service_offering = ServiceOffering.create(cls.api_client,cls.services["service_offering"]) + + cls.virtual_machine = VirtualMachine.create(cls.api_client,cls.services["virtual_machine"], + accountid=cls.account.name,domainid=cls.account.domainid, + serviceofferingid=cls.service_offering.id,mode=cls.zone.networktype) + # Create Shared Network Offering + cls.isolated_network_offering = NetworkOffering.create(cls.api_client,cls.services["isolated_network_offering"],) + # Enable Isolated Network offering + cls.isolated_network_offering.update(cls.api_client, state='Enabled') + + cls.isolated_network = Network.create(cls.api_client,cls.services["isolated_network"],cls.account.name, + cls.account.domainid,networkofferingid=cls.isolated_network_offering.id) + + cls._cleanup = [cls.account,cls.service_offering,cls.isolated_network_offering,] + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + + def tearDown(self): + try: + #Clean up, terminate the created accounts, domains etc + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @classmethod + def tearDownClass(cls): + try: + # Disable Network Offerings + cls.isolated_network_offering.update(cls.api_client, state='Disabled') + # Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @attr(tags = ["advanced"]) + def test_15_add_nic_wrong_vm_id(self): + """Add network to vm with wrong vm id""" + + # 1. Call add network to VM API with correct network id but wrong vm id + + # Validate the following: + # 1. API should throw exception saying unable to find virtual machine + + cmd = addNicToVirtualMachine.addNicToVirtualMachineCmd() + cmd.virtualmachineid = random_gen(id="virtual_machine", size=30) + cmd.networkid = self.isolated_network.id + + with self.assertRaises(Exception) as e: + self.apiclient.addNicToVirtualMachine(cmd) + self.debug("addNicToVirtualMachine API failed with exception: %s" % e.exception) + + return + + @attr(tags = ["advanced"]) + def test_16_add_nic_wrong_network_id(self): + """Add network to vm with wrong network id""" + + # 1. Call add network to VM API with correct network id but wrong network id + + # Validate the following: + # 1. API should throw exception saying unable to find a network + + cmd = addNicToVirtualMachine.addNicToVirtualMachineCmd() + cmd.virtualmachineid = self.virtual_machine.id + cmd.networkid = random_gen(id="network_id", size=30) + + with self.assertRaises(Exception) as e: + self.apiclient.addNicToVirtualMachine(cmd) + self.debug("addNicToVirtualMachine API failed with exception: %s" % e.exception) + + return + + @attr(tags = ["advanced"]) + def test_17_add_nic_different_zone(self): + """Add network to vm where both belong to different zones""" + + # 1. Deploy a VM in zone 1 + # 2. Create a network in zone 2 + # 3. Try to add this network to the VM (both belong to different zones) + + # Validate the following: + # 1. API should throw exception vminstance is in zone, but network is in zone + + foreignZoneId = None + + zones = list_zones(self.apiclient, available=True) + list_zones_validation_result = validateList(zones) + self.assertEqual(list_zones_validation_result[0], PASS, "list zones validation failed due to: %s" % + list_zones_validation_result[2]) + if len(zones) >= 2: + for zone in zones: + if zone.id != self.zone.id: + foreignZoneId = zone.id + break + else: + self.skipTest("This test requires at least two zones to be present in the setup") + + self.services["isolated_network"]["zoneid"] = foreignZoneId + + self.debug("Creating isolated network in zone %s which is foreign to VM" % + foreignZoneId) + isolated_network = Network.create(self.apiclient,self.services["isolated_network"], + networkofferingid=self.isolated_network_offering.id) + self.debug("Created isolated network %s in zone %s" % + (isolated_network.id, foreignZoneId)) + self.cleanup.append(isolated_network) + + self.debug("Trying to add network to VM, both belonging to different zones") + cmd = addNicToVirtualMachine.addNicToVirtualMachineCmd() + cmd.virtualmachineid = self.virtual_machine.id + cmd.networkid = isolated_network.id + + with self.assertRaises(Exception) as e: + self.apiclient.addNicToVirtualMachine(cmd) + self.debug("addNicToVirtualMachine API failed with exception: %s" % e.exception) + + return + + @attr(tags = ["basic"]) + def test_18_add_nic_basic_zone(self): + """Add network to vm in basic zone""" + + # 1. Deploy a vm and create network in basic zone + # 2. Try adding network to vm + + # Validate following + # 1. API should throw exception saying Can't add a new nic to vm in basic network + + basicZone = None + + zones = list_zones(self.apiclient, available=True) + list_zones_validation_result = validateList(zones) + self.assertEqual(list_zones_validation_result[0], PASS, "list zones validation failed due to: %s" % + list_zones_validation_result[2]) + for zone in zones: + if zone.networktype.lower() == 'BASIC': + basicZone = zone.id + break + if basicZone is None: + self.skipTest("This test requires at least one basic zone to be present in the setup") + self.services["isolated_network"]["zoneid"] = basicZone.id + self.debug("Creating isolated network in basic zone: %s" % basicZone.id) + isolated_network = Network.create(self.apiclient,self.services["isolated_network"], + networkofferingid=self.isolated_network_offering.id) + + self.debug("Created isolated network %s:" % isolated_network.id) + self.cleanup.append(isolated_network) + + self.services["virtual_machine"]["zoneid"] = basicZone.id + + self.debug("Deploying virtual machine in basic zone: %s" % basicZone.id) + virtual_machine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + serviceofferingid=self.service_offering.id, + mode=basicZone.networktype) + self.debug("Deployed virtual machine %s: " % virtual_machine.id) + + cmd = addNicToVirtualMachine.addNicToVirtualMachineCmd() + cmd.virtualmachineid = virtual_machine.id + cmd.networkid = isolated_network.id + + self.dedbug("Trying to add isolated network to VM (both in basic zone,\ + this operation should fail") + with self.assertRaises(Exception) as e: + self.apiclient.addNicToVirtualMachine(cmd) + self.debug("addNicToVirtualMachine API failed with exception: %s" % e.exception) + + return + + @attr(tags = ["advanced"]) + def test_26_add_nic_insufficient_permission(self): + """Try to add network to vm with insufficient permission""" + + # 1. Call add network to VM API with api client of other account + + # Validate the following: + # 1. API should throw exception saying insufficient permission + + cmd = addNicToVirtualMachine.addNicToVirtualMachineCmd() + cmd.virtualmachineid = self.virtual_machine.id + cmd.networkid = self.isolated_network.id + + self.debug("Creating new account") + + account = Account.create(self.apiclient,self.services["account"],domainid = self.domain.id) + self.cleanup.append(account) + + self.debug("Created account %s" % account.name) + + self.debug("creating user api client for account: %s" % account.name) + api_client = self.testClient.createUserApiClient(UserName=account.name, DomainName=self.account.domain) + + self.debug("Trying to add network to vm with this api client, this should fail due to \ + insufficient permission") + + with self.assertRaises(Exception) as e: + api_client.addNicToVirtualMachine(cmd) + self.debug("addNicToVirtualMachine API failed with exception: %s" % e.exception) + + return + +class TestFailureScenariosRemoveNicFromVM(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super(TestFailureScenariosRemoveNicFromVM, cls).getClsTestClient().getApiClient() + + hypervisor = get_hypervisor_type(cls.api_client) + if hypervisor.lower() not in ["xenserver","kvm"]: + raise unittest.SkipTest("This feature is supported only on XenServer and KVM") + + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + + template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"]) + # Set Zones and disk offerings + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = template.id + + # Create Accounts & networks + cls.services["isolated_network"]["zoneid"] = cls.zone.id + cls.services["shared_network"]["zoneid"] = cls.zone.id + + cls.account = Account.create(cls.api_client,cls.services["account"],domainid = cls.domain.id) + cls.service_offering = ServiceOffering.create(cls.api_client,cls.services["service_offering"]) + cls.virtual_machine = VirtualMachine.create(cls.api_client,cls.services["virtual_machine"], + accountid=cls.account.name,domainid=cls.account.domainid, + serviceofferingid=cls.service_offering.id, + mode=cls.zone.networktype) + + # Create Shared Network Offering + cls.isolated_network_offering = NetworkOffering.create(cls.api_client, cls.services["isolated_network_offering"],) + # Enable Isolated Network offering + cls.isolated_network_offering.update(cls.api_client, state='Enabled') + cls.isolated_network = Network.create(cls.api_client,cls.services["isolated_network"],cls.account.name, + cls.account.domainid,networkofferingid=cls.isolated_network_offering.id) + + # Add network to VM + cls.virtual_machine.add_nic(cls.api_client, cls.isolated_network.id) + + cls._cleanup = [cls.account,cls.service_offering,cls.isolated_network_offering,] + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + + def tearDown(self): + try: + #Clean up, terminate the created accounts, domains etc + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @classmethod + def tearDownClass(cls): + try: + # Disable Network Offerings + #cls.isolated_network_offering.update(cls.api_client, state='Disabled') + # Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @attr(tags = ["advanced"]) + def test_19_remove_nic_wrong_vm_id(self): + """Try to remove nic from a vm providing wrong vm id to API""" + + # (Frist two steps are perfromed in setupClass) + # 1. Deploy Vm in account + # 2. Add network to VM + # 3. Remove the nic added by the newly added network providing wrong vm id to the API + + # Validate the following: + # 1. API throws exception unable to find a virtual machine with id + + vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + vm = vm_list_validation_result[1] + + nics = [x for x in vm.nic if x.networkid == self.isolated_network.id] + + self.assertEqual(len(nics), 1 , "There should be exactly one nic corresponding to the isolate\ + network %s" % self.isolated_network.id) + + cmd = removeNicFromVirtualMachine.removeNicFromVirtualMachineCmd() + cmd.virtualmachineid = self.virtual_machine.id + random_gen() + cmd.nicid = nics[0].id + + with self.assertRaises(Exception) as e: + self.apiclient.removeNicFromVirtualMachine(cmd) + self.debug("removeNicFromVirtualMachine API failed with exception: %s" % e.exception) + + return + + @attr(tags = ["advanced"]) + def test_20_remove_nic_wrong_nic_id(self): + """Try to remove nic from a vm providing wrong nic id to API""" + + # (Frist two steps are perfromed in setupClass) + # 1. Deploy Vm in account + # 2. Add network to VM + # 3. Remove the nic added by the newly added network providing wrong nic id to the API + + # Validate the following: + # 1. API throws exception unable to find nic with id + + vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + vm = vm_list_validation_result[1] + + nics = [x for x in vm.nic if x.networkid == self.isolated_network.id] + + self.assertEqual(len(nics), 1 , "There should be exactly one nic corresponding to the isolate\ + network %s" % self.isolated_network.id) + + cmd = removeNicFromVirtualMachine.removeNicFromVirtualMachineCmd() + cmd.virtualmachineid = self.virtual_machine.id + cmd.nicid = nics[0].id + random_gen() + + with self.assertRaises(Exception) as e: + self.apiclient.removeNicFromVirtualMachine(cmd) + self.debug("removeNicFromVirtualMachine API failed with exception: %s" % e.exception) + + return + + @attr(tags = ["advanced"]) + def test_27_remove_nic_insufficient_permission(self): + """Try to remove nic from vm with insufficient permission""" + + # 1. Call remove network from VM API with api client of other account + + # Validate the following: + # 1. API should throw exception saying insufficient permission + + vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + vm = vm_list_validation_result[1] + + nics = [x for x in vm.nic if x.networkid == self.isolated_network.id] + + self.assertEqual(len(nics), 1 , "There should be exactly one nic corresponding to the isolate\ + network %s" % self.isolated_network.id) + + cmd = removeNicFromVirtualMachine.removeNicFromVirtualMachineCmd() + cmd.virtualmachineid = self.virtual_machine.id + cmd.nicid = nics[0].id + + self.debug("Creating new account") + + account = Account.create(self.apiclient,self.services["account"],domainid = self.domain.id) + self.cleanup.append(account) + + self.debug("Created account %s" % account.name) + + self.debug("creating user api client for account: %s" % account.name) + api_client = self.testClient.createUserApiClient(UserName=account.name, DomainName=self.account.domain) + + self.debug("Trying to add network to vm with this api client, this should fail due to \ + insufficient permission") + + with self.assertRaises(Exception) as e: + api_client.removeNicFromVirtualMachine(cmd) + self.debug("removeNicFromVirtualMachine API failed with exception: %s" % e.exception) + + return + +class TestFailureScenariosUpdateVirtualMachineNIC(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super(TestFailureScenariosUpdateVirtualMachineNIC, cls).getClsTestClient().getApiClient() + + hypervisor = get_hypervisor_type(cls.api_client) + if hypervisor.lower() not in ["xenserver","kvm"]: + raise unittest.SkipTest("This feature is supported only on XenServer and KVM") + + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + + template = get_template(cls.api_client, cls.zone.id, cls.services["ostype"]) + # Set Zones and disk offerings + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = template.id + + # Create Accounts & networks + cls.services["isolated_network"]["zoneid"] = cls.zone.id + cls.services["shared_network"]["zoneid"] = cls.zone.id + + cls.account = Account.create(cls.api_client, cls.services["account"], domainid = cls.domain.id) + + cls.service_offering = ServiceOffering.create(cls.api_client, cls.services["service_offering"]) + + cls.virtual_machine = VirtualMachine.create(cls.api_client,cls.services["virtual_machine"], + accountid=cls.account.name,domainid=cls.account.domainid, + serviceofferingid=cls.service_offering.id,mode=cls.zone.networktype) + + cls.defaultNetworkId = cls.virtual_machine.nic[0].networkid + + # Create Shared Network Offering + cls.isolated_network_offering = NetworkOffering.create(cls.api_client, cls.services["isolated_network_offering"],) + # Enable Isolated Network offering + cls.isolated_network_offering.update(cls.api_client, state='Enabled') + + cls.isolated_network = Network.create(cls.api_client,cls.services["isolated_network"], + cls.account.name,cls.account.domainid, + networkofferingid=cls.isolated_network_offering.id) + cls.virtual_machine.add_nic(cls.api_client, cls.isolated_network.id) + cls._cleanup = [cls.account,cls.service_offering, + cls.isolated_network_offering,] + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + + def tearDown(self): + try: + #Clean up, terminate the created accounts, domains etc + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @classmethod + def tearDownClass(cls): + try: + # Disable Network Offerings + cls.isolated_network_offering.update(cls.api_client, state='Disabled') + # Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @attr(tags = ["advanced"]) + def test_21_update_nic_wrong_vm_id(self): + """update default nic of vm providing wrong vm id to the API""" + + # (First two steps are performed in setupClass) + # 1. Deploy Vm in account + # 2. Add network to VM + # 3. Update default nic of VM (Make the newly added NIC as default) by providing wrong + # vm id to the API + + # Validate the following: + # 1. API throws exception saying can't find the virtual machine + + self.debug("Listing virtual machine so that to retrive the list of non-default and default nic") + vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + if len(vm_list[0].nic) != 2: + self.fail("VM should have exactly two NICs") + + defaultNicIdBeforeUpdate = None + nonDefaultNicIdBeforeUpdate = None + + for nic in vm_list[0].nic: + if nic.isdefault: + defaultNicIdBeforeUpdate = nic.id + else: + nonDefaultNicIdBeforeUpdate = nic.id + + self.debug("Default nic of VM is %s and non default nic of VM is %s" + % (defaultNicIdBeforeUpdate, nonDefaultNicIdBeforeUpdate)) + self.debug("Making non default nic as default nic") + + cmd = updateDefaultNicForVirtualMachine.updateDefaultNicForVirtualMachineCmd() + cmd.virtualmachineid = self.virtual_machine.id + random_gen() + cmd.nicid = nonDefaultNicIdBeforeUpdate + + with self.assertRaises(Exception) as e: + self.apiclient.updateDefaultNicForVirtualMachine(cmd) + self.debug("updateDefaultNicForVirtualMachine API failed with exception: %s" % + e.exception) + + return + + @attr(tags = ["advanced"]) + def test_22_update_nic_wrong_nic_id(self): + """update default nic of vm providing wrong nic id to the API""" + + # (First two steps are performed in setupClass) + # 1. Deploy Vm in account + # 2. Add network to VM + # 3. Update default nic of VM (Make the newly added NIC as default) by providing wrong + # nic id to the API + + # Validate the following: + # 1. API throws exception saying can't find the nic with id + + self.debug("Listing virtual machine so that to retrive the list of non-default and default nic") + vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + + if len(vm_list[0].nic) != 2: + self.fail("VM should have exactly two NICs") + + defaultNicIdBeforeUpdate = None + nonDefaultNicIdBeforeUpdate = None + + for nic in vm_list[0].nic: + if nic.isdefault: + defaultNicIdBeforeUpdate = nic.id + else: + nonDefaultNicIdBeforeUpdate = nic.id + + self.debug("Default nic of VM is %s and non default nic of VM is %s" + % (defaultNicIdBeforeUpdate, nonDefaultNicIdBeforeUpdate)) + self.debug("Making non default nic as default nic") + + cmd = updateDefaultNicForVirtualMachine.updateDefaultNicForVirtualMachineCmd() + cmd.virtualmachineid = self.virtual_machine.id + cmd.nicid = nonDefaultNicIdBeforeUpdate + random_gen() + + with self.assertRaises(Exception) as e: + self.apiclient.updateDefaultNicForVirtualMachine(cmd) + self.debug("updateDefaultNicForVirtualMachine API failed with exception: %s" % + e.exception) + + return + + @attr(tags = ["advanced"]) + def test_23_update_nic_incorrect_vm_state(self): + """update default nic of vm when vm is state is not Running or Stopped""" + + # (First two steps are performed in setupClass) + # 1. Deploy Vm in account + # 2. Add network to VM + # 3. Destroy virtual machine so that the VM state becomes Destroyed or Expunging + # 4. Update default nic of VM (Make the newly added NIC as default) + + # Validate the following: + # 1. API throws exception instance is not Running or Stopped + + self.debug("Creating new account") + account = Account.create(self.apiclient,self.services["account"],domainid = self.domain.id) + self.debug("Created account %s" % account.name) + + self.cleanup.append(account) + + self.debug("Creating virtual machine in the account %s" % account.name) + virtual_machine = VirtualMachine.create(self.api_client, self.services["virtual_machine"], + accountid=account.name,domainid=account.domainid, + serviceofferingid=self.service_offering.id, + mode=self.zone.networktype) + + self.debug("Created virtual machine %s" % virtual_machine.id) + + self.debug("Creating isolated network in account %s" % account.name) + isolated_network = Network.create(self.apiclient,self.services["isolated_network"],account.name, + account.domainid,networkofferingid=self.isolated_network_offering.id) + + self.debug("Created isolated network %s" % isolated_network.id) + + self.debug("Adding isolated network %s to vm %s" % (isolated_network.id, virtual_machine.id)) + virtual_machine.add_nic(self.apiclient, isolated_network.id) + + self.debug("Listing virtual machine so that to retrive the list of non-default and default nic") + vm_list = list_virtual_machines(self.apiclient, id=virtual_machine.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + + if len(vm_list[0].nic) != 2: + self.fail("VM should have exactly two NICs") + + defaultNicIdBeforeUpdate = None + nonDefaultNicIdBeforeUpdate = None + + for nic in vm_list[0].nic: + if nic.isdefault: + defaultNicIdBeforeUpdate = nic.id + else: + nonDefaultNicIdBeforeUpdate = nic.id + + self.debug("Default nic of VM is %s and non default nic of VM is %s" + % (defaultNicIdBeforeUpdate, nonDefaultNicIdBeforeUpdate)) + self.debug("Destroying VM %s" % virtual_machine.id) + virtual_machine.delete(self.apiclient) + vm_list = list_virtual_machines(self.apiclient, id=virtual_machine.id) + vm_list_validation_result = validateList(vm_list) + + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + vm = vm_list_validation_result[1] + vm_state = vm.state.lower() + self.debug("VM state is: %s" % vm_state) + if vm_state in ["running", "stopped"]: + self.fail("failed to destroy the instance: %s" % vm.id) + + self.debug("Making non default nic as default nic") + + cmd = updateDefaultNicForVirtualMachine.updateDefaultNicForVirtualMachineCmd() + cmd.virtualmachineid = vm.id + cmd.nicid = nonDefaultNicIdBeforeUpdate + + with self.assertRaises(Exception) as e: + self.apiclient.updateDefaultNicForVirtualMachine(cmd) + self.debug("updateDefaultNicForVirtualMachine API failed with exception: %s" % + e.exception) + + return + + @attr(tags = ["advanced"]) + def test_28_update_nic_insufficient_permission(self): + """Try to update default nic of vm with insufficient permission""" + + # 1. Call update nic of VM API with api client of other account + + # Validate the following: + # 1. API should throw exception saying insufficient permission + + account = Account.create(self.apiclient,self.services["account"],domainid = self.domain.id) + self.cleanup.append(account) + + self.debug("Created account %s" % account.name) + + self.debug("creating user api client for account: %s" % account.name) + api_client = self.testClient.createUserApiClient(UserName=account.name, DomainName=self.account.domain) + + self.debug("Listing virtual machine so that to retrive the list of non-default and default nic") + vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % + vm_list_validation_result[2]) + + if len(vm_list[0].nic) != 2: + self.fail("VM should have exactly two NICs") + + defaultNicIdBeforeUpdate = None + nonDefaultNicIdBeforeUpdate = None + + for nic in vm_list[0].nic: + if nic.isdefault: + defaultNicIdBeforeUpdate = nic.id + else: + nonDefaultNicIdBeforeUpdate = nic.id + + self.debug("Default nic of VM is %s and non default nic of VM is %s" + % (defaultNicIdBeforeUpdate, nonDefaultNicIdBeforeUpdate)) + self.debug("Making non default nic as default nic") + + cmd = updateDefaultNicForVirtualMachine.updateDefaultNicForVirtualMachineCmd() + cmd.virtualmachineid = self.virtual_machine.id + cmd.nicid = nonDefaultNicIdBeforeUpdate + + with self.assertRaises(Exception) as e: + api_client.updateDefaultNicForVirtualMachine(cmd) + self.debug("updateDefaultNicForVirtualMachine API failed with exception: %s" % + e.exception) + + return From 0be4a685e8cb0caedf670e45075f1b4e52237f5c Mon Sep 17 00:00:00 2001 From: Jayapal Date: Mon, 25 Nov 2013 14:58:12 +0530 Subject: [PATCH 012/170] CLOUDSTACK-5164 Unmonit for 30 minutes for a failed process --- .../config/opt/cloud/bin/monitor_service.sh | 2 +- .../debian/config/root/monitorServices.py | 203 ++++++++++++++---- 2 files changed, 163 insertions(+), 42 deletions(-) diff --git a/systemvm/patches/debian/config/opt/cloud/bin/monitor_service.sh b/systemvm/patches/debian/config/opt/cloud/bin/monitor_service.sh index c4d99d2207e..51b69235318 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/monitor_service.sh +++ b/systemvm/patches/debian/config/opt/cloud/bin/monitor_service.sh @@ -64,7 +64,7 @@ crontab -l | grep -v monitorServices.py | crontab - create_config $config #add cron job -(crontab -l ;echo -e "SHELL=/bin/bash\nPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin\n */1 * * * * /usr/bin/python /root/monitorServices.py") | crontab - +(crontab -l ;echo -e "SHELL=/bin/bash\nPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin\n */3 * * * * /usr/bin/python /root/monitorServices.py") | crontab - unlock_exit 0 $lock $locked diff --git a/systemvm/patches/debian/config/root/monitorServices.py b/systemvm/patches/debian/config/root/monitorServices.py index 2cec672f0ce..4e1b7e09716 100755 --- a/systemvm/patches/debian/config/root/monitorServices.py +++ b/systemvm/patches/debian/config/root/monitorServices.py @@ -19,14 +19,13 @@ -__author__ = 'jayapalreddy' from ConfigParser import SafeConfigParser from subprocess import * from os import path import time +import os -monitor_log='/var/log/monitor.log' class StatusCodes: SUCCESS = 0 FAILED = 1 @@ -35,42 +34,58 @@ class StatusCodes: STOPPED = 4 STARTING = 5 -class log: +class Log: INFO = 'INFO' ALERT = 'ALERT' CRIT = 'CRIT' NOTIF = 'NOTIF' - +class Config: + MONIT_AFTER_MINS = 30 + SLEEP_SEC = 1 + RETRY_ITERATIONS = 10 + RETRY_FOR_RESTART = 5 + MONITOR_LOG = '/var/log/monitor.log' + UNMONIT_PS_FILE = '/etc/unmonit_psList.txt' def getConfig( config_file_path = "/etc/monitor.conf" ): + """ + Reads the process configuration from the config file. + Config file contains the processes to be monitored. + + """ process_dict = {} parser = SafeConfigParser() parser.read( config_file_path ) - #print 'Read values:\n' for section in parser.sections(): - # print section process_dict[section] = {} for name, value in parser.items(section): process_dict[section][name] = value -# print ' %s = %r' % (name, value) +# printd (" %s = %r" % (name, value)) return process_dict def printd (msg): + """ + prints the debug messages + """ + #for debug + #print msg return 0 - f= open(monitor_log,'r+') + f= open(Config.MONITOR_LOG,'r+') f.seek(0, 2) f.write(str(msg)+"\n") f.close() def raisealert(severity, msg, process_name=None): + """ Writes the alert message""" + #timeStr=str(time.ctime()) if process_name is not None: log = '['+severity +']'+" " + '['+process_name+']' + " " + msg +"\n" @@ -82,9 +97,12 @@ def raisealert(severity, msg, process_name=None): def isPidMatchPidFile(pidfile, pids): + """ Compares the running process pid with the pid in pid file. + If a process with multiple pids then it matches with pid file + """ if pids is None or isinstance(pids,list) != True or len(pids) == 0: - print "Invalid Arguments" + printd ("Invalid Arguments") return StatusCodes.FAILED if not path.isfile(pidfile): #It seems there is no pid file for this service @@ -100,12 +118,18 @@ def isPidMatchPidFile(pidfile, pids): inp = fd.read() + + if not inp: + fd.close() + return StatusCodes.FAILED + printd("file content "+str(inp)) printd(pids) tocheck_pid = inp.strip() for item in pids: if str(tocheck_pid) == item.strip(): printd("pid file matched") + fd.close() return StatusCodes.SUCCESS fd.close() @@ -114,19 +138,22 @@ def isPidMatchPidFile(pidfile, pids): def checkProcessStatus( process ): + """ + Check the process running status, if not running tries to restart + """ process_name = process.get('processname') service_name = process.get('servicename') pidfile = process.get('pidfile') #temp_out = None restartFailed=False - pidFileMatched=1 + pidFileMatched=False + pids='' cmd='' if process_name is None: - print "\n Invalid Process Name" + printd ("\n Invalid Process Name") return StatusCodes.INVALID_INP else: - msg="checking the process " + process_name - printd(msg) + printd("checking the process " + process_name) cmd = 'pidof ' + process_name printd(cmd) #cmd = 'service ' + process_name + ' status' @@ -136,20 +163,19 @@ def checkProcessStatus( process ): #check there is only one pid or not if exitStatus == 0: + pids = temp_out.split(' ') msg="pids: " +temp_out; printd(msg) - pids = temp_out.split(' ') #there is more than one process so match the pid file - #if not matched set pidFileMatched=0 + #if not matched set pidFileMatched=False printd("Checking pid file") if isPidMatchPidFile(pidfile, pids) == StatusCodes.SUCCESS: - pidFileMatched = 1; + pidFileMatched = True; else: - pidFileMatched = 0; + pidFileMatched = False; - printd(pidFileMatched) - if exitStatus == 0 and pidFileMatched == 1: + if exitStatus == 0 and pidFileMatched == True: printd("The process is running ....") return StatusCodes.RUNNING else: @@ -157,28 +183,28 @@ def checkProcessStatus( process ): msg="The process " + process_name +" is not running trying recover " printd(msg) #Retry the process state for few seconds - for i in range(1,10): + for i in range(1, Config.RETRY_ITERATIONS): pout = Popen(cmd, shell=True, stdout=PIPE) exitStatus = pout.wait() temp_out = pout.communicate()[0] - if i < 5: # this is just for trying few more times + if i < Config.RETRY_FOR_RESTART: # this is just for trying few more times if exitStatus == 0: pids = temp_out.split(' ') if isPidMatchPidFile(pidfile, pids) == StatusCodes.SUCCESS: - pidFileMatched = 1; + pidFileMatched = True; printd("pid file is matched ...") - raisealert(log.ALERT, "The process detected as running", process_name) + raisealert(Log.ALERT, "The process detected as running", process_name) break else: printd("pid file is not matched ...") - pidFileMatched = 0; + pidFileMatched = False; + time.sleep(Config.SLEEP_SEC) continue - time.sleep(1) else: msg="The process " +process_name+" is not running trying recover " - raisealert(log.INFO,process_name,msg) + raisealert(Log.INFO,process_name,msg) if service_name == 'apache2': # Killing apache2 process with this the main service will not start @@ -189,7 +215,7 @@ def checkProcessStatus( process ): cmd = 'service ' + service_name + ' restart' - time.sleep(1) + time.sleep(Config.SLEEP_SEC) #return_val= check_call(cmd , shell=True) cout = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT) @@ -198,37 +224,135 @@ def checkProcessStatus( process ): if return_val == 0: printd("The process" + process_name +" recovered successfully ") msg="The process " +process_name+" is recovered successfully " - raisealert(log.INFO,msg,process_name) + raisealert(Log.INFO,msg,process_name) break; else: #retry restarting the process for few tries printd("process restart failing trying again ....") restartFailed=True - time.sleep(1) + time.sleep(Config.SLEEP_SEC) continue #for end here if restartFailed == True: msg="The process %s recover failed "%process_name - raisealert(log.ALERT,process_name,msg) + raisealert(Log.ALERT,process_name,msg) printd("Restart failed after number of retries") return StatusCodes.STOPPED return StatusCodes.RUNNING -def raiseAlert( process_name ): - print "process name %s is raised "%process_name def monitProcess( processes_info ): + """ + Monitors the processes which got from the config file + """ if len( processes_info ) == 0: - print "Invalid Input" + printd("Invalid Input") return StatusCodes.INVALID_INP - for process,properties in processes_info.items(): - if checkProcessStatus( properties) != StatusCodes.RUNNING: - print "\n Process %s is not Running"%process + dict_unmonit={} + umonit_update={} + + if not path.isfile(Config.UNMONIT_PS_FILE): + printd('Unmonit File not exist') + else: + #load the dictionary with unmonit process list + dict_unmonit = loadPsFromUnMonitFile() + + #time for noting process down time + csec = repr(time.time()).split('.')[0] + + unMonitPs=False + + for process,properties in processes_info.items(): + #skip the process it its time stamp less than Config.MONIT_AFTER_MINS + printd ("checking the process %s \n" %process) + + if not is_emtpy(dict_unmonit): + if dict_unmonit.has_key(process): + ts = dict_unmonit[process] + printd("Time difference=%s" %str(int(csec) - int(ts))) + tmin = (int(csec) - int(ts) )/60 + + if ( int(csec) - int(ts) )/60 < Config.MONIT_AFTER_MINS: + raisealert(Log.ALERT, "The %s get monitor after %s minutes " %(process, Config.MONIT_AFTER_MINS)) + printd('process will be monitored after %s min' %(str(int(Config.MONIT_AFTER_MINS) - tmin))) + unMonitPs=True + continue + + if checkProcessStatus( properties) != StatusCodes.RUNNING: + printd( "\n Process %s is not Running"%process) + #add this process into unmonit list + printd ("updating the process for unmonit %s\n" %process) + umonit_update[process]=csec + + + #if dict is not empty write to file else delete it + if not is_emtpy(umonit_update): + writePsListToUnmonitFile(umonit_update) + else: + if is_emtpy(umonit_update) and unMonitPs == False: + #delete file it is there + if path.isfile(Config.UNMONIT_PS_FILE): + printd("Removing the file %s" %Config.UNMONIT_PS_FILE) + os.remove(Config.UNMONIT_PS_FILE) + + + +def loadPsFromUnMonitFile(): + + dict_unmonit = {} + + try: + fd = open(Config.UNMONIT_PS_FILE) + except: + printd("Failed to open file %s " %(Config.UNMONIT_PS_FILE)) + return StatusCodes.FAILED + + ps = fd.read() + + if not ps: + printd("File %s content is empty " %Config.UNMONIT_PS_FILE) + return StatusCodes.FAILED + + printd(ps) + plist = ps.split(',') + plist.remove('') + for i in plist: + dict_unmonit[i.split(':')[0]] = i.split(':')[1] + + fd.close(); + + return dict_unmonit; + + +def writePsListToUnmonitFile(umonit_update): + printd("Write updated unmonit list to file") + line='' + for i in umonit_update: + line+=str(i)+":"+str(umonit_update[i])+',' + printd(line) + try: + fd=open(Config.UNMONIT_PS_FILE,'w') + except: + printd("Failed to open file %s " %Config.UNMONIT_PS_FILE) + return StatusCodes.FAILED + + fd.write(line); + fd.close() + + +def is_emtpy(struct): + """ + Checks wether the given struct is empty or not + """ + if struct: + return False + else: + return True def main(): ''' @@ -238,14 +362,11 @@ def main(): printd("monitoring started") temp_dict = getConfig() - ''' - Step2: Get Previous Run Log - ''' ''' - Step3: Monitor and Raise Alert + Step2: Monitor and Raise Alert ''' - #raisealert(log.INFO, 'Monit started') + #raisealert(Log.INFO, 'Monit started') monitProcess( temp_dict ) From 29c36b2ad20a65085f76f529a0e0007c99310489 Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Fri, 22 Nov 2013 16:43:17 +0530 Subject: [PATCH 013/170] CLOUDSTACK-5122. [VMware] During upgrade from 4.1 system vms don't come up with 'ROOT-x-y VMDK file not found' exception. During VM start, if VM already exists and CS finds a matching disk in storage for each of the existing disk then the VM is reconfigured with VM's existing disk information. This existing disk information for a VM is got from vCenter. CS checks if a matching disk exists in storage by checking if there is a disk in storage whose name atleast partially matches with the name of the existing disk. Post 4.1, Volume path has been changed to ROOT- from ROOT--. Hence in case of an upgraded setup (pre 4.1 to 4.2) during search for an existing disk in storage even though ROOT-- has been deleted, CS does a postive match of the old existing disk because of the partial match with the new disk ROOT- that exists in storage. And so when VM is being powered on by vCenter it looks for ROOT-- and fails to power on. Solution - While looking for a VM's matching disk in storage, instead of checking if a disk with a partial match exists check if a disk with the exact name exists. --- .../hypervisor/vmware/mo/VirtualMachineDiskInfoBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineDiskInfoBuilder.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineDiskInfoBuilder.java index baddfc0b9bb..9e9fa8988a4 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineDiskInfoBuilder.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineDiskInfoBuilder.java @@ -88,7 +88,7 @@ public class VirtualMachineDiskInfoBuilder { for (String backing : chain) { DatastoreFile file = new DatastoreFile(backing); - if (file.getFileBaseName().contains(diskBackingFileBaseName)) + if (file.getFileBaseName().equals(diskBackingFileBaseName)) return true; } From 102331c62e2efa1cbed34d7ec2c42437ac9515fe Mon Sep 17 00:00:00 2001 From: Anshul Gangwar Date: Wed, 13 Nov 2013 17:17:55 +0530 Subject: [PATCH 014/170] CLOUDSTACK-4959: added the connection and socket timeout parameters for SMTP and sending message in new thread so that HA doesn't get blocked beacause of hang in sending email alert --- .../src/com/cloud/alert/AlertManagerImpl.java | 53 ++++++++++++++++--- .../src/com/cloud/configuration/Config.java | 4 ++ setup/db/db/schema-420to421.sql | 2 + 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/server/src/com/cloud/alert/AlertManagerImpl.java b/server/src/com/cloud/alert/AlertManagerImpl.java index cdb65e15eed..05ed03a036d 100755 --- a/server/src/com/cloud/alert/AlertManagerImpl.java +++ b/server/src/com/cloud/alert/AlertManagerImpl.java @@ -25,6 +25,8 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Timer; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import javax.ejb.Local; import javax.inject.Inject; @@ -32,6 +34,7 @@ import javax.mail.Authenticator; import javax.mail.Message.RecipientType; import javax.mail.MessagingException; import javax.mail.PasswordAuthentication; +import javax.mail.SendFailedException; import javax.mail.Session; import javax.mail.URLName; import javax.mail.internet.InternetAddress; @@ -79,6 +82,7 @@ import com.cloud.resource.ResourceManager; import com.cloud.storage.StorageManager; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; import com.cloud.utils.db.SearchCriteria; @@ -132,6 +136,12 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi private double _localStorageCapacityThreshold = 0.75; Map _capacityTypeThresholdMap = new HashMap(); + private final ExecutorService _executor; + + public AlertManagerImpl() { + _executor = Executors.newCachedThreadPool(new NamedThreadFactory("Email-Alerts-Sender")); + } + @Override public boolean configure(String name, Map params) throws ConfigurationException { Map configs = _configDao.getConfiguration("management-server", params); @@ -151,12 +161,14 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi String smtpPassword = configs.get("alert.smtp.password"); String emailSender = configs.get("alert.email.sender"); String smtpDebugStr = configs.get("alert.smtp.debug"); + int smtpTimeout = NumbersUtil.parseInt(configs.get("alert.smtp.timeout"), 30000); + int smtpConnectionTimeout = NumbersUtil.parseInt(configs.get("alert.smtp.connectiontimeout"), 30000); boolean smtpDebug = false; if (smtpDebugStr != null) { smtpDebug = Boolean.parseBoolean(smtpDebugStr); } - _emailAlert = new EmailAlert(emailAddresses, smtpHost, smtpPort, useAuth, smtpUsername, smtpPassword, emailSender, smtpDebug); + _emailAlert = new EmailAlert(emailAddresses, smtpHost, smtpPort, smtpConnectionTimeout, smtpTimeout, useAuth, smtpUsername, smtpPassword, emailSender, smtpDebug); String publicIPCapacityThreshold = _configDao.getValue(Config.PublicIpCapacityThreshold.key()); String privateIPCapacityThreshold = _configDao.getValue(Config.PrivateIpCapacityThreshold.key()); @@ -729,9 +741,11 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi private final String _smtpUsername; private final String _smtpPassword; private final String _emailSender; + private int _smtpTimeout; + private int _smtpConnectionTimeout; - public EmailAlert(String[] recipientList, String smtpHost, int smtpPort, boolean smtpUseAuth, final String smtpUsername, final String smtpPassword, - String emailSender, boolean smtpDebug) { + public EmailAlert(String[] recipientList, String smtpHost, int smtpPort, int smtpConnectionTimeout, int smtpTimeout, boolean smtpUseAuth, final String smtpUsername, + final String smtpPassword, String emailSender, boolean smtpDebug) { if (recipientList != null) { _recipientList = new InternetAddress[recipientList.length]; for (int i = 0; i < recipientList.length; i++) { @@ -749,19 +763,27 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi _smtpUsername = smtpUsername; _smtpPassword = smtpPassword; _emailSender = emailSender; + _smtpTimeout = smtpTimeout; + _smtpConnectionTimeout = smtpConnectionTimeout; if (_smtpHost != null) { Properties smtpProps = new Properties(); smtpProps.put("mail.smtp.host", smtpHost); smtpProps.put("mail.smtp.port", smtpPort); - smtpProps.put("mail.smtp.auth", "" + smtpUseAuth); + smtpProps.put("mail.smtp.auth", ""+smtpUseAuth); + smtpProps.put("mail.smtp.timeout", _smtpTimeout); + smtpProps.put("mail.smtp.connectiontimeout", _smtpConnectionTimeout); + if (smtpUsername != null) { smtpProps.put("mail.smtp.user", smtpUsername); } smtpProps.put("mail.smtps.host", smtpHost); smtpProps.put("mail.smtps.port", smtpPort); - smtpProps.put("mail.smtps.auth", "" + smtpUseAuth); + smtpProps.put("mail.smtps.auth", ""+smtpUseAuth); + smtpProps.put("mail.smtps.timeout", _smtpTimeout); + smtpProps.put("mail.smtps.connectiontimeout", _smtpConnectionTimeout); + if (smtpUsername != null) { smtpProps.put("mail.smtps.user", smtpUsername); } @@ -831,12 +853,27 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi } else { smtpTrans = new SMTPTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword)); } - smtpTrans.connect(); - smtpTrans.sendMessage(msg, msg.getAllRecipients()); - smtpTrans.close(); + sendMessage(smtpTrans, msg); } } + private void sendMessage(final SMTPTransport smtpTrans, final SMTPMessage msg) { + _executor.execute(new Runnable() { + @Override + public void run() { + try { + smtpTrans.connect(); + smtpTrans.sendMessage(msg, msg.getAllRecipients()); + smtpTrans.close(); + } catch (SendFailedException e) { + s_logger.error(" Failed to send email alert " + e); + } catch (MessagingException e) { + s_logger.error(" Failed to send email alert " + e); + } + } + }); + } + public void clearAlert(short alertType, long dataCenterId, Long podId) { if (alertType != -1) { AlertVO alert = _alertDao.getLastAlert(alertType, dataCenterId, podId, null); diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 499b0839455..f2debe7c6ae 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -41,6 +41,7 @@ import com.cloud.vm.snapshot.VMSnapshotManager; public enum Config { + // Alert AlertEmailAddresses( @@ -62,6 +63,9 @@ public enum Config { "Password for SMTP authentication (applies only if alert.smtp.useAuth is true).", null), AlertSMTPPort("Alert", ManagementServer.class, Integer.class, "alert.smtp.port", "465", "Port the SMTP server is listening on.", null), + AlertSMTPConnectionTimeout("Alert", ManagementServer.class, Integer.class, "alert.smtp.connectiontimeout", "30000", + "Socket connection timeout value in milliseconds. -1 for infinite timeout.", null), + AlertSMTPTimeout("Alert", ManagementServer.class, Integer.class, "alert.smtp.timeout", "30000", "Socket I/O timeout value in milliseconds. -1 for infinite timeout.", null), AlertSMTPUseAuth("Alert", ManagementServer.class, String.class, "alert.smtp.useAuth", null, "If true, use SMTP authentication when sending emails.", null), AlertSMTPUsername( "Alert", diff --git a/setup/db/db/schema-420to421.sql b/setup/db/db/schema-420to421.sql index 1d2848535bf..fe1e0d49100 100644 --- a/setup/db/db/schema-420to421.sql +++ b/setup/db/db/schema-420to421.sql @@ -224,3 +224,5 @@ update `cloud`.`volumes` v, `cloud`.`volume_host_ref` vhr set v.format=vhr.fo INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'baremetal.ipmi.lan.interface', 'default', 'option specified in -I option of impitool. candidates are: open/bmc/lipmi/lan/lanplus/free/imb, see ipmitool man page for details. default valule "default" means using default option of ipmitool'); INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'baremetal.ipmi.fail.retry', 'default', "ipmi interface will be temporary out of order after power opertions(e.g. cycle, on), it leads following commands fail immediately. The value specifies retry times before accounting it as real failure"); INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vmware.hung.wokervm.timeout', '7200', 'Worker VM timeout in seconds'); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ("Alert", 'DEFAULT', 'management-server', "alert.smtp.connectiontimeout", "30000", "Socket connection timeout value in milliseconds. -1 for infinite timeout."); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ("Alert", 'DEFAULT', 'management-server', "alert.smtp.timeout", "30000", "Socket I/O timeout value in milliseconds. -1 for infinite timeout."); \ No newline at end of file From eb21239e3f2fdf9d63def52c42c86169e4e3bde6 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Mon, 25 Nov 2013 12:03:49 -0700 Subject: [PATCH 015/170] CLOUDSTACK-5224: Add missing configuration for Netscaler, F5, SRX, and VNMC --- .../cloudstack/cisco-vnmc/module.properties | 18 +++++++++ .../cisco-vnmc/spring-cisco-vnmc-context.xml | 40 +++++++++++++++++++ .../META-INF/cloudstack/f5/module.properties | 18 +++++++++ .../cloudstack/f5/spring-f5-context.xml | 34 ++++++++++++++++ .../META-INF/cloudstack/srx/module.properties | 18 +++++++++ .../cloudstack/srx/spring-srx-context.xml | 35 ++++++++++++++++ .../cloudstack/netscaler/module.properties | 18 +++++++++ .../netscaler/spring-netscaler-context.xml | 35 ++++++++++++++++ 8 files changed, 216 insertions(+) create mode 100644 plugins/network-elements/cisco-vnmc/resources/META-INF/cloudstack/cisco-vnmc/module.properties create mode 100644 plugins/network-elements/cisco-vnmc/resources/META-INF/cloudstack/cisco-vnmc/spring-cisco-vnmc-context.xml create mode 100644 plugins/network-elements/f5/resources/META-INF/cloudstack/f5/module.properties create mode 100644 plugins/network-elements/f5/resources/META-INF/cloudstack/f5/spring-f5-context.xml create mode 100644 plugins/network-elements/juniper-srx/resources/META-INF/cloudstack/srx/module.properties create mode 100644 plugins/network-elements/juniper-srx/resources/META-INF/cloudstack/srx/spring-srx-context.xml create mode 100644 plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/module.properties create mode 100644 plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml diff --git a/plugins/network-elements/cisco-vnmc/resources/META-INF/cloudstack/cisco-vnmc/module.properties b/plugins/network-elements/cisco-vnmc/resources/META-INF/cloudstack/cisco-vnmc/module.properties new file mode 100644 index 00000000000..69ffb6fe1d0 --- /dev/null +++ b/plugins/network-elements/cisco-vnmc/resources/META-INF/cloudstack/cisco-vnmc/module.properties @@ -0,0 +1,18 @@ +# 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. +name=cisco-vnmc +parent=network \ No newline at end of file diff --git a/plugins/network-elements/cisco-vnmc/resources/META-INF/cloudstack/cisco-vnmc/spring-cisco-vnmc-context.xml b/plugins/network-elements/cisco-vnmc/resources/META-INF/cloudstack/cisco-vnmc/spring-cisco-vnmc-context.xml new file mode 100644 index 00000000000..62e2ef088e3 --- /dev/null +++ b/plugins/network-elements/cisco-vnmc/resources/META-INF/cloudstack/cisco-vnmc/spring-cisco-vnmc-context.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + diff --git a/plugins/network-elements/f5/resources/META-INF/cloudstack/f5/module.properties b/plugins/network-elements/f5/resources/META-INF/cloudstack/f5/module.properties new file mode 100644 index 00000000000..efdb64a89e7 --- /dev/null +++ b/plugins/network-elements/f5/resources/META-INF/cloudstack/f5/module.properties @@ -0,0 +1,18 @@ +# 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. +name=f5 +parent=network \ No newline at end of file diff --git a/plugins/network-elements/f5/resources/META-INF/cloudstack/f5/spring-f5-context.xml b/plugins/network-elements/f5/resources/META-INF/cloudstack/f5/spring-f5-context.xml new file mode 100644 index 00000000000..6472d689c4f --- /dev/null +++ b/plugins/network-elements/f5/resources/META-INF/cloudstack/f5/spring-f5-context.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/plugins/network-elements/juniper-srx/resources/META-INF/cloudstack/srx/module.properties b/plugins/network-elements/juniper-srx/resources/META-INF/cloudstack/srx/module.properties new file mode 100644 index 00000000000..dde649bf753 --- /dev/null +++ b/plugins/network-elements/juniper-srx/resources/META-INF/cloudstack/srx/module.properties @@ -0,0 +1,18 @@ +# 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. +name=srx +parent=network \ No newline at end of file diff --git a/plugins/network-elements/juniper-srx/resources/META-INF/cloudstack/srx/spring-srx-context.xml b/plugins/network-elements/juniper-srx/resources/META-INF/cloudstack/srx/spring-srx-context.xml new file mode 100644 index 00000000000..2e17f7cf4ee --- /dev/null +++ b/plugins/network-elements/juniper-srx/resources/META-INF/cloudstack/srx/spring-srx-context.xml @@ -0,0 +1,35 @@ + + + + + + + + diff --git a/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/module.properties b/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/module.properties new file mode 100644 index 00000000000..2f1b641ae1d --- /dev/null +++ b/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/module.properties @@ -0,0 +1,18 @@ +# 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. +name=netscaler +parent=network \ No newline at end of file diff --git a/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml b/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml new file mode 100644 index 00000000000..b70398cd9e0 --- /dev/null +++ b/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml @@ -0,0 +1,35 @@ + + + + + + + + + From a5cff1dfd585f2b1ff2db0cb6818ca73c20bb2f9 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 25 Nov 2013 12:06:57 -0800 Subject: [PATCH 016/170] CLOUDSTACK-4793: UI > Virtual Routers > Select View > group by zone > implement detailView of Zone, Total of Virtual Routers, Virtual Routers require upgrade. --- ui/scripts/system.js | 81 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index d6ced5bd90f..d748b72a69c 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -8735,7 +8735,86 @@ }); } }); - } + }, + detailView: { + name: 'Virtual Routers group by zone', + tabs: { + details: { + title: 'Virtual Routers group by zone', + fields: [{ + name: { + label: 'label.zone' + } + }, { + routerCount: { + label: 'Total of Virtual Routers' + }, + routerRequiresUpgrade: { + label: 'Virtual Routers require upgrade', + converter: function(args) { + if (args > 0) { + return 'Yes'; + } else { + return 'No'; + } + } + } + }], + dataProvider: function(args) { + $.ajax({ + url: createURL('listRouters'), + data: { + zoneid: args.context.routerGroupByZone[0].id + }, + async: false, + success: function(json) { + if (json.listroutersresponse.count != undefined) { + args.context.routerGroupByZone[0].routerCount = json.listroutersresponse.count; + + var routerCountFromAllPages = args.context.routerGroupByZone[0].routerCount; + var currentPage = 1; + var routerCountFromFirstPageToCurrentPage = 0; + var routerRequiresUpgrade = 0; + var callListApiWithPage = function() { + $.ajax({ + url: createURL('listRouters'), + async: false, + data: { + zoneid: args.context.routerGroupByZone[0].id, + page: currentPage, + pagesize: pageSize //global variable + }, + success: function(json) { + routerCountFromFirstPageToCurrentPage += json.listroutersresponse.router.length; + var items = json.listroutersresponse.router; + for (var i = 0; i < items.length; i++) { + if (items[i].requiresupgrade) { + routerRequiresUpgrade++; + } + } + if (routerCountFromFirstPageToCurrentPage < routerCountFromAllPages) { + currentPage++; + callListApiWithPage(); + } + } + }); + } + callListApiWithPage(); + args.context.routerGroupByZone[0].routerRequiresUpgrade = routerRequiresUpgrade; + + } else { + args.context.routerGroupByZone[0].routerCount = 0; + args.context.routerGroupByZone[0].routerRequiresUpgrade = 0; + } + } + }); + args.response.success({ + data: args.context.routerGroupByZone[0] + }) + } + } + } + } } } } From 5a9b4ee843bf44f4d954caaa655bd1d68e61de25 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 25 Nov 2013 13:32:46 -0800 Subject: [PATCH 017/170] CLOUDSTACK-4793: UI > Virtual Routers > Select View > group by zone > detailView > add action "upgrade all routers in this zone to use newer template". --- ui/scripts/system.js | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index d748b72a69c..98b545457d4 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -8737,7 +8737,41 @@ }); }, detailView: { - name: 'Virtual Routers group by zone', + name: 'Virtual Routers group by zone', + actions: { + upgradeRouterToUseNewerTemplate: { + label: 'Upgrade Router to Use Newer Template', + messages: { + confirm: function(args) { + return 'Please confirm that you want to upgrade all routers in this zone to use newer template'; + }, + notification: function (args) { + return 'Upgrade Router to Use Newer Template'; + } + }, + action: function (args) { + $.ajax({ + url: createURL('upgradeRouterTemplate'), + data: { + zoneid: args.context.routerGroupByZone[0].id + }, + success: function (json) { + var jobs = json.upgraderoutertemplateresponse.asyncjobs; + if (jobs != undefined) { + args.response.success({ + _custom: { + jobId: jobs[0].jobid + } + }); + } + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + } + }, tabs: { details: { title: 'Virtual Routers group by zone', From a1ca4f1d5669861b938858add4cbf7c6e0fb5a8c Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Mon, 25 Nov 2013 13:47:42 -0800 Subject: [PATCH 018/170] CLOUDSTACK-5221: In order to keep backward compatibility, listisos should return an empty response than an error when id of a removed iso is passed. --- server/src/com/cloud/api/query/QueryManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index bda7b4dcb20..91222760dc1 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -2769,7 +2769,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { // verify templateId parameter and specially handle it if (templateId != null) { - template = _templateDao.findById(templateId); + template = _templateDao.findByIdIncludingRemoved(templateId); // Done for backward compatibility - Bug-5221 if (template == null) { throw new InvalidParameterValueException("Please specify a valid template ID."); }// If ISO requested then it should be ISO. From 7819a4b7af28071e048ae6914abfdd6a9f3116e4 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 25 Nov 2013 13:50:38 -0800 Subject: [PATCH 019/170] CLOUDSTACK-4793: UI > Virtual Routers > Select View > add "group by pod". --- ui/scripts/system.js | 221 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 220 insertions(+), 1 deletion(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 98b545457d4..f385794330e 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -8850,7 +8850,226 @@ } } } - } + }, + routerGroupByPod: { + id: 'routerGroupByPod', + type: 'select', + title: 'group by pod', + listView: { + id: 'routerGroupByPod', + label: 'label.virtual.appliances', + fields: { + name: { + label: 'label.pod' + }, + routerCount: { + label: 'Total of Virtual Routers' + }, + routerRequiresUpgrade: { + label: 'Virtual Routers require upgrade', + converter: function (args) { + if (args > 0) { + return 'Yes'; + } else { + return 'No'; + } + } + } + }, + + dataProvider: function (args) { + var array1 = []; + if (args.filterBy != null) { + if (args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { + switch (args.filterBy.search.by) { + case "name": + if (args.filterBy.search.value.length > 0) + array1.push("&keyword=" + args.filterBy.search.value); + break; + } + } + } + $.ajax({ + url: createURL("listPods&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), + dataType: "json", + async: true, + success: function (json) { + var podObjs = json.listpodsresponse.pod; + if (podObjs != null) { + for (var i = 0; i < podObjs.length; i++) { + $.ajax({ + url: createURL('listRouters'), + data: { + podid: podObjs[i].id + }, + async: false, + success: function (json) { + if (json.listroutersresponse.count != undefined) { + podObjs[i].routerCount = json.listroutersresponse.count; + + var routerCountFromAllPages = podObjs[i].routerCount; + var currentPage = 1; + var routerCountFromFirstPageToCurrentPage = 0; + var routerRequiresUpgrade = 0; + var callListApiWithPage = function () { + $.ajax({ + url: createURL('listRouters'), + async: false, + data: { + podid: podObjs[i].id, + page: currentPage, + pagesize: pageSize //global variable + }, + success: function (json) { + routerCountFromFirstPageToCurrentPage += json.listroutersresponse.router.length; + var items = json.listroutersresponse.router; + for (var i = 0; i < items.length; i++) { + if (items[i].requiresupgrade) { + routerRequiresUpgrade++; + } + } + if (routerCountFromFirstPageToCurrentPage < routerCountFromAllPages) { + currentPage++; + callListApiWithPage(); + } + } + }); + } + callListApiWithPage(); + podObjs[i].routerRequiresUpgrade = routerRequiresUpgrade; + + } else { + podObjs[i].routerCount = 0; + podObjs[i].routerRequiresUpgrade = 0; + } + } + }); + } + } + args.response.success({ + data: podObjs + }); + } + }); + }, + detailView: { + name: 'Virtual Routers group by pod', + actions: { + upgradeRouterToUseNewerTemplate: { + label: 'Upgrade Router to Use Newer Template', + messages: { + confirm: function (args) { + return 'Please confirm that you want to upgrade all routers in this pod to use newer template'; + }, + notification: function (args) { + return 'Upgrade Router to Use Newer Template'; + } + }, + action: function (args) { + $.ajax({ + url: createURL('upgradeRouterTemplate'), + data: { + podid: args.context.routerGroupByPod[0].id + }, + success: function (json) { + var jobs = json.upgraderoutertemplateresponse.asyncjobs; + if (jobs != undefined) { + args.response.success({ + _custom: { + jobId: jobs[0].jobid + } + }); + } + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + } + }, + tabs: { + details: { + title: 'Virtual Routers group by pod', + fields: [{ + name: { + label: 'label.pod' + } + }, { + routerCount: { + label: 'Total of Virtual Routers' + }, + routerRequiresUpgrade: { + label: 'Virtual Routers require upgrade', + converter: function (args) { + if (args > 0) { + return 'Yes'; + } else { + return 'No'; + } + } + }, + zonename: { + label: 'label.zone' + } + }], + dataProvider: function (args) { + $.ajax({ + url: createURL('listRouters'), + data: { + podid: args.context.routerGroupByPod[0].id + }, + async: false, + success: function (json) { + if (json.listroutersresponse.count != undefined) { + args.context.routerGroupByPod[0].routerCount = json.listroutersresponse.count; + + var routerCountFromAllPages = args.context.routerGroupByPod[0].routerCount; + var currentPage = 1; + var routerCountFromFirstPageToCurrentPage = 0; + var routerRequiresUpgrade = 0; + var callListApiWithPage = function () { + $.ajax({ + url: createURL('listRouters'), + async: false, + data: { + podid: args.context.routerGroupByPod[0].id, + page: currentPage, + pagesize: pageSize //global variable + }, + success: function (json) { + routerCountFromFirstPageToCurrentPage += json.listroutersresponse.router.length; + var items = json.listroutersresponse.router; + for (var i = 0; i < items.length; i++) { + if (items[i].requiresupgrade) { + routerRequiresUpgrade++; + } + } + if (routerCountFromFirstPageToCurrentPage < routerCountFromAllPages) { + currentPage++; + callListApiWithPage(); + } + } + }); + } + callListApiWithPage(); + args.context.routerGroupByPod[0].routerRequiresUpgrade = routerRequiresUpgrade; + + } else { + args.context.routerGroupByPod[0].routerCount = 0; + args.context.routerGroupByPod[0].routerRequiresUpgrade = 0; + } + } + }); + args.response.success({ + data: args.context.routerGroupByPod[0] + }) + } + } + } + } + } + } } }, systemVms: { From 7d4b298d2d8d019d341146e2a6f0c58cbce4ddc5 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 25 Nov 2013 14:26:57 -0800 Subject: [PATCH 020/170] CLOUDSTACK-4793: UI > Virtual Routers > Select View > add "group by cluster". --- ui/scripts/system.js | 221 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 220 insertions(+), 1 deletion(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index f385794330e..e7c535ecea4 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -9069,7 +9069,226 @@ } } } - } + }, + + //??? + routerGroupByCluster: { + id: 'routerGroupByCluster', + type: 'select', + title: 'group by cluster', + listView: { + id: 'routerGroupByCluster', + label: 'label.virtual.appliances', + fields: { + name: { + label: 'label.cluster' + }, + routerCount: { + label: 'Total of Virtual Routers' + }, + routerRequiresUpgrade: { + label: 'Virtual Routers require upgrade', + converter: function (args) { + if (args > 0) { + return 'Yes'; + } else { + return 'No'; + } + } + } + }, + + dataProvider: function (args) { + var array1 = []; + if (args.filterBy != null) { + if (args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { + switch (args.filterBy.search.by) { + case "name": + if (args.filterBy.search.value.length > 0) + array1.push("&keyword=" + args.filterBy.search.value); + break; + } + } + } + $.ajax({ + url: createURL("listClusters&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), + dataType: "json", + async: true, + success: function (json) { + var clusterObjs = json.listclustersresponse.cluster; + if (clusterObjs != null) { + for (var i = 0; i < clusterObjs.length; i++) { + $.ajax({ + url: createURL('listRouters'), + data: { + clusterid: clusterObjs[i].id + }, + async: false, + success: function (json) { + if (json.listroutersresponse.count != undefined) { + clusterObjs[i].routerCount = json.listroutersresponse.count; + + var routerCountFromAllPages = clusterObjs[i].routerCount; + var currentPage = 1; + var routerCountFromFirstPageToCurrentPage = 0; + var routerRequiresUpgrade = 0; + var callListApiWithPage = function () { + $.ajax({ + url: createURL('listRouters'), + async: false, + data: { + clusterid: clusterObjs[i].id, + page: currentPage, + pagesize: pageSize //global variable + }, + success: function (json) { + routerCountFromFirstPageToCurrentPage += json.listroutersresponse.router.length; + var items = json.listroutersresponse.router; + for (var i = 0; i < items.length; i++) { + if (items[i].requiresupgrade) { + routerRequiresUpgrade++; + } + } + if (routerCountFromFirstPageToCurrentPage < routerCountFromAllPages) { + currentPage++; + callListApiWithPage(); + } + } + }); + } + callListApiWithPage(); + clusterObjs[i].routerRequiresUpgrade = routerRequiresUpgrade; + + } else { + clusterObjs[i].routerCount = 0; + clusterObjs[i].routerRequiresUpgrade = 0; + } + } + }); + } + } + args.response.success({ + data: clusterObjs + }); + } + }); + }, + detailView: { + name: 'Virtual Routers group by cluster', + actions: { + upgradeRouterToUseNewerTemplate: { + label: 'Upgrade Router to Use Newer Template', + messages: { + confirm: function (args) { + return 'Please confirm that you want to upgrade all routers in this cluster to use newer template'; + }, + notification: function (args) { + return 'Upgrade Router to Use Newer Template'; + } + }, + action: function (args) { + $.ajax({ + url: createURL('upgradeRouterTemplate'), + data: { + clusterid: args.context.routerGroupByCluster[0].id + }, + success: function (json) { + var jobs = json.upgraderoutertemplateresponse.asyncjobs; + if (jobs != undefined) { + args.response.success({ + _custom: { + jobId: jobs[0].jobid + } + }); + } + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + } + }, + tabs: { + details: { + title: 'Virtual Routers group by cluster', + fields: [{ + name: { + label: 'label.cluster' + } + }, { + routerCount: { + label: 'Total of Virtual Routers' + }, + routerRequiresUpgrade: { + label: 'Virtual Routers require upgrade', + converter: function (args) { + if (args > 0) { + return 'Yes'; + } else { + return 'No'; + } + } + } + }], + dataProvider: function (args) { + $.ajax({ + url: createURL('listRouters'), + data: { + clusterid: args.context.routerGroupByCluster[0].id + }, + async: false, + success: function (json) { + if (json.listroutersresponse.count != undefined) { + args.context.routerGroupByCluster[0].routerCount = json.listroutersresponse.count; + + var routerCountFromAllPages = args.context.routerGroupByCluster[0].routerCount; + var currentPage = 1; + var routerCountFromFirstPageToCurrentPage = 0; + var routerRequiresUpgrade = 0; + var callListApiWithPage = function () { + $.ajax({ + url: createURL('listRouters'), + async: false, + data: { + clusterid: args.context.routerGroupByCluster[0].id, + page: currentPage, + pagesize: pageSize //global variable + }, + success: function (json) { + routerCountFromFirstPageToCurrentPage += json.listroutersresponse.router.length; + var items = json.listroutersresponse.router; + for (var i = 0; i < items.length; i++) { + if (items[i].requiresupgrade) { + routerRequiresUpgrade++; + } + } + if (routerCountFromFirstPageToCurrentPage < routerCountFromAllPages) { + currentPage++; + callListApiWithPage(); + } + } + }); + } + callListApiWithPage(); + args.context.routerGroupByCluster[0].routerRequiresUpgrade = routerRequiresUpgrade; + + } else { + args.context.routerGroupByCluster[0].routerCount = 0; + args.context.routerGroupByCluster[0].routerRequiresUpgrade = 0; + } + } + }); + args.response.success({ + data: args.context.routerGroupByCluster[0] + }) + } + } + } + } + } + } + //??? } }, systemVms: { From 3d5ff393da6bb070aa28680c35210215615c5ea6 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 25 Nov 2013 14:32:16 -0800 Subject: [PATCH 021/170] CLOUDSTACK-4793: UI > Virtual Routers > Select View > group by cluster > detailView > add pod name, zone name. --- ui/scripts/system.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index e7c535ecea4..f0e4cfd0a4f 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -9070,8 +9070,6 @@ } } }, - - //??? routerGroupByCluster: { id: 'routerGroupByCluster', type: 'select', @@ -9229,6 +9227,12 @@ return 'No'; } } + }, + podname: { + label: 'label.pod' + }, + zonename: { + label: 'zone' } }], dataProvider: function (args) { @@ -9287,8 +9291,7 @@ } } } - } - //??? + } } }, systemVms: { From c15ec68210f5fed9c05e357dea619240dacdad6c Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 25 Nov 2013 14:47:01 -0800 Subject: [PATCH 022/170] CLOUDSTACK-4793: UI > Virtual Routers > remove Advanced Search since we now have Select View (group by zone/pod/cluster). --- ui/scripts/system.js | 463 +------------------------------------------ 1 file changed, 1 insertion(+), 462 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index f0e4cfd0a4f..8f1572a91e7 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -7394,342 +7394,7 @@ var listView = $.extend(true, {}, cloudStack.sections.system.subsections.virtualRouters, { sections: { virtualRouterNoGrouping: { - listView: { - actions: { - upgradeRouterToUseNewerTemplate: { - isHeader: true, - - label: 'Upgrade Router to Use Newer Template', - - messages: { - notification: function (args) { - return 'Upgrade Router to Use Newer Template'; - } - }, - - createForm: { - title: 'Upgrade Router to Use Newer Template', - fields: { - zoneid: { - label: 'label.zone', - select: function (args) { - var items = [{ - id: '', - description: '' - }]; - $.ajax({ - url: createURL('listZones'), - data: { - listAll: true - }, - success: function (json) { - var objs = json.listzonesresponse.zone; - if (objs != null) { - for (var i = 0; i < objs.length; i++) { - items.push({ - id: objs[i].id, - description: objs[i].name - }); - } - } - args.response.success({ - data: items - }); - } - }); - } - }, - podid: { - label: 'Pod', - dependsOn: 'zoneid', - select: function (args) { - var items = [{ - id: '', - description: '' - }]; - if (args.zoneid.length > 0) { - $.ajax({ - url: createURL('listPods'), - data: { - zoneid: args.zoneid - }, - success: function (json) { - var objs = json.listpodsresponse.pod; - if (objs != null) { - for (var i = 0; i < objs.length; i++) { - items.push({ - id: objs[i].id, - description: objs[i].name - }); - } - } - args.response.success({ - data: items - }); - } - }); - } else { - args.response.success({ - data: items - }); - } - } - }, - clusterid: { - label: 'label.cluster', - dependsOn: 'podid', - select: function (args) { - var items = [{ - id: '', - description: '' - }]; - if (args.podid.length > 0) { - $.ajax({ - url: createURL('listClusters'), - data: { - podid: args.podid - }, - success: function (json) { - var objs = json.listclustersresponse.cluster; - if (objs != null) { - for (var i = 0; i < objs.length; i++) { - items.push({ - id: objs[i].id, - description: objs[i].name - }); - } - } - args.response.success({ - data: items - }); - } - }); - } else { - args.response.success({ - data: items - }); - } - } - } - } - }, - - action: function (args) { - var data = {}; - if (args.data.clusterid.length > 0) { - $.extend(data, { - clusterid: args.data.clusterid - }); - } else if (args.data.podid.length > 0) { - $.extend(data, { - podid: args.data.podid - }); - } else if (args.data.zoneid.length > 0) { - $.extend(data, { - zoneid: args.data.zoneid - }); - } else { - args.response.error('Please specify a zone, a pod or a cluster.'); - return; - } - - $.ajax({ - url: createURL('upgradeRouterTemplate'), - data: data, - success: function (json) { - //example - /* - json = { - "upgraderoutertemplateresponse": { - "count": 3, - "asyncjobs": [ - { - "jobid": "2d51f1f9-ea39-4871-9512-431f4a65a5f2" - }, - { - "jobid": "d66fa7ef-c91f-425f-b820-2f8ff2a0da8c" - }, - { - "jobid": "850a3cfd-c265-48f1-880a-f001481fc7f7" - } - ] - } - }; - */ - - var jobs = json.upgraderoutertemplateresponse.asyncjobs; - if (jobs != undefined) { - for (var i = 0; i < jobs.length; i++) { - var jid = jobs[i].jobid; - args.response.success({ - _custom: { - jobId: jid - } - }); - - //example begins - /* - { - "queryasyncjobresultresponse": { - "accountid": "ce5820a8-5099-11e3-80db-3c970e739c3e", - "userid": "ce58353e-5099-11e3-80db-3c970e739c3e", - "cmd": "org.apache.cloudstack.api.command.admin.router.RebootRouterCmd", - "jobstatus": 2, - "jobprocstatus": 0, - "jobresultcode": 530, - "jobresulttype": "object", - "jobresult": { - "errorcode": 530, - "errortext": "Resource [DataCenter:1] is unreachable: Unable to reboot domR, it is not in right state Stopped" - }, - "created": "2013-11-19T11:41:40-0800", - "jobid": "2d51f1f9-ea39-4871-9512-431f4a65a5f2" - } - } - { - "queryasyncjobresultresponse": { - "accountid": "9b0ea3b4-a699-431c-932b-570388ef7b86", - "userid": "ce58353e-5099-11e3-80db-3c970e739c3e", - "cmd": "org.apache.cloudstack.api.command.admin.router.RebootRouterCmd", - "jobstatus": 0, - "jobprocstatus": 0, - "jobresultcode": 0, - "jobinstancetype": "DomainRouter", - "jobinstanceid": "d6e625ea-76f9-4c35-9f89-0998a04a3b9c", - "created": "2013-11-19T11:41:40-0800", - "jobid": "d66fa7ef-c91f-425f-b820-2f8ff2a0da8c" - } - } - { - "queryasyncjobresultresponse": { - "accountid": "6b5334a2-1c0e-46e0-b4d9-524698549f08", - "userid": "ce58353e-5099-11e3-80db-3c970e739c3e", - "cmd": "org.apache.cloudstack.api.command.admin.router.RebootRouterCmd", - "jobstatus": 2, - "jobprocstatus": 0, - "jobresultcode": 530, - "jobresulttype": "object", - "jobresult": { - "errorcode": 530, - "errortext": "Resource [DataCenter:1] is unreachable: Unable to reboot domR, it is not in right state Starting" - }, - "created": "2013-11-19T11:41:40-0800", - "jobid": "850a3cfd-c265-48f1-880a-f001481fc7f7" - } - } - - - { - "queryasyncjobresultresponse": { - "accountid": "9b0ea3b4-a699-431c-932b-570388ef7b86", - "userid": "ce58353e-5099-11e3-80db-3c970e739c3e", - "cmd": "org.apache.cloudstack.api.command.admin.router.RebootRouterCmd", - "jobstatus": 0, - "jobprocstatus": 0, - "jobresultcode": 0, - "jobinstancetype": "DomainRouter", - "jobinstanceid": "d6e625ea-76f9-4c35-9f89-0998a04a3b9c", - "created": "2013-11-19T11:41:40-0800", - "jobid": "d66fa7ef-c91f-425f-b820-2f8ff2a0da8c" - } - } - { - "queryasyncjobresultresponse": { - "accountid": "9b0ea3b4-a699-431c-932b-570388ef7b86", - "userid": "ce58353e-5099-11e3-80db-3c970e739c3e", - "cmd": "org.apache.cloudstack.api.command.admin.router.RebootRouterCmd", - "jobstatus": 0, - "jobprocstatus": 0, - "jobresultcode": 0, - "jobinstancetype": "DomainRouter", - "jobinstanceid": "d6e625ea-76f9-4c35-9f89-0998a04a3b9c", - "created": "2013-11-19T11:41:40-0800", - "jobid": "d66fa7ef-c91f-425f-b820-2f8ff2a0da8c" - } - } - { - "queryasyncjobresultresponse": { - "accountid": "9b0ea3b4-a699-431c-932b-570388ef7b86", - "userid": "ce58353e-5099-11e3-80db-3c970e739c3e", - "cmd": "org.apache.cloudstack.api.command.admin.router.RebootRouterCmd", - "jobstatus": 1, - "jobprocstatus": 0, - "jobresultcode": 0, - "jobresulttype": "object", - "jobresult": { - "router": { - "id": "d6e625ea-76f9-4c35-9f89-0998a04a3b9c", - "zoneid": "3bfdd7d1-134a-4d75-8621-0ccfc8641660", - "zonename": "jw-adv", - "dns1": "8.8.8.8", - "gateway": "10.223.67.1", - "name": "r-6-VM", - "linklocalip": "169.254.2.29", - "linklocalmacaddress": "0e:00:a9:fe:02:1d", - "linklocalnetmask": "255.255.0.0", - "linklocalnetworkid": "4a02a05f-1312-484a-a82b-246a86ed6949", - "publicip": "10.223.67.6", - "publicmacaddress": "06:8d:22:00:00:18", - "publicnetmask": "255.255.255.0", - "publicnetworkid": "e7056c3c-2c7f-4e84-909e-af288ae170e9", - "templateid": "cd70f70a-5099-11e3-80db-3c970e739c3e", - "created": "2013-11-19T11:36:04-0800", - "state": "Running", - "account": "aaa_admin", - "domainid": "b95a5b02-e45d-4971-b0d8-d1620f7bf44e", - "domain": "aaa", - "serviceofferingid": "7dd7687c-01f0-4a14-846e-8e46067a8ff9", - "serviceofferingname": "System Offering For Software Router", - "isredundantrouter": false, - "redundantstate": "UNKNOWN", - "version": "3.0", - "role": "VIRTUAL_ROUTER", - "nic": [ - { - "id": "d41bf67e-1d58-4ec9-bf61-41903140cc53", - "networkid": "e7056c3c-2c7f-4e84-909e-af288ae170e9", - "netmask": "255.255.255.0", - "gateway": "10.223.67.1", - "ipaddress": "10.223.67.6", - "isolationuri": "vlan://159", - "broadcasturi": "vlan://159", - "traffictype": "Public", - "isdefault": true, - "macaddress": "06:8d:22:00:00:18" - }, - { - "id": "a6d1f6ac-fc45-474e-b372-3571e639fa8e", - "networkid": "4a02a05f-1312-484a-a82b-246a86ed6949", - "netmask": "255.255.0.0", - "gateway": "169.254.0.1", - "ipaddress": "169.254.2.29", - "traffictype": "Control", - "isdefault": false, - "macaddress": "0e:00:a9:fe:02:1d" - } - ], - "requiresupgrade": true, - "jobid": "d66fa7ef-c91f-425f-b820-2f8ff2a0da8c", - "jobstatus": 0 - } - }, - "created": "2013-11-19T11:41:40-0800", - "jobid": "d66fa7ef-c91f-425f-b820-2f8ff2a0da8c" - } - } - */ - //example ends - } - } - } - }); - }, - notification: { - poll: pollAsyncJobResult - } - } - }, - + listView: { dataProvider: function(args) { var data = {}; listViewDataProvider(args, data); @@ -7922,132 +7587,6 @@ } } }, - - advSearchFields: { - name: { - label: 'Name' - }, - zoneid: { - label: 'Zone', - select: function(args) { - $.ajax({ - url: createURL('listZones'), - data: { - listAll: true - }, - success: function(json) { - var zones = json.listzonesresponse.zone ? json.listzonesresponse.zone : []; - - args.response.success({ - data: $.map(zones, function(zone) { - return { - id: zone.id, - description: zone.name - }; - }) - }); - } - }); - } - }, - podid: { - label: 'Pod', - dependsOn: 'zoneid', - select: function (args) { - $.ajax({ - url: createURL("listPods&zoneid=" + args.zoneid), - dataType: "json", - async: true, - success: function (json) { - var pods = json.listpodsresponse.pod ? json.listpodsresponse.pod : []; - args.response.success({ - data: $.map(pods, function(pod) { - return { - id: pod.id, - description: pod.name - }; - }) - }); - } - }); - } - }, - clusterid: { - label: 'label.cluster', - dependsOn: 'podid', - select: function(args) { - $.ajax({ - url: createURL("listClusters&podid=" + args.podid), - dataType: "json", - async: false, - success: function(json) { - var clusters = json.listclustersresponse.cluster ? json.listclustersresponse.cluster : []; - args.response.success({ - data: $.map(clusters, function(cluster) { - return { - id: cluster.id, - description: cluster.name - }; - }) - }); - } - }); - } - }, - domainid: { - label: 'Domain', - select: function(args) { - if (isAdmin() || isDomainAdmin()) { - $.ajax({ - url: createURL('listDomains'), - data: { - listAll: true, - details: 'min' - }, - success: function(json) { - var array1 = [{ - id: '', - description: '' - }]; - var domains = json.listdomainsresponse.domain; - if (domains != null && domains.length > 0) { - for (var i = 0; i < domains.length; i++) { - array1.push({ - id: domains[i].id, - description: domains[i].path - }); - } - } - args.response.success({ - data: array1 - }); - } - }); - } else { - args.response.success({ - data: null - }); - } - }, - isHidden: function(args) { - if (isAdmin() || isDomainAdmin()) - return false; - else - return true; - } - }, - - account: { - label: 'Account', - isHidden: function(args) { - if (isAdmin() || isDomainAdmin()) - return false; - else - return true; - } - } - }, - dataProvider: function(args) { var array1 = []; if (args.filterBy != null) { From c37e8b7e8ca8408dc3b1b05f42fe03b0e7ab7260 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Mon, 25 Nov 2013 14:36:02 -0800 Subject: [PATCH 023/170] Resource metadata - fixed the bug in removeResourceDetail API - when "key" parameter was passed in, used to remove the details matching the key, for all the resources, not just the one defined by resource_id --- .../apache/cloudstack/resourcedetail/ResourceDetailsDaoBase.java | 1 + 1 file changed, 1 insertion(+) diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/ResourceDetailsDaoBase.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/ResourceDetailsDaoBase.java index 5a94a15f688..2d086444213 100644 --- a/engine/schema/src/org/apache/cloudstack/resourcedetail/ResourceDetailsDaoBase.java +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/ResourceDetailsDaoBase.java @@ -75,6 +75,7 @@ public abstract class ResourceDetailsDaoBase extends G public void removeDetail(long resourceId, String key) { if (key != null) { SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("resourceId", resourceId); sc.setParameters("name", key); remove(sc); } From 9dd650aca753dc41995ce1ef209371d275bc598b Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Mon, 25 Nov 2013 16:03:13 -0800 Subject: [PATCH 024/170] Disable VR UI quickview, due to technical limitations --- ui/scripts/system.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 8f1572a91e7..b9a27bea506 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -7636,6 +7636,7 @@ }); }, detailView: { + noCompact: true, name: 'Virtual applicance details', actions: { start: { @@ -8276,7 +8277,8 @@ }); }, detailView: { - name: 'Virtual Routers group by zone', + noCompact: true, + name: 'Virtual Routers group by zone', actions: { upgradeRouterToUseNewerTemplate: { label: 'Upgrade Router to Use Newer Template', @@ -8492,6 +8494,7 @@ }); }, detailView: { + noCompact: true, name: 'Virtual Routers group by pod', actions: { upgradeRouterToUseNewerTemplate: { @@ -8711,6 +8714,7 @@ }); }, detailView: { + noCompact: true, name: 'Virtual Routers group by cluster', actions: { upgradeRouterToUseNewerTemplate: { From 84be2ab3be8c6496dae7b24bc1fc1a581ec74ae1 Mon Sep 17 00:00:00 2001 From: Anthony Xu Date: Mon, 25 Nov 2013 16:06:00 -0800 Subject: [PATCH 025/170] CLOUDSTACK-4913: Don't enable ebtables/iptables for non-security group zone --- .../xen/discoverer/XcpServerDiscoverer.java | 11 +++++++++++ .../hypervisor/xen/resource/CitrixResourceBase.java | 1 - 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java index 8ca515fcdc8..6dfc0d4759c 100755 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java @@ -748,6 +748,17 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L return new DeleteHostAnswer(true); } + @Override + protected HashMap buildConfigParams(HostVO host){ + HashMap params = super.buildConfigParams(host); + DataCenterVO zone = _dcDao.findById(host.getDataCenterId()); + if ( zone != null ) { + boolean securityGroupEnabled = zone.isSecurityGroupEnabled(); + params.put("securitygroupenabled", Boolean.toString(securityGroupEnabled)); + } + return params; + } + @Override public boolean stop() { _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName()); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 2cc0ec0a6b2..a8ab69184c9 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -5987,7 +5987,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe details.put("private.network.device", _privateNetworkName); } - details.put("can_bridge_firewall", Boolean.toString(_canBridgeFirewall)); cmd.setHostDetails(details); cmd.setName(hr.nameLabel); cmd.setGuid(_host.uuid); From e5595730817c16de581f6775e118456881b41adf Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Mon, 25 Nov 2013 16:16:06 -0800 Subject: [PATCH 026/170] Revert "Disable VR UI quickview, due to technical limitations" This reverts commit 9dd650aca753dc41995ce1ef209371d275bc598b. --- ui/scripts/system.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index b9a27bea506..8f1572a91e7 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -7636,7 +7636,6 @@ }); }, detailView: { - noCompact: true, name: 'Virtual applicance details', actions: { start: { @@ -8277,8 +8276,7 @@ }); }, detailView: { - noCompact: true, - name: 'Virtual Routers group by zone', + name: 'Virtual Routers group by zone', actions: { upgradeRouterToUseNewerTemplate: { label: 'Upgrade Router to Use Newer Template', @@ -8494,7 +8492,6 @@ }); }, detailView: { - noCompact: true, name: 'Virtual Routers group by pod', actions: { upgradeRouterToUseNewerTemplate: { @@ -8714,7 +8711,6 @@ }); }, detailView: { - noCompact: true, name: 'Virtual Routers group by cluster', actions: { upgradeRouterToUseNewerTemplate: { From c1ed540af8e714d4ff719b1c441e571baca8bdf3 Mon Sep 17 00:00:00 2001 From: Jayapal Date: Tue, 26 Nov 2013 09:49:22 +0530 Subject: [PATCH 027/170] Monitoring python script organized into more methods --- .../debian/config/root/monitorServices.py | 157 +++++++++--------- 1 file changed, 80 insertions(+), 77 deletions(-) diff --git a/systemvm/patches/debian/config/root/monitorServices.py b/systemvm/patches/debian/config/root/monitorServices.py index 4e1b7e09716..3646c81923b 100755 --- a/systemvm/patches/debian/config/root/monitorServices.py +++ b/systemvm/patches/debian/config/root/monitorServices.py @@ -135,6 +135,49 @@ def isPidMatchPidFile(pidfile, pids): fd.close() return StatusCodes.FAILED +def checkProcessRunningStatus(process_name, pidFile): + printd("checking the process " + process_name) + cmd = '' + pids = [] + cmd = 'pidof ' + process_name + printd(cmd) + + #cmd = 'service ' + process_name + ' status' + pout = Popen(cmd, shell=True, stdout=PIPE) + exitStatus = pout.wait() + temp_out = pout.communicate()[0] + + #check there is only one pid or not + if exitStatus == 0: + pids = temp_out.split(' ') + printd("pid(s) of process %s are %s " %(process_name, pids)) + + #there is more than one process so match the pid file + #if not matched set pidFileMatched=False + printd("Checking pid file") + if isPidMatchPidFile(pidFile, pids) == StatusCodes.SUCCESS: + return True,pids; + + printd("pid of exit status %s" %exitStatus) + + return False,pids; + +def restartService(service_name): + + cmd = 'service ' + service_name + ' restart' + cout = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT) + return_val = cout.wait() + + if return_val == 0: + printd("The service " + service_name +" recovered successfully ") + msg="The process " +service_name+" is recovered successfully " + raisealert(Log.INFO,msg,service_name) + return True + else: + printd("process restart failed ....") + + return False + def checkProcessStatus( process ): @@ -152,56 +195,28 @@ def checkProcessStatus( process ): if process_name is None: printd ("\n Invalid Process Name") return StatusCodes.INVALID_INP - else: - printd("checking the process " + process_name) - cmd = 'pidof ' + process_name - printd(cmd) - #cmd = 'service ' + process_name + ' status' - pout = Popen(cmd, shell=True, stdout=PIPE) - exitStatus = pout.wait() - temp_out = pout.communicate()[0] - #check there is only one pid or not - if exitStatus == 0: - pids = temp_out.split(' ') - msg="pids: " +temp_out; - printd(msg) + status, pids = checkProcessRunningStatus(process_name, pidfile) - #there is more than one process so match the pid file - #if not matched set pidFileMatched=False - printd("Checking pid file") - if isPidMatchPidFile(pidfile, pids) == StatusCodes.SUCCESS: - pidFileMatched = True; - else: - pidFileMatched = False; - - if exitStatus == 0 and pidFileMatched == True: + if status == True: printd("The process is running ....") return StatusCodes.RUNNING else: - printd('exit status:'+str(exitStatus)) - msg="The process " + process_name +" is not running trying recover " - printd(msg) + printd("Process %s is not running trying to recover" %process_name) #Retry the process state for few seconds + for i in range(1, Config.RETRY_ITERATIONS): - pout = Popen(cmd, shell=True, stdout=PIPE) - exitStatus = pout.wait() - temp_out = pout.communicate()[0] + time.sleep(Config.SLEEP_SEC) if i < Config.RETRY_FOR_RESTART: # this is just for trying few more times - if exitStatus == 0: - pids = temp_out.split(' ') - if isPidMatchPidFile(pidfile, pids) == StatusCodes.SUCCESS: - pidFileMatched = True; - printd("pid file is matched ...") - raisealert(Log.ALERT, "The process detected as running", process_name) - break - else: - printd("pid file is not matched ...") - pidFileMatched = False; - time.sleep(Config.SLEEP_SEC) - continue + status, pids = checkProcessRunningStatus(process_name, pidfile) + if status == True: + raisealert(Log.ALERT, "The process detected as running", process_name) + break + else: + printd("Process %s is not running checking the status again..." %process_name) + continue else: msg="The process " +process_name+" is not running trying recover " raisealert(Log.INFO,process_name,msg) @@ -213,25 +228,10 @@ def checkProcessStatus( process ): printd(cmd) Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT) - cmd = 'service ' + service_name + ' restart' - - time.sleep(Config.SLEEP_SEC) - #return_val= check_call(cmd , shell=True) - - cout = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT) - return_val = cout.wait() - - if return_val == 0: - printd("The process" + process_name +" recovered successfully ") - msg="The process " +process_name+" is recovered successfully " - raisealert(Log.INFO,msg,process_name) - - break; + if restartService(service_name) == True: + break else: - #retry restarting the process for few tries - printd("process restart failing trying again ....") - restartFailed=True - time.sleep(Config.SLEEP_SEC) + restartFailed = True continue #for end here @@ -255,6 +255,7 @@ def monitProcess( processes_info ): dict_unmonit={} umonit_update={} + unMonitPs=False if not path.isfile(Config.UNMONIT_PS_FILE): printd('Unmonit File not exist') @@ -265,42 +266,48 @@ def monitProcess( processes_info ): #time for noting process down time csec = repr(time.time()).split('.')[0] - unMonitPs=False - for process,properties in processes_info.items(): #skip the process it its time stamp less than Config.MONIT_AFTER_MINS - printd ("checking the process %s \n" %process) + printd ("checking the service %s \n" %process) if not is_emtpy(dict_unmonit): if dict_unmonit.has_key(process): ts = dict_unmonit[process] - printd("Time difference=%s" %str(int(csec) - int(ts))) - tmin = (int(csec) - int(ts) )/60 - if ( int(csec) - int(ts) )/60 < Config.MONIT_AFTER_MINS: - raisealert(Log.ALERT, "The %s get monitor after %s minutes " %(process, Config.MONIT_AFTER_MINS)) - printd('process will be monitored after %s min' %(str(int(Config.MONIT_AFTER_MINS) - tmin))) - unMonitPs=True + if checkPsTimeStampForMonitor (csec, ts, properties) == False: + unMonitPs = True continue if checkProcessStatus( properties) != StatusCodes.RUNNING: - printd( "\n Process %s is not Running"%process) + printd( "\n Service %s is not Running"%process) #add this process into unmonit list - printd ("updating the process for unmonit %s\n" %process) + printd ("updating the service for unmonit %s\n" %process) umonit_update[process]=csec - #if dict is not empty write to file else delete it if not is_emtpy(umonit_update): writePsListToUnmonitFile(umonit_update) else: if is_emtpy(umonit_update) and unMonitPs == False: #delete file it is there - if path.isfile(Config.UNMONIT_PS_FILE): - printd("Removing the file %s" %Config.UNMONIT_PS_FILE) - os.remove(Config.UNMONIT_PS_FILE) + removeFile(Config.UNMONIT_PS_FILE) +def checkPsTimeStampForMonitor(csec,ts, process): + printd("Time difference=%s" %str(int(csec) - int(ts))) + tmin = (int(csec) - int(ts) )/60 + + if ( int(csec) - int(ts) )/60 < Config.MONIT_AFTER_MINS: + raisealert(Log.ALERT, "The %s get monitor after %s minutes " %(process, Config.MONIT_AFTER_MINS)) + printd('process will be monitored after %s min' %(str(int(Config.MONIT_AFTER_MINS) - tmin))) + return False + + return True + +def removeFile(fileName): + if path.isfile(fileName): + printd("Removing the file %s" %fileName) + os.remove(fileName) def loadPsFromUnMonitFile(): @@ -358,18 +365,14 @@ def main(): ''' Step1 : Get Config ''' - printd("monitoring started") temp_dict = getConfig() - ''' Step2: Monitor and Raise Alert ''' - #raisealert(Log.INFO, 'Monit started') monitProcess( temp_dict ) - if __name__ == "__main__": main() From 764dec45fd89bb1a2f9d6ca13820f0290f5d3174 Mon Sep 17 00:00:00 2001 From: Jayapal Date: Tue, 26 Nov 2013 11:24:37 +0530 Subject: [PATCH 028/170] Monitoring python script removed semicolon --- .../patches/debian/config/root/monitorServices.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/systemvm/patches/debian/config/root/monitorServices.py b/systemvm/patches/debian/config/root/monitorServices.py index 3646c81923b..0319ece6b87 100755 --- a/systemvm/patches/debian/config/root/monitorServices.py +++ b/systemvm/patches/debian/config/root/monitorServices.py @@ -156,11 +156,11 @@ def checkProcessRunningStatus(process_name, pidFile): #if not matched set pidFileMatched=False printd("Checking pid file") if isPidMatchPidFile(pidFile, pids) == StatusCodes.SUCCESS: - return True,pids; + return True,pids printd("pid of exit status %s" %exitStatus) - return False,pids; + return False,pids def restartService(service_name): @@ -224,7 +224,7 @@ def checkProcessStatus( process ): if service_name == 'apache2': # Killing apache2 process with this the main service will not start for pid in pids: - cmd = 'kill -9 '+pid; + cmd = 'kill -9 '+pid printd(cmd) Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT) @@ -331,9 +331,9 @@ def loadPsFromUnMonitFile(): for i in plist: dict_unmonit[i.split(':')[0]] = i.split(':')[1] - fd.close(); + fd.close() - return dict_unmonit; + return dict_unmonit def writePsListToUnmonitFile(umonit_update): @@ -348,7 +348,7 @@ def writePsListToUnmonitFile(umonit_update): printd("Failed to open file %s " %Config.UNMONIT_PS_FILE) return StatusCodes.FAILED - fd.write(line); + fd.write(line) fd.close() From d6298302a1872eea1be52ccf5922174e469ed807 Mon Sep 17 00:00:00 2001 From: Ashutosh K Date: Tue, 26 Nov 2013 11:46:56 +0530 Subject: [PATCH 029/170] CLOUDSTACK-5257: Fixed Network ACL issue related to Egress traffic Signed-off-by: Girish Shilamkar --- .../component/test_vpc_vms_deployment.py | 361 +++++++----------- 1 file changed, 136 insertions(+), 225 deletions(-) diff --git a/test/integration/component/test_vpc_vms_deployment.py b/test/integration/component/test_vpc_vms_deployment.py index baefa55ba75..0a244ab656a 100644 --- a/test/integration/component/test_vpc_vms_deployment.py +++ b/test/integration/component/test_vpc_vms_deployment.py @@ -18,14 +18,33 @@ """ Component tests VM deployment in VPC network functionality """ #Import Local Modules -import marvin from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * -import datetime +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.integration.lib.base import (VirtualMachine, + NetworkOffering, + VpcOffering, + VPC, + NetworkACL, + PrivateGateway, + StaticRoute, + Router, + Network, + Account, + ServiceOffering, + PublicIPAddress, + NATRule, + StaticNATRule, + Configurations) + +from marvin.integration.lib.common import (get_domain, + get_zone, + get_template, + wait_for_cleanup, + get_free_vlan) + +from marvin.integration.lib.utils import cleanup_resources +from marvin.cloudstackAPI import rebootRouter + class Services: @@ -105,18 +124,6 @@ class Services: # Max networks allowed as per hypervisor # Xenserver -> 5, VMWare -> 9 }, - "lbrule": { - "name": "SSH", - "alg": "leastconn", - # Algorithm used for load balancing - "privateport": 22, - "publicport": 2222, - "openfirewall": False, - "startport": 22, - "endport": 2222, - "protocol": "TCP", - "cidrlist": '0.0.0.0/0', - }, "natrule": { "privateport": 22, "publicport": 22, @@ -132,11 +139,9 @@ class Services: # Any network (For creating FW rule) "protocol": "TCP" }, - "http_rule": { - "startport": 80, - "endport": 80, + "icmp_rule": { "cidrlist": '0.0.0.0/0', - "protocol": "TCP" + "protocol": "ICMP" }, "virtual_machine": { "displayname": "Test VM", @@ -1893,23 +1898,15 @@ class TestVMDeployVPC(cloudstackTestCase): network_1.id )) - nat_rule = NATRule.create( - self.apiclient, - vm_1, - self.services["natrule"], - ipaddressid=public_ip_1.ipaddress.id, - openfirewall=False, - networkid=network_1.id, - vpcid=vpc.id - ) - - self.debug("Adding NetwrokACl rules to make NAT rule accessible") - nwacl_nat = NetworkACL.create( - self.apiclient, - networkid=network_1.id, - services=self.services["natrule"], - traffictype='Ingress' - ) + NATRule.create( + self.apiclient, + vm_1, + self.services["natrule"], + ipaddressid=public_ip_1.ipaddress.id, + openfirewall=False, + networkid=network_1.id, + vpcid=vpc.id + ) self.debug("Associating public IP for network: %s" % network_1.name) public_ip_2 = PublicIPAddress.create( @@ -1972,26 +1969,92 @@ class TestVMDeployVPC(cloudstackTestCase): network_2.id )) - self.debug("Adding NetworkACl rules to make PF accessible") - nwacl_lb = NetworkACL.create( + NATRule.create( + self.apiclient, + vm_3, + self.services["natrule"], + ipaddressid=public_ip_3.ipaddress.id, + openfirewall=False, + networkid=network_2.id, + vpcid=vpc.id + ) + + self.debug("Associating public IP for network: %s" % network_2.name) + public_ip_4 = PublicIPAddress.create( self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, networkid=network_2.id, - services=self.services["lbrule"], - traffictype='Ingress' + vpcid=vpc.id ) + self.debug("Associated %s with network %s" % ( + public_ip_4.ipaddress.ipaddress, + network_2.id + )) + self.debug("Enabling static NAT for IP: %s" % + public_ip_4.ipaddress.ipaddress) + try: + StaticNATRule.enable( + self.apiclient, + ipaddressid=public_ip_4.ipaddress.id, + virtualmachineid=vm_3.id, + networkid=network_2.id + ) + self.debug("Static NAT enabled for IP: %s" % + public_ip_4.ipaddress.ipaddress) + except Exception as e: + self.fail("Failed to enable static NAT on IP: %s - %s" % ( + public_ip_4.ipaddress.ipaddress, e)) + + public_ips = PublicIPAddress.list( + self.apiclient, + networkid=network_2.id, + listall=True, + isstaticnat=True, + account=self.account.name, + domainid=self.account.domainid + ) + self.assertEqual( + isinstance(public_ips, list), + True, + "List public Ip for network should list the Ip addr" + ) + self.assertEqual( + public_ips[0].ipaddress, + public_ip_4.ipaddress.ipaddress, + "List public Ips %s for network should list the Ip addr %s" + % (public_ips[0].ipaddress, public_ip_4.ipaddress.ipaddress ) + ) + + self.debug("Adding NetwrokACl rules to make NAT rule accessible with network %s" % network_1.id) + NetworkACL.create( + self.apiclient, + networkid=network_1.id, + services=self.services["natrule"], + traffictype='Ingress' + ) + + self.debug("Adding NetworkACl rules to make NAT rule accessible with network: %s" % network_2.id) + NetworkACL.create( + self.apiclient, + networkid=network_2.id, + services=self.services["natrule"], + traffictype='Ingress' + ) self.debug( "Adding Egress rules to network to allow access to internet") - nwacl_internet_1 = NetworkACL.create( + NetworkACL.create( self.apiclient, networkid=network_1.id, - services=self.services["http_rule"], + services=self.services["icmp_rule"], traffictype='Egress' ) - nwacl_internet_2 = NetworkACL.create( + NetworkACL.create( self.apiclient, networkid=network_2.id, - services=self.services["http_rule"], + services=self.services["icmp_rule"], traffictype='Egress' ) @@ -2037,165 +2100,6 @@ class TestVMDeployVPC(cloudstackTestCase): "List static route should return a valid response" ) - self.debug("Associating public IP for network: %s" % network_2.name) - public_ip_5 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network_2.id, - vpcid=vpc.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_5.ipaddress.ipaddress, - network_2.id - )) - - nat_rule = NATRule.create( - self.apiclient, - vm_3, - self.services["natrule"], - ipaddressid=public_ip_5.ipaddress.id, - openfirewall=False, - networkid=network_2.id, - vpcid=vpc.id - ) - - self.debug("Adding NetworkACl rules to make NAT rule accessible") - nwacl_nat = NetworkACL.create( - self.apiclient, - networkid=network_2.id, - services=self.services["natrule"], - traffictype='Ingress' - ) - - self.debug("Associating public IP for network: %s" % network_2.name) - public_ip_6 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network_2.id, - vpcid=vpc.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_6.ipaddress.ipaddress, - network_2.id - )) - self.debug("Enabling static NAT for IP: %s" % - public_ip_6.ipaddress.ipaddress) - try: - StaticNATRule.enable( - self.apiclient, - ipaddressid=public_ip_6.ipaddress.id, - virtualmachineid=vm_3.id, - networkid=network_2.id - ) - self.debug("Static NAT enabled for IP: %s" % - public_ip_6.ipaddress.ipaddress) - except Exception as e: - self.fail("Failed to enable static NAT on IP: %s - %s" % ( - public_ip_6.ipaddress.ipaddress, e)) - - public_ips = PublicIPAddress.list( - self.apiclient, - networkid=network_2.id, - listall=True, - isstaticnat=True, - account=self.account.name, - domainid=self.account.domainid - ) - self.assertEqual( - isinstance(public_ips, list), - True, - "List public Ip for network should list the Ip addr" - ) - self.assertEqual( - public_ips[0].ipaddress, - public_ip_6.ipaddress.ipaddress, - "List public Ips %s for network should list the Ip addr %s" - % (public_ips[0].ipaddress, public_ip_6.ipaddress.ipaddress ) - ) - - self.debug("Associating public IP for network: %s" % vpc.name) - public_ip_7 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network_2.id, - vpcid=vpc.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_7.ipaddress.ipaddress, - network_2.id - )) - - self.debug("Adding NetwrokACl rules to make PF accessible") - nwacl_lb = NetworkACL.create( - self.apiclient, - networkid=network_2.id, - services=self.services["lbrule"], - traffictype='Ingress' - ) - - self.debug( - "Adding Egress rules to network to allow access to internet") - nwacl_internet_3 = NetworkACL.create( - self.apiclient, - networkid=network_1.id, - services=self.services["http_rule"], - traffictype='Egress' - ) - nwacl_internet_4 = NetworkACL.create( - self.apiclient, - networkid=network_2.id, - services=self.services["http_rule"], - traffictype='Egress' - ) - - vlan = get_free_vlan(self.api_client, self.zone.id)[1] - if vlan is None: - self.fail("Failed to get free vlan id in the zone") - - self.debug("Creating private gateway in VPC: %s" % vpc.name) - private_gateway = PrivateGateway.create( - self.apiclient, - gateway='10.2.4.1', - ipaddress='10.2.4.2', - netmask='255.255.255.0', - vlan=vlan, - vpcid=vpc.id - ) - self.debug("Check if the private gateway created successfully?") - gateways = PrivateGateway.list( - self.apiclient, - id=private_gateway.id, - listall=True - ) - self.assertEqual( - isinstance(gateways, list), - True, - "List private gateways should return a valid response" - ) - self.debug("Creating static route for this gateway") - static_route = StaticRoute.create( - self.apiclient, - cidr='10.2.4.0/24', - gatewayid=private_gateway.id - ) - self.debug("Check if the static route created successfully?") - static_routes = StaticRoute.list( - self.apiclient, - id=static_route.id, - listall=True - ) - self.assertEqual( - isinstance(static_routes, list), - True, - "List static route should return a valid response" - ) - self.debug("Restaring the network 1 (%s) with cleanup=True" % network_1.name) try: @@ -2298,10 +2202,19 @@ class TestVMDeployVPC(cloudstackTestCase): except Exception as e: self.fail("Failed to delete network: %s, %s" % (network_1.name, e)) + self.debug("Restaring the network 2 (%s) with cleanup=True" % + network_2.name) + try: + network_2.restart(self.apiclient, cleanup=True) + except Exception as e: + self.fail( + "Failed to restart network: %s, %s" % + (network_2.name, e)) + self.debug("Checking if we can SSH into VM_3?") try: - ssh_4 = vm_3.get_ssh_client( - ipaddress=public_ip_5.ipaddress.ipaddress, + ssh_3 = vm_3.get_ssh_client( + ipaddress=public_ip_3.ipaddress.ipaddress, reconnect=True, port=self.services["natrule"]["publicport"] ) @@ -2309,7 +2222,7 @@ class TestVMDeployVPC(cloudstackTestCase): self.debug("Verifying if we can ping to outside world from VM?") # Ping to outsite world - res = ssh_4.execute("ping -c 1 www.google.com") + res = ssh_3.execute("ping -c 1 www.google.com") # res = 64 bytes from maa03s17-in-f20.1e100.net (74.125.236.212): # icmp_req=1 ttl=57 time=25.9 ms # --- www.l.google.com ping statistics --- @@ -2317,7 +2230,7 @@ class TestVMDeployVPC(cloudstackTestCase): # rtt min/avg/max/mdev = 25.970/25.970/25.970/0.000 ms except Exception as e: self.fail("Failed to SSH into VM - %s, %s" % - (public_ip_5.ipaddress.ipaddress, e)) + (public_ip_3.ipaddress.ipaddress, e)) result = str(res) self.assertEqual( @@ -2326,20 +2239,20 @@ class TestVMDeployVPC(cloudstackTestCase): "Ping to outside world from VM should be successful" ) - self.debug("Checking if we can SSH into VM_2?") + self.debug("Checking if we can SSH into VM_4?") try: - ssh_5 = vm_3.get_ssh_client( - ipaddress=public_ip_6.ipaddress.ipaddress, + ssh_4 = vm_4.get_ssh_client( + ipaddress=public_ip_4.ipaddress.ipaddress, reconnect=True, port=self.services["natrule"]["publicport"] ) self.debug("SSH into VM is successfully") self.debug("Verifying if we can ping to outside world from VM?") - res = ssh_5.execute("ping -c 1 www.google.com") + res = ssh_4.execute("ping -c 1 www.google.com") except Exception as e: self.fail("Failed to SSH into VM - %s, %s" % - (public_ip_6.ipaddress.ipaddress, e)) + (public_ip_4.ipaddress.ipaddress, e)) result = str(res) self.assertEqual( @@ -2369,15 +2282,13 @@ class TestVMDeployVPC(cloudstackTestCase): None, "List VPC network should not return a valid list" ) - networks = Network.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid - ) - self.assertEqual( - networks, - None, - "List networks shall not return any response" + + self.debug("Trying to list the networks in the account, this should fail as account does not exist now") + with self.assertRaises(Exception): + Network.list( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid ) return From 7a6751aa770eaf8065864f497bff401012f553ae Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Thu, 14 Nov 2013 08:37:02 +0100 Subject: [PATCH 030/170] Make sure that if the file does not exist an Exception is thrown and that once it exists it is also closed after the properties are loaded. Signed-off-by: Hugo Trippaers --- .../management/ManagementNetworkGuru.java | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ManagementNetworkGuru.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ManagementNetworkGuru.java index e86e98a215b..d3d9366ce4b 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ManagementNetworkGuru.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ManagementNetworkGuru.java @@ -19,6 +19,8 @@ package org.apache.cloudstack.network.contrail.management; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; import java.util.Map; import java.util.Properties; @@ -60,12 +62,29 @@ public class ManagementNetworkGuru extends ContrailGuru { @Override public boolean configure(String name, Map params) throws ConfigurationException { File configFile = PropertiesUtil.findConfigFile(configuration); + FileInputStream inputFile = null; + + try { + if (null == configFile) { + throw new FileNotFoundException("Configuration file was not found!"); + } + inputFile = new FileInputStream(configFile); + } catch (FileNotFoundException e) { + s_logger.error(e.getMessage()); + throw new ConfigurationException(e.getMessage()); + } + final Properties configProps = new Properties(); try { - configProps.load(new FileInputStream(configFile)); - } catch (Exception ex) { - ex.printStackTrace(); - throw new ConfigurationException(ex.getMessage()); + configProps.load(inputFile); + } catch (IOException e) { + s_logger.error(e.getMessage()); + throw new ConfigurationException(e.getMessage()); + } finally { + try { + inputFile.close(); + } catch (IOException e) { + } } _mgmt_cidr = configProps.getProperty("management.cidr"); _mgmt_gateway = configProps.getProperty("management.gateway"); @@ -100,8 +119,8 @@ public class ManagementNetworkGuru extends ContrailGuru { return null; } NetworkVO network = - new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Lswitch, offering.getId(), Network.State.Allocated, plan.getDataCenterId(), - plan.getPhysicalNetworkId()); + new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Lswitch, offering.getId(), Network.State.Allocated, plan.getDataCenterId(), + plan.getPhysicalNetworkId()); if (_mgmt_cidr != null) { network.setCidr(_mgmt_cidr); network.setGateway(_mgmt_gateway); From 58fd6f0603673efb51b6027f06b9ee39e727be09 Mon Sep 17 00:00:00 2001 From: Parth Jagirdar Date: Tue, 26 Nov 2013 13:23:40 +0530 Subject: [PATCH 031/170] CLOUDSTACK-5223: Fix hosttags. Signed-off-by: Girish Shilamkar --- test/integration/component/test_vpc_vm_life_cycle.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/component/test_vpc_vm_life_cycle.py b/test/integration/component/test_vpc_vm_life_cycle.py index 5e2e7a7ca43..aed9f9581f7 100644 --- a/test/integration/component/test_vpc_vm_life_cycle.py +++ b/test/integration/component/test_vpc_vm_life_cycle.py @@ -57,7 +57,7 @@ class Services: "cpunumber": 1, "cpuspeed": 100, "memory": 128, - "hosttags": "host1" + "tags": "host1" }, "service_offering_2": { "name": "Tiny Instance- tagged host 2", @@ -65,7 +65,7 @@ class Services: "cpunumber": 1, "cpuspeed": 100, "memory": 128, - "hosttags": "host2" + "tags": "host2" }, "network_offering": { "name": 'VPC Network offering', From ef40e156ed376968fa9fd15078034d54b97deecc Mon Sep 17 00:00:00 2001 From: Bharat Kumar Date: Tue, 26 Nov 2013 14:09:55 +0530 Subject: [PATCH 032/170] CLOUDSTACK-5162 Usage details are not getting populated when using dynamic offerings. Signed-off-by: Koushik Das --- .../src/com/cloud/service/ServiceOfferingVO.java | 10 +++++++++- server/src/com/cloud/vm/UserVmManagerImpl.java | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/engine/schema/src/com/cloud/service/ServiceOfferingVO.java b/engine/schema/src/com/cloud/service/ServiceOfferingVO.java index 67fea00a43e..d968de55c74 100755 --- a/engine/schema/src/com/cloud/service/ServiceOfferingVO.java +++ b/engine/schema/src/com/cloud/service/ServiceOfferingVO.java @@ -83,6 +83,11 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering @Transient Map details; + // This flag is required to tell if the offering is dynamic once the cpu, memory and speed are set. + // In some cases cpu, memory and speed are set to non-null values even if the offering is dynamic. + @Transient + boolean isDynamic; + protected ServiceOfferingVO() { super(); } @@ -297,7 +302,10 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering @Override public boolean isDynamic() { - return cpu == null || speed == null || ramSize == null; + return cpu == null || speed == null || ramSize == null || isDynamic; } + public void setDynamicFlag(boolean isdynamic) { + this.isDynamic = isdynamic; + } } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 00d8063da4e..934304326ba 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -2593,6 +2593,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir details.add(new UserVmDetailVO(id, ServiceOfferingVO.DynamicParameters.cpuSpeed.toString(), cpuSpeed.toString())); details.add(new UserVmDetailVO(id, ServiceOfferingVO.DynamicParameters.memory.toString(), memory.toString())); offering = _serviceOfferingDao.getcomputeOffering(serviceOffering.getId(), cpuNumber, cpuSpeed, memory); + offering.setDynamicFlag(true); } if (hostName != null) { // Check is hostName is RFC compliant From b2f0a0bce26e342f18da42a51ae19d51c238a762 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Tue, 26 Nov 2013 14:52:19 +0530 Subject: [PATCH 033/170] CLOUDSTACK-4737: handling usage events for dynamic compute offering Signed-off-by: Koushik Das --- .../event/dao/UsageEventDetailsDaoImpl.java | 44 ++++++++++++++++--- .../com/cloud/usage/UsageVMInstanceVO.java | 37 ++++++++++++++++ setup/db/db/schema-421to430.sql | 3 ++ .../src/com/cloud/usage/UsageManagerImpl.java | 36 +++++++++++++-- 4 files changed, 111 insertions(+), 9 deletions(-) diff --git a/engine/schema/src/com/cloud/event/dao/UsageEventDetailsDaoImpl.java b/engine/schema/src/com/cloud/event/dao/UsageEventDetailsDaoImpl.java index b2be1c934eb..2126fff45c6 100644 --- a/engine/schema/src/com/cloud/event/dao/UsageEventDetailsDaoImpl.java +++ b/engine/schema/src/com/cloud/event/dao/UsageEventDetailsDaoImpl.java @@ -16,12 +16,17 @@ // under the License. package com.cloud.event.dao; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.ejb.Local; +import com.cloud.utils.exception.CloudRuntimeException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -36,6 +41,8 @@ import com.cloud.utils.db.TransactionLegacy; public class UsageEventDetailsDaoImpl extends GenericDaoBase implements UsageEventDetailsDao { public static final Logger s_logger = Logger.getLogger(UsageEventDetailsDaoImpl.class.getName()); + private static final String EVENT_DETAILS_QUERY = "SELECT details.id, details.usage_event_id, details.name, details.value FROM `cloud`.`usage_event_details` details WHERE details.usage_event_id = ?"; + protected final SearchBuilder EventDetailsSearch; protected final SearchBuilder DetailSearch; @@ -74,13 +81,38 @@ public class UsageEventDetailsDaoImpl extends GenericDaoBase findDetails(long eventId) { - SearchCriteria sc = EventDetailsSearch.create(); - sc.setParameters("eventId", eventId); + Connection conn = null; + PreparedStatement pstmt = null; + ResultSet resultSet = null; + Map details = new HashMap(); + try { + conn = TransactionLegacy.getStandaloneConnection(); - List results = search(sc, null); - Map details = new HashMap(results.size()); - for (UsageEventDetailsVO result : results) { - details.put(result.getKey(), result.getValue()); + pstmt = conn.prepareStatement(EVENT_DETAILS_QUERY); + pstmt.setLong(1, eventId); + resultSet = pstmt.executeQuery(); + + while (resultSet.next()) { + details.put(resultSet.getString(3), resultSet.getString(4)); + } + + } catch (SQLException e) { + throw new CloudRuntimeException("Error while executing SQL prepared statement", e); + } catch (Throwable e) { + throw new CloudRuntimeException("Caught: " + e); + } finally { + if (pstmt != null) { + try { + pstmt.close(); + } catch (SQLException e) { + } + } + if (conn != null) { + try { + conn.close(); + } catch (SQLException e) { + } + } } return details; diff --git a/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java b/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java index 06a7beeecf0..cd746c2ca9d 100644 --- a/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java +++ b/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java @@ -27,6 +27,10 @@ import javax.persistence.TemporalType; @Entity @Table(name = "usage_vm_instance") public class UsageVMInstanceVO { + public enum DynamicParameters { + cpuSpeed, cpuNumber, memory + }; + @Column(name = "usage_type") private int usageType; @@ -45,6 +49,15 @@ public class UsageVMInstanceVO { @Column(name = "service_offering_id") private long serviceOfferingId; + @Column(name="cpu_cores") + private Long cpuCores; + + @Column(name="memory") + private Long memory; + + @Column(name="cpu_speed") + private Long cpuSpeed; + @Column(name = "template_id") private long templateId; @@ -127,4 +140,28 @@ public class UsageVMInstanceVO { public void setEndDate(Date endDate) { this.endDate = endDate; } + + public Long getMemory() { + return memory; + } + + public void setMemory(Long memory) { + this.memory = memory; + } + + public Long getCpuCores() { + return cpuCores; + } + + public void setCpuCores(Long cpuCores) { + this.cpuCores = cpuCores; + } + + public Long getCpuSpeed() { + return cpuSpeed; + } + + public void setCpuSpeed(Long cpuSpeed) { + this.cpuSpeed = cpuSpeed; + } } diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql index 8be0fb14896..521ac168231 100644 --- a/setup/db/db/schema-421to430.sql +++ b/setup/db/db/schema-421to430.sql @@ -755,6 +755,9 @@ CREATE VIEW `cloud`.`domain_router_view` AS INSERT IGNORE INTO `cloud`.`configuration` VALUES ("Advanced", 'DEFAULT', 'management-server', "vmware.vcenter.session.timeout", "1200", "VMware client timeout in seconds", "1200", NULL,NULL,0); INSERT IGNORE INTO `cloud`.`configuration` VALUES ("Advanced", 'DEFAULT', 'management-server', "mgt.server.vendor", "ACS", "the vendor of management server", "ACS", NULL,NULL,0); +ALTER TABLE `cloud_usage`.`usage_vm_instance` ADD COLUMN `cpu_speed` INT(10) UNSIGNED NULL COMMENT 'speed per core in Mhz', + ADD COLUMN `cpu_cores` INT(10) UNSIGNED NULL COMMENT 'number of cpu cores', + ADD COLUMN `memory` INT(10) UNSIGNED NULL COMMENT 'memory in MB'; CREATE TABLE `cloud`.`vpc_details` ( `id` bigint unsigned NOT NULL auto_increment, diff --git a/usage/src/com/cloud/usage/UsageManagerImpl.java b/usage/src/com/cloud/usage/UsageManagerImpl.java index 37131e0a47a..81e7892f1a7 100644 --- a/usage/src/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/com/cloud/usage/UsageManagerImpl.java @@ -85,6 +85,7 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.TransactionLegacy; +import com.cloud.event.dao.UsageEventDetailsDao; @Component @Local(value = {UsageManager.class}) @@ -137,6 +138,8 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna @Inject protected UsageEventDao _usageEventDao; @Inject + protected UsageEventDetailsDao _usageEventDetailsDao; + @Inject ConfigurationDao _configDao; @Inject private UsageVMSnapshotDao m_usageVMSnapshotDao; @@ -1102,10 +1105,37 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna try { Long templateId = event.getTemplateId(); String hypervisorType = event.getResourceType(); + Long cpuCores= null; + Long memory = null; + Long cpuSpeed = null; + + //populate the cpu, memory and cpuSpeed of the vm when created from a dynamic offering. + Map usageDetails = _usageEventDetailsDao.findDetails(event.getId()); + + if (usageDetails != null && usageDetails.size() != 0) { + if (usageDetails.get(UsageVMInstanceVO.DynamicParameters.cpuNumber.name()) != null) { + cpuCores = Long.parseLong(usageDetails.get(UsageVMInstanceVO.DynamicParameters.cpuNumber.name())); + } + if (usageDetails.get(UsageVMInstanceVO.DynamicParameters.cpuSpeed.name()) != null) { + cpuSpeed = Long.parseLong(usageDetails.get(UsageVMInstanceVO.DynamicParameters.cpuSpeed.name())); + } + if (usageDetails.get(UsageVMInstanceVO.DynamicParameters.memory.name()) != null) { + memory = Long.parseLong(usageDetails.get(UsageVMInstanceVO.DynamicParameters.memory.name())); + } + } + // add this VM to the usage helper table - UsageVMInstanceVO usageInstanceNew = - new UsageVMInstanceVO(UsageTypes.ALLOCATED_VM, zoneId, event.getAccountId(), vmId, vmName, soId, templateId, hypervisorType, event.getCreateDate(), - null); + UsageVMInstanceVO usageInstanceNew = new UsageVMInstanceVO(UsageTypes.ALLOCATED_VM, zoneId, event.getAccountId(), vmId, vmName, + soId, templateId, hypervisorType, event.getCreateDate(), null); + if (cpuCores != null) { + usageInstanceNew.setCpuCores(cpuCores); + } + if (cpuSpeed != null) { + usageInstanceNew.setCpuSpeed(cpuSpeed); + } + if (memory != null) { + usageInstanceNew.setMemory(memory); + } m_usageInstanceDao.persist(usageInstanceNew); } catch (Exception ex) { s_logger.error("Error saving usage instance for vm: " + vmId, ex); From e0fbc3f14753a9d596dc0a23ec1758603b01e322 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Tue, 26 Nov 2013 14:05:18 +0100 Subject: [PATCH 034/170] CLOUDSTACK-5272: return unlimit if max.account.* or max.project.* is set to negative (cherry picked from commit 888ddd724aabbd22d675fe2bba873971888e1a8a) --- .../com/cloud/resourcelimit/ResourceLimitManagerImpl.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index 9b46627bf5e..ed4c480e602 100755 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -283,6 +283,9 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim value = accountResourceLimitMap.get(type); } if (value != null) { + if (value < 0) { // return unlimit if value is set to negative + return max; + } // convert the value from GiB to bytes in case of primary or secondary storage. if (type == ResourceType.primary_storage || type == ResourceType.secondary_storage) { value = value * ResourceType.bytesToGiB; @@ -316,6 +319,9 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim value = accountResourceLimitMap.get(type); } if (value != null) { + if (value < 0) { // return unlimit if value is set to negative + return max; + } if (type == ResourceType.primary_storage || type == ResourceType.secondary_storage) { value = value * ResourceType.bytesToGiB; } From 9be402cb0693d8aeb779aa7f5ccbe7070c2f03de Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Tue, 26 Nov 2013 15:01:23 +0100 Subject: [PATCH 035/170] CLOUDSTACK-2940: Allowing Replacement of realhostip.com with a customized domain for SSVM (cherry picked from commit e23b10319f55fe8cbb822c0c29dc64b56509c119) Conflicts: plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java server/src/com/cloud/storage/upload/UploadMonitorImpl.java --- .../datastore/driver/CloudStackImageStoreDriverImpl.java | 7 ++++++- .../com/cloud/storage/download/DownloadMonitorImpl.java | 2 +- server/src/com/cloud/storage/upload/UploadMonitorImpl.java | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 0450a7a0786..1db10e2eb32 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -89,12 +89,17 @@ public class CloudStackImageStoreDriverImpl extends BaseImageStoreDriverImpl { String scheme = "http"; boolean _sslCopy = false; String sslCfg = _configDao.getValue(Config.SecStorageEncryptCopy.toString()); + String _ssvmUrlDomain = _configDao.getValue("secstorage.ssl.cert.domain"); if (sslCfg != null) { _sslCopy = Boolean.parseBoolean(sslCfg); } if (_sslCopy) { hostname = ipAddress.replace(".", "-"); - hostname = hostname + ".realhostip.com"; + if(_ssvmUrlDomain != null && _ssvmUrlDomain.length() > 0){ + hostname = hostname + "." + _ssvmUrlDomain; + } else { + hostname = hostname + ".realhostip.com"; + } scheme = "https"; } return scheme + "://" + hostname + "/userdata/" + uuid; diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index 86e5792b0a2..d9003334f6c 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -106,7 +106,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor @Override public boolean configure(String name, Map params) { - final Map configs = _configDao.getConfiguration("ManagementServer", params); + final Map configs = _configDao.getConfiguration("management-server", params); _sslCopy = Boolean.parseBoolean(configs.get("secstorage.encrypt.copy")); _proxy = configs.get(Config.SecStorageProxy.key()); diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java index 5d491c3b733..991f35f7c69 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java +++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java @@ -380,7 +380,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { @Override public boolean configure(String name, Map params) throws ConfigurationException { - final Map configs = _configDao.getConfiguration("ManagementServer", params); + final Map configs = _configDao.getConfiguration("management-server", params); _sslCopy = Boolean.parseBoolean(configs.get("secstorage.encrypt.copy")); String cert = configs.get("secstorage.secure.copy.cert"); From 8b237eb0a2360ba8aaba798a8febab8ceb5477cb Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Tue, 26 Nov 2013 15:02:44 +0100 Subject: [PATCH 036/170] CLOUDSTACK-4505: allow domain admin to expunge a destroyed VM --- client/tomcatconf/commands.properties.in | 2 +- ui/scripts/instances.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index cb9dcf0b071..28490a91d77 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -71,7 +71,7 @@ assignVirtualMachine=7 migrateVirtualMachine=1 migrateVirtualMachineWithVolume=1 recoverVirtualMachine=7 -expungeVirtualMachine=1 +expungeVirtualMachine=7 #### snapshot commands createSnapshot=15 diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index 71c5a320bb8..06acc16583a 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -1765,7 +1765,7 @@ else if (isAdmin()) jsonObj = $.extend(args.context.instances[0], { state: "Expunged" - }); //after root admin expunge a VM, listVirtualMachines API will no longer returns this expunged VM to all users. + }); //after root/domain admin expunge a VM, listVirtualMachines API will no longer returns this expunged VM to all users. else jsonObj = $.extend(args.context.instances[0], { state: "Destroyed" @@ -2101,7 +2101,7 @@ if (isAdmin() || isDomainAdmin()) { allowedActions.push("restore"); } - if (isAdmin()) + if (isAdmin() || isDomainAdmin()) allowedActions.push("expunge"); } else if (jsonObj.state == 'Running') { allowedActions.push("stop"); @@ -2161,7 +2161,7 @@ } else if (jsonObj.state == 'Error') { allowedActions.push("destroy"); } else if (jsonObj.state == 'Expunging') { - if (isAdmin()) + if (isAdmin() || isDomainAdmin()) allowedActions.push("expunge"); } return allowedActions; From 6bea532efa2e754407d33ac2f56cf56d1385eda0 Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Tue, 26 Nov 2013 09:52:17 -0800 Subject: [PATCH 037/170] CLOUDSTACK-5206: Ability to control the external id of first class objects. Putting in the generic methods and trying it for objects like vm, volume. This is the first cut --- .../com/cloud/storage/VolumeApiService.java | 2 +- api/src/com/cloud/vm/UserVmService.java | 43 +++----- .../apache/cloudstack/api/ApiConstants.java | 1 + .../api/BaseAsyncCreateCustomIdCmd.java | 27 +++++ .../cloudstack/api/BaseAsyncCustomIdCmd.java | 27 +++++ .../cloudstack/api/BaseCustomIdCmd.java | 27 +++++ .../api/command/user/vm/DeployVMCmd.java | 9 +- .../api/command/user/vm/UpdateVMCmd.java | 3 +- .../command/user/volume/CreateVolumeCmd.java | 6 +- .../command/user/volume/UpdateVolumeCmd.java | 5 +- .../src/com/cloud/vm/dao/UserVmDao.java | 4 +- .../src/com/cloud/vm/dao/UserVmDaoImpl.java | 6 +- .../spring-server-core-managers-context.xml | 2 + .../cloud/storage/VolumeApiServiceImpl.java | 17 ++- .../com/cloud/uuididentity/UUIDManager.java | 38 +++++++ .../cloud/uuididentity/UUIDManagerImpl.java | 102 ++++++++++++++++++ server/src/com/cloud/vm/UserVmManager.java | 2 +- .../src/com/cloud/vm/UserVmManagerImpl.java | 43 ++++---- 18 files changed, 300 insertions(+), 64 deletions(-) create mode 100644 api/src/org/apache/cloudstack/api/BaseAsyncCreateCustomIdCmd.java create mode 100644 api/src/org/apache/cloudstack/api/BaseAsyncCustomIdCmd.java create mode 100644 api/src/org/apache/cloudstack/api/BaseCustomIdCmd.java create mode 100644 server/src/com/cloud/uuididentity/UUIDManager.java create mode 100644 server/src/com/cloud/uuididentity/UUIDManagerImpl.java diff --git a/api/src/com/cloud/storage/VolumeApiService.java b/api/src/com/cloud/storage/VolumeApiService.java index 47afa104b4d..7e9ea62de2e 100644 --- a/api/src/com/cloud/storage/VolumeApiService.java +++ b/api/src/com/cloud/storage/VolumeApiService.java @@ -87,7 +87,7 @@ public interface VolumeApiService { Snapshot allocSnapshot(Long volumeId, Long policyId) throws ResourceAllocationException; - Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume); + Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId); /** * Extracts the volume to a particular location. diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java index 444c47ab96c..ac14da753b1 100755 --- a/api/src/com/cloud/vm/UserVmService.java +++ b/api/src/com/cloud/vm/UserVmService.java @@ -137,6 +137,7 @@ public interface UserVmService { * caller. * * + * * @param zone * - availability zone for the virtual machine * @param serviceOffering @@ -182,15 +183,10 @@ public interface UserVmService { * @param displayVm * - Boolean flag whether to the display the vm to the end user or not * @param affinityGroupIdList - * @param accountName - * - an optional account for the virtual machine. Must be used - * with domainId - * @param domainId - * - an optional domainId for the virtual machine. If the account - * parameter is used, domainId must also be used * @param cpuSpeed * @param memory * @param cpuNumber + * @param customId * @return UserVm object if successful. * * @throws InsufficientCapacityException @@ -204,9 +200,9 @@ public interface UserVmService { * @throws InsufficientResourcesException */ UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List securityGroupIdList, - Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, - String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard, - List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootdisksize) throws InsufficientCapacityException, + Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, + String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard, + List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootdisksize, String customId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; /** @@ -214,6 +210,7 @@ public interface UserVmService { * the database and returns the VM to the caller. * * + * * @param zone * - availability zone for the virtual machine * @param serviceOffering @@ -261,15 +258,9 @@ public interface UserVmService { * @param displayVm * - Boolean flag whether to the display the vm to the end user or not * @param affinityGroupIdList - * @param accountName - * - an optional account for the virtual machine. Must be used - * with domainId - * @param domainId - * - an optional domainId for the virtual machine. If the account - * parameter is used, domainId must also be used - * @param CpuSpeed * @param memory * @param cpuNumber + * @param customId * @return UserVm object if successful. * * @throws InsufficientCapacityException @@ -283,9 +274,9 @@ public interface UserVmService { * @throws InsufficientResourcesException */ UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List networkIdList, - List securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, - HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, - List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootdisksize) throws InsufficientCapacityException, + List securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, + HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, + List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootdisksize, String customId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; /** @@ -293,6 +284,7 @@ public interface UserVmService { * in the database and returns the VM to the caller. * * + * * @param zone * - availability zone for the virtual machine * @param serviceOffering @@ -337,15 +329,10 @@ public interface UserVmService { * @param displayVm * - Boolean flag whether to the display the vm to the end user or not * @param affinityGroupIdList - * @param accountName - * - an optional account for the virtual machine. Must be used - * with domainId - * @param domainId - * - an optional domainId for the virtual machine. If the account - * parameter is used, domainId must also be used * @param cpuSpeed * @param memory * @param cpuNumber + * @param customId * @return UserVm object if successful. * * @throws InsufficientCapacityException @@ -359,9 +346,9 @@ public interface UserVmService { * @throws InsufficientResourcesException */ UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List networkIdList, Account owner, - String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData, - String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List affinityGroupIdList, - Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootdkisksize) + String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData, + String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List affinityGroupIdList, + Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootdkisksize, String customId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 6f919c170a2..7b872648f65 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -54,6 +54,7 @@ public class ApiConstants { public static final String CREATED = "created"; public static final String CUSTOMIZED = "customized"; public static final String CUSTOMIZED_IOPS = "customizediops"; + public static final String CUSTOM_ID = "customid"; public static final String MIN_IOPS = "miniops"; public static final String MAX_IOPS = "maxiops"; public static final String HYPERVISOR_SNAPSHOT_RESERVE = "hypervisorsnapshotreserve"; diff --git a/api/src/org/apache/cloudstack/api/BaseAsyncCreateCustomIdCmd.java b/api/src/org/apache/cloudstack/api/BaseAsyncCreateCustomIdCmd.java new file mode 100644 index 00000000000..0f75653e35d --- /dev/null +++ b/api/src/org/apache/cloudstack/api/BaseAsyncCreateCustomIdCmd.java @@ -0,0 +1,27 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api; + + +public abstract class BaseAsyncCreateCustomIdCmd extends BaseAsyncCreateCmd{ + @Parameter(name=ApiConstants.CUSTOM_ID, type=CommandType.STRING, description="an optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only") + private String customId; + + public String getCustomId() { + return customId; + } +} diff --git a/api/src/org/apache/cloudstack/api/BaseAsyncCustomIdCmd.java b/api/src/org/apache/cloudstack/api/BaseAsyncCustomIdCmd.java new file mode 100644 index 00000000000..95be24f5483 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/BaseAsyncCustomIdCmd.java @@ -0,0 +1,27 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api; + + +public abstract class BaseAsyncCustomIdCmd extends BaseAsyncCmd { + @Parameter(name=ApiConstants.CUSTOM_ID, type=CommandType.STRING, description="an optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only") + private String customId; + + public String getCustomId() { + return customId; + } +} diff --git a/api/src/org/apache/cloudstack/api/BaseCustomIdCmd.java b/api/src/org/apache/cloudstack/api/BaseCustomIdCmd.java new file mode 100644 index 00000000000..df59b44a56a --- /dev/null +++ b/api/src/org/apache/cloudstack/api/BaseCustomIdCmd.java @@ -0,0 +1,27 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api; + +public abstract class BaseCustomIdCmd extends BaseCmd { + + @Parameter(name=ApiConstants.CUSTOM_ID, type=CommandType.STRING, description="an optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only") + private String customId; + + public String getCustomId() { + return customId; + } +} diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java index 7180f4ea3d5..f075082c3f8 100755 --- a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java @@ -24,6 +24,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import org.apache.cloudstack.api.BaseAsyncCreateCustomIdCmd; import org.apache.log4j.Logger; import org.apache.cloudstack.acl.SecurityChecker.AccessType; @@ -69,7 +70,7 @@ import com.cloud.uservm.UserVm; @APICommand(name = "deployVirtualMachine", description = "Creates and automatically starts a virtual machine based on a service offering, disk offering, and template.", responseObject = UserVmResponse.class) -public class DeployVMCmd extends BaseAsyncCreateCmd { +public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd { public static final Logger s_logger = Logger.getLogger(DeployVMCmd.class.getName()); private static final String s_name = "deployvirtualmachineresponse"; @@ -576,14 +577,14 @@ public class DeployVMCmd extends BaseAsyncCreateCmd { vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(), owner, name, displayName, diskOfferingId, size, group, getHypervisor(), getHttpMethod(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, displayVm, keyboard, - getAffinityGroupIdList(), cpuSpeed, memory, cpuNumber, rootdisksize); + getAffinityGroupIdList(), cpuSpeed, memory, cpuNumber, rootdisksize, getCustomId()); } } else { if (zone.isSecurityGroupEnabled()) { vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, getNetworkIds(), getSecurityGroupIdList(), owner, name, displayName, diskOfferingId, size, group, getHypervisor(), getHttpMethod(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, displayVm, - keyboard, getAffinityGroupIdList(), cpuSpeed, memory, cpuNumber, rootdisksize); + keyboard, getAffinityGroupIdList(), cpuSpeed, memory, cpuNumber, rootdisksize, getCustomId()); } else { if (getSecurityGroupIdList() != null && !getSecurityGroupIdList().isEmpty()) { @@ -592,7 +593,7 @@ public class DeployVMCmd extends BaseAsyncCreateCmd { vm = _userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, getNetworkIds(), owner, name, displayName, diskOfferingId, size, group, getHypervisor(), getHttpMethod(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, displayVm, keyboard, getAffinityGroupIdList(), - cpuSpeed, memory, cpuNumber, rootdisksize); + cpuSpeed, memory, cpuNumber, rootdisksize, getCustomId()); } } diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java index fbb785f2c33..967d8f4d525 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java @@ -16,6 +16,7 @@ // under the License. package org.apache.cloudstack.api.command.user.vm; +import org.apache.cloudstack.api.BaseCustomIdCmd; import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; @@ -36,7 +37,7 @@ import com.cloud.uservm.UserVm; @APICommand(name = "updateVirtualMachine", description = "Updates properties of a virtual machine. The VM has to be stopped and restarted for the " + "new properties to take effect. UpdateVirtualMachine does not first check whether the VM is stopped. " + "Therefore, stop the VM manually before issuing this call.", responseObject = UserVmResponse.class) -public class UpdateVMCmd extends BaseCmd { +public class UpdateVMCmd extends BaseCustomIdCmd { public static final Logger s_logger = Logger.getLogger(UpdateVMCmd.class.getName()); private static final String s_name = "updatevirtualmachineresponse"; diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java index eb4ac88a835..437638c5e41 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java @@ -16,6 +16,8 @@ // under the License. package org.apache.cloudstack.api.command.user.volume; +import org.apache.cloudstack.api.BaseAsyncCreateCustomIdCmd; +import org.apache.cloudstack.api.BaseCmd; import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; @@ -41,7 +43,7 @@ import com.cloud.storage.Volume; @APICommand(name = "createVolume", responseObject = VolumeResponse.class, description = "Creates a disk volume from a disk offering. This disk volume must still be attached to a virtual machine to make use of it.") -public class CreateVolumeCmd extends BaseAsyncCreateCmd { +public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd { public static final Logger s_logger = Logger.getLogger(CreateVolumeCmd.class.getName()); private static final String s_name = "createvolumeresponse"; @@ -50,7 +52,7 @@ public class CreateVolumeCmd extends BaseAsyncCreateCmd { ///////////////////////////////////////////////////// @Parameter(name = ApiConstants.ACCOUNT, - type = CommandType.STRING, + type = BaseCmd.CommandType.STRING, description = "the account associated with the disk volume. Must be used with the domainId parameter.") private String accountName; diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java index f12cef844f0..a47c9233d7d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java @@ -16,6 +16,7 @@ // under the License. package org.apache.cloudstack.api.command.user.volume; +import org.apache.cloudstack.api.BaseAsyncCustomIdCmd; import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; @@ -34,7 +35,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.storage.Volume; @APICommand(name = "updateVolume", description = "Updates the volume.", responseObject = VolumeResponse.class) -public class UpdateVolumeCmd extends BaseAsyncCmd { +public class UpdateVolumeCmd extends BaseAsyncCustomIdCmd { public static final Logger s_logger = Logger.getLogger(UpdateVolumeCmd.class.getName()); private static final String s_name = "updatevolumeresponse"; @@ -140,7 +141,7 @@ public class UpdateVolumeCmd extends BaseAsyncCmd { @Override public void execute() { CallContext.current().setEventDetails("Volume Id: " + getId()); - Volume result = _volumeService.updateVolume(getId(), getPath(), getState(), getStorageId(), getDisplayVolume()); + Volume result = _volumeService.updateVolume(getId(), getPath(), getState(), getStorageId(), getDisplayVolume(), getCustomId()); if (result != null) { VolumeResponse response = _responseGenerator.createVolumeResponse(result); response.setResponseName(getCommandName()); diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmDao.java b/engine/schema/src/com/cloud/vm/dao/UserVmDao.java index 606d424c034..0a4acbbe8b0 100755 --- a/engine/schema/src/com/cloud/vm/dao/UserVmDao.java +++ b/engine/schema/src/com/cloud/vm/dao/UserVmDao.java @@ -40,11 +40,11 @@ public interface UserVmDao extends GenericDao { /** * Updates display name and group for vm; enables/disables ha * @param id vm id. - * @param displan name and enable for ha * @param userData updates the userData of the vm * @param displayVm updates the displayvm attribute signifying whether it has to be displayed to the end user or not. + * @param customId */ - void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm, boolean isDynamicallyScalable); + void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm, boolean isDynamicallyScalable, String customId); List findDestroyedVms(Date date); diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java index 43bdef16ba5..b675fb61bc0 100755 --- a/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java @@ -215,7 +215,7 @@ public class UserVmDaoImpl extends GenericDaoBase implements Use } @Override - public void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm, boolean isDynamicallyScalable) { + public void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm, boolean isDynamicallyScalable, String customId) { UserVmVO vo = createForUpdate(); vo.setDisplayName(displayName); vo.setHaEnabled(enable); @@ -223,6 +223,10 @@ public class UserVmDaoImpl extends GenericDaoBase implements Use vo.setUserData(userData); vo.setDisplayVm(displayVm); vo.setDynamicallyScalable(isDynamicallyScalable); + if (customId != null){ + vo.setUuid(customId); + } + update(id, vo); } diff --git a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml index 2a080f90f18..dcfbf3ab582 100644 --- a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml +++ b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml @@ -116,6 +116,8 @@ + + diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index c6935276935..aaf0fe3e548 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -26,6 +26,7 @@ import java.util.concurrent.ExecutionException; import javax.inject.Inject; +import com.cloud.uuididentity.UUIDManager; import org.apache.log4j.Logger; import org.apache.cloudstack.api.BaseCmd; @@ -302,6 +303,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic UploadMonitor _uploadMonitor; @Inject UploadDao _uploadDao; + @Inject + UUIDManager _uuidMgr; @Inject protected HypervisorCapabilitiesDao _hypervisorCapabilitiesDao; @@ -604,18 +607,21 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic userSpecifiedName = getRandomVolumeName(); } - VolumeVO volume = commitVolume(cmd, caller, ownerId, displayVolumeEnabled, zoneId, diskOfferingId, size, minIops, maxIops, parentVolume, userSpecifiedName); + VolumeVO volume = commitVolume(cmd, caller, ownerId, displayVolumeEnabled, zoneId, diskOfferingId, size, minIops, + maxIops, parentVolume, userSpecifiedName, _uuidMgr.generateUuid(Volume.class, cmd.getCustomId())); return volume; } private VolumeVO commitVolume(final CreateVolumeCmd cmd, final Account caller, final long ownerId, final Boolean displayVolumeEnabled, final Long zoneId, - final Long diskOfferingId, final Long size, final Long minIops, final Long maxIops, final VolumeVO parentVolume, final String userSpecifiedName) { + final Long diskOfferingId, final Long size, final Long minIops, final Long maxIops, final VolumeVO parentVolume, + final String userSpecifiedName, final String uuid) { return Transaction.execute(new TransactionCallback() { @Override public VolumeVO doInTransaction(TransactionStatus status) { VolumeVO volume = new VolumeVO(userSpecifiedName, -1, -1, -1, -1, new Long(-1), null, null, 0, Volume.Type.DATADISK); volume.setPoolId(null); + volume.setUuid(uuid); volume.setDataCenterId(zoneId); volume.setPodId(null); volume.setAccountId(ownerId); @@ -1134,7 +1140,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPDATE, eventDescription = "updating volume", async = true) - public Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume) { + public Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId) { VolumeVO volume = _volumeDao.findById(volumeId); if (path != null) { @@ -1162,6 +1168,11 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic volume.setPoolId(pool.getId()); } + if (customId != null){ + _uuidMgr.checkUuid(customId, Volume.class); + volume.setUuid(customId); + } + _volumeDao.update(volumeId, volume); return volume; diff --git a/server/src/com/cloud/uuididentity/UUIDManager.java b/server/src/com/cloud/uuididentity/UUIDManager.java new file mode 100644 index 00000000000..6bef87a1cde --- /dev/null +++ b/server/src/com/cloud/uuididentity/UUIDManager.java @@ -0,0 +1,38 @@ +// 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.uuididentity; + +import org.apache.cloudstack.api.Identity; + +public interface UUIDManager { + + /** + * Generates a new uuid or uses the customId + * @param entityType the type of entity + * @param customId optional custom uuid of the object. + * @return newly created uuid. + */ + public String generateUuid(Class entityType, String customId); + + /** + * Checks the uuid for correct format, uniqueness and permissions. + * @param uuid uuid to check + * @param entityType the type of entity + * . + */ + void checkUuid(String uuid, Class entityType); +} diff --git a/server/src/com/cloud/uuididentity/UUIDManagerImpl.java b/server/src/com/cloud/uuididentity/UUIDManagerImpl.java new file mode 100644 index 00000000000..852b2dcaf7d --- /dev/null +++ b/server/src/com/cloud/uuididentity/UUIDManagerImpl.java @@ -0,0 +1,102 @@ +// 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.uuididentity; + +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.storage.Volume; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.utils.db.EntityManager; +import com.cloud.utils.exception.CloudRuntimeException; +import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.context.CallContext; + +import javax.ejb.Local; +import javax.inject.Inject; +import java.util.UUID; + +@Local(value = { UUIDManager.class }) +public class UUIDManagerImpl implements UUIDManager { + + + @Inject + EntityManager _entityMgr; + @Inject + AccountManager _accountMgr; + //TODO - Make this configurable. + private final int UUID_RETRY = 3; + + + @Override + public void checkUuid(String uuid, Class entityType){ + + if(uuid == null) return; + + Account caller = CallContext.current().getCallingAccount(); + + // Only admin and system allowed to do this + if ( !(caller.getId() == Account.ACCOUNT_ID_SYSTEM || _accountMgr.isRootAdmin(caller.getType())) ) { + throw new PermissionDeniedException("Please check your permissions, you are not allowed to create/update custom id"); + } + + // check format + if(!IsUuidFormat(uuid)) + throw new InvalidParameterValueException("UUID: " + uuid + " doesn't follow the UUID format"); + + // check unique + if(!IsUuidUnique(entityType, uuid)) + throw new InvalidParameterValueException("UUID: " + uuid + " already exists so can't create/update with custom id"); + + } + + public boolean IsUuidFormat(String uuid){ + + // Match against UUID regex to check if input is uuid string + boolean isUuid = uuid.matches("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"); + return isUuid; + } + + public boolean IsUuidUnique(Class entityType, String uuid){ + + T obj = _entityMgr.findByUuid(entityType, uuid); + if(obj != null) + return false; + else + return true; + } + + @Override + public String generateUuid(Class entityType, String customId){ + + if(customId == null){ // if no customid is passed then generate it. + int retry = UUID_RETRY; + while (retry-- != 0) { // there might be collision so retry + String uuid = UUID.randomUUID().toString(); + if(IsUuidUnique(entityType, uuid)) + return uuid; + } + + throw new CloudRuntimeException("Unable to generate a unique uuid, please try again"); + }else { + checkUuid(customId, entityType); + return customId; + } + } + +} diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java index b7b4bd5b82a..8463326ece6 100755 --- a/server/src/com/cloud/vm/UserVmManager.java +++ b/server/src/com/cloud/vm/UserVmManager.java @@ -116,5 +116,5 @@ public interface UserVmManager extends UserVmService { void collectVmDiskStatistics(UserVmVO userVm); UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData, - Boolean isDynamicallyScalable, HTTPMethod httpMethod) throws ResourceUnavailableException, InsufficientCapacityException; + Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId) throws ResourceUnavailableException, InsufficientCapacityException; } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 934304326ba..45b141f4b4e 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -34,6 +34,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.uuididentity.UUIDManager; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; @@ -445,6 +446,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir VolumeDataFactory volFactory; @Inject UserVmDetailsDao _uservmDetailsDao; + @Inject + UUIDManager _uuidMgr; protected ScheduledExecutorService _executor = null; protected int _expungeInterval; @@ -1731,12 +1734,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } } - return updateVirtualMachine(id, displayName, group, ha, isDisplayVmEnabled, osTypeId, userData, isDynamicallyScalable, cmd.getHttpMethod()); + return updateVirtualMachine(id, displayName, group, ha, isDisplayVmEnabled, osTypeId, userData, isDynamicallyScalable, cmd.getHttpMethod(), cmd.getCustomId()); } @Override public UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData, - Boolean isDynamicallyScalable, HTTPMethod httpMethod) throws ResourceUnavailableException, InsufficientCapacityException { + Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId) throws ResourceUnavailableException, InsufficientCapacityException { UserVmVO vm = _vmDao.findById(id); if (vm == null) { throw new CloudRuntimeException("Unable to find virual machine with id " + id); @@ -1791,7 +1794,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir isDynamicallyScalable = vm.isDynamicallyScalable(); } - _vmDao.updateVM(id, displayName, ha, osTypeId, userData, isDisplayVmEnabled, isDynamicallyScalable); + _uuidMgr.checkUuid(customId, UserVm.class); + + _vmDao.updateVM(id, displayName, ha, osTypeId, userData, isDisplayVmEnabled, isDynamicallyScalable, customId); if (updateUserdata) { boolean result = updateUserDataInternal(_vmDao.findById(id)); @@ -2083,9 +2088,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir @Override @ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "deploying Vm", create = true) public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, - List securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, - HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, - List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootDiskSize) throws InsufficientCapacityException, + List securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, + HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, + List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootDiskSize, String customId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); @@ -2131,16 +2136,16 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, httpmethod, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, cpuSpeed, memory, cpuNumber, - rootDiskSize); + rootDiskSize, customId); } @Override @ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "deploying Vm", create = true) public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List networkIdList, - List securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, - HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, - List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootDiskSize) throws InsufficientCapacityException, + List securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, + HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, + List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootDiskSize, String customId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); @@ -2240,15 +2245,15 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, httpmethod, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, cpuSpeed, memory, cpuNumber, - rootDiskSize); + rootDiskSize, customId); } @Override @ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "deploying Vm", create = true) public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List networkIdList, - Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, - String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayvm, String keyboard, - List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootDiskSize) throws InsufficientCapacityException, + Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, + String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayvm, String keyboard, + List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootDiskSize, String customId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); @@ -2337,7 +2342,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, null, group, httpmethod, - userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayvm, keyboard, affinityGroupIdList, cpuSpeed, memory, cpuNumber, rootDiskSize); + userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayvm, keyboard, affinityGroupIdList, cpuSpeed, memory, cpuNumber, rootDiskSize, customId); } public void checkNameForRFCCompliance(String name) { @@ -2349,9 +2354,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir @DB protected UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate tmplt, String hostName, String displayName, - Account owner, Long diskOfferingId, Long diskSize, List networkList, List securityGroupIdList, String group, HTTPMethod httpmethod, - String userData, String sshKeyPair, HypervisorType hypervisor, Account caller, Map requestedIps, IpAddresses defaultIps, - Boolean isDisplayVmEnabled, String keyboard, List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootDiskSize) + Account owner, Long diskOfferingId, Long diskSize, List networkList, List securityGroupIdList, String group, HTTPMethod httpmethod, + String userData, String sshKeyPair, HypervisorType hypervisor, Account caller, Map requestedIps, IpAddresses defaultIps, + Boolean isDisplayVmEnabled, String keyboard, List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootDiskSize, String customId) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException { _accountMgr.checkAccess(caller, null, true, owner); @@ -2601,7 +2606,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } String instanceName = null; - String uuidName = UUID.randomUUID().toString(); + String uuidName = _uuidMgr.generateUuid(UserVm.class, customId); if (_instanceNameFlag && hypervisor.equals(HypervisorType.VMware)) { if (hostName == null) { if (displayName != null) { From 5d974a234c82487206f4d12baa9cff510e3a3260 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Tue, 26 Nov 2013 11:28:20 -0800 Subject: [PATCH 038/170] Resource metadata support for VPC Private Gateway --- api/src/com/cloud/server/ResourceTag.java | 3 +- ...spring-engine-schema-core-daos-context.xml | 1 + .../resourcedetail/VpcGatewayDetailVO.java | 81 +++++++++++++++++++ .../dao/VpcGatewayDetailsDao.java | 27 +++++++ .../dao/VpcGatewayDetailsDaoImpl.java | 33 ++++++++ .../metadata/ResourceMetaDataManagerImpl.java | 9 ++- .../cloud/tags/TaggedResourceManagerImpl.java | 9 ++- setup/db/db/schema-421to430.sql | 11 +++ 8 files changed, 167 insertions(+), 7 deletions(-) create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/VpcGatewayDetailVO.java create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcGatewayDetailsDao.java create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcGatewayDetailsDaoImpl.java diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java index 8a9116423ac..1881b9f479b 100644 --- a/api/src/com/cloud/server/ResourceTag.java +++ b/api/src/com/cloud/server/ResourceTag.java @@ -44,7 +44,8 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit RemoteAccessVpn(true, true), Zone(false, true), ServiceOffering(false, true), - Storage(false, true); + Storage(false, true), + PrivateGateway(false, true); ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport) { this.resourceTagsSupport = resourceTagsSupport; diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index 23db19d3b0c..4a31b91e0a8 100644 --- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -324,6 +324,7 @@ + diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/VpcGatewayDetailVO.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/VpcGatewayDetailVO.java new file mode 100644 index 00000000000..b78bfa8b5db --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/VpcGatewayDetailVO.java @@ -0,0 +1,81 @@ +// 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.resourcedetail; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.apache.cloudstack.api.ResourceDetail; + +@Entity +@Table(name = "vpc_gateway_details") +public class VpcGatewayDetailVO implements ResourceDetail { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "vpc_gateway_id") + private long resourceId; + + @Column(name = "name") + private String name; + + @Column(name = "value", length = 1024) + private String value; + + @Column(name = "display") + private boolean display; + + public VpcGatewayDetailVO() { + } + + public VpcGatewayDetailVO(long id, String name, String value) { + this.resourceId = id; + this.name = name; + this.value = value; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getValue() { + return value; + } + + @Override + public long getResourceId() { + return resourceId; + } + + @Override + public boolean isDisplay() { + return display; + } +} diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcGatewayDetailsDao.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcGatewayDetailsDao.java new file mode 100644 index 00000000000..4f1691926a8 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcGatewayDetailsDao.java @@ -0,0 +1,27 @@ +// 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.resourcedetail.dao; + +import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; +import org.apache.cloudstack.resourcedetail.VpcGatewayDetailVO; + +import com.cloud.utils.db.GenericDao; + +public interface VpcGatewayDetailsDao extends GenericDao, ResourceDetailsDao { + +} + diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcGatewayDetailsDaoImpl.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcGatewayDetailsDaoImpl.java new file mode 100644 index 00000000000..2b4c563a4cf --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcGatewayDetailsDaoImpl.java @@ -0,0 +1,33 @@ +// 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.resourcedetail.dao; + +import javax.ejb.Local; + +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; +import org.apache.cloudstack.resourcedetail.VpcGatewayDetailVO; +import org.springframework.stereotype.Component; + +@Component +@Local(value = { VpcGatewayDetailsDao.class }) +public class VpcGatewayDetailsDaoImpl extends ResourceDetailsDaoBase implements VpcGatewayDetailsDao { + + @Override + public void addDetail(long resourceId, String key, String value) { + super.addDetail(new VpcGatewayDetailVO(resourceId, key, value)); + } +} \ No newline at end of file diff --git a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java index 583401a9094..587f4feb563 100644 --- a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java +++ b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java @@ -24,16 +24,16 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import org.apache.cloudstack.api.ResourceDetail; import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; import org.apache.cloudstack.resourcedetail.dao.FirewallRuleDetailsDao; import org.apache.cloudstack.resourcedetail.dao.RemoteAccessVpnDetailsDao; import org.apache.cloudstack.resourcedetail.dao.UserIpAddressDetailsDao; import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao; +import org.apache.cloudstack.resourcedetail.dao.VpcGatewayDetailsDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.dc.dao.DataCenterDetailsDao; import com.cloud.event.ActionEvent; @@ -84,6 +84,8 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource RemoteAccessVpnDetailsDao _vpnDetailsDao; @Inject VpcDetailsDao _vpcDetailsDao; + @Inject + VpcGatewayDetailsDao _vpcGatewayDetailsDao; private static Map> _daoMap = new HashMap>(); @@ -104,6 +106,7 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource _daoMap.put(ResourceObjectType.LoadBalancer, _firewallRuleDetailsDao); _daoMap.put(ResourceObjectType.RemoteAccessVpn, _vpnDetailsDao); _daoMap.put(ResourceObjectType.Vpc, _vpcDetailsDao); + _daoMap.put(ResourceObjectType.PrivateGateway, _vpcGatewayDetailsDao); return true; } diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index f6529b2eba0..d78105bd448 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -25,11 +25,10 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.api.query.dao.ResourceTagJoinDao; import com.cloud.dc.dao.DataCenterDao; @@ -48,6 +47,7 @@ import com.cloud.network.security.dao.SecurityGroupDao; import com.cloud.network.vpc.NetworkACLItemDao; import com.cloud.network.vpc.dao.StaticRouteDao; import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.network.vpc.dao.VpcGatewayDao; import com.cloud.projects.dao.ProjectDao; import com.cloud.server.ResourceTag; import com.cloud.server.ResourceTag.ResourceObjectType; @@ -133,6 +133,8 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso ServiceOfferingDao _serviceOffDao; @Inject PrimaryDataStoreDao _storagePoolDao; + @Inject + VpcGatewayDao _vpcGatewayDao; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -157,6 +159,7 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso _daoMap.put(ResourceObjectType.Zone, _dataCenterDao); _daoMap.put(ResourceObjectType.ServiceOffering, _serviceOffDao); _daoMap.put(ResourceObjectType.Storage, _storagePoolDao); + _daoMap.put(ResourceObjectType.PrivateGateway, _vpcGatewayDao); return true; } diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql index 521ac168231..cf2cff4ec07 100644 --- a/setup/db/db/schema-421to430.sql +++ b/setup/db/db/schema-421to430.sql @@ -768,3 +768,14 @@ CREATE TABLE `cloud`.`vpc_details` ( PRIMARY KEY (`id`), CONSTRAINT `fk_vpc_details__vpc_id` FOREIGN KEY `fk_vpc_details__vpc_id`(`vpc_id`) REFERENCES `vpc`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`vpc_gateway_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `vpc_gateway_id` bigint unsigned NOT NULL COMMENT 'VPC gateway id', + `name` varchar(255) NOT NULL, + `value` varchar(1024) NOT NULL, + `display` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'True if the detail can be displayed to the end user', + PRIMARY KEY (`id`), + CONSTRAINT `fk_vpc_gateway_details__vpc_gateway_id` FOREIGN KEY `fk_vpc_gateway_details__vpc_gateway_id`(`vpc_gateway_id`) REFERENCES `vpc_gateways`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; From 2145505d3092472d0365b7a53679d6eb44708c42 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Tue, 26 Nov 2013 23:37:39 +0100 Subject: [PATCH 039/170] CLOUDSTACK-5280: fix issue in getBroadcastUriFromBridge (cherry picked from commit 96842475d95532cb39f0838b77b02f68c1d26dcf) Conflicts: plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java --- .../hypervisor/kvm/resource/LibvirtComputingResource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 834e26e3dd8..c88a279fb9d 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 @@ -1609,13 +1609,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv private String getBroadcastUriFromBridge(String brName) { String pif = matchPifFileInDirectory(brName); - Pattern pattern = Pattern.compile("(\\D+)(\\d+)"); + Pattern pattern = Pattern.compile("(\\D+)(\\d+)(\\D*)(\\d*)"); Matcher matcher = pattern.matcher(pif); if (matcher.find()) { if (brName.startsWith("brvx")) { return BroadcastDomainType.Vxlan.toUri(matcher.group(2)).toString(); } else { - return BroadcastDomainType.Vlan.toUri(matcher.group(2)).toString(); + return BroadcastDomainType.Vlan.toUri(matcher.group(4)).toString(); } } else { s_logger.debug("failed to get vNet id from bridge " + brName + "attached to physical interface" + pif); From 8ce6d5271c91d9a1fdb920d64c44c0438b5fbff0 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 26 Nov 2013 15:04:08 -0800 Subject: [PATCH 040/170] CLOUDSTACK-4428: UI > volume > take snapshot action, recurring snapshot action > for volumes whose hypervisor is KVM and whose VM is not Running, always show the 2 actions regardless value of "kvm.snapshot.enabled". --- ui/scripts/storage.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ui/scripts/storage.js b/ui/scripts/storage.js index 22330e80b9c..03b88f82d9c 100644 --- a/ui/scripts/storage.js +++ b/ui/scripts/storage.js @@ -1896,14 +1896,15 @@ if (jsonObj.hypervisor != "Ovm" && jsonObj.state == "Ready") { if (jsonObj.hypervisor == 'KVM') { - if (g_KVMsnapshotenabled == true) { + if (json.vmstate == 'Running') { + if (g_KVMsnapshotenabled == true) { //"kvm.snapshot.enabled" flag should be taken to account only when snapshot is being created for Running vm (CLOUDSTACK-4428) + allowedActions.push("takeSnapshot"); + allowedActions.push("recurringSnapshot"); + } + } else { allowedActions.push("takeSnapshot"); allowedActions.push("recurringSnapshot"); - } else { - if(jsonObj.vmstate == 'Stopped' || jsonObj.virtualmachineid == undefined) { //volume of stopped VM, or detached volume - allowedActions.push("takeSnapshot"); - } - } + } } else { allowedActions.push("takeSnapshot"); allowedActions.push("recurringSnapshot"); From 414d415dba380e655dcd8d8baac621bc2a0db7ab Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Tue, 26 Nov 2013 16:21:45 -0800 Subject: [PATCH 041/170] CLOUDSTACK-5281: Resource limit shouldnt be counted for resources with display flag = 0. Adding functions to resourcelimitmanager and doing it for the volumes at the moment. --- .../com/cloud/storage/VolumeApiService.java | 2 +- .../com/cloud/user/ResourceLimitService.java | 36 +++++++++++++ .../command/user/volume/UpdateVolumeCmd.java | 2 +- .../com/cloud/storage/dao/VolumeDaoImpl.java | 4 ++ .../ResourceLimitManagerImpl.java | 47 +++++++++++++++++ .../cloud/storage/VolumeApiServiceImpl.java | 51 ++++++++++--------- .../vpc/MockResourceLimitManagerImpl.java | 21 ++++++++ 7 files changed, 137 insertions(+), 26 deletions(-) diff --git a/api/src/com/cloud/storage/VolumeApiService.java b/api/src/com/cloud/storage/VolumeApiService.java index 7e9ea62de2e..db23c1be227 100644 --- a/api/src/com/cloud/storage/VolumeApiService.java +++ b/api/src/com/cloud/storage/VolumeApiService.java @@ -87,7 +87,7 @@ public interface VolumeApiService { Snapshot allocSnapshot(Long volumeId, Long policyId) throws ResourceAllocationException; - Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId); + Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId, long owner); /** * Extracts the volume to a particular location. diff --git a/api/src/com/cloud/user/ResourceLimitService.java b/api/src/com/cloud/user/ResourceLimitService.java index bec65d5b7e8..f8923b708a9 100644 --- a/api/src/com/cloud/user/ResourceLimitService.java +++ b/api/src/com/cloud/user/ResourceLimitService.java @@ -139,4 +139,40 @@ public interface ResourceLimitService { */ public long getResourceCount(Account account, ResourceType type); + + /** + * Checks if a limit has been exceeded for an account depending on the displayResource flag + * + * @param account + * @param type + * @param displayResource + * @param count + * the number of resources being allocated, count will be added to current allocation and compared + * against maximum allowed allocation + * @throws ResourceAllocationException + */ + void checkResourceLimit(Account account, ResourceType type, Boolean displayResource, long... count) throws ResourceAllocationException; + + + /** + * Increments the resource count depending on the displayResource flag + * + * @param accountId + * @param type + * @param displayResource + * @param delta + */ + void incrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta); + + /** + * Increments/Decrements the resource count depending on the displayResource flag + * + * @param accountId + * @param type + * @param displayResource + * @param delta + */ + void changeResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta); + + void decrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta); } diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java index a47c9233d7d..7233b4fb5d3 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java @@ -141,7 +141,7 @@ public class UpdateVolumeCmd extends BaseAsyncCustomIdCmd { @Override public void execute() { CallContext.current().setEventDetails("Volume Id: " + getId()); - Volume result = _volumeService.updateVolume(getId(), getPath(), getState(), getStorageId(), getDisplayVolume(), getCustomId()); + Volume result = _volumeService.updateVolume(getId(), getPath(), getState(), getStorageId(), getDisplayVolume(), getCustomId(), getEntityOwnerId()); if (result != null) { VolumeResponse response = _responseGenerator.createVolumeResponse(result); response.setResponseName(getCommandName()); diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java index c64a253b81c..5120387433f 100755 --- a/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java @@ -346,6 +346,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol CountByAccount.select(null, Func.COUNT, null); CountByAccount.and("account", CountByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); CountByAccount.and("state", CountByAccount.entity().getState(), SearchCriteria.Op.NIN); + CountByAccount.and("displayVolume", CountByAccount.entity().isDisplayVolume(), Op.EQ); CountByAccount.done(); primaryStorageSearch = createSearchBuilder(SumCount.class); @@ -355,6 +356,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol primaryStorageSearch.and().op("path", primaryStorageSearch.entity().getPath(), Op.NNULL); primaryStorageSearch.or("states", primaryStorageSearch.entity().getState(), Op.IN); primaryStorageSearch.cp(); + primaryStorageSearch.and("displayVolume", primaryStorageSearch.entity().isDisplayVolume(), Op.EQ); primaryStorageSearch.and("isRemoved", primaryStorageSearch.entity().getRemoved(), Op.NULL); primaryStorageSearch.done(); @@ -382,6 +384,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol SearchCriteria sc = CountByAccount.create(); sc.setParameters("account", accountId); sc.setParameters("state", Volume.State.Destroy); + sc.setParameters("displayVolume", 1); return customSearch(sc, null).get(0); } @@ -393,6 +396,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol sc.setParameters("virtualRouterVmIds", virtualRouters.toArray(new Object[virtualRouters.size()])); } sc.setParameters("states", State.Allocated); + sc.setParameters("displayVolume", 1); List storageSpace = customSearch(sc, null); if (storageSpace != null) { return storageSpace.get(0).sum; diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index ed4c480e602..70e8cdf3c4f 100755 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -954,6 +954,53 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim return _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type); } + @Override + public void checkResourceLimit(Account account, ResourceType type, Boolean displayResource, long... count) throws ResourceAllocationException { + + // By default its always on. + // TODO boilerplate code. + boolean displayflag = (displayResource == null) || (displayResource != null && displayResource); + + if(displayflag){ + checkResourceLimit(account, type, count); + } + } + + @Override + public void incrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) { + + // 1. If its null assume displayResource = 1 + // 2. If its not null then increment if displayResource = 1 + if(displayResource == null || (displayResource != null && displayResource)){ + incrementResourceCount(accountId, type, delta); + } + } + + @Override + public void decrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) { + + // 1. If its null assume displayResource = 1 + // 2. If its not null then decrement if displayResource = 1 + if(displayResource == null || (displayResource != null && displayResource)){ + decrementResourceCount(accountId, type, delta); + } + } + + @Override + public void changeResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) { + + // meaning that the display flag is not changed so neither increment or decrement + if(displayResource == null) return; + + // Increment because the display is turned on. + if(displayResource){ + // checkResourceLimit((Account)_accountDao.findById(accountId), type, delta); + incrementResourceCount(accountId, type, delta); + }else{ + decrementResourceCount(accountId, type, delta); + } + } + protected class ResourceCountCheckTask extends ManagedContextRunnable { public ResourceCountCheckTask() { diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index aaf0fe3e548..0fd0ab0872d 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -458,8 +458,16 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic // permission check _accountMgr.checkAccess(caller, null, true, _accountMgr.getActiveAccountById(ownerId)); + if (displayVolumeEnabled == null) { + displayVolumeEnabled = true; + } else { + if (!_accountMgr.isRootAdmin(caller.getType())) { + throw new PermissionDeniedException("Cannot update parameter displayvolume, only admin permitted "); + } + } + // Check that the resource limit for volumes won't be exceeded - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.volume); + _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.volume, displayVolumeEnabled); Long zoneId = cmd.getZoneId(); Long diskOfferingId = null; @@ -574,16 +582,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic _accountMgr.checkAccess(caller, null, true, snapshotCheck); } - if (displayVolumeEnabled == null) { - displayVolumeEnabled = true; - } else { - if (!_accountMgr.isRootAdmin(caller.getType())) { - throw new PermissionDeniedException("Cannot update parameter displayvolume, only admin permitted "); - } - } - // Check that the resource limit for primary storage won't be exceeded - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.primary_storage, new Long(size)); + _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.primary_storage, displayVolumeEnabled, new Long(size)); // Verify that zone exists DataCenterVO zone = _dcDao.findById(zoneId); @@ -652,8 +652,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic // Increment resource count during allocation; if actual creation fails, // decrement it - _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume); - _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize())); + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume, displayVolumeEnabled); + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, displayVolumeEnabled, new Long(volume.getSize())); return volume; } }); @@ -691,8 +691,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic } finally { if (!created) { s_logger.trace("Decrementing volume resource count for account id=" + volume.getAccountId() + " as volume failed to create on the backend"); - _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume); - _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize())); + _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, cmd.getDisplayVolume()); + _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, cmd.getDisplayVolume(), new Long(volume.getSize())); } } } @@ -825,7 +825,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic if (!shrinkOk) { /* Check resource limit for this account on primary storage resource */ - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), ResourceType.primary_storage, new Long(newSize - currentSize)); + _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), ResourceType.primary_storage, volume.isDisplayVolume(), new Long(newSize - currentSize)); } /* @@ -875,9 +875,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic /* Update resource count for the account on primary storage resource */ if (!shrinkOk) { - _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, new Long(newSize - currentSize)); + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), new Long(newSize - currentSize)); } else { - _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, new Long(currentSize - newSize)); + _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), new Long(currentSize - newSize)); } return volume; } catch (InterruptedException e) { @@ -928,11 +928,11 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic VMInstanceVO vmInstance = _vmInstanceDao.findById(instanceId); if (instanceId == null || (vmInstance.getType().equals(VirtualMachine.Type.User))) { // Decrement the resource count for volumes and primary storage belonging user VM's only - _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume); + _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplayVolume()); /* If volume is in primary storage, decrement primary storage count else decrement secondary storage count (in case of upload volume). */ if (volume.getFolder() != null || volume.getPath() != null || volume.getState() == Volume.State.Allocated) { - _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize())); + _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), new Long(volume.getSize())); } else { _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), ResourceType.secondary_storage.getOrdinal()); } @@ -1140,17 +1140,14 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPDATE, eventDescription = "updating volume", async = true) - public Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId) { + public Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId, long entityOwnerId) { + VolumeVO volume = _volumeDao.findById(volumeId); if (path != null) { volume.setPath(path); } - if (displayVolume != null) { - volume.setDisplayVolume(displayVolume); - } - if (state != null) { try { Volume.State volumeState = Volume.State.valueOf(state); @@ -1173,6 +1170,12 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic volume.setUuid(customId); } + if (displayVolume != null && displayVolume != volume.isDisplayVolume()) { // No need to check permissions since only Admin allowed to call this API. + volume.setDisplayVolume(displayVolume); + _resourceLimitMgr.changeResourceCount(entityOwnerId, ResourceType.volume, displayVolume); + _resourceLimitMgr.changeResourceCount(entityOwnerId, ResourceType.primary_storage, displayVolume, new Long(volume.getSize())); + } + _volumeDao.update(volumeId, volume); return volume; diff --git a/server/test/com/cloud/vpc/MockResourceLimitManagerImpl.java b/server/test/com/cloud/vpc/MockResourceLimitManagerImpl.java index 77568254503..aec82fd5db1 100644 --- a/server/test/com/cloud/vpc/MockResourceLimitManagerImpl.java +++ b/server/test/com/cloud/vpc/MockResourceLimitManagerImpl.java @@ -22,6 +22,7 @@ import java.util.Map; import javax.ejb.Local; import javax.naming.ConfigurationException; +import com.cloud.configuration.Resource; import org.springframework.stereotype.Component; import com.cloud.configuration.Resource.ResourceType; @@ -148,6 +149,26 @@ public class MockResourceLimitManagerImpl extends ManagerBase implements Resourc return 0; } + @Override + public void checkResourceLimit(Account account, ResourceType type, Boolean displayResource, long... count) throws ResourceAllocationException { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void incrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void changeResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void decrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) { + //To change body of implemented methods use File | Settings | File Templates. + } + /* (non-Javadoc) * @see com.cloud.utils.component.Manager#configure(java.lang.String, java.util.Map) */ From 7af387c894dc273bd40626cc6050a041a7082c54 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Tue, 26 Nov 2013 14:55:04 -0800 Subject: [PATCH 042/170] Resource metadata support for NetworkACLList Conflicts: server/src/com/cloud/tags/TaggedResourceManagerImpl.java --- api/src/com/cloud/server/ResourceTag.java | 3 +- ...spring-engine-schema-core-daos-context.xml | 2 + .../NetworkACLListDetailVO.java | 82 +++++++++++++++++++ .../dao/NetworkACLListDetailsDao.java | 26 ++++++ .../dao/NetworkACLListDetailsDaoImpl.java | 33 ++++++++ .../metadata/ResourceMetaDataManagerImpl.java | 4 + .../cloud/tags/TaggedResourceManagerImpl.java | 4 + setup/db/db/schema-421to430.sql | 10 +++ 8 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/NetworkACLListDetailVO.java create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLListDetailsDao.java create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLListDetailsDaoImpl.java diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java index 1881b9f479b..e76b777737f 100644 --- a/api/src/com/cloud/server/ResourceTag.java +++ b/api/src/com/cloud/server/ResourceTag.java @@ -45,7 +45,8 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit Zone(false, true), ServiceOffering(false, true), Storage(false, true), - PrivateGateway(false, true); + PrivateGateway(false, true), + NetworkACLList(false, true); ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport) { this.resourceTagsSupport = resourceTagsSupport; diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index 4a31b91e0a8..d12e5cba88f 100644 --- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -325,6 +325,8 @@ + + diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/NetworkACLListDetailVO.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/NetworkACLListDetailVO.java new file mode 100644 index 00000000000..71cf563478a --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/NetworkACLListDetailVO.java @@ -0,0 +1,82 @@ +// 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.resourcedetail; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.apache.cloudstack.api.ResourceDetail; + +@Entity +@Table(name = "network_acl_details") +public class NetworkACLListDetailVO implements ResourceDetail { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "network_acl_id") + private long resourceId; + + @Column(name = "name") + private String name; + + @Column(name = "value", length = 1024) + private String value; + + @Column(name = "display") + private boolean display; + + public NetworkACLListDetailVO() { + } + + public NetworkACLListDetailVO(long id, String name, String value) { + this.resourceId = id; + this.name = name; + this.value = value; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getValue() { + return value; + } + + @Override + public long getResourceId() { + return resourceId; + } + + @Override + public boolean isDisplay() { + return display; + } +} + diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLListDetailsDao.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLListDetailsDao.java new file mode 100644 index 00000000000..1c8524505dd --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLListDetailsDao.java @@ -0,0 +1,26 @@ +// 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.resourcedetail.dao; + +import org.apache.cloudstack.resourcedetail.NetworkACLListDetailVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; + +import com.cloud.utils.db.GenericDao; + +public interface NetworkACLListDetailsDao extends GenericDao, ResourceDetailsDao { + +} \ No newline at end of file diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLListDetailsDaoImpl.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLListDetailsDaoImpl.java new file mode 100644 index 00000000000..0b7037f7975 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLListDetailsDaoImpl.java @@ -0,0 +1,33 @@ +// 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.resourcedetail.dao; + +import javax.ejb.Local; + +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; +import org.apache.cloudstack.resourcedetail.NetworkACLListDetailVO; +import org.springframework.stereotype.Component; + +@Component +@Local(value = { NetworkACLListDetailsDao.class }) +public class NetworkACLListDetailsDaoImpl extends ResourceDetailsDaoBase implements NetworkACLListDetailsDao { + + @Override + public void addDetail(long resourceId, String key, String value) { + super.addDetail(new NetworkACLListDetailVO(resourceId, key, value)); + } +} diff --git a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java index 587f4feb563..ec000bf80de 100644 --- a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java +++ b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java @@ -27,6 +27,7 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.api.ResourceDetail; import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; import org.apache.cloudstack.resourcedetail.dao.FirewallRuleDetailsDao; +import org.apache.cloudstack.resourcedetail.dao.NetworkACLListDetailsDao; import org.apache.cloudstack.resourcedetail.dao.RemoteAccessVpnDetailsDao; import org.apache.cloudstack.resourcedetail.dao.UserIpAddressDetailsDao; import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao; @@ -86,6 +87,8 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource VpcDetailsDao _vpcDetailsDao; @Inject VpcGatewayDetailsDao _vpcGatewayDetailsDao; + @Inject + NetworkACLListDetailsDao _networkACLListDetailsDao; private static Map> _daoMap = new HashMap>(); @@ -107,6 +110,7 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource _daoMap.put(ResourceObjectType.RemoteAccessVpn, _vpnDetailsDao); _daoMap.put(ResourceObjectType.Vpc, _vpcDetailsDao); _daoMap.put(ResourceObjectType.PrivateGateway, _vpcGatewayDetailsDao); + _daoMap.put(ResourceObjectType.NetworkACLList, _networkACLListDetailsDao); return true; } diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index d78105bd448..6b52a97c07c 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -45,6 +45,7 @@ import com.cloud.network.dao.RemoteAccessVpnDao; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.network.security.dao.SecurityGroupDao; import com.cloud.network.vpc.NetworkACLItemDao; +import com.cloud.network.vpc.dao.NetworkACLDao; import com.cloud.network.vpc.dao.StaticRouteDao; import com.cloud.network.vpc.dao.VpcDao; import com.cloud.network.vpc.dao.VpcGatewayDao; @@ -135,6 +136,8 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso PrimaryDataStoreDao _storagePoolDao; @Inject VpcGatewayDao _vpcGatewayDao; + @Inject + NetworkACLDao _networkACLListDao; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -160,6 +163,7 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso _daoMap.put(ResourceObjectType.ServiceOffering, _serviceOffDao); _daoMap.put(ResourceObjectType.Storage, _storagePoolDao); _daoMap.put(ResourceObjectType.PrivateGateway, _vpcGatewayDao); + _daoMap.put(ResourceObjectType.NetworkACLList, _networkACLListDao); return true; } diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql index cf2cff4ec07..dad9a6b0993 100644 --- a/setup/db/db/schema-421to430.sql +++ b/setup/db/db/schema-421to430.sql @@ -779,3 +779,13 @@ CREATE TABLE `cloud`.`vpc_gateway_details` ( PRIMARY KEY (`id`), CONSTRAINT `fk_vpc_gateway_details__vpc_gateway_id` FOREIGN KEY `fk_vpc_gateway_details__vpc_gateway_id`(`vpc_gateway_id`) REFERENCES `vpc_gateways`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`network_acl_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `network_acl_id` bigint unsigned NOT NULL COMMENT 'VPC gateway id', + `name` varchar(255) NOT NULL, + `value` varchar(1024) NOT NULL, + `display` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'True if the detail can be displayed to the end user', + PRIMARY KEY (`id`), + CONSTRAINT `fk_network_acl_details__network_acl_id` FOREIGN KEY `fk_network_acl_details__network_acl_id`(`network_acl_id`) REFERENCES `network_acl`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; From 6c9edaf6132ea4e7a2d5255786b619eed1f0e19e Mon Sep 17 00:00:00 2001 From: Jayapal Date: Wed, 27 Nov 2013 11:01:36 +0530 Subject: [PATCH 043/170] CLOUDSTACK-5285 Corrected the API description --- .../cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java index 6cbb78b0dd2..9b86577f8e3 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java @@ -37,7 +37,7 @@ import com.cloud.network.Network; import com.cloud.user.Account; import com.cloud.vm.NicSecondaryIp; -@APICommand(name = "removeIpFromNic", description = "Assigns secondary IP to NIC.", responseObject = SuccessResponse.class) +@APICommand(name = "removeIpFromNic", description = "Removes secondary IP from the NIC.", responseObject = SuccessResponse.class) public class RemoveIpFromVmNicCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RemoveIpFromVmNicCmd.class.getName()); private static final String s_name = "removeipfromnicresponse"; From c781e3b668c9b4562bed74d7f314c59a1af5826e Mon Sep 17 00:00:00 2001 From: Devdeep Singh Date: Wed, 27 Nov 2013 13:01:28 +0530 Subject: [PATCH 044/170] Fixing creation of VM with virtual disks on a shared storage for hyperv. The shared storage path wasn't getting interpreted correctly by the agent. --- .../HypervResource/CloudStackTypes.cs | 133 ++++++++++++++++-- .../HypervResource/HypervResource.csproj | 1 + .../HypervResourceController.cs | 48 ++++++- .../HypervResource/WmiCallsV2.cs | 6 +- 4 files changed, 170 insertions(+), 18 deletions(-) diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs index dfc3e206f06..af8c61f20f5 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs @@ -31,23 +31,114 @@ namespace HypervResource { public class PrimaryDataStoreTO { - public string path; + private string path; + public string host; + private string poolType; + public Uri uri; + public string _role; + + public string Path + { + get + { + if (this.isLocal) + { + return path; + } + else + { + return this.UncPath; + } + } + set + { + this.path = value; + } + } + + public string UncPath + { + get + { + string uncPath = null; + if (uri.Scheme.Equals("cifs") || uri.Scheme.Equals("networkfilesystem")) + { + uncPath = @"\\" + uri.Host + uri.LocalPath; + } + return uncPath; + } + } + + public string User + { + get + { + var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); + return System.Web.HttpUtility.UrlDecode(queryDictionary["user"]); + } + } + + public string Password + { + get + { + var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); + return System.Web.HttpUtility.UrlDecode(queryDictionary["password"]); + } + } + + public string Domain + { + get + { + var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); + if (queryDictionary["domain"] != null) + { + return System.Web.HttpUtility.UrlDecode(queryDictionary["domain"]); + } + else return uri.Host; + } + } + + public Boolean isLocal + { + get + { + if (poolType.Equals("Filesystem")) + { + return true; + } + else + { + return false; + } + } + } public static PrimaryDataStoreTO ParseJson(dynamic json) { PrimaryDataStoreTO result = null; - if (json == null) { return result; } + dynamic primaryDataStoreTOJson = json[CloudStackTypes.PrimaryDataStoreTO]; if (primaryDataStoreTOJson != null) { result = new PrimaryDataStoreTO() { - path = (string)primaryDataStoreTOJson.path + path = (string)primaryDataStoreTOJson.path, + host = (string)primaryDataStoreTOJson.host, + poolType = (string)primaryDataStoreTOJson.poolType }; + + if (!result.isLocal) + { + // Delete security credentials in original command. Prevents logger from spilling the beans, as it were. + String uriStr = @"cifs://" + result.host + result.path; + result.uri = new Uri(uriStr); + } } return result; } @@ -61,12 +152,22 @@ namespace HypervResource { get { - String result = Path.Combine(this.primaryDataStore.path, this.name); + string fileName = null; + if (this.primaryDataStore.isLocal) + { + fileName = Path.Combine(this.primaryDataStore.Path, this.name); + } + else + { + fileName = @"\\" + this.primaryDataStore.uri.Host + this.primaryDataStore.uri.LocalPath + @"\" + this.name; + } + if (this.format != null) { - result = result + "." + this.format.ToLowerInvariant(); + fileName = fileName + "." + this.format.ToLowerInvariant(); } - return result; + + return fileName; } } @@ -116,11 +217,16 @@ namespace HypervResource { logger.Info("No image format in VolumeObjectTO, going to use format from first file that matches " + volInfo.FullFileName); - string[] choices = Directory.GetFiles(volInfo.primaryDataStore.path, volInfo.name + ".vhd*"); + string path = volInfo.primaryDataStore.Path; + if (!volInfo.primaryDataStore.isLocal) + { + path = volInfo.primaryDataStore.UncPath; + } + string[] choices = choices = Directory.GetFiles(path, volInfo.name + ".vhd*"); if (choices.Length != 1) { - String errMsg = "Tried to guess file extension, but cannot find file corresponding to " + Path.Combine(volInfo.primaryDataStore.path, volInfo.name); // format being guessed. + String errMsg = "Tried to guess file extension, but cannot find file corresponding to " + Path.Combine(volInfo.primaryDataStore.Path, volInfo.name); // format being guessed. logger.Debug(errMsg); } else @@ -145,7 +251,16 @@ namespace HypervResource { if (String.IsNullOrEmpty(this.path)) { - return Path.Combine(this.primaryDataStore.path, this.name) + '.' + this.format.ToLowerInvariant(); + string fileName = null; + if (this.primaryDataStore.isLocal) + { + fileName = Path.Combine(this.primaryDataStore.Path, this.name); + } + else + { + fileName = @"\\" + this.primaryDataStore.uri.Host + this.primaryDataStore.uri.LocalPath + @"\" + this.name; + } + return fileName +'.' + this.format.ToLowerInvariant(); } return this.path; } diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResource.csproj b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResource.csproj index 05a0f513d8b..a2dc323d5ef 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResource.csproj +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResource.csproj @@ -63,6 +63,7 @@ ..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll + diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index 0d56fef0acd..a5c54a6e0ad 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -23,7 +23,10 @@ using Microsoft.CSharp.RuntimeBinder; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; +using System.Collections; +using System.Collections.Specialized; using System.Collections.Generic; +using System.Configuration; using System.IO; using System.Linq; using System.Net; @@ -78,6 +81,31 @@ namespace HypervResource public ulong ParentPartitionMinMemoryMb; public string LocalSecondaryStoragePath; public string systemVmIso; + + private string getPrimaryKey(string id) + { + return "primary_storage_" + id; + } + + public string getPrimaryStorage(string id) + { + NameValueCollection settings = ConfigurationManager.AppSettings; + return settings.Get(getPrimaryKey(id)); + } + + public void setPrimaryStorage(string id, string path) + { + Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); + KeyValueConfigurationCollection settings = config.AppSettings.Settings; + string key = getPrimaryKey(id); + if (settings[key] != null) + { + settings.Remove(key); + } + settings.Add(key, path); + config.Save(ConfigurationSaveMode.Modified); + ConfigurationManager.RefreshSection("appSettings"); + } } /// @@ -1092,14 +1120,24 @@ namespace HypervResource logger.Info(CloudStackTypes.CopyCommand + cmd.ToString()); + string destFile = null; + if (destTemplateObjectTO != null && destTemplateObjectTO.primaryDataStore != null) + { + destFile = destTemplateObjectTO.FullFileName; + if (!destTemplateObjectTO.primaryDataStore.isLocal) + { + PrimaryDataStoreTO primary = destTemplateObjectTO.primaryDataStore; + Utils.ConnectToRemote(primary.UncPath, primary.Domain, primary.User, primary.Password); + } + } + // Already exists? - if (destTemplateObjectTO != null && - File.Exists(destTemplateObjectTO.FullFileName) && + if (destFile != null && File.Exists(destFile) && !String.IsNullOrEmpty(destTemplateObjectTO.checksum)) { // TODO: checksum fails us, because it is of the compressed image. // ASK: should we store the compressed or uncompressed version or is the checksum not calculated correctly? - result = VerifyChecksum(destTemplateObjectTO.FullFileName, destTemplateObjectTO.checksum); + result = VerifyChecksum(destFile, destTemplateObjectTO.checksum); } // Do we have to create a new one? @@ -1112,8 +1150,6 @@ namespace HypervResource // NFS provider download to primary storage? if ((srcTemplateObjectTO.s3DataStoreTO != null || srcTemplateObjectTO.nfsDataStoreTO != null) && destTemplateObjectTO.primaryDataStore != null) { - string destFile = destTemplateObjectTO.FullFileName; - if (File.Exists(destFile)) { logger.Info("Deleting existing file " + destFile); @@ -1187,7 +1223,7 @@ namespace HypervResource { destVolumeObjectTO.format = srcTemplateObjectTO.format; } - string destFile = destVolumeObjectTO.FullFileName; + destFile = destVolumeObjectTO.FullFileName; string srcFile = srcTemplateObjectTO.FullFileName; if (!File.Exists(srcFile)) diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs index 0a3f008750b..ca49bd90c90 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs @@ -286,13 +286,13 @@ namespace HypervResource throw new ArgumentException(errMsg); } errMsg = vmName + ": Malformed PrimaryDataStore for disk " + diskDrive.ToString(); - if (String.IsNullOrEmpty(volInfo.primaryDataStore.path)) + if (String.IsNullOrEmpty(volInfo.primaryDataStore.Path)) { logger.Error(errMsg); throw new ArgumentException(errMsg); } - errMsg = vmName + ": Missing folder PrimaryDataStore for disk " + diskDrive.ToString() + ", missing path: " + volInfo.primaryDataStore.path; - if (!Directory.Exists(volInfo.primaryDataStore.path)) + errMsg = vmName + ": Missing folder PrimaryDataStore for disk " + diskDrive.ToString() + ", missing path: " + volInfo.primaryDataStore.Path; + if (!Directory.Exists(volInfo.primaryDataStore.Path)) { logger.Error(errMsg); throw new ArgumentException(errMsg); From 2774b62d64989bddc1e4664ef7a93dff11c77657 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Fri, 8 Nov 2013 15:18:05 +0100 Subject: [PATCH 045/170] Fixing bugs from Coverity related to Dereferenced Null after check and as return value. Signed-off-by: Daan Hoogland --- agent/src/com/cloud/agent/AgentShell.java | 14 +- .../management/ServiceManagerImpl.java | 16 +- .../contrail/model/VirtualMachineModel.java | 64 +++---- .../api/command/LdapImportUsersCmd.java | 37 ++-- .../cloud/server/ConfigurationServerImpl.java | 159 +++++++++--------- utils/src/com/cloud/utils/nio/Link.java | 9 +- 6 files changed, 158 insertions(+), 141 deletions(-) diff --git a/agent/src/com/cloud/agent/AgentShell.java b/agent/src/com/cloud/agent/AgentShell.java index 936e3cd7a27..87004f9a1e4 100644 --- a/agent/src/com/cloud/agent/AgentShell.java +++ b/agent/src/com/cloud/agent/AgentShell.java @@ -167,7 +167,8 @@ public class AgentShell implements IAgentShell, Daemon { void loadProperties() throws ConfigurationException { final File file = PropertiesUtil.findConfigFile("agent.properties"); - if (file == null) { + + if (null == file) { throw new ConfigurationException("Unable to find agent.properties."); } @@ -303,12 +304,17 @@ public class AgentShell implements IAgentShell, Daemon { // For KVM agent, do it specially here File file = new File("/etc/cloudstack/agent/log4j-cloud.xml"); - if (!file.exists()) { + if(!file.exists()) { file = PropertiesUtil.findConfigFile("log4j-cloud.xml"); } - DOMConfigurator.configureAndWatch(file.getAbsolutePath()); - s_logger.info("Agent started"); + if (null != file) { + DOMConfigurator.configureAndWatch(file.getAbsolutePath()); + + s_logger.info("Agent started"); + } else { + s_logger.error("Could not start the Agent because the absolut path of the \"log4j-cloud.xml\" file cannot be determined."); + } final Class c = this.getClass(); _version = c.getPackage().getImplementationVersion(); diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java index ca44757d07c..e15e2ce8ff6 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java @@ -29,14 +29,11 @@ import net.juniper.contrail.api.ApiConnector; import net.juniper.contrail.api.types.ServiceInstance; import net.juniper.contrail.api.types.VirtualNetwork; -import org.apache.log4j.Logger; - -import com.google.gson.Gson; - import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.network.contrail.api.response.ServiceInstanceResponse; import org.apache.cloudstack.network.contrail.model.ServiceInstanceModel; import org.apache.cloudstack.network.contrail.model.VirtualMachineModel; +import org.apache.log4j.Logger; import com.cloud.api.ApiDBUtils; import com.cloud.dc.DataCenter; @@ -61,6 +58,7 @@ import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.VirtualMachineName; import com.cloud.vm.dao.UserVmDao; +import com.google.gson.Gson; @Local(value = {ServiceManager.class}) public class ServiceManagerImpl implements ServiceManager { @@ -98,7 +96,7 @@ public class ServiceManagerImpl implements ServiceManager { */ @ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "createServiceInstance", create = true) private ServiceVirtualMachine createServiceVM(DataCenter zone, Account owner, VirtualMachineTemplate template, ServiceOffering serviceOffering, String name, - ServiceInstance siObj, Network left, Network right) { + ServiceInstance siObj, Network left, Network right) { long id = _vmDao.getNextInSequence(Long.class, "id"); DataCenterDeployment plan = new DataCenterDeployment(zone.getId()); @@ -111,8 +109,8 @@ public class ServiceManagerImpl implements ServiceManager { String instanceName = VirtualMachineName.getVmName(id, owner.getId(), "SRV"); ServiceVirtualMachine svm = - new ServiceVirtualMachine(id, instanceName, name, template.getId(), serviceOffering.getId(), template.getHypervisorType(), template.getGuestOSId(), - zone.getId(), owner.getDomainId(), owner.getAccountId(), false); + new ServiceVirtualMachine(id, instanceName, name, template.getId(), serviceOffering.getId(), template.getHypervisorType(), template.getGuestOSId(), + zone.getId(), owner.getDomainId(), owner.getAccountId(), false); // database synchronization code must be able to distinguish service instance VMs. Map kvmap = new HashMap(); @@ -132,7 +130,7 @@ public class ServiceManagerImpl implements ServiceManager { @Override public ServiceVirtualMachine createServiceInstance(DataCenter zone, Account owner, VirtualMachineTemplate template, ServiceOffering serviceOffering, String name, - Network left, Network right) { + Network left, Network right) { s_logger.debug("createServiceInstance by " + owner.getAccountName()); // TODO: permission model. // service instances need to be able to access the public network. @@ -227,10 +225,12 @@ public class ServiceManagerImpl implements ServiceManager { @Override public ServiceInstanceResponse createServiceInstanceResponse(long instanceId) { s_logger.debug("ServiceInstance response for id: " + instanceId); + UserVmVO vm = _vmDao.findById(instanceId); ServiceInstanceResponse response = new ServiceInstanceResponse(); response.setId(vm.getUuid()); Account owner = _accountService.getAccount(vm.getAccountId()); + if (owner.getType() == Account.ACCOUNT_TYPE_PROJECT) { Project project = ApiDBUtils.findProjectByProjectAccountIdIncludingRemoved(owner.getAccountId()); response.setProjectId(project.getUuid()); diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualMachineModel.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualMachineModel.java index 32d5d938996..96cea95250d 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualMachineModel.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualMachineModel.java @@ -27,12 +27,8 @@ import net.juniper.contrail.api.types.Project; import net.juniper.contrail.api.types.ServiceInstance; import net.juniper.contrail.api.types.VirtualMachine; -import org.apache.log4j.Logger; - -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; - import org.apache.cloudstack.network.contrail.management.ContrailManager; +import org.apache.log4j.Logger; import com.cloud.exception.InternalErrorException; import com.cloud.network.dao.NetworkDao; @@ -42,11 +38,13 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.NicVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.dao.NicDao; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; public class VirtualMachineModel extends ModelObjectBase { private static final Logger s_logger = Logger.getLogger(VirtualMachineModel.class); - private String _uuid; + private final String _uuid; private long _instanceId; /* @@ -113,8 +111,12 @@ public class VirtualMachineModel extends ModelObjectBase { throw new CloudRuntimeException("Unable to read service-instance object", ex); } if (siObj == null) { + //If the ServiceInstance object is null, do not call build. It will break in many places. Instead, call update passing the controller as parameter. + //It will then create a new ServiceInstance is that's null. siModel = new ServiceInstanceModel(serviceUuid); - siModel.build(controller, siObj); + siModel.update(controller); + + siObj = siModel.getServiceInstance(); } } _serviceModel = siModel; @@ -197,21 +199,21 @@ public class VirtualMachineModel extends ModelObjectBase { boolean isActiveInstance(VMInstanceVO instance) { switch (instance.getState()) { - case Migrating: - case Starting: - case Running: - case Shutdowned: - case Stopped: - case Stopping: - return true; + case Migrating: + case Starting: + case Running: + case Shutdowned: + case Stopped: + case Stopping: + return true; - case Destroyed: - case Error: - case Expunging: - return false; + case Destroyed: + case Error: + case Expunging: + return false; - default: - s_logger.warn("Unknown VMInstance state " + instance.getState().getDescription()); + default: + s_logger.warn("Unknown VMInstance state " + instance.getState().getDescription()); } return true; } @@ -255,17 +257,17 @@ public class VirtualMachineModel extends ModelObjectBase { String tag; switch (nic.getDeviceId()) { - case 0: - tag = "management"; - break; - case 1: - tag = "left"; - break; - case 2: - tag = "right"; - break; - default: - tag = null; + case 0: + tag = "management"; + break; + case 1: + tag = "left"; + break; + case 2: + tag = "right"; + break; + default: + tag = null; } VMInterfaceModel vmiModel = getVMInterface(nic.getUuid()); diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java index 129392ea931..d817c334de8 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java @@ -25,10 +25,6 @@ import java.util.UUID; import javax.inject.Inject; -import org.apache.commons.lang.StringUtils; -import org.apache.log4j.Logger; -import org.bouncycastle.util.encoders.Base64; - import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -41,6 +37,9 @@ import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.ldap.LdapManager; import org.apache.cloudstack.ldap.LdapUser; import org.apache.cloudstack.ldap.NoLdapUserMatchingQueryException; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.bouncycastle.util.encoders.Base64; import com.cloud.domain.Domain; import com.cloud.exception.ConcurrentOperationException; @@ -60,29 +59,29 @@ public class LdapImportUsersCmd extends BaseListCmd { private static final String s_name = "ldapuserresponse"; @Parameter(name = ApiConstants.TIMEZONE, - type = CommandType.STRING, - description = "Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.") + type = CommandType.STRING, + description = "Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.") private String timezone; @Parameter(name = ApiConstants.ACCOUNT_TYPE, - type = CommandType.SHORT, - required = true, - description = "Type of the account. Specify 0 for user, 1 for root admin, and 2 for domain admin") + type = CommandType.SHORT, + required = true, + description = "Type of the account. Specify 0 for user, 1 for root admin, and 2 for domain admin") private Short accountType; @Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "details for account used to store specific parameters") private Map details; @Parameter(name = ApiConstants.DOMAIN_ID, - type = CommandType.UUID, - entityType = DomainResponse.class, - description = "Specifies the domain to which the ldap users are to be " - + "imported. If no domain is specified, a domain will created using group parameter. If the group is also not specified, a domain name based on the OU information will be " - + "created. If no OU hierarchy exists, will be defaulted to ROOT domain") + type = CommandType.UUID, + entityType = DomainResponse.class, + description = "Specifies the domain to which the ldap users are to be " + + "imported. If no domain is specified, a domain will created using group parameter. If the group is also not specified, a domain name based on the OU information will be " + + "created. If no OU hierarchy exists, will be defaulted to ROOT domain") private Long domainId; @Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "Specifies the group name from which the ldap users are to be imported. " - + "If no group is specified, all the users will be imported.") + + "If no group is specified, all the users will be imported.") private String groupName; private Domain _domain; @@ -103,11 +102,12 @@ public class LdapImportUsersCmd extends BaseListCmd { @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, - ResourceAllocationException, NetworkRuleConflictException { + ResourceAllocationException, NetworkRuleConflictException { List users; try { if (StringUtils.isNotBlank(groupName)) { + users = _ldapManager.getUsersInGroup(groupName); } else { users = _ldapManager.getUsers(); @@ -122,7 +122,7 @@ public class LdapImportUsersCmd extends BaseListCmd { Domain domain = getDomain(user); try { _accountService.createUserAccount(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, - user.getUsername(), accountType, domain.getId(), domain.getNetworkDomain(), details, UUID.randomUUID().toString(), UUID.randomUUID().toString()); + user.getUsername(), accountType, domain.getId(), domain.getNetworkDomain(), details, UUID.randomUUID().toString(), UUID.randomUUID().toString()); addedUsers.add(user); } catch (InvalidParameterValueException ex) { s_logger.error("Failed to create user with username: " + user.getUsername() + " ::: " + ex.getMessage()); @@ -194,7 +194,8 @@ public class LdapImportUsersCmd extends BaseListCmd { final SecureRandom randomGen = SecureRandom.getInstance("SHA1PRNG"); final byte bytes[] = new byte[20]; randomGen.nextBytes(bytes); - return Base64.encode(bytes).toString(); + String encodedPassword = new String(Base64.encode(bytes)); + return encodedPassword; } catch (final NoSuchAlgorithmException e) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate random password"); } diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index cfc95ca973e..f907831767d 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -42,15 +42,14 @@ import javax.crypto.SecretKey; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.io.FileUtils; -import org.apache.log4j.Logger; - import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigDepotAdmin; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.config.impl.ConfigurationVO; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.FileUtils; +import org.apache.log4j.Logger; import com.cloud.cluster.ClusterManager; import com.cloud.configuration.Config; @@ -158,7 +157,6 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio @Override public boolean configure(String name, Map params) throws ConfigurationException { - try { persistDefaultValues(); _configDepotAdmin.populateConfigurations(); @@ -285,7 +283,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio long startIPLong = NetUtils.ip2Long(startIp); long endIPLong = NetUtils.ip2Long(endIp); config.savePublicIPRange(TransactionLegacy.currentTxn(), startIPLong, endIPLong, vlan.getDataCenterId(), vlan.getId(), vlan.getNetworkId(), - vlan.getPhysicalNetworkId()); + vlan.getPhysicalNetworkId()); } }); @@ -372,16 +370,16 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio if (resouce == null) continue; if (resouce.equalsIgnoreCase("com.cloud.hypervisor.xen.resource.XenServer56Resource") || - resouce.equalsIgnoreCase("com.cloud.hypervisor.xen.resource.XenServer56FP1Resource") || - resouce.equalsIgnoreCase("com.cloud.hypervisor.xen.resource.XenServer56SP2Resource") || - resouce.equalsIgnoreCase("com.cloud.hypervisor.xen.resource.XenServer600Resource") || - resouce.equalsIgnoreCase("com.cloud.hypervisor.xen.resource.XenServer602Resource")) { + resouce.equalsIgnoreCase("com.cloud.hypervisor.xen.resource.XenServer56FP1Resource") || + resouce.equalsIgnoreCase("com.cloud.hypervisor.xen.resource.XenServer56SP2Resource") || + resouce.equalsIgnoreCase("com.cloud.hypervisor.xen.resource.XenServer600Resource") || + resouce.equalsIgnoreCase("com.cloud.hypervisor.xen.resource.XenServer602Resource")) { pvdriverversion = "xenserver56"; break; } } _configDao.getValueAndInitIfNotExist(Config.XenPVdriverVersion.key(), Config.XenPVdriverVersion.getCategory(), pvdriverversion, - Config.XenPVdriverVersion.getDescription()); + Config.XenPVdriverVersion.getDescription()); sql = "select id from vm_template where hypervisor_type='XenServer' and format!='ISO' and removed is null"; pstmt = txn.prepareAutoCloseStatement(sql); rs2 = pstmt.executeQuery(); @@ -421,7 +419,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio _identityDao.initializeDefaultUuid("user_ip_address"); _identityDao.initializeDefaultUuid("counter"); } - */ + */ private String getMountParent() { return getEnvironmentProperty("mount.parent"); @@ -457,8 +455,8 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio } // insert system user insertSql = - "INSERT INTO `cloud`.`user` (id, uuid, username, password, account_id, firstname, lastname, created, user.default)" - + " VALUES (1, UUID(), 'system', RAND(), 1, 'system', 'cloud', now(), 1)"; + "INSERT INTO `cloud`.`user` (id, uuid, username, password, account_id, firstname, lastname, created, user.default)" + + " VALUES (1, UUID(), 'system', RAND(), 1, 'system', 'cloud', now(), 1)"; txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); @@ -475,7 +473,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio // create an account for the admin user first insertSql = - "INSERT INTO `cloud`.`account` (id, uuid, account_name, type, domain_id, account.default) VALUES (" + id + ", UUID(), '" + username + "', '1', '1', 1)"; + "INSERT INTO `cloud`.`account` (id, uuid, account_name, type, domain_id, account.default) VALUES (" + id + ", UUID(), '" + username + "', '1', '1', 1)"; txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); @@ -485,7 +483,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio // now insert the user insertSql = - "INSERT INTO `cloud`.`user` (id, uuid, username, password, account_id, firstname, lastname, created, state, user.default) " + "VALUES (" + id + + "INSERT INTO `cloud`.`user` (id, uuid, username, password, account_id, firstname, lastname, created, state, user.default) " + "VALUES (" + id + ", UUID(), '" + username + "', RAND(), 2, '" + firstname + "','" + lastname + "',now(), 'disabled', 1)"; txn = TransactionLegacy.currentTxn(); @@ -513,11 +511,11 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio // save default security group if (tableName.equals("security_group")) { insertSql = - "INSERT INTO " + tableName + " (uuid, name, description, account_id, domain_id) " + "VALUES (UUID(), 'default', 'Default Security Group', 2, 1)"; + "INSERT INTO " + tableName + " (uuid, name, description, account_id, domain_id) " + "VALUES (UUID(), 'default', 'Default Security Group', 2, 1)"; } else { insertSql = - "INSERT INTO " + tableName + " (name, description, account_id, domain_id, account_name) " + - "VALUES ('default', 'Default Security Group', 2, 1, 'admin')"; + "INSERT INTO " + tableName + " (name, description, account_id, domain_id, account_name) " + + "VALUES ('default', 'Default Security Group', 2, 1, 'admin')"; } txn = TransactionLegacy.currentTxn(); @@ -597,27 +595,34 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio } String dbString = _configDao.getValue("ssl.keystore"); + File confFile = PropertiesUtil.findConfigFile("db.properties"); - /* This line may throw a NPE, but that's due to fail to find db.properities, meant some bugs in the other places */ - String confPath = confFile.getParent(); - String keystorePath = confPath + "/cloudmanagementserver.keystore"; - File keystoreFile = new File(keystorePath); + String confPath = null; + String keystorePath = null; + File keystoreFile = null; + + if (null != confFile) { + confPath = confFile.getParent(); + keystorePath = confPath + "/cloud.keystore"; + keystoreFile = new File(keystorePath); + } + boolean dbExisted = (dbString != null && !dbString.isEmpty()); s_logger.info("SSL keystore located at " + keystorePath); try { - if (!dbExisted) { + if (!dbExisted && null != confFile) { if (!keystoreFile.exists()) { generateDefaultKeystore(keystorePath); s_logger.info("Generated SSL keystore."); } String base64Keystore = getBase64Keystore(keystorePath); ConfigurationVO configVO = - new ConfigurationVO("Hidden", "DEFAULT", "management-server", "ssl.keystore", DBEncryptionUtil.encrypt(base64Keystore), - "SSL Keystore for the management servers"); + new ConfigurationVO("Hidden", "DEFAULT", "management-server", "ssl.keystore", DBEncryptionUtil.encrypt(base64Keystore), + "SSL Keystore for the management servers"); _configDao.persist(configVO); s_logger.info("Stored SSL keystore to database."); - } else if (keystoreFile.exists()) { // and dbExisted + } else if (null != keystoreFile && keystoreFile.exists()) { // and dbExisted // Check if they are the same one, otherwise override with local keystore String base64Keystore = getBase64Keystore(keystorePath); if (base64Keystore.compareTo(dbString) != 0) { @@ -634,7 +639,11 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio fo.close(); Script script = new Script(true, "cp", 5000, null); script.add(tmpKeystorePath); - script.add(keystorePath); + + //There is a chance, although small, that the keystorePath is null. In that case, do not add it to the script. + if (null != keystorePath) { + script.add(keystorePath); + } String result = script.execute(); if (result != null) { throw new IOException(); @@ -666,9 +675,9 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio try { String rpassword = PasswordGenerator.generatePresharedKey(8); String wSql = - "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " + - "VALUES ('Secure','DEFAULT', 'management-server','system.vm.password', '" + DBEncryptionUtil.encrypt(rpassword) + - "','randmon password generated each management server starts for system vm')"; + "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " + + "VALUES ('Secure','DEFAULT', 'management-server','system.vm.password', '" + DBEncryptionUtil.encrypt(rpassword) + + "','randmon password generated each management server starts for system vm')"; PreparedStatement stmt = txn.prepareAutoCloseStatement(wSql); stmt.executeUpdate(wSql); s_logger.info("Updated systemvm password in database"); @@ -743,13 +752,13 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio String publicKey = new String(arr2).trim(); String insertSql1 = - "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " + - "VALUES ('Hidden','DEFAULT', 'management-server','ssh.privatekey', '" + DBEncryptionUtil.encrypt(privateKey) + - "','Private key for the entire CloudStack')"; + "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " + + "VALUES ('Hidden','DEFAULT', 'management-server','ssh.privatekey', '" + DBEncryptionUtil.encrypt(privateKey) + + "','Private key for the entire CloudStack')"; String insertSql2 = - "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " + - "VALUES ('Hidden','DEFAULT', 'management-server','ssh.publickey', '" + DBEncryptionUtil.encrypt(publicKey) + - "','Public key for the entire CloudStack')"; + "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " + + "VALUES ('Hidden','DEFAULT', 'management-server','ssh.publickey', '" + DBEncryptionUtil.encrypt(publicKey) + + "','Public key for the entire CloudStack')"; TransactionLegacy txn = TransactionLegacy.currentTxn(); try { @@ -882,9 +891,9 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio String password = PasswordGenerator.generateRandomPassword(12); String insertSql1 = - "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " + - "VALUES ('Hidden','DEFAULT', 'management-server','secstorage.copy.password', '" + DBEncryptionUtil.encrypt(password) + - "','Password used to authenticate zone-to-zone template copy requests')"; + "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " + + "VALUES ('Hidden','DEFAULT', 'management-server','secstorage.copy.password', '" + DBEncryptionUtil.encrypt(password) + + "','Password used to authenticate zone-to-zone template copy requests')"; TransactionLegacy txn = TransactionLegacy.currentTxn(); try { @@ -915,7 +924,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio @DB protected HostPodVO createPod(long userId, String podName, final long zoneId, String gateway, String cidr, final String startIp, String endIp) - throws InternalErrorException { + throws InternalErrorException { String[] cidrPair = cidr.split("\\/"); String cidrAddress = cidrPair[0]; int cidrSize = Integer.parseInt(cidrPair[1]); @@ -974,7 +983,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio } private DiskOfferingVO createdefaultDiskOffering(Long domainId, String name, String description, int numGibibytes, String tags, boolean isCustomized, - boolean isSystemUse) { + boolean isSystemUse) { long diskSize = numGibibytes; diskSize = diskSize * 1024 * 1024 * 1024; tags = cleanupTags(tags); @@ -987,10 +996,10 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio } private ServiceOfferingVO createServiceOffering(long userId, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired, - boolean offerHA, String tags) { + boolean offerHA, String tags) { tags = cleanupTags(tags); ServiceOfferingVO offering = - new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, offerHA, displayText, localStorageRequired, false, tags, false, null, false); + new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, offerHA, displayText, localStorageRequired, false, tags, false, null, false); offering.setUniqueName("Cloud.Com-" + name); offering = _serviceOfferingDao.persistSystemServiceOffering(offering); return offering; @@ -1065,87 +1074,87 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio public void doInTransactionWithoutResult(TransactionStatus status) { // Offering #1 NetworkOfferingVO defaultSharedSGNetworkOffering = - new NetworkOfferingVO(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks", - TrafficType.Guest, false, true, null, null, true, Availability.Optional, null, Network.GuestType.Shared, true, true, false, false, false); + new NetworkOfferingVO(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks", + TrafficType.Guest, false, true, null, null, true, Availability.Optional, null, Network.GuestType.Shared, true, true, false, false, false); defaultSharedSGNetworkOffering.setState(NetworkOffering.State.Enabled); defaultSharedSGNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultSharedSGNetworkOffering); for (Service service : defaultSharedSGNetworkOfferingProviders.keySet()) { NetworkOfferingServiceMapVO offService = - new NetworkOfferingServiceMapVO(defaultSharedSGNetworkOffering.getId(), service, defaultSharedSGNetworkOfferingProviders.get(service)); + new NetworkOfferingServiceMapVO(defaultSharedSGNetworkOffering.getId(), service, defaultSharedSGNetworkOfferingProviders.get(service)); _ntwkOfferingServiceMapDao.persist(offService); s_logger.trace("Added service for the network offering: " + offService); } // Offering #2 NetworkOfferingVO defaultSharedNetworkOffering = - new NetworkOfferingVO(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, false, true, null, null, true, - Availability.Optional, null, Network.GuestType.Shared, true, true, false, false, false); + new NetworkOfferingVO(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, false, true, null, null, true, + Availability.Optional, null, Network.GuestType.Shared, true, true, false, false, false); defaultSharedNetworkOffering.setState(NetworkOffering.State.Enabled); defaultSharedNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultSharedNetworkOffering); for (Service service : defaultSharedNetworkOfferingProviders.keySet()) { NetworkOfferingServiceMapVO offService = - new NetworkOfferingServiceMapVO(defaultSharedNetworkOffering.getId(), service, defaultSharedNetworkOfferingProviders.get(service)); + new NetworkOfferingServiceMapVO(defaultSharedNetworkOffering.getId(), service, defaultSharedNetworkOfferingProviders.get(service)); _ntwkOfferingServiceMapDao.persist(offService); s_logger.trace("Added service for the network offering: " + offService); } // Offering #3 NetworkOfferingVO defaultIsolatedSourceNatEnabledNetworkOffering = - new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService, - "Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, false, false, null, null, true, Availability.Required, null, - Network.GuestType.Isolated, true, false, false, false, true); + new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService, + "Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, false, false, null, null, true, Availability.Required, null, + Network.GuestType.Isolated, true, false, false, false, true); defaultIsolatedSourceNatEnabledNetworkOffering.setState(NetworkOffering.State.Enabled); defaultIsolatedSourceNatEnabledNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultIsolatedSourceNatEnabledNetworkOffering); for (Service service : defaultIsolatedSourceNatEnabledNetworkOfferingProviders.keySet()) { NetworkOfferingServiceMapVO offService = - new NetworkOfferingServiceMapVO(defaultIsolatedSourceNatEnabledNetworkOffering.getId(), service, - defaultIsolatedSourceNatEnabledNetworkOfferingProviders.get(service)); + new NetworkOfferingServiceMapVO(defaultIsolatedSourceNatEnabledNetworkOffering.getId(), service, + defaultIsolatedSourceNatEnabledNetworkOfferingProviders.get(service)); _ntwkOfferingServiceMapDao.persist(offService); s_logger.trace("Added service for the network offering: " + offService); } // Offering #4 NetworkOfferingVO defaultIsolatedEnabledNetworkOffering = - new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOffering, "Offering for Isolated networks with no Source Nat service", TrafficType.Guest, - false, true, null, null, true, Availability.Optional, null, Network.GuestType.Isolated, true, true, false, false, false); + new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOffering, "Offering for Isolated networks with no Source Nat service", TrafficType.Guest, + false, true, null, null, true, Availability.Optional, null, Network.GuestType.Isolated, true, true, false, false, false); defaultIsolatedEnabledNetworkOffering.setState(NetworkOffering.State.Enabled); defaultIsolatedEnabledNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultIsolatedEnabledNetworkOffering); for (Service service : defaultIsolatedNetworkOfferingProviders.keySet()) { NetworkOfferingServiceMapVO offService = - new NetworkOfferingServiceMapVO(defaultIsolatedEnabledNetworkOffering.getId(), service, defaultIsolatedNetworkOfferingProviders.get(service)); + new NetworkOfferingServiceMapVO(defaultIsolatedEnabledNetworkOffering.getId(), service, defaultIsolatedNetworkOfferingProviders.get(service)); _ntwkOfferingServiceMapDao.persist(offService); s_logger.trace("Added service for the network offering: " + offService); } // Offering #5 NetworkOfferingVO defaultNetscalerNetworkOffering = - new NetworkOfferingVO(NetworkOffering.DefaultSharedEIPandELBNetworkOffering, - "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, false, true, null, null, true, - Availability.Optional, null, Network.GuestType.Shared, true, false, false, false, true, true, true, false, false, true, true, false, false); + new NetworkOfferingVO(NetworkOffering.DefaultSharedEIPandELBNetworkOffering, + "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, false, true, null, null, true, + Availability.Optional, null, Network.GuestType.Shared, true, false, false, false, true, true, true, false, false, true, true, false, false); defaultNetscalerNetworkOffering.setState(NetworkOffering.State.Enabled); defaultNetscalerNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetscalerNetworkOffering); for (Service service : netscalerServiceProviders.keySet()) { NetworkOfferingServiceMapVO offService = - new NetworkOfferingServiceMapVO(defaultNetscalerNetworkOffering.getId(), service, netscalerServiceProviders.get(service)); + new NetworkOfferingServiceMapVO(defaultNetscalerNetworkOffering.getId(), service, netscalerServiceProviders.get(service)); _ntwkOfferingServiceMapDao.persist(offService); s_logger.trace("Added service for the network offering: " + offService); } // Offering #6 NetworkOfferingVO defaultNetworkOfferingForVpcNetworks = - new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks, - "Offering for Isolated Vpc networks with Source Nat service enabled", TrafficType.Guest, false, false, null, null, true, Availability.Optional, - null, Network.GuestType.Isolated, false, false, false, false, true); + new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks, + "Offering for Isolated Vpc networks with Source Nat service enabled", TrafficType.Guest, false, false, null, null, true, Availability.Optional, + null, Network.GuestType.Isolated, false, false, false, false, true); defaultNetworkOfferingForVpcNetworks.setState(NetworkOffering.State.Enabled); defaultNetworkOfferingForVpcNetworks = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworks); @@ -1164,16 +1173,16 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio for (Service service : defaultVpcNetworkOfferingProviders.keySet()) { NetworkOfferingServiceMapVO offService = - new NetworkOfferingServiceMapVO(defaultNetworkOfferingForVpcNetworks.getId(), service, defaultVpcNetworkOfferingProviders.get(service)); + new NetworkOfferingServiceMapVO(defaultNetworkOfferingForVpcNetworks.getId(), service, defaultVpcNetworkOfferingProviders.get(service)); _ntwkOfferingServiceMapDao.persist(offService); s_logger.trace("Added service for the network offering: " + offService); } // Offering #7 NetworkOfferingVO defaultNetworkOfferingForVpcNetworksNoLB = - new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB, - "Offering for Isolated Vpc networks with Source Nat service enabled and LB service Disabled", TrafficType.Guest, false, false, null, null, true, - Availability.Optional, null, Network.GuestType.Isolated, false, false, false, false, false); + new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB, + "Offering for Isolated Vpc networks with Source Nat service enabled and LB service Disabled", TrafficType.Guest, false, false, null, null, true, + Availability.Optional, null, Network.GuestType.Isolated, false, false, false, false, false); defaultNetworkOfferingForVpcNetworksNoLB.setState(NetworkOffering.State.Enabled); defaultNetworkOfferingForVpcNetworksNoLB = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworksNoLB); @@ -1191,16 +1200,16 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio for (Service service : defaultVpcNetworkOfferingProvidersNoLB.keySet()) { NetworkOfferingServiceMapVO offService = - new NetworkOfferingServiceMapVO(defaultNetworkOfferingForVpcNetworksNoLB.getId(), service, defaultVpcNetworkOfferingProvidersNoLB.get(service)); + new NetworkOfferingServiceMapVO(defaultNetworkOfferingForVpcNetworksNoLB.getId(), service, defaultVpcNetworkOfferingProvidersNoLB.get(service)); _ntwkOfferingServiceMapDao.persist(offService); s_logger.trace("Added service for the network offering: " + offService); } //offering #8 - network offering with internal lb service NetworkOfferingVO internalLbOff = - new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB, - "Offering for Isolated Vpc networks with Internal LB support", TrafficType.Guest, false, false, null, null, true, Availability.Optional, null, - Network.GuestType.Isolated, false, false, false, true, false); + new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB, + "Offering for Isolated Vpc networks with Internal LB support", TrafficType.Guest, false, false, null, null, true, Availability.Optional, null, + Network.GuestType.Isolated, false, false, false, true, false); internalLbOff.setState(NetworkOffering.State.Enabled); internalLbOff = _networkOfferingDao.persistDefaultNetworkOffering(internalLbOff); @@ -1275,8 +1284,8 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio if (broadcastDomainType != null) { NetworkVO network = - new NetworkVO(id, trafficType, mode, broadcastDomainType, networkOfferingId, domainId, accountId, related, null, null, networkDomain, - Network.GuestType.Shared, zoneId, null, null, specifyIpRanges, null); + new NetworkVO(id, trafficType, mode, broadcastDomainType, networkOfferingId, domainId, accountId, related, null, null, networkDomain, + Network.GuestType.Shared, zoneId, null, null, specifyIpRanges, null); network.setGuruName(guruNames.get(network.getTrafficType())); network.setDns1(zone.getDns1()); network.setDns2(zone.getDns2()); diff --git a/utils/src/com/cloud/utils/nio/Link.java b/utils/src/com/cloud/utils/nio/Link.java index 3b300531d50..e20210db71a 100755 --- a/utils/src/com/cloud/utils/nio/Link.java +++ b/utils/src/com/cloud/utils/nio/Link.java @@ -150,7 +150,7 @@ public class Link { pkgBuf.clear(); engResult = sslEngine.wrap(buffers, pkgBuf); if (engResult.getHandshakeStatus() != HandshakeStatus.FINISHED && engResult.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING && - engResult.getStatus() != SSLEngineResult.Status.OK) { + engResult.getStatus() != SSLEngineResult.Status.OK) { throw new IOException("SSL: SSLEngine return bad result! " + engResult); } @@ -276,7 +276,7 @@ public class Link { appBuf = ByteBuffer.allocate(sslSession.getApplicationBufferSize() + 40); engResult = _sslEngine.unwrap(_readBuffer, appBuf); if (engResult.getHandshakeStatus() != HandshakeStatus.FINISHED && engResult.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING && - engResult.getStatus() != SSLEngineResult.Status.OK) { + engResult.getStatus() != SSLEngineResult.Status.OK) { throw new IOException("SSL: SSLEngine return bad result! " + engResult); } if (remaining == _readBuffer.remaining()) { @@ -404,10 +404,9 @@ public class Link { KeyStore ks = KeyStore.getInstance("JKS"); TrustManager[] tms; - if (!isClient) { + File confFile = PropertiesUtil.findConfigFile("db.properties"); + if (null != confFile && !isClient) { char[] passphrase = "vmops.com".toCharArray(); - File confFile = PropertiesUtil.findConfigFile("db.properties"); - /* This line may throw a NPE, but that's due to fail to find db.properities, meant some bugs in the other places */ String confPath = confFile.getParent(); String keystorePath = confPath + "/cloud.keystore"; if (new File(keystorePath).exists()) { From d19688103ba7f7c53c264fb67cb534dd693c95cd Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Mon, 18 Nov 2013 15:35:34 +0100 Subject: [PATCH 046/170] Fixing coverity issues related to resource leak on FileInputStream being created anonymously Signed-off-by: Daan Hoogland --- .../cloud/bridge/service/EC2RestServlet.java | 46 +++++++------ .../controller/s3/ServiceProvider.java | 15 +++-- .../bridge/service/core/ec2/EC2Engine.java | 65 ++++++++++--------- .../com/cloud/cluster/ClusterManagerImpl.java | 40 ++++++------ .../com/cloud/consoleproxy/ConsoleProxy.java | 21 ++++-- 5 files changed, 104 insertions(+), 83 deletions(-) diff --git a/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java b/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java index 5c56e9d0506..fd2919dc117 100644 --- a/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java +++ b/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java @@ -58,6 +58,7 @@ import org.apache.axis2.databinding.ADBBean; import org.apache.axis2.databinding.ADBException; import org.apache.axis2.databinding.utils.writer.MTOMAwareXMLSerializer; import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.IOUtils; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import org.springframework.web.context.support.SpringBeanAutowiringSupport; @@ -103,7 +104,6 @@ import com.amazon.ec2.RunInstancesResponse; import com.amazon.ec2.StartInstancesResponse; import com.amazon.ec2.StopInstancesResponse; import com.amazon.ec2.TerminateInstancesResponse; - import com.cloud.bridge.model.UserCredentialsVO; import com.cloud.bridge.persist.dao.CloudStackUserDaoImpl; import com.cloud.bridge.persist.dao.OfferingDaoImpl; @@ -203,12 +203,16 @@ public class EC2RestServlet extends HttpServlet { if (null != propertiesFile) { logger.info("Use EC2 properties file: " + propertiesFile.getAbsolutePath()); EC2Prop = new Properties(); + FileInputStream ec2PropFile = null; try { - EC2Prop.load(new FileInputStream(propertiesFile)); + ec2PropFile = new FileInputStream(propertiesFile); + EC2Prop.load(ec2PropFile); } catch (FileNotFoundException e) { logger.warn("Unable to open properties file: " + propertiesFile.getAbsolutePath(), e); } catch (IOException e) { logger.warn("Unable to read properties file: " + propertiesFile.getAbsolutePath(), e); + } finally { + IOUtils.closeQuietly(ec2PropFile); } String keystore = EC2Prop.getProperty("keystore"); keystorePassword = EC2Prop.getProperty("keystorePass"); @@ -492,7 +496,7 @@ public class EC2RestServlet extends HttpServlet { response.sendError(530, "Missing cert parameter"); return; } -// logger.debug( "SetCertificate cert: [" + certificate[0] + "]" ); + // logger.debug( "SetCertificate cert: [" + certificate[0] + "]" ); String[] accessKey = request.getParameterValues("AWSAccessKeyId"); if (null == accessKey || 0 == accessKey.length) { @@ -578,12 +582,12 @@ public class EC2RestServlet extends HttpServlet { credentialDao.setCertificateId( accessKey[0], null ); */txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); - UserCredentialsVO user = ucDao.getByAccessKey(accessKey[0]); - user.setCertUniqueId(null); - ucDao.update(user.getId(), user); - response.setStatus(200); - endResponse(response, "User certificate deleted successfully"); - txn.commit(); + UserCredentialsVO user = ucDao.getByAccessKey(accessKey[0]); + user.setCertUniqueId(null); + ucDao.update(user.getId(), user); + response.setStatus(200); + endResponse(response, "User certificate deleted successfully"); + txn.commit(); } else response.setStatus(404); @@ -830,7 +834,7 @@ public class EC2RestServlet extends HttpServlet { // -> execute the request RevokeSecurityGroupIngressResponse EC2response = - EC2SoapServiceImpl.toRevokeSecurityGroupIngressResponse(ServiceProvider.getInstance().getEC2Engine().revokeSecurityGroup(EC2request)); + EC2SoapServiceImpl.toRevokeSecurityGroupIngressResponse(ServiceProvider.getInstance().getEC2Engine().revokeSecurityGroup(EC2request)); serializeResponse(response, EC2response); } @@ -915,7 +919,7 @@ public class EC2RestServlet extends HttpServlet { // -> execute the request AuthorizeSecurityGroupIngressResponse EC2response = - EC2SoapServiceImpl.toAuthorizeSecurityGroupIngressResponse(ServiceProvider.getInstance().getEC2Engine().authorizeSecurityGroup(EC2request)); + EC2SoapServiceImpl.toAuthorizeSecurityGroupIngressResponse(ServiceProvider.getInstance().getEC2Engine().authorizeSecurityGroup(EC2request)); serializeResponse(response, EC2response); } @@ -1012,7 +1016,7 @@ public class EC2RestServlet extends HttpServlet { // -> execute the request CreateSecurityGroupResponse EC2response = - EC2SoapServiceImpl.toCreateSecurityGroupResponse(ServiceProvider.getInstance().getEC2Engine().createSecurityGroup(groupName, groupDescription)); + EC2SoapServiceImpl.toCreateSecurityGroupResponse(ServiceProvider.getInstance().getEC2Engine().createSecurityGroup(groupName, groupDescription)); serializeResponse(response, EC2response); } @@ -1028,7 +1032,7 @@ public class EC2RestServlet extends HttpServlet { // -> execute the request DeleteSecurityGroupResponse EC2response = - EC2SoapServiceImpl.toDeleteSecurityGroupResponse(ServiceProvider.getInstance().getEC2Engine().deleteSecurityGroup(groupName)); + EC2SoapServiceImpl.toDeleteSecurityGroupResponse(ServiceProvider.getInstance().getEC2Engine().deleteSecurityGroup(groupName)); serializeResponse(response, EC2response); } @@ -1166,7 +1170,7 @@ public class EC2RestServlet extends HttpServlet { // -> execute the request ModifyImageAttributeResponse EC2response = - EC2SoapServiceImpl.toModifyImageAttributeResponse(ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute(ec2request)); + EC2SoapServiceImpl.toModifyImageAttributeResponse(ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute(ec2request)); serializeResponse(response, EC2response); } @@ -1231,7 +1235,7 @@ public class EC2RestServlet extends HttpServlet { // -> execute the request ResetImageAttributeResponse EC2response = - EC2SoapServiceImpl.toResetImageAttributeResponse(ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute(ec2request)); + EC2SoapServiceImpl.toResetImageAttributeResponse(ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute(ec2request)); serializeResponse(response, EC2response); } @@ -1443,7 +1447,7 @@ public class EC2RestServlet extends HttpServlet { // -> execute the request DescribeAvailabilityZonesResponse EC2response = - EC2SoapServiceImpl.toDescribeAvailabilityZonesResponse(ServiceProvider.getInstance().getEC2Engine().describeAvailabilityZones(EC2request)); + EC2SoapServiceImpl.toDescribeAvailabilityZonesResponse(ServiceProvider.getInstance().getEC2Engine().describeAvailabilityZones(EC2request)); serializeResponse(response, EC2response); } @@ -1499,7 +1503,7 @@ public class EC2RestServlet extends HttpServlet { } DescribeImageAttributeResponse EC2response = - EC2SoapServiceImpl.toDescribeImageAttributeResponse(ServiceProvider.getInstance().getEC2Engine().describeImageAttribute(ec2request)); + EC2SoapServiceImpl.toDescribeImageAttributeResponse(ServiceProvider.getInstance().getEC2Engine().describeImageAttribute(ec2request)); serializeResponse(response, EC2response); } @@ -1677,7 +1681,7 @@ public class EC2RestServlet extends HttpServlet { // -> execute the request DescribeInstanceAttributeResponse EC2response = - EC2SoapServiceImpl.toDescribeInstanceAttributeResponse(ServiceProvider.getInstance().getEC2Engine().describeInstances(EC2request)); + EC2SoapServiceImpl.toDescribeInstanceAttributeResponse(ServiceProvider.getInstance().getEC2Engine().describeInstances(EC2request)); serializeResponse(response, EC2response); } @@ -1707,7 +1711,7 @@ public class EC2RestServlet extends HttpServlet { // -> execute the request ModifyInstanceAttributeResponse EC2response = - EC2SoapServiceImpl.toModifyInstanceAttributeResponse(ServiceProvider.getInstance().getEC2Engine().modifyInstanceAttribute(ec2Request)); + EC2SoapServiceImpl.toModifyInstanceAttributeResponse(ServiceProvider.getInstance().getEC2Engine().modifyInstanceAttribute(ec2Request)); serializeResponse(response, EC2response); } @@ -1766,7 +1770,7 @@ public class EC2RestServlet extends HttpServlet { // -> execute the request EC2Engine engine = ServiceProvider.getInstance().getEC2Engine(); DescribeVolumesResponse EC2response = - EC2SoapServiceImpl.toDescribeVolumesResponse(ServiceProvider.getInstance().getEC2Engine().describeVolumes(EC2request), engine); + EC2SoapServiceImpl.toDescribeVolumesResponse(ServiceProvider.getInstance().getEC2Engine().describeVolumes(EC2request), engine); serializeResponse(response, EC2response); } @@ -1988,7 +1992,7 @@ public class EC2RestServlet extends HttpServlet { * parameter to see if the signature has expired and if so the request fails. */ private boolean authenticateRequest(HttpServletRequest request, HttpServletResponse response) throws SignatureException, IOException, InstantiationException, - IllegalAccessException, ClassNotFoundException, SQLException, ParseException { + IllegalAccessException, ClassNotFoundException, SQLException, ParseException { String cloudSecretKey = null; String cloudAccessKey = null; String signature = null; diff --git a/awsapi/src/com/cloud/bridge/service/controller/s3/ServiceProvider.java b/awsapi/src/com/cloud/bridge/service/controller/s3/ServiceProvider.java index deb886f411f..e00408e1edf 100644 --- a/awsapi/src/com/cloud/bridge/service/controller/s3/ServiceProvider.java +++ b/awsapi/src/com/cloud/bridge/service/controller/s3/ServiceProvider.java @@ -34,15 +34,14 @@ import javax.annotation.PostConstruct; import javax.inject.Inject; import org.apache.axis2.AxisFault; +import org.apache.cloudstack.managed.context.ManagedContextTimerTask; +import org.apache.commons.io.IOUtils; import org.apache.log4j.Logger; import org.apache.log4j.xml.DOMConfigurator; import org.springframework.stereotype.Component; import com.amazon.ec2.AmazonEC2SkeletonInterface; import com.amazon.s3.AmazonS3SkeletonInterface; - -import org.apache.cloudstack.managed.context.ManagedContextTimerTask; - import com.cloud.bridge.model.MHostVO; import com.cloud.bridge.model.SHost; import com.cloud.bridge.model.SHostVO; @@ -111,8 +110,8 @@ public class ServiceProvider extends ManagerBase { instance = this; } + @Override public boolean configure(String name, Map params) throws ConfigurationException { - initialize(); return true; } @@ -122,7 +121,7 @@ public class ServiceProvider extends ManagerBase { long mhostId = 0; if (mhost != null) mhostId = mhost.getId() != null ? mhost.getId().longValue() : 0L; - return mhostId; + return mhostId; } /** @@ -268,12 +267,16 @@ public class ServiceProvider extends ManagerBase { File propertiesFile = ConfigurationHelper.findConfigurationFile("cloud-bridge.properties"); properties = new Properties(); if (propertiesFile != null) { + FileInputStream startProps = null; try { - properties.load(new FileInputStream(propertiesFile)); + startProps = new FileInputStream(propertiesFile); + properties.load(startProps); } catch (FileNotFoundException e) { logger.warn("Unable to open properties file: " + propertiesFile.getAbsolutePath(), e); } catch (IOException e) { logger.warn("Unable to read properties file: " + propertiesFile.getAbsolutePath(), e); + } finally { + IOUtils.closeQuietly(startProps); } logger.info("Use startup properties file: " + propertiesFile.getAbsolutePath()); diff --git a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java index 59abca0e2aa..ccac6749479 100644 --- a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java +++ b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java @@ -35,6 +35,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import javax.xml.parsers.ParserConfigurationException; +import org.apache.commons.io.IOUtils; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import org.xml.sax.SAXException; @@ -122,12 +123,18 @@ public class EC2Engine extends ManagerBase { if (null != propertiesFile) { logger.info("Use EC2 properties file: " + propertiesFile.getAbsolutePath()); Properties EC2Prop = new Properties(); + FileInputStream ec2PropFile = null; try { EC2Prop.load(new FileInputStream(propertiesFile)); + ec2PropFile = new FileInputStream( propertiesFile ); + EC2Prop.load(ec2PropFile); + } catch (FileNotFoundException e) { logger.warn("Unable to open properties file: " + propertiesFile.getAbsolutePath(), e); } catch (IOException e) { logger.warn("Unable to read properties file: " + propertiesFile.getAbsolutePath(), e); + } finally { + IOUtils.closeQuietly(ec2PropFile); } managementServer = EC2Prop.getProperty("managementServer"); cloudAPIPort = EC2Prop.getProperty("cloudAPIPort", null); @@ -364,12 +371,12 @@ public class EC2Engine extends ManagerBase { CloudStackSecurityGroup resp = null; if (ipPerm.getProtocol().equalsIgnoreCase("icmp")) { resp = - getApi().authorizeSecurityGroupIngress(null, constructList(ipPerm.getIpRangeSet()), null, null, ipPerm.getIcmpCode(), ipPerm.getIcmpType(), - ipPerm.getProtocol(), null, request.getName(), null, secGroupList); + getApi().authorizeSecurityGroupIngress(null, constructList(ipPerm.getIpRangeSet()), null, null, ipPerm.getIcmpCode(), ipPerm.getIcmpType(), + ipPerm.getProtocol(), null, request.getName(), null, secGroupList); } else { resp = - getApi().authorizeSecurityGroupIngress(null, constructList(ipPerm.getIpRangeSet()), null, ipPerm.getToPort().longValue(), null, null, - ipPerm.getProtocol(), null, request.getName(), ipPerm.getFromPort().longValue(), secGroupList); + getApi().authorizeSecurityGroupIngress(null, constructList(ipPerm.getIpRangeSet()), null, ipPerm.getToPort().longValue(), null, null, + ipPerm.getProtocol(), null, request.getName(), ipPerm.getFromPort().longValue(), secGroupList); } if (resp != null) { List ingressRules = resp.getIngressRules(); @@ -808,7 +815,7 @@ public class EC2Engine extends ManagerBase { CloudStackIpAddress cloudIp = cloudIps.get(0); List vmList = - getApi().listVirtualMachines(null, null, true, null, null, null, null, request.getInstanceId(), null, null, null, null, null, null, null, null, null); + getApi().listVirtualMachines(null, null, true, null, null, null, null, request.getInstanceId(), null, null, null, null, null, null, null, null, null); if (vmList == null || vmList.size() == 0) { throw new Exception("Instance not found"); } @@ -863,7 +870,7 @@ public class EC2Engine extends ManagerBase { CloudStackZone zone = findZone(); //CloudStackNetwork net = findNetwork(zone); -// CloudStackIpAddress resp = getApi().associateIpAddress(null, null, null, "0036952d-48df-4422-9fd0-94b0885e18cb"); + //CloudStackIpAddress resp = getApi().associateIpAddress(null, null, null, "0036952d-48df-4422-9fd0-94b0885e18cb"); CloudStackIpAddress resp = getApi().associateIpAddress(zone.getId(), caller.getName(), caller.getDomainId(), null); ec2Address.setAssociatedInstanceId(resp.getId()); @@ -965,8 +972,8 @@ public class EC2Engine extends ManagerBase { String osTypeId = imageSet[0].getOsTypeId(); CloudStackTemplate resp = - getApi().createTemplate((request.getDescription() == null ? "" : request.getDescription()), request.getName(), osTypeId, null, null, null, null, null, - null, volumeId); + getApi().createTemplate((request.getDescription() == null ? "" : request.getDescription()), request.getName(), osTypeId, null, null, null, null, null, + null, volumeId); if (resp == null || resp.getId() == null) { throw new Exception("Image couldn't be created"); } @@ -996,9 +1003,9 @@ public class EC2Engine extends ManagerBase { EC2CreateImageResponse image = new EC2CreateImageResponse(); try { List templates = - getApi().registerTemplate((request.getDescription() == null ? request.getName() : request.getDescription()), request.getFormat(), - request.getHypervisor(), request.getName(), toOSTypeId(request.getOsTypeName()), request.getLocation(), toZoneId(request.getZoneName(), null), null, - null, null, null, null, null, null, null, null); + getApi().registerTemplate((request.getDescription() == null ? request.getName() : request.getDescription()), request.getFormat(), + request.getHypervisor(), request.getName(), toOSTypeId(request.getOsTypeName()), request.getLocation(), toZoneId(request.getZoneName(), null), null, + null, null, null, null, null, null, null, null); if (templates != null) { // technically we will only ever register a single template... for (CloudStackTemplate template : templates) { @@ -1217,13 +1224,13 @@ public class EC2Engine extends ManagerBase { throw new EC2ServiceException(ServerError.InternalError, "No Customize Disk Offering Found"); } -// // -> no volume name is given in the Amazon request but is required in the cloud API + // -> no volume name is given in the Amazon request but is required in the cloud API CloudStackVolume vol = - getApi().createVolume(UUID.randomUUID().toString(), null, diskOfferingId, null, size, snapshotId, toZoneId(request.getZoneName(), null)); + getApi().createVolume(UUID.randomUUID().toString(), null, diskOfferingId, null, size, snapshotId, toZoneId(request.getZoneName(), null)); if (vol != null) { resp.setAttached(vol.getAttached()); resp.setCreated(vol.getCreated()); -// resp.setDevice(); + //resp.setDevice(); resp.setDeviceId(vol.getDeviceId()); resp.setHypervisor(vol.getHypervisor()); resp.setId(vol.getId()); @@ -1442,8 +1449,8 @@ public class EC2Engine extends ManagerBase { for (int i = 0; i < createInstances; i++) { try { CloudStackUserVm resp = - getApi().deployVirtualMachine(svcOffering.getId(), request.getTemplateId(), zoneId, null, null, null, null, null, null, null, - request.getKeyName(), null, null, groupIds, groupNames, request.getSize().longValue(), request.getUserData()); + getApi().deployVirtualMachine(svcOffering.getId(), request.getTemplateId(), zoneId, null, null, null, null, null, null, null, + request.getKeyName(), null, null, groupIds, groupNames, request.getSize().longValue(), request.getUserData()); EC2Instance vm = new EC2Instance(); vm.setId(resp.getId().toString()); vm.setName(resp.getName()); @@ -1666,7 +1673,7 @@ public class EC2Engine extends ManagerBase { * @param ifs - filter out unwanted instances */ private EC2DescribeInstancesResponse listVirtualMachines(String[] virtualMachineIds, EC2InstanceFilterSet ifs, List resourceTags) - throws Exception { + throws Exception { EC2DescribeInstancesResponse instances = new EC2DescribeInstancesResponse(); if (null == virtualMachineIds || 0 == virtualMachineIds.length) { @@ -1690,7 +1697,7 @@ public class EC2Engine extends ManagerBase { * @param instanceId - if interested in volumes for a specific instance, null if instance is not important */ private EC2DescribeVolumesResponse listVolumes(String volumeId, String instanceId, EC2DescribeVolumesResponse volumes, List resourceTagSet) - throws Exception { + throws Exception { List vols = getApi().listVolumes(null, null, null, volumeId, null, null, null, null, null, instanceId, null, resourceTagSet); if (vols != null && vols.size() > 0) { @@ -1881,11 +1888,11 @@ public class EC2Engine extends ManagerBase { * EC2Instance objects loaded. */ private EC2DescribeInstancesResponse lookupInstances(String instanceId, EC2DescribeInstancesResponse instances, List resourceTagSet) - throws Exception { + throws Exception { String instId = instanceId != null ? instanceId : null; List vms = - getApi().listVirtualMachines(null, null, true, null, null, null, null, instId, null, null, null, null, null, null, null, null, resourceTagSet); + getApi().listVirtualMachines(null, null, true, null, null, null, null, instId, null, null, null, null, null, null, null, null, resourceTagSet); if (vms != null && vms.size() > 0) { for (CloudStackUserVm cloudVm : vms) { @@ -2301,7 +2308,7 @@ public class EC2Engine extends ManagerBase { */ private CloudStackNetwork createDefaultGuestNetwork(String zoneId, CloudStackNetworkOffering offering, CloudStackAccount owner) throws Exception { return getApi().createNetwork(owner.getName() + "-network", owner.getName() + "-network", offering.getId(), zoneId, owner.getName(), owner.getDomainId(), true, - null, null, null, null, null, null, null, null); + null, null, null, null, null, null, null, null); } /** @@ -2688,8 +2695,8 @@ public class EC2Engine extends ManagerBase { if (errorMessage.contains("Object vm_instance(uuid:") && errorMessage.contains(") does not exist")) { throw new EC2ServiceException(ClientError.InvalidInstanceID_NotFound, "Specified Instance ID does not exist"); } else if (errorMessage.contains("Unable to find security group by name") || errorMessage.contains("Unable to find security group") || - (errorMessage.contains("Object security_group(uuid:") && errorMessage.contains(") does not exist")) || - errorMessage.contains("Unable to find group by name ")) { + (errorMessage.contains("Object security_group(uuid:") && errorMessage.contains(") does not exist")) || + errorMessage.contains("Unable to find group by name ")) { throw new EC2ServiceException(ClientError.InvalidGroup_NotFound, "Specified Security Group does not exist"); } else if (errorMessage.contains("Invalid port numbers")) { throw new EC2ServiceException(ClientError.InvalidPermission_Malformed, "Specified Port value is invalid"); @@ -2708,7 +2715,7 @@ public class EC2Engine extends ManagerBase { } else if (errorMessage.contains("Object snapshots(uuid:") && errorMessage.contains(") does not exist")) { throw new EC2ServiceException(ClientError.InvalidSnapshot_NotFound, "Specified Snapshot ID doesn't exist"); } else if ((errorMessage.contains("A key pair with name '") && errorMessage.contains("' does not exist")) || - (errorMessage.contains("A key pair with name '") && errorMessage.contains("' was not found"))) { + (errorMessage.contains("A key pair with name '") && errorMessage.contains("' was not found"))) { throw new EC2ServiceException(ClientError.InvalidKeyPair_NotFound, "Specified Key pair name is invalid"); } else if (errorMessage.contains("A key pair with name '") && errorMessage.contains("' already exists")) { throw new EC2ServiceException(ClientError.InvalidKeyPair_Duplicate, "Specified Key pair already exists"); @@ -2735,7 +2742,7 @@ public class EC2Engine extends ManagerBase { } else if (errorMessage.contains("Unable to find tags by parameters specified")) { throw new EC2ServiceException(ClientError.InvalidParameterValue, "Specified resourceTag for the specified resourceId doesn't exist"); } else if (errorMessage.contains("Failed to enable static nat for the ip address with specified ipId " - + "as vm with specified vmId is already associated with specified currentIp")) { + + "as vm with specified vmId is already associated with specified currentIp")) { throw new EC2ServiceException(ClientError.InvalidParameterValue, "Specified publicIp is already associated to the specified VM"); } else if (errorMessage.contains("Specified IP address id is not associated with any vm Id")) { throw new EC2ServiceException(ClientError.InvalidParameterValue, "Specified publicIp is not associated to any VM"); @@ -2783,7 +2790,7 @@ public class EC2Engine extends ManagerBase { throw new EC2ServiceException(ClientError.InvalidAMIID_NotFound, "Specified ImageId is unavailable"); } else if (errorMessage.contains("cannot stop VM") && errorMessage.contains("when it is in state Starting")) { throw new EC2ServiceException(ClientError.IncorrectInstanceState, - "Unable to stop. One or more of the specified instances is in an incorrect state 'pending'"); + "Unable to stop. One or more of the specified instances is in an incorrect state 'pending'"); } else if (errorMessage.contains("Failed to authorize security group ingress rule(s)")) { throw new EC2ServiceException(ClientError.InvalidParameterValue, "Specified Ip-permission is invalid" + " or the Ip-permission already exists"); } else if (errorMessage.contains("Failed to reboot vm instance")) { @@ -2798,7 +2805,7 @@ public class EC2Engine extends ManagerBase { throw new EC2ServiceException(ClientError.VolumeLimitExceeded, "You have reached the limit on the number of volumes that can be created"); } else if (errorMessage.contains("Maximum number of resources of type 'public_ip' for account") && errorMessage.contains("has been exceeded")) { throw new EC2ServiceException(ClientError.AddressLimitExceeded, - "You have reached the limit on the number of elastic ip addresses your account can have"); + "You have reached the limit on the number of elastic ip addresses your account can have"); } else if (errorMessage.contains("Unable to apply save userdata entry on router")) { throw new EC2ServiceException(ClientError.InvalidParameterValue, "The value supplied for parameter UserData is invalid"); } else { @@ -2846,7 +2853,7 @@ public class EC2Engine extends ManagerBase { throw new EC2ServiceException(ServerError.InternalError, "Unable to start the instance that was stopped during image creation"); } else if (errorMessage.contains("One or more of instanceIds specified is in stopped state")) { throw new EC2ServiceException(ClientError.IncorrectInstanceState, - "Unable to reboot. One or more of the specified instances is in an incorrect state 'stopped'"); + "Unable to reboot. One or more of the specified instances is in an incorrect state 'stopped'"); } else if (errorMessage.contains("Specified ipAddress doesn't exist")) { throw new EC2ServiceException(ClientError.InvalidParameterValue, "Specified publicIp doesn't exist"); } else if (errorMessage.contains("Min Count is greater than the number of instances left to allocate")) { @@ -2865,7 +2872,7 @@ public class EC2Engine extends ManagerBase { throw new EC2ServiceException(ClientError.InvalidInstanceID_NotFound, "One or more of the specified instanceId not found"); } else if (errorMessage.contains("Cannot modify, instance should be in stopped state")) { throw new EC2ServiceException(ClientError.IncorrectInstanceState, - "Unable to modify instance attribute. Specified instance is not in the correct state 'stopped'"); + "Unable to modify instance attribute. Specified instance is not in the correct state 'stopped'"); } else { throw new EC2ServiceException(ServerError.InternalError, "An unexpected error occured"); } diff --git a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java b/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java index 3e7138f46d7..1058da3fedd 100644 --- a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java +++ b/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java @@ -40,13 +40,12 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; - import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.utils.identity.ManagementServerNode; +import org.apache.log4j.Logger; import com.cloud.cluster.dao.ManagementServerHostDao; import com.cloud.cluster.dao.ManagementServerHostPeerDao; @@ -256,15 +255,15 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C try { if (s_logger.isDebugEnabled()) { s_logger.debug("Cluster PDU " + getSelfPeerName() + " -> " + pdu.getDestPeer() + ". agent: " + pdu.getAgentId() + ", pdu seq: " + - pdu.getSequenceId() + ", pdu ack seq: " + pdu.getAckSequenceId() + ", json: " + pdu.getJsonPackage()); + pdu.getSequenceId() + ", pdu ack seq: " + pdu.getAckSequenceId() + ", json: " + pdu.getJsonPackage()); } long startTick = System.currentTimeMillis(); String strResult = peerService.execute(pdu); if (s_logger.isDebugEnabled()) { s_logger.debug("Cluster PDU " + getSelfPeerName() + " -> " + pdu.getDestPeer() + " completed. time: " + - (System.currentTimeMillis() - startTick) + "ms. agent: " + pdu.getAgentId() + ", pdu seq: " + pdu.getSequenceId() + - ", pdu ack seq: " + pdu.getAckSequenceId() + ", json: " + pdu.getJsonPackage()); + (System.currentTimeMillis() - startTick) + "ms. agent: " + pdu.getAgentId() + ", pdu seq: " + pdu.getSequenceId() + + ", pdu ack seq: " + pdu.getAckSequenceId() + ", json: " + pdu.getJsonPackage()); } if ("true".equals(strResult)) @@ -274,7 +273,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C invalidatePeerService(pdu.getDestPeer()); if (s_logger.isInfoEnabled()) { s_logger.info("Exception on remote execution, peer: " + pdu.getDestPeer() + ", iteration: " + i + ", exception message :" + - e.getMessage()); + e.getMessage()); } } } @@ -564,7 +563,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C if (profiler.getDuration() >= HeartbeatInterval.value()) { if (s_logger.isDebugEnabled()) s_logger.debug("Management server heartbeat takes too long to finish. profiler: " + profiler.toString() + ", profilerHeartbeatUpdate: " + - profilerHeartbeatUpdate.toString() + ", profilerPeerScan: " + profilerPeerScan.toString()); + profilerHeartbeatUpdate.toString() + ", profilerPeerScan: " + profilerPeerScan.toString()); } } @@ -625,8 +624,10 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C if (_heartbeatConnection != null) { Connection conn = TransactionLegacy.getStandaloneConnection(); if (conn != null) { - _heartbeatConnection.reset(TransactionLegacy.getStandaloneConnection()); + _heartbeatConnection.reset(conn); } + // The stand-alone connection does not have to be closed here because there will be another reference to it. + // As a matter of fact, it will be assigned to the connection instance variable in the ConnectionConcierge class. } } @@ -720,7 +721,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C } } } - break; + break; case nodeRemoved: { List l = msg.getNodes(); @@ -730,11 +731,10 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C } } } - break; + break; default: break; - } } @@ -772,7 +772,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C s_logger.info("Found " + inactiveList.size() + " inactive management server node based on timestamp"); for (ManagementServerHostVO host : inactiveList) s_logger.info("management server node msid: " + host.getMsid() + ", name: " + host.getName() + ", service ip: " + host.getServiceIP() + - ", version: " + host.getVersion()); + ", version: " + host.getVersion()); } List downHostList = new ArrayList(); @@ -810,7 +810,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C if (_mshostPeerDao.countStateSeenInPeers(_mshostId, _runId, ManagementServerHost.State.Down) > 0) { String msg = - "We have detected that at least one management server peer reports that this management server is down, perform active fencing to avoid split-brain situation"; + "We have detected that at least one management server peer reports that this management server is down, perform active fencing to avoid split-brain situation"; s_logger.error(msg); throw new ActiveFencingException(msg); } @@ -831,7 +831,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C if (entry.getKey().longValue() != _mshostId.longValue()) { if (s_logger.isDebugEnabled()) { s_logger.debug("Detected management node left because of invalidated session, id:" + entry.getKey() + ", nodeIP:" + - entry.getValue().getServiceIP()); + entry.getValue().getServiceIP()); } invalidatedNodeList.add(entry.getValue()); } @@ -918,8 +918,8 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C if (profiler.getDuration() >= HeartbeatInterval.value()) { if (s_logger.isDebugEnabled()) s_logger.debug("Peer scan takes too long to finish. profiler: " + profiler.toString() + ", profilerQueryActiveList: " + - profilerQueryActiveList.toString() + ", profilerSyncClusterInfo: " + profilerSyncClusterInfo.toString() + ", profilerInvalidatedNodeList: " + - profilerInvalidatedNodeList.toString() + ", profilerRemovedList: " + profilerRemovedList.toString()); + profilerQueryActiveList.toString() + ", profilerSyncClusterInfo: " + profilerSyncClusterInfo.toString() + ", profilerInvalidatedNodeList: " + + profilerInvalidatedNodeList.toString() + ", profilerRemovedList: " + profilerRemovedList.toString()); } } @@ -970,7 +970,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C } _mshostDao.update(mshost.getId(), getCurrentRunId(), NetUtils.getHostName(), version, _clusterNodeIP, _currentServiceAdapter.getServicePort(), - DateUtil.currentGMTTime()); + DateUtil.currentGMTTime()); } return mshost; @@ -1165,19 +1165,19 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C throw new ConfigurationException(msg); } else { String msg = - "Detected another management node with localhost IP is considered as running in DB, however it is not pingable, we will continue cluster initialization with this management server node"; + "Detected another management node with localhost IP is considered as running in DB, however it is not pingable, we will continue cluster initialization with this management server node"; s_logger.info(msg); } } else { if (pingManagementNode(peer.getMsid())) { String msg = - "Detected that another management node with the same IP " + peer.getServiceIP() + + "Detected that another management node with the same IP " + peer.getServiceIP() + " is already running, please check your cluster configuration"; s_logger.error(msg); throw new ConfigurationException(msg); } else { String msg = - "Detected that another management node with the same IP " + peer.getServiceIP() + + "Detected that another management node with the same IP " + peer.getServiceIP() + " is considered as running in DB, however it is not pingable, we will continue cluster initialization with this management server node"; s_logger.info(msg); } diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java index 0d28e0978a6..e52a751c831 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java @@ -19,6 +19,7 @@ package com.cloud.consoleproxy; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -35,11 +36,10 @@ import java.util.concurrent.Executor; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.xml.DOMConfigurator; -import com.google.gson.Gson; -import com.sun.net.httpserver.HttpServer; - import com.cloud.consoleproxy.util.Logger; import com.cloud.utils.PropertiesUtil; +import com.google.gson.Gson; +import com.sun.net.httpserver.HttpServer; /** * @@ -195,8 +195,8 @@ public class ConsoleProxy { Object result; try { result = - authMethod.invoke(ConsoleProxy.context, param.getClientHostAddress(), String.valueOf(param.getClientHostPort()), param.getClientTag(), - param.getClientHostPassword(), param.getTicket(), new Boolean(reauthentication)); + authMethod.invoke(ConsoleProxy.context, param.getClientHostAddress(), String.valueOf(param.getClientHostPort()), param.getClientTag(), + param.getClientHostPassword(), param.getTicket(), new Boolean(reauthentication)); } catch (IllegalAccessException e) { s_logger.error("Unable to invoke authenticateConsoleAccess due to IllegalAccessException" + " for vm: " + param.getClientTag(), e); authResult.setSuccess(false); @@ -387,6 +387,12 @@ public class ConsoleProxy { conf.load(confs); } catch (Exception e) { s_logger.error(e.toString(), e); + } finally { + try { + confs.close(); + } catch (IOException ioex) { + s_logger.error(ioex.toString(), ioex); + } } } start(conf); @@ -411,7 +417,7 @@ public class ConsoleProxy { viewer.initClient(param); } else if (!param.getClientHostPassword().equals(viewer.getClientHostPassword())) { s_logger.warn("Bad sid detected(VNC port may be reused). sid in session: " + viewer.getClientHostPassword() + ", sid in request: " + - param.getClientHostPassword()); + param.getClientHostPassword()); viewer.initClient(param); } } @@ -450,10 +456,11 @@ public class ConsoleProxy { } if (param.getClientHostPassword() == null || param.getClientHostPassword().isEmpty() || - !param.getClientHostPassword().equals(viewer.getClientHostPassword())) + !param.getClientHostPassword().equals(viewer.getClientHostPassword())) throw new AuthenticationException("Cannot use the existing viewer " + viewer + ": bad sid"); if (!viewer.isFrontEndAlive()) { + authenticationExternally(param); viewer.initClient(param); reportLoadChange = true; From de2c4ceeb9b1724599979c864cf0c7e7c3ff8b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20Nyg=C3=A5rd?= Date: Wed, 27 Nov 2013 13:54:22 +0100 Subject: [PATCH 047/170] Fixed typo Signed-off-by: Daan Hoogland --- client/WEB-INF/classes/resources/messages.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index 461aa84ee8a..384a0778bb2 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -50,7 +50,7 @@ message.action.delete.nic=Please confirm that want to remove this NIC, which wil changed.item.properties=Changed item properties confirm.enable.s3=Please fill in the following information to enable support for S3-backed Secondary Storage confirm.enable.swift=Please fill in the following information to enable support for Swift -error.could.not.change.your.password.because.ldap.is.enabled=Error cloud not change your password because LDAP is enabled. +error.could.not.change.your.password.because.ldap.is.enabled=Error could not change your password because LDAP is enabled. error.could.not.enable.zone=Could not enable zone error.installWizard.message=Something went wrong; you may go back and correct any errors error.invalid.username.password=Invalid username or password From 226b193488638dfeff7a003b8c1ca6c760e00cd1 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Tue, 19 Nov 2013 10:41:04 +0100 Subject: [PATCH 048/170] Fix for Coverity issues CID_1116744, CID_1116718 and CID_1116682, all related to resource leak Signed-off-by: Daan Hoogland --- .../serializer/OnwireClassRegistry.java | 8 ++++++-- .../com/cloud/api/doc/ApiXmlDocWriter.java | 19 +++++++++---------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/framework/ipc/src/org/apache/cloudstack/framework/serializer/OnwireClassRegistry.java b/framework/ipc/src/org/apache/cloudstack/framework/serializer/OnwireClassRegistry.java index 177ae09a592..83c8a4291e8 100644 --- a/framework/ipc/src/org/apache/cloudstack/framework/serializer/OnwireClassRegistry.java +++ b/framework/ipc/src/org/apache/cloudstack/framework/serializer/OnwireClassRegistry.java @@ -32,6 +32,8 @@ import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; +import org.apache.commons.io.IOUtils; + // // Finding classes in a given package code is taken and modified from // Credit: http://internna.blogspot.com/2007/11/java-5-retrieving-all-classes-from.html @@ -39,7 +41,7 @@ import java.util.jar.JarInputStream; public class OnwireClassRegistry { private List packages = new ArrayList(); - private Map> registry = new HashMap>(); + private final Map> registry = new HashMap>(); public OnwireClassRegistry() { registry.put("Object", Object.class); @@ -166,13 +168,15 @@ public class OnwireClassRegistry { } } } + IOUtils.closeQuietly(jarFile); } } while (jarEntry != null); + IOUtils.closeQuietly(jarFile); return classes; } static String stripFilenameExtension(String file) { return file.substring(0, file.lastIndexOf('.')); } -} +} \ No newline at end of file diff --git a/server/src/com/cloud/api/doc/ApiXmlDocWriter.java b/server/src/com/cloud/api/doc/ApiXmlDocWriter.java index a91530b3825..d3a8ade7176 100644 --- a/server/src/com/cloud/api/doc/ApiXmlDocWriter.java +++ b/server/src/com/cloud/api/doc/ApiXmlDocWriter.java @@ -41,11 +41,6 @@ import java.util.TreeMap; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; -import org.apache.log4j.Logger; - -import com.google.gson.annotations.SerializedName; -import com.thoughtworks.xstream.XStream; - import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.cloudstack.api.BaseAsyncCreateCmd; @@ -61,11 +56,14 @@ import org.apache.cloudstack.api.response.StoragePoolResponse; import org.apache.cloudstack.api.response.TemplateResponse; import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.api.response.VolumeResponse; +import org.apache.log4j.Logger; import com.cloud.alert.AlertManager; import com.cloud.serializer.Param; import com.cloud.utils.IteratorUtil; import com.cloud.utils.ReflectUtil; +import com.google.gson.annotations.SerializedName; +import com.thoughtworks.xstream.XStream; public class ApiXmlDocWriter { public static final Logger s_logger = Logger.getLogger(ApiXmlDocWriter.class.getName()); @@ -136,6 +134,7 @@ public class ApiXmlDocWriter { try { FileInputStream in = new FileInputStream(fileName); preProcessedCommands.load(in); + in.close(); } catch (FileNotFoundException ex) { System.out.println("Can't find file " + fileName); System.exit(2); @@ -395,13 +394,13 @@ public class ApiXmlDocWriter { // Generate request request.add(new Argument("username", "Username", true)); request.add(new Argument( - "password", - "Hashed password (Default is MD5). If you wish to use any other hashing algorithm, you would need to write a custom authentication adapter See Docs section.", - true)); + "password", + "Hashed password (Default is MD5). If you wish to use any other hashing algorithm, you would need to write a custom authentication adapter See Docs section.", + true)); request.add(new Argument("domain", - "path of the domain that the user belongs to. Example: domain=/com/cloud/internal. If no domain is passed in, the ROOT domain is assumed.", false)); + "path of the domain that the user belongs to. Example: domain=/com/cloud/internal. If no domain is passed in, the ROOT domain is assumed.", false)); request.add(new Argument("domainId", - "id of the domain that the user belongs to. If both domain and domainId are passed in, \"domainId\" parameter takes precendence", false)); + "id of the domain that the user belongs to. If both domain and domainId are passed in, \"domainId\" parameter takes precendence", false)); apiCommand.setRequest(request); // Generate response From f17f35eeb853ef170ba48d67ddd99d4f91f6a231 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Wed, 27 Nov 2013 14:38:25 +0100 Subject: [PATCH 049/170] CLOUDSTACK-5293: fix issue when collect vm disk statistics from iso --- server/src/com/cloud/server/StatsCollector.java | 5 ++++- server/src/com/cloud/vm/UserVmManagerImpl.java | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java index 470c37d6d1e..53001058a91 100755 --- a/server/src/com/cloud/server/StatsCollector.java +++ b/server/src/com/cloud/server/StatsCollector.java @@ -433,7 +433,10 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc for (VmDiskStatsEntry vmDiskStat : vmDiskStats) { SearchCriteria sc_volume = _volsDao.createSearchCriteria(); sc_volume.addAnd("path", SearchCriteria.Op.EQ, vmDiskStat.getPath()); - VolumeVO volume = _volsDao.search(sc_volume, null).get(0); + List volumes = _volsDao.search(sc_volume, null); + if ((volumes == null) || (volumes.size() == 0)) + break; + VolumeVO volume = volumes.get(0); VmDiskStatisticsVO previousVmDiskStats = _vmDiskStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), vmId, volume.getId()); VmDiskStatisticsVO vmDiskStat_lock = _vmDiskStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), vmId, volume.getId()); diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 45b141f4b4e..c0b0031a8e9 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -3351,7 +3351,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir for (VmDiskStatsEntry vmDiskStat : vmDiskStats) { SearchCriteria sc_volume = _volsDao.createSearchCriteria(); sc_volume.addAnd("path", SearchCriteria.Op.EQ, vmDiskStat.getPath()); - VolumeVO volume = _volsDao.search(sc_volume, null).get(0); + List volumes = _volsDao.search(sc_volume, null); + if ((volumes == null) || (volumes.size() == 0)) + break; + VolumeVO volume = volumes.get(0); VmDiskStatisticsVO previousVmDiskStats = _vmDiskStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId()); VmDiskStatisticsVO vmDiskStat_lock = _vmDiskStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId()); From 0b5a6cb0cff2ab13481a158227201593705b7c76 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Wed, 27 Nov 2013 13:05:47 -0800 Subject: [PATCH 050/170] CLOUDSTACK-1889: UI > accounts > Update Resource Count action > after action succeeds, pop up a dialog to show updated count of resources. --- ui/scripts/accounts.js | 54 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/ui/scripts/accounts.js b/ui/scripts/accounts.js index 7267252bf7f..72bc00f7576 100644 --- a/ui/scripts/accounts.js +++ b/ui/scripts/accounts.js @@ -372,7 +372,59 @@ data: data, async: true, success: function(json) { - //var resourcecounts= json.updateresourcecountresponse.resourcecount; //do nothing + var resourcecounts= json.updateresourcecountresponse.resourcecount; + //pop up API response in a dialog box since only updateResourceCount API returns resourcecount (listResourceLimits API does NOT return resourcecount) + var msg = ''; + if (resourcecounts != null) { + for (var i = 0; i < resourcecounts.length; i++) { + switch (resourcecounts[i].resourcetype) { + case '0': + msg += 'Instance'; //vmLimit + break; + case '1': + msg += 'Public IP'; //ipLimit + break; + case '2': + msg += 'Volume'; //volumeLimit + break; + case '3': + msg += 'Snapshot'; //snapshotLimit + break; + case '4': + msg += 'Template'; //templateLimit + break; + case '5': + continue; //resourcetype 5 is not in use. so, skip to next item. + break; + case '6': + msg += 'Network'; //networkLimit + break; + case '7': + msg += 'VPC'; //vpcLimit + break; + case '8': + msg += 'CPU'; //cpuLimit + break; + case '9': + msg += 'Memory'; //memoryLimit + break; + case '10': + msg += 'Primary Storage'; //primaryStorageLimit + break; + case '11': + msg += 'Secondary Storage'; //secondaryStorageLimit + break; + } + + msg += ' Count: ' + resourcecounts[i].resourcecount + '
'; + } + } + + + cloudStack.dialog.notice({ + message: msg + }); + args.response.success(); }, error: function(json) { From 426f564944f9aa51e9af042f1d4636ddc13fedc4 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Wed, 27 Nov 2013 10:57:11 -0800 Subject: [PATCH 051/170] Resource metadata support for NetworkACLItem Conflicts: api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLsCmd.java --- api/src/com/cloud/server/ResourceTag.java | 2 +- .../user/network/ListNetworkACLsCmd.java | 3 +- ...spring-engine-schema-core-daos-context.xml | 1 + .../NetworkACLItemDetailVO.java | 82 +++++++++++++++++++ .../dao/NetworkACLItemDetailsDao.java | 26 ++++++ .../dao/NetworkACLItemDetailsDaoImpl.java | 33 ++++++++ .../metadata/ResourceMetaDataManagerImpl.java | 5 ++ setup/db/db/schema-421to430.sql | 10 +++ 8 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/NetworkACLItemDetailVO.java create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLItemDetailsDao.java create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLItemDetailsDaoImpl.java diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java index e76b777737f..6d18834c6b5 100644 --- a/api/src/com/cloud/server/ResourceTag.java +++ b/api/src/com/cloud/server/ResourceTag.java @@ -38,7 +38,7 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit PublicIpAddress(true, true), Project(true, false), Vpc(true, true), - NetworkACL(true, false), + NetworkACL(true, true), StaticRoute(true, false), VMSnapshot(true, false), RemoteAccessVpn(true, true), diff --git a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLsCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLsCmd.java index 0aa319a6bfe..99c620ca14d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLsCmd.java @@ -43,7 +43,8 @@ public class ListNetworkACLsCmd extends BaseListTaggedResourcesCmd { ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = FirewallRuleResponse.class, description = "Lists network ACL Item with the specified ID") + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = NetworkACLItemResponse.class, + description="Lists network ACL Item with the specified ID") private Long id; @Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, description = "list network ACL Items by network Id") diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index d12e5cba88f..dfab28caf82 100644 --- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -326,6 +326,7 @@ + diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/NetworkACLItemDetailVO.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/NetworkACLItemDetailVO.java new file mode 100644 index 00000000000..fb27d374a94 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/NetworkACLItemDetailVO.java @@ -0,0 +1,82 @@ +// 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.resourcedetail; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.apache.cloudstack.api.ResourceDetail; + +@Entity +@Table(name = "network_acl_item_details") +public class NetworkACLItemDetailVO implements ResourceDetail { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "network_acl_item_id") + private long resourceId; + + @Column(name = "name") + private String name; + + @Column(name = "value", length = 1024) + private String value; + + @Column(name = "display") + private boolean display; + + public NetworkACLItemDetailVO() { + } + + public NetworkACLItemDetailVO(long id, String name, String value) { + this.resourceId = id; + this.name = name; + this.value = value; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getValue() { + return value; + } + + @Override + public long getResourceId() { + return resourceId; + } + + @Override + public boolean isDisplay() { + return display; + } +} + diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLItemDetailsDao.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLItemDetailsDao.java new file mode 100644 index 00000000000..db820ac5123 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLItemDetailsDao.java @@ -0,0 +1,26 @@ +// 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.resourcedetail.dao; + +import org.apache.cloudstack.resourcedetail.NetworkACLItemDetailVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; + +import com.cloud.utils.db.GenericDao; + +public interface NetworkACLItemDetailsDao extends GenericDao, ResourceDetailsDao { + +} \ No newline at end of file diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLItemDetailsDaoImpl.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLItemDetailsDaoImpl.java new file mode 100644 index 00000000000..930c77a4500 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLItemDetailsDaoImpl.java @@ -0,0 +1,33 @@ +// 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.resourcedetail.dao; + +import javax.ejb.Local; + +import org.apache.cloudstack.resourcedetail.NetworkACLItemDetailVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; +import org.springframework.stereotype.Component; + +@Component +@Local(value = { NetworkACLItemDetailsDao.class }) +public class NetworkACLItemDetailsDaoImpl extends ResourceDetailsDaoBase implements NetworkACLItemDetailsDao { + + @Override + public void addDetail(long resourceId, String key, String value) { + super.addDetail(new NetworkACLItemDetailVO(resourceId, key, value)); + } +} \ No newline at end of file diff --git a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java index ec000bf80de..e1fc37fa2f7 100644 --- a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java +++ b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java @@ -27,6 +27,7 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.api.ResourceDetail; import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; import org.apache.cloudstack.resourcedetail.dao.FirewallRuleDetailsDao; +import org.apache.cloudstack.resourcedetail.dao.NetworkACLItemDetailsDao; import org.apache.cloudstack.resourcedetail.dao.NetworkACLListDetailsDao; import org.apache.cloudstack.resourcedetail.dao.RemoteAccessVpnDetailsDao; import org.apache.cloudstack.resourcedetail.dao.UserIpAddressDetailsDao; @@ -89,6 +90,9 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource VpcGatewayDetailsDao _vpcGatewayDetailsDao; @Inject NetworkACLListDetailsDao _networkACLListDetailsDao; + @Inject + NetworkACLItemDetailsDao _networkACLDetailsDao; + private static Map> _daoMap = new HashMap>(); @@ -111,6 +115,7 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource _daoMap.put(ResourceObjectType.Vpc, _vpcDetailsDao); _daoMap.put(ResourceObjectType.PrivateGateway, _vpcGatewayDetailsDao); _daoMap.put(ResourceObjectType.NetworkACLList, _networkACLListDetailsDao); + _daoMap.put(ResourceObjectType.NetworkACL, _networkACLDetailsDao); return true; } diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql index dad9a6b0993..45f874cfca5 100644 --- a/setup/db/db/schema-421to430.sql +++ b/setup/db/db/schema-421to430.sql @@ -789,3 +789,13 @@ CREATE TABLE `cloud`.`network_acl_details` ( PRIMARY KEY (`id`), CONSTRAINT `fk_network_acl_details__network_acl_id` FOREIGN KEY `fk_network_acl_details__network_acl_id`(`network_acl_id`) REFERENCES `network_acl`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`network_acl_item_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `network_acl_item_id` bigint unsigned NOT NULL COMMENT 'VPC gateway id', + `name` varchar(255) NOT NULL, + `value` varchar(1024) NOT NULL, + `display` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'True if the detail can be displayed to the end user', + PRIMARY KEY (`id`), + CONSTRAINT `fk_network_acl_item_details__network_acl_item_id` FOREIGN KEY `fk_network_acl_item_details__network_acl_item_id`(`network_acl_item_id`) REFERENCES `network_acl_item`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; From ab39b658ad84e400a543a7b8a0c001600a603cad Mon Sep 17 00:00:00 2001 From: Abhinandan Prateek Date: Thu, 28 Nov 2013 09:24:32 +0530 Subject: [PATCH 052/170] added valid values for system.vm.default.hypervisor in desc --- server/src/com/cloud/configuration/Config.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index f2debe7c6ae..1490926cc42 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -703,7 +703,13 @@ public enum Config { "true", "Indicates whether or not to automatically reserver system VM standby capacity.", null), - SystemVMDefaultHypervisor("Advanced", ManagementServer.class, String.class, "system.vm.default.hypervisor", null, "Hypervisor type used to create system vm", null), + SystemVMDefaultHypervisor("Advanced", + ManagementServer.class, + String.class, + "system.vm.default.hypervisor", + null, + "Hypervisor type used to create system vm, valid values are: XenServer, KVM, VMware, Hyperv, VirtualBox, Parralels, BareMetal, Ovm, LXC, Any", + null), SystemVMRandomPassword( "Advanced", ManagementServer.class, From 221aea573008a0b13d115f4949ea3eed2d574ac0 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Thu, 28 Nov 2013 10:47:21 +0100 Subject: [PATCH 053/170] CLOUDSTACK-5299: set hypervisor_type of volumes from image format if not set. --- server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java index 36f67409ac6..a8631f781ed 100644 --- a/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java @@ -171,8 +171,12 @@ public class VolumeJoinDaoImpl extends GenericDaoBase implem // return hypervisor and storage pool info for ROOT and Resource domain only if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { - if (volume.getState() != Volume.State.UploadOp && volume.getHypervisorType() != null) { - volResponse.setHypervisor(volume.getHypervisorType().toString()); + if (volume.getState() != Volume.State.UploadOp) { + if (volume.getHypervisorType() != null) { + volResponse.setHypervisor(volume.getHypervisorType().toString()); + } else { + volResponse.setHypervisor(ApiDBUtils.getHypervisorTypeFromFormat(volume.getFormat()).toString()); + } } Long poolId = volume.getPoolId(); String poolName = (poolId == null) ? "none" : volume.getPoolName(); From 64c03dbc3129fe7b2c613f2981b3f645d88b449b Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Thu, 28 Nov 2013 10:47:37 +0100 Subject: [PATCH 054/170] [UI] kvm vm snapshot not shown if kvm.snapshot.enabled is set to false --- ui/scripts/instances.js | 6 ++++-- ui/scripts/storage.js | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index 06acc16583a..27e0e4f962c 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -2106,7 +2106,8 @@ } else if (jsonObj.state == 'Running') { allowedActions.push("stop"); allowedActions.push("restart"); - allowedActions.push("snapshot"); + if (jsonObj.hypervisor != 'KVM' || g_KVMsnapshotenabled == true) + allowedActions.push("snapshot"); allowedActions.push("destroy"); allowedActions.push("reset"); @@ -2135,7 +2136,8 @@ allowedActions.push("start"); allowedActions.push("destroy"); allowedActions.push("reset"); - allowedActions.push("snapshot"); + if (jsonObj.hypervisor != 'KVM' || g_KVMsnapshotenabled == true) + allowedActions.push("snapshot"); allowedActions.push("scaleUp"); //when vm is stopped, scaleUp is supported for all hypervisors allowedActions.push("changeAffinity"); diff --git a/ui/scripts/storage.js b/ui/scripts/storage.js index 03b88f82d9c..4875662d99a 100644 --- a/ui/scripts/storage.js +++ b/ui/scripts/storage.js @@ -1896,7 +1896,7 @@ if (jsonObj.hypervisor != "Ovm" && jsonObj.state == "Ready") { if (jsonObj.hypervisor == 'KVM') { - if (json.vmstate == 'Running') { + if (jsonObj.vmstate == 'Running') { if (g_KVMsnapshotenabled == true) { //"kvm.snapshot.enabled" flag should be taken to account only when snapshot is being created for Running vm (CLOUDSTACK-4428) allowedActions.push("takeSnapshot"); allowedActions.push("recurringSnapshot"); From d473d5a36a4c50793988081a52b602d58d95f302 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Thu, 28 Nov 2013 10:47:51 +0100 Subject: [PATCH 055/170] CLOUDSTACK-5293: get vm disk statistics only from DISK (not for ISO/FLOPPY) --- .../hypervisor/kvm/resource/LibvirtComputingResource.java | 3 +++ 1 file changed, 3 insertions(+) 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 c88a279fb9d..b951b212b2c 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 @@ -207,6 +207,7 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.CpuModeDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.CpuTuneDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DevicesDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; +import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.deviceType; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.diskProtocol; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.FeaturesDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.FilesystemDef; @@ -4603,6 +4604,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv List disks = getDisks(conn, vmName); for (DiskDef disk : disks) { + if (disk.getDeviceType() != deviceType.DISK) + break; DomainBlockStats blockStats = dm.blockStats(disk.getDiskLabel()); String path = disk.getDiskPath(); // for example, path = /mnt/pool_uuid/disk_path/ String diskPath = null; From 81c07f179103e19a0607a6d1a718f28ffc1874ae Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Thu, 28 Nov 2013 10:48:07 +0100 Subject: [PATCH 056/170] allow delete snapshot with ERROR state --- .../cloudstack/storage/snapshot/XenserverSnapshotStrategy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java index 22182b1615e..14fb6180861 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java @@ -201,7 +201,7 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase { return true; } - if (!Snapshot.State.BackedUp.equals(snapshotVO.getState())) { + if (!Snapshot.State.BackedUp.equals(snapshotVO.getState()) && !Snapshot.State.Error.equals(snapshotVO.getState())) { throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId + " due to it is in " + snapshotVO.getState() + " Status"); } From 6bda2739c82724db6510d8a593ccc0a5f8e8b992 Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Thu, 28 Nov 2013 15:40:05 +0530 Subject: [PATCH 057/170] CLOUDSTACK-5302. listHosts API response - value of cpuallocated is always 0% --- server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java index 3112702c645..1b95d9b24cc 100644 --- a/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java @@ -109,7 +109,7 @@ public class HostJoinDaoImpl extends GenericDaoBase implements if (details.contains(HostDetails.all) || details.contains(HostDetails.capacity)) { // set allocated capacities Long mem = host.getMemReservedCapacity() + host.getMemUsedCapacity(); - Long cpu = host.getCpuReservedCapacity() + host.getCpuReservedCapacity(); + Long cpu = host.getCpuReservedCapacity() + host.getCpuUsedCapacity(); hostResponse.setMemoryAllocated(mem); hostResponse.setMemoryTotal(host.getTotalMemory()); From 36201b9776d3e48fd7832a4dc21136f83524379f Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Mon, 25 Nov 2013 22:55:12 +0100 Subject: [PATCH 058/170] Fix issue with sourceCidr not being passed to the VRouter on start. Signed-off-by: Abhinandan Prateek --- .../router/VirtualNetworkApplianceManagerImpl.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 4bbc872e7cf..d5b9d3cf038 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -202,6 +202,7 @@ import com.cloud.network.router.VirtualRouter.Role; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.LoadBalancerContainer.Scheme; +import com.cloud.network.rules.FirewallRuleVO; import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.RulesManager; import com.cloud.network.rules.StaticNat; @@ -2788,9 +2789,6 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V UserVmVO vm = _userVmDao.findById(profile.getId()); _userVmDao.loadDetails(vm); - final boolean isZoneBasic = (dest.getDataCenter().getNetworkType() == NetworkType.Basic); - final Long podId = isZoneBasic ? dest.getPod().getId() : null; - //Asuming we have only one router per network For Now. DomainRouterVO router = routers.get(0); if (router.getState() != State.Running) { @@ -2820,7 +2818,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V if (ipInVmsubnet == false) { try { if (network.getTrafficType() == TrafficType.Guest && network.getGuestType() == GuestType.Shared) { - Pod pod = _podDao.findById(vm.getPodIdToDeployIn()); + _podDao.findById(vm.getPodIdToDeployIn()); Account caller = CallContext.current().getCallingAccount(); List vlanList = _vlanDao.listVlansByNetworkIdAndGateway(network.getId(), nic.getGateway()); List vlanDbIdList = new ArrayList(); @@ -3471,7 +3469,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V ipList.add(DhcpTO); ipAliasVO.setVmId(router.getId()); } - DataCenterVO dcvo = _dcDao.findById(router.getDataCenterId()); + _dcDao.findById(router.getDataCenterId()); DnsMasqConfigCommand dnsMasqConfigCmd = new DnsMasqConfigCommand(ipList); dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); @@ -3719,6 +3717,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } rulesTO = new ArrayList(); for (FirewallRule rule : rules) { + _rulesDao.loadSourceCidrs((FirewallRuleVO)rule); FirewallRule.TrafficType traffictype = rule.getTrafficType(); if (traffictype == FirewallRule.TrafficType.Ingress) { IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId()); From 5cc47f77c5d7c1c8c40c5e7cb2f7083fd2ce56cd Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Fri, 29 Nov 2013 10:39:04 +0100 Subject: [PATCH 059/170] CLOUDSTACK-5033: set origin ip address in logs if management servers is behind a reverse proxy or load balancer --- server/src/com/cloud/api/ApiServlet.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java index 6a33c14baaf..6386929e936 100755 --- a/server/src/com/cloud/api/ApiServlet.java +++ b/server/src/com/cloud/api/ApiServlet.java @@ -121,7 +121,13 @@ public class ApiServlet extends HttpServlet { private void processRequestInContext(HttpServletRequest req, HttpServletResponse resp) { StringBuffer auditTrailSb = new StringBuffer(); - auditTrailSb.append(" " + req.getRemoteAddr()); + String ipAddress = req.getHeader("X-FORWARDED-FOR"); + if (ipAddress == null) { + ipAddress = req.getRemoteAddr(); + } else { + ipAddress = ipAddress.split(",")[0]; + } + auditTrailSb.append(" " + ipAddress); auditTrailSb.append(" -- " + req.getMethod() + " "); // get the response format since we'll need it in a couple of places String responseType = BaseCmd.RESPONSE_TYPE_XML; From 6ab27267beb11b63d968ca32203352d6a44ce39f Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Fri, 29 Nov 2013 10:40:33 +0100 Subject: [PATCH 060/170] CLOUDSTACK-5310: fix issue: offering display twice in dropdown when create network --- ui/scripts/network.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/ui/scripts/network.js b/ui/scripts/network.js index d2b2c4da26d..65394527c06 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -540,11 +540,8 @@ domain: { label: 'label.domain', select: function(args) { - var items = []; $.ajax({ url: createURL("listDomains&listAll=true"), - dataType: "json", - async: false, success: function(json) { var items = []; items.push({ From abd4a826e9e2d481e8b18be134429c7b37778708 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Fri, 29 Nov 2013 10:52:51 +0100 Subject: [PATCH 061/170] Revert "CLOUDSTACK-5033: set origin ip address in logs if management servers is behind a reverse proxy or load balancer" This reverts commit 5cc47f77c5d7c1c8c40c5e7cb2f7083fd2ce56cd. --- server/src/com/cloud/api/ApiServlet.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java index 6386929e936..6a33c14baaf 100755 --- a/server/src/com/cloud/api/ApiServlet.java +++ b/server/src/com/cloud/api/ApiServlet.java @@ -121,13 +121,7 @@ public class ApiServlet extends HttpServlet { private void processRequestInContext(HttpServletRequest req, HttpServletResponse resp) { StringBuffer auditTrailSb = new StringBuffer(); - String ipAddress = req.getHeader("X-FORWARDED-FOR"); - if (ipAddress == null) { - ipAddress = req.getRemoteAddr(); - } else { - ipAddress = ipAddress.split(",")[0]; - } - auditTrailSb.append(" " + ipAddress); + auditTrailSb.append(" " + req.getRemoteAddr()); auditTrailSb.append(" -- " + req.getMethod() + " "); // get the response format since we'll need it in a couple of places String responseType = BaseCmd.RESPONSE_TYPE_XML; From 68406ba29d7dc31dcfd9ef2cefc673ff32cfa514 Mon Sep 17 00:00:00 2001 From: Bharat Kumar Date: Thu, 28 Nov 2013 07:53:21 +0530 Subject: [PATCH 062/170] CLOUDSTACK-5161 enable scaling of a vm using custom offering Signed-off-by: Koushik Das --- .../apache/cloudstack/api/ApiConstants.java | 1 + .../admin/systemvm/ScaleSystemVMCmd.java | 25 +++ .../admin/systemvm/UpgradeSystemVMCmd.java | 25 +++ .../api/command/user/vm/ScaleVMCmd.java | 29 +++ .../api/command/user/vm/UpgradeVMCmd.java | 25 +++ .../api/response/ServiceOfferingResponse.java | 21 ++- .../com/cloud/vm/VirtualMachineManager.java | 4 +- .../cloud/vm/VirtualMachineManagerImpl.java | 9 +- .../cloud/entity/api/VMEntityManagerImpl.java | 1 + .../src/com/cloud/event/UsageEventVO.java | 4 + .../com/cloud/service/ServiceOfferingVO.java | 18 +- .../cloud/service/dao/ServiceOfferingDao.java | 3 +- .../service/dao/ServiceOfferingDaoImpl.java | 34 ++-- .../src/com/cloud/storage/DiskOfferingVO.java | 16 ++ .../com/cloud/usage/UsageVMInstanceVO.java | 3 - .../query/dao/ServiceOfferingJoinDaoImpl.java | 1 + .../api/query/vo/ServiceOfferingJoinVO.java | 16 +- .../cloud/capacity/CapacityManagerImpl.java | 5 +- .../ConfigurationManagerImpl.java | 7 + .../cloud/server/ManagementServerImpl.java | 29 ++- server/src/com/cloud/vm/UserVmManager.java | 12 +- .../src/com/cloud/vm/UserVmManagerImpl.java | 172 ++++++++++++++---- .../test/com/cloud/vm/UserVmManagerTest.java | 6 +- .../src/com/cloud/usage/UsageManagerImpl.java | 12 +- 24 files changed, 389 insertions(+), 89 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 7b872648f65..efdff12b0c6 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -72,6 +72,7 @@ public class ApiConstants { public static final String DISPLAY_VM = "displayvm"; public static final String DISPLAY_OFFERING = "displayoffering"; public static final String DISPLAY_VOLUME = "displayvolume"; + public static final String CUSTOM_PARAMETERS = "customparameters"; public static final String DNS1 = "dns1"; public static final String DNS2 = "dns2"; public static final String IP6_DNS1 = "ip6dns1"; diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java index a7c864da53d..247df1eaed5 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java @@ -39,6 +39,11 @@ import com.cloud.offering.ServiceOffering; import com.cloud.user.Account; import com.cloud.vm.VirtualMachine; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + @APICommand(name = "scaleSystemVm", responseObject = SystemVmResponse.class, description = "Scale the service offering for a system vm (console proxy or secondary storage). " + "The system vm must be in a \"Stopped\" state for " @@ -61,6 +66,11 @@ public class ScaleSystemVMCmd extends BaseAsyncCmd { description = "the service offering ID to apply to the system vm") private Long serviceOfferingId; + @Parameter(name=ApiConstants.CUSTOM_PARAMETERS, + type = CommandType.MAP, + description = "name value pairs of custom parameters for cpu, memory and cpunumber. example customparameters[i].name=value") + private Map customParameters; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -73,6 +83,21 @@ public class ScaleSystemVMCmd extends BaseAsyncCmd { return serviceOfferingId; } + public Map getCustomParameters() { + Map customparameterMap = new HashMap(); + if (customParameters != null && customParameters.size() != 0) { + Collection parameterCollection = customParameters.values(); + Iterator iter = parameterCollection.iterator(); + while (iter.hasNext()) { + HashMap value = (HashMap) iter.next(); + for (String key : value.keySet()) { + customparameterMap.put(key, value.get(key)); + } + } + } + return customparameterMap; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java index 1357a7d8d63..a49828be89f 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java @@ -34,6 +34,11 @@ import com.cloud.offering.ServiceOffering; import com.cloud.user.Account; import com.cloud.vm.VirtualMachine; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + @APICommand(name = "changeServiceForSystemVm", responseObject = SystemVmResponse.class, description = "Changes the service offering for a system vm (console proxy or secondary storage). " + "The system vm must be in a \"Stopped\" state for " @@ -56,6 +61,11 @@ public class UpgradeSystemVMCmd extends BaseCmd { description = "the service offering ID to apply to the system vm") private Long serviceOfferingId; + @Parameter(name=ApiConstants.CUSTOM_PARAMETERS, + type = CommandType.MAP, + description = "name value pairs of custom parameters for cpu, memory and cpunumber. example customparameters[i].name=value") + private Map customParameters; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -68,6 +78,21 @@ public class UpgradeSystemVMCmd extends BaseCmd { return serviceOfferingId; } + public Map getCustomParameters() { + Map customparameterMap = new HashMap(); + if (customParameters != null && customParameters.size() !=0){ + Collection parameterCollection = customParameters.values(); + Iterator iter = parameterCollection.iterator(); + while (iter.hasNext()) { + HashMap value = (HashMap) iter.next(); + for (String key : value.keySet()) { + customparameterMap.put(key, value.get(key)); + } + } + } + return customparameterMap; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java index 6cb49c165e4..08a4a5673dc 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java @@ -39,6 +39,12 @@ import com.cloud.exception.VirtualMachineMigrationException; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + + @APICommand(name = "scaleVirtualMachine", description = "Scales the virtual machine to a new service offering.", responseObject = SuccessResponse.class) public class ScaleVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(ScaleVMCmd.class.getName()); @@ -60,6 +66,11 @@ public class ScaleVMCmd extends BaseAsyncCmd { description = "the ID of the service offering for the virtual machine") private Long serviceOfferingId; + @Parameter(name=ApiConstants.CUSTOM_PARAMETERS, + type = CommandType.MAP, + description = "name value pairs of custom parameters for cpu, memory and cpunumber. example customparameters[i].name=value") + private Map customParameters; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -72,6 +83,24 @@ public class ScaleVMCmd extends BaseAsyncCmd { return serviceOfferingId; } + //instead of reading a map directly we are using collections. + //it is because customParameters.values() cannot be cast to a map. + //it gives a exception + public Map getCustomParameters() { + Map customparameterMap = new HashMap(); + if (customParameters != null && customParameters.size() !=0){ + Collection parameterCollection = customParameters.values(); + Iterator iter = parameterCollection.iterator(); + while (iter.hasNext()) { + HashMap value = (HashMap) iter.next(); + for (String key : value.keySet()) { + customparameterMap.put(key, value.get(key)); + } + } + } + return customparameterMap; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java index 3dfcdf9f158..43497811b13 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java @@ -34,6 +34,11 @@ import com.cloud.offering.ServiceOffering; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + @APICommand(name = "changeServiceForVirtualMachine", responseObject = UserVmResponse.class, description = "Changes the service offering for a virtual machine. " + "The virtual machine must be in a \"Stopped\" state for " + "this command to take effect.") public class UpgradeVMCmd extends BaseCmd { @@ -54,6 +59,11 @@ public class UpgradeVMCmd extends BaseCmd { description = "the service offering ID to apply to the virtual machine") private Long serviceOfferingId; + @Parameter(name=ApiConstants.CUSTOM_PARAMETERS, + type = CommandType.MAP, + description = "name value pairs of custom parameters for cpu, memory and cpunumber. example customparameters[i].name=value") + private Map customParameters; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -66,6 +76,21 @@ public class UpgradeVMCmd extends BaseCmd { return serviceOfferingId; } + public Map getCustomParameters() { + Map customparameterMap = new HashMap(); + if (customParameters != null && customParameters.size() !=0){ + Collection parameterCollection = customParameters.values(); + Iterator iter = parameterCollection.iterator(); + while (iter.hasNext()) { + HashMap value = (HashMap) iter.next(); + for (String key : value.keySet()) { + customparameterMap.put(key, value.get(key)); + } + } + } + return customparameterMap; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java index 7ec739eed00..c8dee140323 100644 --- a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java @@ -44,15 +44,15 @@ public class ServiceOfferingResponse extends BaseResponse { @SerializedName("cpunumber") @Param(description = "the number of CPU") - private int cpuNumber; + private Integer cpuNumber; @SerializedName("cpuspeed") @Param(description = "the clock rate CPU speed in Mhz") - private int cpuSpeed; + private Integer cpuSpeed; @SerializedName("memory") @Param(description = "the memory in MB") - private int memory; + private Integer memory; @SerializedName("created") @Param(description = "the date this service offering was created") @@ -130,6 +130,10 @@ public class ServiceOfferingResponse extends BaseResponse { @Param(description = "additional key/value details tied with this service offering", since = "4.2.0") private Map details; + @SerializedName("iscustomized") + @Param(description = "is true if the offering is customized", since = "4.3.0") + private Boolean isCustomized; + public ServiceOfferingResponse() { } @@ -185,7 +189,7 @@ public class ServiceOfferingResponse extends BaseResponse { return cpuNumber; } - public void setCpuNumber(int cpuNumber) { + public void setCpuNumber(Integer cpuNumber) { this.cpuNumber = cpuNumber; } @@ -193,7 +197,7 @@ public class ServiceOfferingResponse extends BaseResponse { return cpuSpeed; } - public void setCpuSpeed(int cpuSpeed) { + public void setCpuSpeed(Integer cpuSpeed) { this.cpuSpeed = cpuSpeed; } @@ -201,7 +205,7 @@ public class ServiceOfferingResponse extends BaseResponse { return memory; } - public void setMemory(int memory) { + public void setMemory(Integer memory) { this.memory = memory; } @@ -309,4 +313,9 @@ public class ServiceOfferingResponse extends BaseResponse { this.details = details; } + public void setIscutomized(boolean iscutomized) { + this.isCustomized = iscutomized; + + } + } diff --git a/engine/api/src/com/cloud/vm/VirtualMachineManager.java b/engine/api/src/com/cloud/vm/VirtualMachineManager.java index c78942fbd05..fbbed213bfd 100644 --- a/engine/api/src/com/cloud/vm/VirtualMachineManager.java +++ b/engine/api/src/com/cloud/vm/VirtualMachineManager.java @@ -145,9 +145,9 @@ public interface VirtualMachineManager extends Manager { /** * @param vmInstance - * @param newServiceOfferingId + * @param newServiceOffering */ - void checkIfCanUpgrade(VirtualMachine vmInstance, long newServiceOfferingId); + void checkIfCanUpgrade(VirtualMachine vmInstance, ServiceOffering newServiceOffering); /** * @param vmId diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 3a3de701f9f..6b551cc57ec 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -3011,10 +3011,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } @Override - public void checkIfCanUpgrade(VirtualMachine vmInstance, long newServiceOfferingId) { - ServiceOfferingVO newServiceOffering = _offeringDao.findById(vmInstance.getId(), newServiceOfferingId); + public void checkIfCanUpgrade(VirtualMachine vmInstance, ServiceOffering newServiceOffering) { if (newServiceOffering == null) { - throw new InvalidParameterValueException("Unable to find a service offering with id " + newServiceOfferingId); + throw new InvalidParameterValueException("Unable to find a service offering with id " + newServiceOffering.getId()); } // Check that the VM is stopped / running @@ -3025,7 +3024,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } // Check if the service offering being upgraded to is what the VM is already running with - if (vmInstance.getServiceOfferingId() == newServiceOffering.getId()) { + if (!newServiceOffering.isDynamic() && vmInstance.getServiceOfferingId() == newServiceOffering.getId()) { if (s_logger.isInfoEnabled()) { s_logger.info("Not upgrading vm " + vmInstance.toString() + " since it already has the requested " + "service offering (" + newServiceOffering.getName() + ")"); @@ -3734,7 +3733,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac VMInstanceVO vm = _vmDao.findByUuid(vmUuid); long newServiceofferingId = vm.getServiceOfferingId(); - ServiceOffering newServiceOffering = _entityMgr.findById(ServiceOffering.class, newServiceofferingId); + ServiceOffering newServiceOffering = _offeringDao.findById(vm.getId(), newServiceofferingId); HostVO hostVo = _hostDao.findById(vm.getHostId()); Float memoryOvercommitRatio = CapacityManager.MemOverprovisioningFactor.valueIn(hostVo.getClusterId()); 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 c02e0adf98e..40b0f447392 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 @@ -146,6 +146,7 @@ public class VMEntityManagerImpl implements VMEntityManager { //FIXME: profile should work on VirtualMachineEntity VMInstanceVO vm = _vmDao.findByUuid(vmEntityVO.getUuid()); VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm); + vmProfile.setServiceOffering(_serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId())); DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterId(), vm.getPodIdToDeployIn(), null, null, null, null); if (planToDeploy != null && planToDeploy.getDataCenterId() != 0) { plan = diff --git a/engine/schema/src/com/cloud/event/UsageEventVO.java b/engine/schema/src/com/cloud/event/UsageEventVO.java index 719a79bde6e..2278103b82e 100644 --- a/engine/schema/src/com/cloud/event/UsageEventVO.java +++ b/engine/schema/src/com/cloud/event/UsageEventVO.java @@ -30,6 +30,10 @@ import com.cloud.utils.db.GenericDao; @Entity @Table(name = "usage_event") public class UsageEventVO implements UsageEvent { + public enum DynamicParameters { + cpuSpeed, cpuNumber, memory + }; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") diff --git a/engine/schema/src/com/cloud/service/ServiceOfferingVO.java b/engine/schema/src/com/cloud/service/ServiceOfferingVO.java index d968de55c74..f1cc39b9326 100755 --- a/engine/schema/src/com/cloud/service/ServiceOfferingVO.java +++ b/engine/schema/src/com/cloud/service/ServiceOfferingVO.java @@ -34,10 +34,6 @@ import com.cloud.vm.VirtualMachine; @DiscriminatorValue(value = "Service") @PrimaryKeyJoinColumn(name = "id") public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering { - public enum DynamicParameters { - cpuSpeed, cpuNumber, memory - }; - @Column(name = "cpu") private Integer cpu; @@ -167,6 +163,20 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering this.deploymentPlanner = deploymentPlanner; } + public ServiceOfferingVO(ServiceOfferingVO offering) { + super(offering.getId(), offering.getName(), offering.getDisplayText(), false, offering.getTags(), offering.isRecreatable(), offering.getUseLocalStorage(), offering.getSystemUse(), true, offering.getDomainId()); + this.cpu = offering.getCpu(); + this.ramSize = offering.getRamSize(); + this.speed = offering.getSpeed(); + this.rateMbps = offering.getRateMbps(); + this.multicastRateMbps = offering.getMulticastRateMbps(); + this.offerHA = offering.getOfferHA(); + this.limitCpuUse = offering.getLimitCpuUse(); + this.volatileVm = offering.getVolatileVm(); + this.hostTag = offering.getHostTag(); + this.vm_type = offering.getSystemVmType(); + } + @Override public boolean getOfferHA() { return offerHA; diff --git a/engine/schema/src/com/cloud/service/dao/ServiceOfferingDao.java b/engine/schema/src/com/cloud/service/dao/ServiceOfferingDao.java index 10d661687e1..ecab8d2943c 100644 --- a/engine/schema/src/com/cloud/service/dao/ServiceOfferingDao.java +++ b/engine/schema/src/com/cloud/service/dao/ServiceOfferingDao.java @@ -17,6 +17,7 @@ package com.cloud.service.dao; import java.util.List; +import java.util.Map; import com.cloud.service.ServiceOfferingVO; import com.cloud.utils.db.GenericDao; @@ -47,5 +48,5 @@ public interface ServiceOfferingDao extends GenericDao boolean isDynamic(long serviceOfferingId); - ServiceOfferingVO getcomputeOffering(long serviceOfferingId, Integer cpuCores, Integer cpuSpeed, Integer memory); + ServiceOfferingVO getcomputeOffering(ServiceOfferingVO serviceOffering, Map customParameters); } diff --git a/engine/schema/src/com/cloud/service/dao/ServiceOfferingDaoImpl.java b/engine/schema/src/com/cloud/service/dao/ServiceOfferingDaoImpl.java index f1f97fc79f5..5d423e0a1e7 100644 --- a/engine/schema/src/com/cloud/service/dao/ServiceOfferingDaoImpl.java +++ b/engine/schema/src/com/cloud/service/dao/ServiceOfferingDaoImpl.java @@ -25,6 +25,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.persistence.EntityExistsException; +import com.cloud.event.UsageEventVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -191,14 +192,12 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase dynamicOffering = userVmDetailsDao.listDetailsKeyPairs(vmId); - offering.setCpu(Integer.parseInt(dynamicOffering.get(ServiceOfferingVO.DynamicParameters.cpuNumber.name()))); - offering.setSpeed(Integer.parseInt(dynamicOffering.get(ServiceOfferingVO.DynamicParameters.cpuSpeed.name()))); - offering.setRamSize(Integer.parseInt(dynamicOffering.get(ServiceOfferingVO.DynamicParameters.memory.name()))); - return offering; + return getcomputeOffering(offering, dynamicOffering); } return offering; } @@ -207,15 +206,12 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase dynamicOffering = userVmDetailsDao.listDetailsKeyPairs(vmId); - offering.setCpu(Integer.parseInt(dynamicOffering.get(ServiceOfferingVO.DynamicParameters.cpuNumber.name()))); - offering.setSpeed(Integer.parseInt(dynamicOffering.get(ServiceOfferingVO.DynamicParameters.cpuSpeed.name()))); - offering.setRamSize(Integer.parseInt(dynamicOffering.get(ServiceOfferingVO.DynamicParameters.memory.name()))); - return offering; - + return getcomputeOffering(offering, dynamicOffering); } return offering; } @@ -227,11 +223,19 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase customParameters) { + ServiceOfferingVO dummyoffering = new ServiceOfferingVO(serviceOffering); + dummyoffering.setDynamicFlag(true); + if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuNumber.name())) { + dummyoffering.setCpu(Integer.parseInt(customParameters.get(UsageEventVO.DynamicParameters.cpuNumber.name()))); + } + if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuSpeed.name())) { + dummyoffering.setSpeed(Integer.parseInt(customParameters.get(UsageEventVO.DynamicParameters.cpuSpeed.name()))); + } + if (customParameters.containsKey(UsageEventVO.DynamicParameters.memory.name())) { + dummyoffering.setRamSize(Integer.parseInt(customParameters.get(UsageEventVO.DynamicParameters.memory.name()))); + } + + return dummyoffering; } } diff --git a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java index 8a9dd3d32f8..1ff62ab7f24 100755 --- a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java +++ b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java @@ -206,6 +206,22 @@ public class DiskOfferingVO implements DiskOffering { state = State.Active; } + public DiskOfferingVO(long id, String name, String displayText, boolean mirrored, String tags, boolean recreatable, + boolean useLocalStorage, boolean systemUse, boolean customized, Long domainId) { + this.id = id; + type = Type.Service; + this.name = name; + this.displayText = displayText; + this.tags = tags; + this.recreatable = recreatable; + this.useLocalStorage = useLocalStorage; + this.systemUse = systemUse; + this.customized = customized; + this.domainId = domainId; + uuid = UUID.randomUUID().toString(); + state = State.Active; + } + @Override public State getState() { return state; diff --git a/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java b/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java index cd746c2ca9d..8d9491f54a1 100644 --- a/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java +++ b/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java @@ -27,9 +27,6 @@ import javax.persistence.TemporalType; @Entity @Table(name = "usage_vm_instance") public class UsageVMInstanceVO { - public enum DynamicParameters { - cpuSpeed, cpuNumber, memory - }; @Column(name = "usage_type") private int usageType; diff --git a/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java index 4f351ebaeaa..7e113e4baed 100644 --- a/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java @@ -79,6 +79,7 @@ public class ServiceOfferingJoinDaoImpl extends GenericDaoBase 2147483647))) { throw new InvalidParameterValueException("Failed to create service offering " + name + ": specify the cpu number value between 1 and 2147483647"); } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index d34da4f07a4..860f1654734 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -42,6 +42,8 @@ import javax.crypto.spec.SecretKeySpec; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.service.dao.ServiceOfferingDao; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; @@ -716,6 +718,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe AccountService _accountService; @Inject ConfigurationManager _configMgr; + @Inject + ServiceOfferingDao _offeringDao; @Inject DeploymentPlanningManager _dpMgr; @@ -3769,8 +3773,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe if (vmInstance.getHypervisorType() == HypervisorType.XenServer && vmInstance.getState().equals(State.Running)) { throw new InvalidParameterValueException("Dynamic Scaling operation is not permitted for this hypervisor on system vm"); } - boolean result = _userVmMgr.upgradeVirtualMachine(cmd.getId(), cmd.getServiceOfferingId()); - if (result) { + boolean result = _userVmMgr.upgradeVirtualMachine(cmd.getId(), cmd.getServiceOfferingId(), cmd.getCustomParameters()); + if(result){ VirtualMachine vm = _vmInstanceDao.findById(cmd.getId()); return vm; } else { @@ -3782,11 +3786,11 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe public VirtualMachine upgradeSystemVM(UpgradeSystemVMCmd cmd) { Long systemVmId = cmd.getId(); Long serviceOfferingId = cmd.getServiceOfferingId(); - return upgradeStoppedSystemVm(systemVmId, serviceOfferingId); + return upgradeStoppedSystemVm(systemVmId, serviceOfferingId, cmd.getCustomParameters()); } - private VirtualMachine upgradeStoppedSystemVm(Long systemVmId, Long serviceOfferingId) { + private VirtualMachine upgradeStoppedSystemVm(Long systemVmId, Long serviceOfferingId, Map customparameters){ Account caller = CallContext.current().getCallingAccount(); VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(systemVmId, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm); @@ -3797,10 +3801,25 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe _accountMgr.checkAccess(caller, null, true, systemVm); // Check that the specified service offering ID is valid - _itMgr.checkIfCanUpgrade(systemVm, serviceOfferingId); + ServiceOfferingVO newServiceOffering = _offeringDao.findById(serviceOfferingId); + ServiceOfferingVO currentServiceOffering = _offeringDao.findById(systemVmId,systemVm.getServiceOfferingId()); + if (newServiceOffering.isDynamic()){ + newServiceOffering.setDynamicFlag(true); + _userVmMgr.validateCustomParameters(newServiceOffering, customparameters); + newServiceOffering = _offeringDao.getcomputeOffering(newServiceOffering, customparameters); + } + _itMgr.checkIfCanUpgrade(systemVm, newServiceOffering); boolean result = _itMgr.upgradeVmDb(systemVmId, serviceOfferingId); + if (newServiceOffering.isDynamic()) { + //save the custom values to the database. + _userVmMgr.saveCustomOfferingDetails(systemVmId, newServiceOffering); + } + if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) { + _userVmMgr.removeCustomOfferingDetails(systemVmId); + } + if (result) { return _vmInstanceDao.findById(systemVmId); } else { diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java index 8463326ece6..da60f330abd 100755 --- a/server/src/com/cloud/vm/UserVmManager.java +++ b/server/src/com/cloud/vm/UserVmManager.java @@ -20,6 +20,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import com.cloud.offering.ServiceOffering; +import com.cloud.service.ServiceOfferingVO; import org.apache.cloudstack.api.BaseCmd.HTTPMethod; import org.apache.cloudstack.framework.config.ConfigKey; @@ -108,7 +110,7 @@ public interface UserVmManager extends UserVmService { Pair> startVirtualMachine(long vmId, Long hostId, Map additionalParams) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; - boolean upgradeVirtualMachine(Long id, Long serviceOfferingId) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, + boolean upgradeVirtualMachine(Long id, Long serviceOfferingId, Map customParameters) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException; boolean setupVmForPvlan(boolean add, Long hostId, NicProfile nic); @@ -117,4 +119,12 @@ public interface UserVmManager extends UserVmService { UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData, Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId) throws ResourceUnavailableException, InsufficientCapacityException; + + //the validateCustomParameters, save and remove CustomOfferingDetils functions can be removed from the interface once we can + //find a common place for all the scaling and upgrading code of both user and systemvms. + void validateCustomParameters(ServiceOfferingVO serviceOffering, Map customParameters); + + public void saveCustomOfferingDetails(long vmId, ServiceOffering serviceOffering); + + public void removeCustomOfferingDetails(long vmId); } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index c0b0031a8e9..1d5a1877036 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -34,6 +34,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.event.UsageEventVO; import com.cloud.uuididentity.UUIDManager; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; @@ -773,7 +774,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir _accountMgr.checkAccess(caller, null, true, vmInstance); // Check resource limits for CPU and Memory. + Map customParameters = cmd.getCustomParameters(); ServiceOfferingVO newServiceOffering = _offeringDao.findById(svcOffId); + if (newServiceOffering.isDynamic()) { + newServiceOffering.setDynamicFlag(true); + validateCustomParameters(newServiceOffering, cmd.getCustomParameters()); + newServiceOffering = _offeringDao.getcomputeOffering(newServiceOffering, customParameters); + } ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId()); int newCpu = newServiceOffering.getCpu(); @@ -789,7 +796,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } // Check that the specified service offering ID is valid - _itMgr.checkIfCanUpgrade(vmInstance, svcOffId); + _itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering); // remove diskAndMemory VM snapshots List vmSnapshots = _vmSnapshotDao.findByVm(vmId); @@ -805,6 +812,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } _itMgr.upgradeVmDb(vmId, svcOffId); + if (newServiceOffering.isDynamic()) { + //save the custom values to the database. + saveCustomOfferingDetails(vmId, newServiceOffering); + } + if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) { + removeCustomOfferingDetails(vmId); + } // Increment or decrement CPU and Memory count accordingly. if (newCpu > currentCpu) { @@ -818,15 +832,46 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(currentMemory - newMemory)); } - // Generate usage event for VM upgrade - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_UPGRADE, vmInstance.getAccountId(), vmInstance.getDataCenterId(), vmInstance.getId(), - vmInstance.getHostName(), vmInstance.getServiceOfferingId(), vmInstance.getTemplateId(), vmInstance.getHypervisorType().toString(), - VirtualMachine.class.getName(), vmInstance.getUuid()); + generateUsageEvent(newServiceOffering, cmd.getCustomParameters(), _vmDao.findById(vmId), EventTypes.EVENT_VM_UPGRADE); return _vmDao.findById(vmInstance.getId()); } - private UserVm upgradeStoppedVirtualMachine(Long vmId, Long svcOffId) throws ResourceAllocationException { + @Override + public void validateCustomParameters(ServiceOfferingVO serviceOffering, Map customParameters) { + if (customParameters.size() !=0 ) { + if (serviceOffering.getCpu() == null) { + String cpuNumber = customParameters.get(UsageEventVO.DynamicParameters.cpuNumber.name()); + if ((cpuNumber == null) || (NumbersUtil.parseInt(cpuNumber, -1) <= 0 || NumbersUtil.parseInt(cpuNumber, -1) > 2147483647)) { + throw new InvalidParameterValueException("Invalid cpu cores value, specify a value between 1 and 2147483647"); + } + } else if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuNumber.name())) { + throw new InvalidParameterValueException("The cpu cores of this offering id:"+serviceOffering.getId()+" is not customizable. This is predefined in the template."); + } + + if (serviceOffering.getSpeed() == null) { + String cpuSpeed = customParameters.get(UsageEventVO.DynamicParameters.cpuSpeed.name()); + if ((cpuSpeed == null) || (NumbersUtil.parseInt(cpuSpeed, -1) <= 0 || NumbersUtil.parseInt(cpuSpeed, -1) > 2147483647 )) { + throw new InvalidParameterValueException("Invalid cpu speed value, specify a value between 1 and 2147483647"); + } + } else if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuSpeed.name())) { + throw new InvalidParameterValueException("The cpu speed of this offering id:"+serviceOffering.getId()+" is not customizable. This is predefined in the template."); + } + + if (serviceOffering.getRamSize() == null) { + String memory = customParameters.get(UsageEventVO.DynamicParameters.memory.name()); + if (memory == null || (NumbersUtil.parseInt(memory, -1) < 32 || NumbersUtil.parseInt(memory, -1) > 2147483647)) { + throw new InvalidParameterValueException("Invalid memory value, specify a value between 32 and 2147483647 MB"); + } + } else if (customParameters.containsKey(UsageEventVO.DynamicParameters.memory.name())){ + throw new InvalidParameterValueException("The memory of this offering id:"+serviceOffering.getId()+" is not customizable. This is predefined in the template."); + } + } else { + throw new InvalidParameterValueException("Need to specify custom parameter values cpu, cpu speed and memory when using custom offering"); + } + } + + private UserVm upgradeStoppedVirtualMachine(Long vmId, Long svcOffId, Map customParameters) throws ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); // Verify input parameters @@ -840,6 +885,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir // Check resource limits for CPU and Memory. ServiceOfferingVO newServiceOffering = _offeringDao.findById(svcOffId); + if (newServiceOffering.isDynamic()) { + newServiceOffering.setDynamicFlag(true); + validateCustomParameters(newServiceOffering, customParameters); + newServiceOffering = _offeringDao.getcomputeOffering(newServiceOffering, customParameters); + } ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId()); int newCpu = newServiceOffering.getCpu(); @@ -855,7 +905,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } // Check that the specified service offering ID is valid - _itMgr.checkIfCanUpgrade(vmInstance, svcOffId); + _itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering); // remove diskAndMemory VM snapshots List vmSnapshots = _vmSnapshotDao.findByVm(vmId); @@ -871,6 +921,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } _itMgr.upgradeVmDb(vmId, svcOffId); + if (newServiceOffering.isDynamic()) { + //save the custom values to the database. + saveCustomOfferingDetails(vmId, newServiceOffering); + } + if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) { + removeCustomOfferingDetails(vmId); + } // Increment or decrement CPU and Memory count accordingly. if (newCpu > currentCpu) { @@ -1149,20 +1206,16 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir Long newServiceOfferingId = cmd.getServiceOfferingId(); CallContext.current().setEventDetails("Vm Id: " + vmId); - boolean result = upgradeVirtualMachine(vmId, newServiceOfferingId); - if (result) { + boolean result = upgradeVirtualMachine(vmId, newServiceOfferingId,cmd.getCustomParameters()); + if(result){ UserVmVO vmInstance = _vmDao.findById(vmId); if (vmInstance.getState().equals(State.Stopped)) { // Generate usage event for VM upgrade - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_UPGRADE, vmInstance.getAccountId(), vmInstance.getDataCenterId(), vmInstance.getId(), - vmInstance.getHostName(), vmInstance.getServiceOfferingId(), vmInstance.getTemplateId(), vmInstance.getHypervisorType().toString(), - VirtualMachine.class.getName(), vmInstance.getUuid()); + generateUsageEvent(_serviceOfferingDao.findById(newServiceOfferingId), cmd.getCustomParameters(), vmInstance, EventTypes.EVENT_VM_UPGRADE); } if (vmInstance.getState().equals(State.Running)) { // Generate usage event for Dynamic scaling of VM - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DYNAMIC_SCALE, vmInstance.getAccountId(), vmInstance.getDataCenterId(), vmInstance.getId(), - vmInstance.getHostName(), vmInstance.getServiceOfferingId(), vmInstance.getTemplateId(), vmInstance.getHypervisorType().toString(), - VirtualMachine.class.getName(), vmInstance.getUuid()); + generateUsageEvent(_serviceOfferingDao.findById(newServiceOfferingId),cmd.getCustomParameters(), vmInstance, EventTypes.EVENT_VM_UPGRADE); } return vmInstance; } else { @@ -1207,24 +1260,22 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } @Override - public boolean upgradeVirtualMachine(Long vmId, Long newServiceOfferingId) throws ResourceUnavailableException, ConcurrentOperationException, - ManagementServerException, VirtualMachineMigrationException { + public boolean upgradeVirtualMachine(Long vmId, Long newServiceOfferingId, Map customParameters) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException{ // Verify input parameters VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId); if (vmInstance.getState().equals(State.Stopped)) { - upgradeStoppedVirtualMachine(vmId, newServiceOfferingId); + upgradeStoppedVirtualMachine(vmId, newServiceOfferingId, customParameters); return true; } - if (vmInstance.getState().equals(State.Running)) { - return upgradeRunningVirtualMachine(vmId, newServiceOfferingId); + if(vmInstance.getState().equals(State.Running)){ + return upgradeRunningVirtualMachine(vmId, newServiceOfferingId, customParameters); } return false; } - private boolean upgradeRunningVirtualMachine(Long vmId, Long newServiceOfferingId) throws ResourceUnavailableException, ConcurrentOperationException, - ManagementServerException, VirtualMachineMigrationException { + private boolean upgradeRunningVirtualMachine(Long vmId, Long newServiceOfferingId, Map customParameters) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException{ Account caller = CallContext.current().getCallingAccount(); VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId); @@ -1234,11 +1285,17 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir _accountMgr.checkAccess(caller, null, true, vmInstance); - // Check that the specified service offering ID is valid - _itMgr.checkIfCanUpgrade(vmInstance, newServiceOfferingId); - //Check if its a scale "up" - ServiceOffering newServiceOffering = _entityMgr.findById(ServiceOffering.class, newServiceOfferingId); + ServiceOfferingVO newServiceOffering = (ServiceOfferingVO) _offeringDao.findById(newServiceOfferingId); + if (newServiceOffering.isDynamic()) { + newServiceOffering.setDynamicFlag(true); + validateCustomParameters(newServiceOffering, customParameters); + newServiceOffering = _offeringDao.getcomputeOffering(newServiceOffering, customParameters); + } + + // Check that the specified service offering ID is valid + _itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering); + ServiceOffering currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId()); int newCpu = newServiceOffering.getCpu(); int newMemory = newServiceOffering.getRamSize(); @@ -1304,9 +1361,16 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir // #3 scale the vm now _itMgr.upgradeVmDb(vmId, newServiceOfferingId); + if (newServiceOffering.isDynamic()) { + //save the custom values to the database. + saveCustomOfferingDetails(vmId, newServiceOffering); + } vmInstance = _vmInstanceDao.findById(vmId); _itMgr.reConfigureVm(vmInstance.getUuid(), currentServiceOffering, existingHostHasCapacity); success = true; + if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) { + removeCustomOfferingDetails(vmId); + } return success; } catch (InsufficientCapacityException e) { s_logger.warn("Received exception while scaling ", e); @@ -1319,6 +1383,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } finally { if (!success) { _itMgr.upgradeVmDb(vmId, currentServiceOffering.getId()); // rollback + if (newServiceOffering.isDynamic()) { + removeCustomOfferingDetails(vmId); + } // Decrement CPU and Memory count accordingly. if (newCpu > currentCpu) { _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu)); @@ -1330,10 +1397,38 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } } } - return success; } + @Override + public void saveCustomOfferingDetails(long vmId, ServiceOffering serviceOffering) { + //save the custom values to the database. + Map details = _uservmDetailsDao.listDetailsKeyPairs(vmId); + details.put(UsageEventVO.DynamicParameters.cpuNumber.name(), serviceOffering.getCpu().toString()); + details.put(UsageEventVO.DynamicParameters.cpuSpeed.name(), serviceOffering.getSpeed().toString()); + details.put(UsageEventVO.DynamicParameters.memory.name(), serviceOffering.getRamSize().toString()); + List detailList = new ArrayList(); + for (String key : details.keySet()) { + UserVmDetailVO detailVO = new UserVmDetailVO(vmId, key, details.get(key)); + detailList.add(detailVO); + } + _uservmDetailsDao.saveDetails(detailList); + } + + @Override + public void removeCustomOfferingDetails(long vmId){ + Map details = _uservmDetailsDao.listDetailsKeyPairs(vmId); + details.remove(UsageEventVO.DynamicParameters.cpuNumber.name()); + details.remove(UsageEventVO.DynamicParameters.cpuSpeed.name()); + details.remove(UsageEventVO.DynamicParameters.memory.name()); + List detailList = new ArrayList(); + for (String key : details.keySet()) { + UserVmDetailVO detailVO = new UserVmDetailVO(vmId, key, details.get(key)); + detailList.add(detailVO); + } + _uservmDetailsDao.saveDetails(detailList); + } + @Override public HashMap getVirtualMachineStatistics(long hostId, String hostName, List vmIds) throws CloudRuntimeException { HashMap vmStatsById = new HashMap(); @@ -2594,10 +2689,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } } - details.add(new UserVmDetailVO(id, ServiceOfferingVO.DynamicParameters.cpuNumber.toString(), cpuNumber.toString())); - details.add(new UserVmDetailVO(id, ServiceOfferingVO.DynamicParameters.cpuSpeed.toString(), cpuSpeed.toString())); - details.add(new UserVmDetailVO(id, ServiceOfferingVO.DynamicParameters.memory.toString(), memory.toString())); - offering = _serviceOfferingDao.getcomputeOffering(serviceOffering.getId(), cpuNumber, cpuSpeed, memory); + details.add(new UserVmDetailVO(id, UsageEventVO.DynamicParameters.cpuNumber.toString(), cpuNumber.toString())); + details.add(new UserVmDetailVO(id, UsageEventVO.DynamicParameters.cpuSpeed.toString(), cpuSpeed.toString())); + details.add(new UserVmDetailVO(id, UsageEventVO.DynamicParameters.memory.toString(), memory.toString())); + offering.setCpu(cpuNumber); + offering.setRamSize(memory); + offering.setSpeed(cpuSpeed); offering.setDynamicFlag(true); } if (hostName != null) { @@ -2814,6 +2911,19 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir }); } + private void generateUsageEvent(ServiceOfferingVO serviceOffering, Map customParameters, UserVmVO vm, String eventType){ + if (!serviceOffering.isDynamic()) { + UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), + vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm.getHypervisorType().toString(), + VirtualMachine.class.getName(), vm.getUuid()); + } + else { + UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), + vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm.getHypervisorType().toString(), + VirtualMachine.class.getName(), vm.getUuid(), customParameters); + } + } + private void validateUserData(String userData, HTTPMethod httpmethod) { byte[] decodedUserData = null; if (userData != null) { diff --git a/server/test/com/cloud/vm/UserVmManagerTest.java b/server/test/com/cloud/vm/UserVmManagerTest.java index 71bbebea386..83f75206252 100755 --- a/server/test/com/cloud/vm/UserVmManagerTest.java +++ b/server/test/com/cloud/vm/UserVmManagerTest.java @@ -136,6 +136,8 @@ public class UserVmManagerTest { @Mock ServiceOfferingDao _offeringDao; @Mock + ServiceOfferingVO _offeringVo; + @Mock EntityManager _entityMgr; @Mock ResourceLimitService _resourceLimitMgr; @@ -384,12 +386,12 @@ public class UserVmManagerTest { doNothing().when(_accountMgr).checkAccess(_account, null, true, _templateMock); - doNothing().when(_itMgr).checkIfCanUpgrade(_vmMock, cmd.getServiceOfferingId()); + doNothing().when(_itMgr).checkIfCanUpgrade(_vmMock, _offeringVo); ServiceOffering so1 = getSvcoffering(512); ServiceOffering so2 = getSvcoffering(256); - when(_entityMgr.findById(eq(ServiceOffering.class), anyLong())).thenReturn(so1); + when(_offeringDao.findById(anyLong())).thenReturn((ServiceOfferingVO)so1); when(_offeringDao.findByIdIncludingRemoved(anyLong(), anyLong())).thenReturn((ServiceOfferingVO)so1); Account account = new AccountVO("testaccount", 1L, "networkdomain", (short)0, UUID.randomUUID().toString()); diff --git a/usage/src/com/cloud/usage/UsageManagerImpl.java b/usage/src/com/cloud/usage/UsageManagerImpl.java index 81e7892f1a7..3da7d48618a 100644 --- a/usage/src/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/com/cloud/usage/UsageManagerImpl.java @@ -1113,14 +1113,14 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna Map usageDetails = _usageEventDetailsDao.findDetails(event.getId()); if (usageDetails != null && usageDetails.size() != 0) { - if (usageDetails.get(UsageVMInstanceVO.DynamicParameters.cpuNumber.name()) != null) { - cpuCores = Long.parseLong(usageDetails.get(UsageVMInstanceVO.DynamicParameters.cpuNumber.name())); + if (usageDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name()) != null) { + cpuCores = Long.parseLong(usageDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name())); } - if (usageDetails.get(UsageVMInstanceVO.DynamicParameters.cpuSpeed.name()) != null) { - cpuSpeed = Long.parseLong(usageDetails.get(UsageVMInstanceVO.DynamicParameters.cpuSpeed.name())); + if (usageDetails.get(UsageEventVO.DynamicParameters.cpuSpeed.name()) != null) { + cpuSpeed = Long.parseLong(usageDetails.get(UsageEventVO.DynamicParameters.cpuSpeed.name())); } - if (usageDetails.get(UsageVMInstanceVO.DynamicParameters.memory.name()) != null) { - memory = Long.parseLong(usageDetails.get(UsageVMInstanceVO.DynamicParameters.memory.name())); + if (usageDetails.get(UsageEventVO.DynamicParameters.memory.name()) != null) { + memory = Long.parseLong(usageDetails.get(UsageEventVO.DynamicParameters.memory.name())); } } From cd6e6a4d3cd7e210595a8f0624ff717d599d83e5 Mon Sep 17 00:00:00 2001 From: Jayapal Date: Mon, 2 Dec 2013 10:53:51 +0530 Subject: [PATCH 063/170] CLOUDSTACK-1762 Fixed assigning network or broadcast ip to nic --- .../cloud/network/IpAddressManagerImpl.java | 7 ++++-- utils/src/com/cloud/utils/net/NetUtils.java | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/network/IpAddressManagerImpl.java b/server/src/com/cloud/network/IpAddressManagerImpl.java index b350fe07f5d..230f19db902 100644 --- a/server/src/com/cloud/network/IpAddressManagerImpl.java +++ b/server/src/com/cloud/network/IpAddressManagerImpl.java @@ -1644,6 +1644,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage Set availableIps = _networkModel.getAvailableIps(network, requestedIp); if (availableIps == null || availableIps.isEmpty()) { + s_logger.debug("There are no free ips in the network " + network ); return null; } @@ -1656,9 +1657,11 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage if (!isSameCidr) { s_logger.warn("Requested ip address " + requestedIp + " doesn't belong to the network " + network + " cidr"); return null; - } else { - return requestedIp; + } else if (NetUtils.IsIpEqualToNetworkOrBroadCastIp(requestedIp, cidr[0], Integer.parseInt(cidr[1]))) { + s_logger.warn("Requested ip address " + requestedIp + " is equal to the to the network/broadcast ip of the network" + network); + return null; } + return requestedIp; } String result; diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java index 46a048fef30..c0c792fcb0d 100755 --- a/utils/src/com/cloud/utils/net/NetUtils.java +++ b/utils/src/com/cloud/utils/net/NetUtils.java @@ -1427,4 +1427,26 @@ public class NetUtils { SubnetUtils subnetUtils = new SubnetUtils(cidr); return subnetUtils.getInfo().isInRange(ipAddress); } + + public static Boolean IsIpEqualToNetworkOrBroadCastIp(String requestedIp, String cidr, long size) { + assert (size < 32) : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size; + + long ip = ip2Long(cidr); + long startNetMask = ip2Long(getCidrNetmask(size)); + + long start = (ip & startNetMask); + long end = start; + + end = end >> (32 - size); + + end++; + end = (end << (32 - size)) - 1; + + long reqIp = ip2Long(requestedIp); + if (reqIp == start || reqIp == end) { + return true; + } + return false; + } + } From 71fd0a49e3f746420d5afacb0b4a67dec380e376 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 2 Dec 2013 16:10:08 -0800 Subject: [PATCH 064/170] CLOUDSTACK-4738: UI > Instances > Change Service Offering > dialog > add 3 new fields: CPU speed, CPU number, memory. Show the 3 new fields when selected compute offerings is custom. Hide them otherwise. --- ui/scripts/instances.js | 104 +++++++++++++++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 13 deletions(-) diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index 27e0e4f962c..0074335d2d4 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -1430,37 +1430,115 @@ return description; }, fields: { - serviceOffering: { + serviceofferingid: { label: 'label.compute.offering', select: function(args) { + var serviceofferingObjs; $.ajax({ url: createURL("listServiceOfferings&VirtualMachineId=" + args.context.instances[0].id), dataType: "json", async: true, success: function(json) { - var serviceofferings = json.listserviceofferingsresponse.serviceoffering; - var items = []; - $(serviceofferings).each(function() { - items.push({ - id: this.id, - description: this.name - }); - }); + serviceofferingObjs = json.listserviceofferingsresponse.serviceoffering; + var items = []; + if (serviceofferingObjs != null) { + for (var i = 0; i < serviceofferingObjs.length; i++) { + items.push({ + id: serviceofferingObjs[i].id, + description: serviceofferingObjs[i].name + }); + } + } args.response.success({ data: items }); } }); + + args.$select.change(function(){ + var $form = $(this).closest('form'); + + var serviceofferingid = $(this).val(); + if (serviceofferingid == null || serviceofferingid.length == 0) + return; + + var items = []; + var selectedServiceofferingObj; + if (serviceofferingObjs != null) { + for (var i = 0; i < serviceofferingObjs.length; i++) { + if (serviceofferingObjs[i].id == serviceofferingid) { + selectedServiceofferingObj = serviceofferingObjs[i]; + break; + } + } + } + if (selectedServiceofferingObj == undefined) + return; + + if (selectedServiceofferingObj.iscustomized == true) { + $form.find('.form-item[rel=cpuSpeed]').css('display', 'inline-block'); + $form.find('.form-item[rel=cpuNumber]').css('display', 'inline-block'); + $form.find('.form-item[rel=memory]').css('display', 'inline-block'); + } else { + $form.find('.form-item[rel=cpuSpeed]').hide(); + $form.find('.form-item[rel=cpuNumber]').hide(); + $form.find('.form-item[rel=memory]').hide(); + } + }); } - } + }, + cpuSpeed: { + label: 'label.cpu.mhz', + validation: { + required: true, + number: true + }, + isHidden: true + }, + cpuNumber: { + label: 'label.num.cpu.cores', + validation: { + required: true, + number: true + }, + isHidden: true + }, + memory: { + label: 'label.memory.mb', + validation: { + required: true, + number: true + }, + isHidden: true + } } }, action: function(args) { + var data = { + id: args.context.instances[0].id, + serviceofferingid: args.data.serviceofferingid + }; + + if (args.$form.find('.form-item[rel=cpuSpeed]').is(':visible')) { + $.extend(data, { + 'customparameters[0].cpuSpeed': args.data.cpuSpeed + }); + } + if (args.$form.find('.form-item[rel=cpuNumber]').is(':visible')) { + $.extend(data, { + 'customparameters[0].cpuNumber': args.data.cpuNumber + }); + } + if (args.$form.find('.form-item[rel=memory]').is(':visible')) { + $.extend(data, { + 'customparameters[0].memory': args.data.memory + }); + } + $.ajax({ - url: createURL("scaleVirtualMachine&id=" + args.context.instances[0].id + "&serviceofferingid=" + args.data.serviceOffering), - dataType: "json", - async: true, + url: createURL('scaleVirtualMachine'), + data: data, success: function(json) { var jid = json.scalevirtualmachineresponse.jobid; args.response.success({ From d5e497859f770d6e11f603f4c12a041251dbce93 Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Mon, 2 Dec 2013 17:27:13 -0800 Subject: [PATCH 065/170] CLOUDSTACK-4881: changeServiceForVirtualMachine API should be used to scale up a stopped vm only --- server/src/com/cloud/vm/UserVmManagerImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 1d5a1877036..d3dd35663b9 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -769,6 +769,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId); if (vmInstance == null) { throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId); + }else if (!(vmInstance.getState().equals(State.Stopped))) { + throw new InvalidParameterValueException("Unable to upgrade virtual machine " + vmInstance.toString() + " " + " in state " + vmInstance.getState() + + "; make sure the virtual machine is stopped"); } _accountMgr.checkAccess(caller, null, true, vmInstance); From 875e1ea28154073fb0419ea84ddee0795bfc1dd4 Mon Sep 17 00:00:00 2001 From: Rajesh Battala Date: Mon, 25 Nov 2013 18:43:23 +0530 Subject: [PATCH 066/170] Added contextMap data to all the command responses in HyperV --- .../HypervResourceController.cs | 86 +++++++++++++------ 1 file changed, 58 insertions(+), 28 deletions(-) diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index a5c54a6e0ad..f24ba804ed4 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -142,6 +142,7 @@ namespace HypervResource private static ILog logger = LogManager.GetLogger(typeof(HypervResourceController)); private static string systemVmIso; + Dictionary contextMap = new Dictionary(); public static void Initialize() { @@ -203,7 +204,8 @@ namespace HypervResource { result = result, details = "success - NOP", - _reconnect = false + _reconnect = false, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.SetupAnswer); @@ -248,7 +250,8 @@ namespace HypervResource object ansContent = new { result = result, - details = details + details = details, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.AttachAnswer); @@ -292,7 +295,8 @@ namespace HypervResource object ansContent = new { result = result, - details = details + details = details, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.DettachAnswer); @@ -335,7 +339,8 @@ namespace HypervResource object ansContent = new { result = result, - details = details + details = details, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.RebootAnswer); @@ -397,7 +402,8 @@ namespace HypervResource object ansContent = new { result = result, - details = details + details = details, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer); @@ -512,7 +518,8 @@ namespace HypervResource { result = result, details = details, - volume = volume + volume = volume, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CreateAnswer); } @@ -580,7 +587,8 @@ namespace HypervResource result = result, details = details, templateSize = size, - installPath = newCopyFileName + installPath = newCopyFileName, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.PrimaryStorageDownloadAnswer); } @@ -682,7 +690,8 @@ namespace HypervResource object ansContent = new { result = true, - details = "resource is alive" + details = "resource is alive", + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CheckHealthAnswer); } @@ -700,7 +709,8 @@ namespace HypervResource object ansContent = new { result = true, - details = "NOP, TODO: implement properly" + details = "NOP, TODO: implement properly", + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CheckSshAnswer); } @@ -736,7 +746,8 @@ namespace HypervResource { result = result, details = details, - state = state + state = state, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CheckVirtualMachineAnswer); } @@ -753,7 +764,8 @@ namespace HypervResource object ansContent = new { result = true, - details = "Current implementation does not delete local path corresponding to storage pool!" + details = "Current implementation does not delete local path corresponding to storage pool!", + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer); } @@ -775,7 +787,8 @@ namespace HypervResource object ansContent = new { result = true, - details = "success - NOP" + details = "success - NOP", + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer); } @@ -800,7 +813,8 @@ namespace HypervResource ansContent = new { result = result, - details = details + details = details, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer); } @@ -843,7 +857,8 @@ namespace HypervResource result = result, details = details, templateInfo = tInfo, - poolInfo = poolInfo + poolInfo = poolInfo, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.ModifyStoragePoolAnswer); @@ -885,7 +900,8 @@ namespace HypervResource object ansContent = new { result = false, - details = "nothing to cleanup in our current implementation" + details = "nothing to cleanup in our current implementation", + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer); } @@ -902,7 +918,8 @@ namespace HypervResource object ansContent = new { result = true, - details = (string)null + details = (string)null, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CheckNetworkAnswer); } @@ -919,7 +936,8 @@ namespace HypervResource object ansContent = new { result = true, - details = (string)null + details = (string)null, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.ReadyAnswer); } @@ -952,7 +970,8 @@ namespace HypervResource { result = result, details = details, - vm = cmd.vm + vm = cmd.vm, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.StartAnswer); } @@ -984,7 +1003,8 @@ namespace HypervResource { result = result, details = details, - vm = cmd.vm + vm = cmd.vm, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.StopAnswer); } @@ -1004,7 +1024,8 @@ namespace HypervResource { result = true, details = "success - NOP for MaintainCommand", - _reconnect = false + _reconnect = false, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.MaintainAnswer); @@ -1025,7 +1046,8 @@ namespace HypervResource { result = true, details = "success - NOP for PingRoutingCommand", - _reconnect = false + _reconnect = false, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer); @@ -1046,7 +1068,8 @@ namespace HypervResource { result = true, details = "success - NOP for PingCommand", - _reconnect = false + _reconnect = false, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer); @@ -1092,6 +1115,7 @@ namespace HypervResource vmInfos = vmProcessorInfo, result = result, details = details, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetVmStatsAnswer); } @@ -1261,7 +1285,8 @@ namespace HypervResource { result = result, details = details, - newData = cmd.destTO + newData = cmd.destTO, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CopyCmdAnswer); } @@ -1374,7 +1399,8 @@ namespace HypervResource result = result, details = details, capacity = capacity, - used = used + used = used, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetStorageStatsAnswer); } @@ -1435,7 +1461,8 @@ namespace HypervResource { result = result, hostStats = hostStats, - details = details + details = details, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetHostStatsAnswer); } @@ -1466,7 +1493,8 @@ namespace HypervResource object ansContent = new { result = result, - details = details + details = details, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.PrepareForMigrationAnswer); @@ -1498,7 +1526,8 @@ namespace HypervResource object ansContent = new { result = result, - details = details + details = details, + contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.MigrateAnswer); @@ -1589,7 +1618,8 @@ namespace HypervResource poolInfo = pi, guid = pi.uuid, dataCenter = strtRouteCmd.dataCenter, - resourceType = StorageResourceType.STORAGE_POOL.ToString() // TODO: check encoding + resourceType = StorageResourceType.STORAGE_POOL.ToString(), // TODO: check encoding + contextMap = contextMap }; JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.StartupStorageCommand, ansContent); cmdArray.Add(ansObj); From 4d187192b31129087bbdd37c9c4406a4d125a4e3 Mon Sep 17 00:00:00 2001 From: Rajesh Battala Date: Wed, 27 Nov 2013 16:03:14 +0530 Subject: [PATCH 067/170] Fix VM stats collections in HyperV --- .../ServerResource/HypervResource/HypervResourceController.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index f24ba804ed4..fd6fe9f5583 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -1112,9 +1112,8 @@ namespace HypervResource object ansContent = new { - vmInfos = vmProcessorInfo, + vmStatsMap = vmProcessorInfo, result = result, - details = details, contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetVmStatsAnswer); From 4a61e928c4485020a78d0bfbc4be2f06e2e4c301 Mon Sep 17 00:00:00 2001 From: Rajesh Battala Date: Wed, 27 Nov 2013 16:05:21 +0530 Subject: [PATCH 068/170] Added hv kvp daemon support for 64 bit systemvm template to support system vms to run on HyperV. hv_kvp daemon is used to pass the boot args from host to the guest. --- .../appliance/definitions/systemvm64template/postinstall.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/appliance/definitions/systemvm64template/postinstall.sh b/tools/appliance/definitions/systemvm64template/postinstall.sh index d9ce8a17163..d25ba13c617 100644 --- a/tools/appliance/definitions/systemvm64template/postinstall.sh +++ b/tools/appliance/definitions/systemvm64template/postinstall.sh @@ -70,6 +70,11 @@ install_packages() { echo "iptables-persistent iptables-persistent/autosave_v4 boolean true" | debconf-set-selections echo "iptables-persistent iptables-persistent/autosave_v6 boolean true" | debconf-set-selections apt-get --no-install-recommends -q -y --force-yes install iptables-persistent + + # Hyperv kvp daemon + # Download the hv kvp daemon + wget http://people.apache.org/~rajeshbattala/hv-kvp-daemon_3.1_amd64.deb + dpkg -i hv-kvp-daemon_3.1_amd64.deb # vmware tools apt-get --no-install-recommends -q -y --force-yes install open-vm-tools From 1d3a4f46454c1d5c3726206e3f0a57773e05645f Mon Sep 17 00:00:00 2001 From: Rajesh Battala Date: Mon, 2 Dec 2013 18:03:59 +0530 Subject: [PATCH 069/170] Fixed issues on HyperV Agent code for shared network VR issues --- .../DotNet/ServerResource/HypervResource/WmiCallsV2.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs index ca49bd90c90..e2d4f6c4b91 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs @@ -431,7 +431,15 @@ namespace HypervResource System.Threading.Thread.Sleep(90000); SetState(newVm, RequiredState.Reset); // wait for the second boot and then return with sucesss - pingResource(publicIpAddress); + //if publicIPAddress is empty or null don't ping the ip + if (publicIpAddress.Equals("") == true) + { + System.Threading.Thread.Sleep(90000); + } + else + { + pingResource(publicIpAddress); + } } logger.InfoFormat("Started VM {0}", vmName); return newVm; From 30db5d648b9b867c2cbc13e501a3f40aa6214ea4 Mon Sep 17 00:00:00 2001 From: Anshul Gangwar Date: Wed, 13 Nov 2013 08:58:10 -0800 Subject: [PATCH 070/170] code to install and uninstall agent as windows service --- .../AgentShell/AgentShell.csproj | 9 +- .../ServerResource/AgentShell/Program.cs | 180 ++++++++++++++++-- .../AgentShell/ProjectInstaller.Designer.cs | 60 ++++++ .../AgentShell/ProjectInstaller.cs | 19 ++ 4 files changed, 253 insertions(+), 15 deletions(-) create mode 100644 plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.Designer.cs create mode 100644 plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.cs diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentShell.csproj b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentShell.csproj index 39fef1606a2..a4c6b1fc073 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentShell.csproj +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentShell.csproj @@ -70,6 +70,7 @@ ..\packages\NSubstitute.1.6.1.0\lib\NET40\NSubstitute.dll + @@ -101,6 +102,12 @@ + + Component + + + ProjectInstaller.cs + True @@ -137,4 +144,4 @@ --> - + \ No newline at end of file diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/Program.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/Program.cs index 10663708508..e84350020c4 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/Program.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/Program.cs @@ -21,12 +21,15 @@ using System.Linq; using System.ServiceProcess; using System.Text; using System.Threading.Tasks; +using System.Configuration.Install; +using System.Collections; namespace CloudStack.Plugin.AgentShell { static class Program { private static ILog logger = LogManager.GetLogger(typeof(Program)); + private static string serviceName = "CloudStack ServerResource"; /// /// Application entry point allows service to run in console application or as a Windows service. @@ -34,25 +37,174 @@ namespace CloudStack.Plugin.AgentShell /// static void Main(params string[] args) { - string arg1 = string.Empty; - - if (args.Length > 0) - { - arg1 = args[0]; - logger.DebugFormat("CloudStack ServerResource arg is ", arg1); - } - - if (string.Compare(arg1, "--console", true) == 0) - { - logger.InfoFormat("CloudStack ServerResource running as console app"); - new AgentService().RunConsole(args); - } - else + if (args.Length == 0) { logger.InfoFormat("CloudStack ServerResource running as Windows Service"); ServiceBase[] ServicesToRun = new ServiceBase[] { new AgentService() }; ServiceBase.Run(ServicesToRun); } + else if (args.Length == 1) + { + logger.DebugFormat("CloudStack ServerResource arg is ", args[0]); + switch (args[0]) + { + case "--install": + logger.InfoFormat("Installing and running CloudStack ServerResource "); + InstallService(); + StartService(); + break; + case "--uninstall": + logger.InfoFormat("stopping and uninstalling CloudStack ServerResource "); + StopService(); + UninstallService(); + break; + case "--console": + logger.InfoFormat("CloudStack ServerResource running as console app"); + new AgentService().RunConsole(args); + break; + default: + throw new NotImplementedException(); + } + } + } + + private static bool IsInstalled() + { + using (ServiceController controller = + new ServiceController(serviceName)) + { + try + { + ServiceControllerStatus status = controller.Status; + } + catch + { + return false; + } + return true; + } + } + + private static bool IsRunning() + { + using (ServiceController controller = + new ServiceController(serviceName)) + { + if (!IsInstalled()) return false; + return (controller.Status == ServiceControllerStatus.Running); + } + } + + private static AssemblyInstaller GetInstaller() + { + AssemblyInstaller installer = new AssemblyInstaller( + typeof(Program).Assembly, null); + installer.UseNewContext = true; + return installer; + } + + private static void InstallService() + { + if (IsInstalled()) return; + + try + { + using (AssemblyInstaller installer = GetInstaller()) + { + IDictionary state = new Hashtable(); + try + { + installer.Install(state); + installer.Commit(state); + } + catch + { + try + { + installer.Rollback(state); + } + catch { } + throw; + } + } + } + catch (Exception ex) + { + logger.ErrorFormat(" Error occured in installing service " + ex.Message); + throw; + } + } + + private static void UninstallService() + { + if (!IsInstalled()) return; + try + { + using (AssemblyInstaller installer = GetInstaller()) + { + IDictionary state = new Hashtable(); + try + { + installer.Uninstall(state); + } + catch + { + throw; + } + } + } + catch (Exception ex) + { + logger.ErrorFormat(" Error occured in uninstalling service " + ex.Message); + throw; + } + } + + private static void StartService() + { + if (!IsInstalled()) return; + + using (ServiceController controller = + new ServiceController(serviceName)) + { + try + { + if (controller.Status != ServiceControllerStatus.Running) + { + controller.Start(); + controller.WaitForStatus(ServiceControllerStatus.Running, + TimeSpan.FromSeconds(10)); + } + } + catch (Exception ex) + { + logger.ErrorFormat(" Error occured in starting service " + ex.Message); + throw; + } + } + } + + private static void StopService() + { + if (!IsInstalled()) return; + using (ServiceController controller = + new ServiceController(serviceName)) + { + try + { + if (controller.Status != ServiceControllerStatus.Stopped) + { + controller.Stop(); + controller.WaitForStatus(ServiceControllerStatus.Stopped, + TimeSpan.FromSeconds(10)); + } + } + catch (Exception ex) + { + logger.ErrorFormat(" Error occured in stopping service " + ex.Message); + throw; + } + } } } } diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.Designer.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.Designer.cs new file mode 100644 index 00000000000..9b9dbb6edb9 --- /dev/null +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.Designer.cs @@ -0,0 +1,60 @@ +namespace CloudStack.Plugin.AgentShell +{ + partial class ProjectInstaller + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller(); + this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller(); + // + // serviceProcessInstaller1 + // + this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem; + this.serviceProcessInstaller1.Password = null; + this.serviceProcessInstaller1.Username = null; + // + // serviceInstaller1 + // + this.serviceInstaller1.Description = "CloudStack Agent"; + this.serviceInstaller1.DisplayName = "CloudStack ServerResource"; + this.serviceInstaller1.ServiceName = "CloudStack ServerResource"; + this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic; + // + // ProjectInstaller + // + this.Installers.AddRange(new System.Configuration.Install.Installer[] { + this.serviceProcessInstaller1, + this.serviceInstaller1}); + + } + + #endregion + + private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1; + private System.ServiceProcess.ServiceInstaller serviceInstaller1; + } +} \ No newline at end of file diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.cs new file mode 100644 index 00000000000..c3a225f540a --- /dev/null +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Configuration.Install; +using System.Linq; +using System.Threading.Tasks; + +namespace CloudStack.Plugin.AgentShell +{ + [RunInstaller(true)] + public partial class ProjectInstaller : System.Configuration.Install.Installer + { + public ProjectInstaller() + { + InitializeComponent(); + } + } +} From 5a062e155ccb2ce19cb80ba87287d66b45cb33cd Mon Sep 17 00:00:00 2001 From: Anthony Xu Date: Tue, 3 Dec 2013 01:36:24 -0800 Subject: [PATCH 071/170] put shell scripts to a seperate directory in XS use same scripts for both XS and XCP --- .../xen/resource/CitrixResourceBase.java | 9 + .../copy_vhd_from_secondarystorage.sh | 2 +- .../xenserver/copy_vhd_to_secondarystorage.sh | 5 +- .../create_privatetemplate_from_snapshot.sh | 2 +- scripts/vm/hypervisor/xenserver/launch_hb.sh | 4 +- scripts/vm/hypervisor/xenserver/ovs-pvlan | 10 +- .../xenserver/setup_heartbeat_file.sh | 2 +- .../vm/hypervisor/xenserver/setupxenserver.sh | 2 +- scripts/vm/hypervisor/xenserver/swiftxen | 2 +- .../hypervisor/xenserver/upgrade_snapshot.sh | 2 +- scripts/vm/hypervisor/xenserver/vmops | 35 +- scripts/vm/hypervisor/xenserver/vmopsSnapshot | 10 +- scripts/vm/hypervisor/xenserver/vmopspremium | 21 +- .../xcposs/copy_vhd_from_secondarystorage.sh | 188 --- .../xcposs/copy_vhd_to_secondarystorage.sh | 130 -- .../create_privatetemplate_from_snapshot.sh | 138 -- scripts/vm/hypervisor/xenserver/xcposs/patch | 68 +- scripts/vm/hypervisor/xenserver/xcposs/vmops | 1493 ----------------- .../hypervisor/xenserver/xcposs/vmopsSnapshot | 601 ------- .../hypervisor/xenserver/xcposs/vmopspremium | 146 -- .../vm/hypervisor/xenserver/xcpserver/patch | 58 +- .../vm/hypervisor/xenserver/xenheartbeat.sh | 2 +- .../vm/hypervisor/xenserver/xenserver56/patch | 58 +- .../hypervisor/xenserver/xenserver56fp1/patch | 58 +- .../vm/hypervisor/xenserver/xenserver60/patch | 68 +- 25 files changed, 219 insertions(+), 2895 deletions(-) delete mode 100755 scripts/vm/hypervisor/xenserver/xcposs/copy_vhd_from_secondarystorage.sh delete mode 100755 scripts/vm/hypervisor/xenserver/xcposs/copy_vhd_to_secondarystorage.sh delete mode 100755 scripts/vm/hypervisor/xenserver/xcposs/create_privatetemplate_from_snapshot.sh delete mode 100644 scripts/vm/hypervisor/xenserver/xcposs/vmops delete mode 100644 scripts/vm/hypervisor/xenserver/xcposs/vmopsSnapshot delete mode 100644 scripts/vm/hypervisor/xenserver/xcposs/vmopspremium diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index a8ab69184c9..2a5913ab34f 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -301,6 +301,9 @@ import com.cloud.vm.VirtualMachine.PowerState; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.snapshot.VMSnapshot; +import com.cloud.utils.ssh.SSHCmdHelper; + + /** * CitrixResourceBase encapsulates the calls to the XenServer Xapi process * to perform the required functionalities for CloudStack. @@ -5299,6 +5302,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } com.trilead.ssh2.Session session = sshConnection.openSession(); + + String cmd = "mkdir -p /opt/cloud/bin"; + if (!SSHCmdHelper.sshExecuteCmd(sshConnection, cmd)) { + throw new CloudRuntimeException("Cannot create directory /opt/cloud/bin on XenServer hosts"); + } + SCPClient scp = new SCPClient(sshConnection); List files = getPatchFiles(); diff --git a/scripts/vm/hypervisor/xenserver/copy_vhd_from_secondarystorage.sh b/scripts/vm/hypervisor/xenserver/copy_vhd_from_secondarystorage.sh index 2443891a73d..098015a419d 100755 --- a/scripts/vm/hypervisor/xenserver/copy_vhd_from_secondarystorage.sh +++ b/scripts/vm/hypervisor/xenserver/copy_vhd_from_secondarystorage.sh @@ -89,7 +89,7 @@ fi -VHDUTIL="/opt/xensource/bin/vhd-util" +VHDUTIL="/opt/cloud/bin/vhd-util" copyvhd() { diff --git a/scripts/vm/hypervisor/xenserver/copy_vhd_to_secondarystorage.sh b/scripts/vm/hypervisor/xenserver/copy_vhd_to_secondarystorage.sh index b315c07b356..36e8222bf3a 100755 --- a/scripts/vm/hypervisor/xenserver/copy_vhd_to_secondarystorage.sh +++ b/scripts/vm/hypervisor/xenserver/copy_vhd_to_secondarystorage.sh @@ -78,6 +78,7 @@ if [ $? -ne 0 ]; then fi vhdfile=$localmp/${vdiuuid}.vhd +VHDUTIL="vhd-util" if [ $type == "nfs" -o $type == "ext" ]; then dd if=/var/run/sr-mount/$sruuid/${vdiuuid}.vhd of=$vhdfile bs=2M @@ -94,7 +95,7 @@ elif [ $type == "lvmoiscsi" -o $type == "lvm" -o $type == "lvmohba" ]; then cleanup exit 0 fi - size=$(vhd-util query -s -n /dev/VG_XenStorage-$sruuid/VHD-$vdiuuid) + size=$($VHDUTIL query -s -n /dev/VG_XenStorage-$sruuid/VHD-$vdiuuid) if [ $? -ne 0 ]; then echo "10#can not get physical size of /dev/VG_XenStorage-$sruuid/VHD-$vdiuuid" cleanup @@ -112,7 +113,7 @@ elif [ $type == "lvmoiscsi" -o $type == "lvm" -o $type == "lvmohba" ]; then fi #in byte unit size=$((size<<21)) - vhd-util modify -s $size -n $vhdfile + $VHDUTIL modify -s $size -n $vhdfile if [ $? -ne 0 ]; then rm -f $vhdfile echo "11#failed to change $vhdfile physical size" diff --git a/scripts/vm/hypervisor/xenserver/create_privatetemplate_from_snapshot.sh b/scripts/vm/hypervisor/xenserver/create_privatetemplate_from_snapshot.sh index 93b8705e575..d39fc6e9ab8 100755 --- a/scripts/vm/hypervisor/xenserver/create_privatetemplate_from_snapshot.sh +++ b/scripts/vm/hypervisor/xenserver/create_privatetemplate_from_snapshot.sh @@ -96,7 +96,7 @@ if [ $? -ne 0 ]; then exit 0 fi -VHDUTIL="/opt/xensource/bin/vhd-util" +VHDUTIL="/opt/cloud/bin/vhd-util" copyvhd() { diff --git a/scripts/vm/hypervisor/xenserver/launch_hb.sh b/scripts/vm/hypervisor/xenserver/launch_hb.sh index b8a36a041ad..289eb5f8de6 100755 --- a/scripts/vm/hypervisor/xenserver/launch_hb.sh +++ b/scripts/vm/hypervisor/xenserver/launch_hb.sh @@ -33,7 +33,7 @@ if [ -z $2 ]; then exit 3 fi -if [ ! -f /opt/xensource/bin/xenheartbeat.sh ]; then +if [ ! -f /opt/cloud/bin/xenheartbeat.sh ]; then printf "Error: Unable to find xenheartbeat.sh to launch\n" exit 4 fi @@ -42,5 +42,5 @@ for psid in `ps -ef | grep xenheartbeat | grep -v grep | awk '{print $2}'`; do kill $psid done -nohup /opt/xensource/bin/xenheartbeat.sh $1 $2 >/dev/null 2>/dev/null & +nohup /opt/cloud/bin/xenheartbeat.sh $1 $2 >/dev/null 2>/dev/null & echo "======> DONE <======" diff --git a/scripts/vm/hypervisor/xenserver/ovs-pvlan b/scripts/vm/hypervisor/xenserver/ovs-pvlan index c821870d64d..8579b551d9d 100755 --- a/scripts/vm/hypervisor/xenserver/ovs-pvlan +++ b/scripts/vm/hypervisor/xenserver/ovs-pvlan @@ -32,11 +32,11 @@ from time import localtime as _localtime, asctime as _asctime xePath = "/opt/xensource/bin/xe" lib.setup_logging("/var/log/ovs-pvlan.log") -dhcpSetupPath = "/opt/xensource/bin/ovs-pvlan-dhcp-host.sh" -vmSetupPath = "/opt/xensource/bin/ovs-pvlan-vm.sh" -getDhcpIfacePath = "/opt/xensource/bin/ovs-get-dhcp-iface.sh" -pvlanCleanupPath = "/opt/xensource/bin/ovs-pvlan-cleanup.sh" -getBridgePath = "/opt/xensource/bin/ovs-get-bridge.sh" +dhcpSetupPath = "/opt/cloud/bin/ovs-pvlan-dhcp-host.sh" +vmSetupPath = "/opt/cloud/bin/ovs-pvlan-vm.sh" +getDhcpIfacePath = "/opt/cloud/bin/ovs-get-dhcp-iface.sh" +pvlanCleanupPath = "/opt/cloud/bin/ovs-pvlan-cleanup.sh" +getBridgePath = "/opt/cloud/bin/ovs-get-bridge.sh" def echo(fn): def wrapped(*v, **k): diff --git a/scripts/vm/hypervisor/xenserver/setup_heartbeat_file.sh b/scripts/vm/hypervisor/xenserver/setup_heartbeat_file.sh index fb178e012bc..125fc2bcd16 100755 --- a/scripts/vm/hypervisor/xenserver/setup_heartbeat_file.sh +++ b/scripts/vm/hypervisor/xenserver/setup_heartbeat_file.sh @@ -58,7 +58,7 @@ if [ `xe pbd-list sr-uuid=$2 | grep -B 1 $1 | wc -l` -eq 0 ]; then exit 0 fi -hbfile=/opt/xensource/bin/heartbeat +hbfile=/opt/cloud/bin/heartbeat if [ "$3" = "true" ]; then diff --git a/scripts/vm/hypervisor/xenserver/setupxenserver.sh b/scripts/vm/hypervisor/xenserver/setupxenserver.sh index 311f2738bb3..14ba1c28c90 100755 --- a/scripts/vm/hypervisor/xenserver/setupxenserver.sh +++ b/scripts/vm/hypervisor/xenserver/setupxenserver.sh @@ -55,7 +55,7 @@ mv -n /etc/cron.daily/logrotate /etc/cron.hourly 2>&1 echo 1048576 >/proc/sys/fs/aio-max-nr # empty heartbeat -cat /dev/null > /opt/xensource/bin/heartbeat +cat /dev/null > /opt/cloud/bin/heartbeat # empty knownhost cat /dev/null > /root/.ssh/known_hosts diff --git a/scripts/vm/hypervisor/xenserver/swiftxen b/scripts/vm/hypervisor/xenserver/swiftxen index 1be4107f82c..46229e37262 100644 --- a/scripts/vm/hypervisor/xenserver/swiftxen +++ b/scripts/vm/hypervisor/xenserver/swiftxen @@ -34,7 +34,7 @@ def echo(fn): return res return wrapped -SWIFT = "/opt/xensource/bin/swift" +SWIFT = "/opt/cloud/bin/swift" MAX_SEG_SIZE = 5 * 1024 * 1024 * 1024 diff --git a/scripts/vm/hypervisor/xenserver/upgrade_snapshot.sh b/scripts/vm/hypervisor/xenserver/upgrade_snapshot.sh index 6dcc2c451eb..4cb2e3053f5 100755 --- a/scripts/vm/hypervisor/xenserver/upgrade_snapshot.sh +++ b/scripts/vm/hypervisor/xenserver/upgrade_snapshot.sh @@ -87,7 +87,7 @@ if [ $? -ne 0 ]; then exit 0 fi -VHDUTIL="/opt/xensource/bin/vhd-util" +VHDUTIL="/opt/cloud/bin/vhd-util" upgradeSnapshot() { diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 3f11960aab1..5383e0e6218 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -22,7 +22,10 @@ import os, sys, time import XenAPIPlugin -sys.path.extend(["/opt/xensource/sm/", "/usr/local/sbin/", "/sbin/"]) +if os.path.exists("/opt/xensource/sm"): + sys.path.extend(["/opt/xensource/sm/", "/usr/local/sbin/", "/sbin/"]) +if os.path.exists("/usr/lib/xcp/sm"): + sys.path.extend(["/usr/lib/xcp/sm/", "/usr/local/sbin/", "/sbin/"]) import base64 import hostvmstats import socket @@ -48,7 +51,7 @@ def add_to_VCPUs_params_live(session, args): value = args['value'] vmname = args['vmname'] try: - cmd = ["bash", "/opt/xensource/bin/add_to_vcpus_params_live.sh", vmname, key, value] + cmd = ["bash", "/opt/cloud/bin/add_to_vcpus_params_live.sh", vmname, key, value] txt = util.pread2(cmd) except: return 'false' @@ -67,7 +70,7 @@ def gethostvmstats(session, args): def setup_iscsi(session, args): uuid=args['uuid'] try: - cmd = ["bash", "/opt/xensource/bin/setup_iscsi.sh", uuid] + cmd = ["bash", "/opt/cloud/bin/setup_iscsi.sh", uuid] txt = util.pread2(cmd) except: txt = '' @@ -78,7 +81,7 @@ def setup_iscsi(session, args): def getgateway(session, args): mgmt_ip = args['mgmtIP'] try: - cmd = ["bash", "/opt/xensource/bin/network_info.sh", "-g", mgmt_ip] + cmd = ["bash", "/opt/cloud/bin/network_info.sh", "-g", mgmt_ip] txt = util.pread2(cmd) except: txt = '' @@ -89,7 +92,7 @@ def getgateway(session, args): def preparemigration(session, args): uuid = args['uuid'] try: - cmd = ["/opt/xensource/bin/make_migratable.sh", uuid] + cmd = ["/opt/cloud/bin/make_migratable.sh", uuid] util.pread2(cmd) txt = 'success' except: @@ -101,7 +104,7 @@ def preparemigration(session, args): @echo def setIptables(session, args): try: - cmd = ["/bin/bash", "/opt/xensource/bin/setupxenserver.sh"] + cmd = ["/bin/bash", "/opt/cloud/bin/setupxenserver.sh"] txt = util.pread2(cmd) txt = 'success' except: @@ -130,7 +133,7 @@ def pingdomr(session, args): def kill_copy_process(session, args): namelabel = args['namelabel'] try: - cmd = ["bash", "/opt/xensource/bin/kill_copy_process.sh", namelabel] + cmd = ["bash", "/opt/cloud/bin/kill_copy_process.sh", namelabel] txt = util.pread2(cmd) except: txt = 'false' @@ -144,7 +147,7 @@ def pingxenserver(session, args): def pingtest(session, args): sargs = args['args'] cmd = sargs.split(' ') - cmd.insert(0, "/opt/xensource/bin/pingtest.sh") + cmd.insert(0, "/opt/cloud/bin/pingtest.sh") cmd.insert(0, "/bin/bash") try: txt = util.pread2(cmd) @@ -159,7 +162,7 @@ def pingtest(session, args): def savePassword(session, args): sargs = args['args'] cmd = sargs.split(' ') - cmd.insert(0, "/opt/xensource/bin/save_password_to_domr.sh") + cmd.insert(0, "/opt/cloud/bin/save_password_to_domr.sh") cmd.insert(0, "/bin/bash") try: txt = util.pread2(cmd) @@ -174,7 +177,7 @@ def savePassword(session, args): def saveDhcpEntry(session, args): sargs = args['args'] cmd = sargs.split(' ') - cmd.insert(0, "/opt/xensource/bin/dhcp_entry.sh") + cmd.insert(0, "/opt/cloud/bin/dhcp_entry.sh") cmd.insert(0, "/bin/bash") try: txt = util.pread2(cmd) @@ -236,7 +239,7 @@ def setLinkLocalIP(session, args): def setFirewallRule(session, args): sargs = args['args'] cmd = sargs.split(' ') - cmd.insert(0, "/opt/xensource/bin/call_firewall.sh") + cmd.insert(0, "/opt/cloud/bin/call_firewall.sh") cmd.insert(0, "/bin/bash") try: txt = util.pread2(cmd) @@ -251,7 +254,7 @@ def setFirewallRule(session, args): def routerProxy(session, args): sargs = args['args'] cmd = sargs.split(' ') - cmd.insert(0, "/opt/xensource/bin/router_proxy.sh") + cmd.insert(0, "/opt/cloud/bin/router_proxy.sh") cmd.insert(0, "/bin/bash") try: txt = util.pread2(cmd) @@ -269,7 +272,7 @@ def routerProxy(session, args): def setLoadBalancerRule(session, args): sargs = args['args'] cmd = sargs.split(' ') - cmd.insert(0, "/opt/xensource/bin/call_loadbalancer.sh") + cmd.insert(0, "/opt/cloud/bin/call_loadbalancer.sh") cmd.insert(0, "/bin/bash") try: txt = util.pread2(cmd) @@ -296,7 +299,7 @@ def configdnsmasq(session, args): def createipAlias(session, args): args = args['args'] cmd = args.split(' ') - cmd.insert(0, "/opt/xensource/bin/createipAlias.sh") + cmd.insert(0, "/opt/cloud/bin/createipAlias.sh") cmd.insert(0, "bin/bash") try: txt=util.pread2(cmd) @@ -310,7 +313,7 @@ def createipAlias(session, args): def deleteipAlias(session, args): args = args['args'] cmd = args.split(' ') - cmd.insert(0, "/opt/xensource/bin/deleteipAlias.sh") + cmd.insert(0, "/opt/cloud/bin/deleteipAlias.sh") cmd.insert(0, "bin/bash") try: txt=util.pread2(cmd) @@ -1616,7 +1619,7 @@ def network_rules(session, args): def bumpUpPriority(session, args): sargs = args['args'] cmd = sargs.split(' ') - cmd.insert(0, "/opt/xensource/bin/bumpUpPriority.sh") + cmd.insert(0, "/opt/cloud/bin/bumpUpPriority.sh") cmd.insert(0, "/bin/bash") try: txt = util.pread2(cmd) diff --git a/scripts/vm/hypervisor/xenserver/vmopsSnapshot b/scripts/vm/hypervisor/xenserver/vmopsSnapshot index f638de4fe32..00ed93af337 100755 --- a/scripts/vm/hypervisor/xenserver/vmopsSnapshot +++ b/scripts/vm/hypervisor/xenserver/vmopsSnapshot @@ -22,7 +22,11 @@ import os, sys, time import XenAPIPlugin -sys.path.append("/opt/xensource/sm/") +if os.path.exists("/opt/xensource/sm"): + sys.path.extend(["/opt/xensource/sm/", "/usr/local/sbin/", "/sbin/"]) +if os.path.exists("/usr/lib/xcp/sm"): + sys.path.extend(["/usr/lib/xcp/sm/", "/usr/local/sbin/", "/sbin/"]) + import SR, VDI, SRCommand, util, lvutil from util import CommandException import vhdutil @@ -35,7 +39,7 @@ import cleanup import stat import random -VHD_UTIL = '/opt/xensource/bin/vhd-util' +VHDUTIL = "vhd-util" VHD_PREFIX = 'VHD-' CLOUD_DIR = '/var/run/cloud_mount' @@ -263,7 +267,7 @@ def getParentOfSnapshot(snapshotUuid, primarySRPath, isISCSI): def setParent(parent, child): try: - cmd = [VHD_UTIL, "modify", "-p", parent, "-n", child] + cmd = [VHDUTIL, "modify", "-p", parent, "-n", child] txt = util.pread2(cmd) except: errMsg = "Unexpected error while trying to set parent of " + child + " to " + parent diff --git a/scripts/vm/hypervisor/xenserver/vmopspremium b/scripts/vm/hypervisor/xenserver/vmopspremium index 38ec2e8c1d8..d7d0c6f60bf 100755 --- a/scripts/vm/hypervisor/xenserver/vmopspremium +++ b/scripts/vm/hypervisor/xenserver/vmopspremium @@ -22,7 +22,10 @@ import os, sys, time import XenAPIPlugin -sys.path.append("/opt/xensource/sm/") +if os.path.exists("/opt/xensource/sm"): + sys.path.extend(["/opt/xensource/sm/", "/usr/local/sbin/", "/sbin/"]) +if os.path.exists("/usr/lib/xcp/sm"): + sys.path.extend(["/usr/lib/xcp/sm/", "/usr/local/sbin/", "/sbin/"]) import util import socket @@ -52,7 +55,7 @@ def create_privatetemplate_from_snapshot(session, args): snapshotPath = args['snapshotPath'] tmpltLocalDir = args['tmpltLocalDir'] try: - cmd = ["bash", "/opt/xensource/bin/create_privatetemplate_from_snapshot.sh",snapshotPath, templatePath, tmpltLocalDir] + cmd = ["bash", "/opt/cloud/bin/create_privatetemplate_from_snapshot.sh",snapshotPath, templatePath, tmpltLocalDir] txt = util.pread2(cmd) except: txt = '10#failed' @@ -63,7 +66,7 @@ def upgrade_snapshot(session, args): templatePath = args['templatePath'] snapshotPath = args['snapshotPath'] try: - cmd = ["bash", "/opt/xensource/bin/upgrate_snapshot.sh",snapshotPath, templatePath] + cmd = ["bash", "/opt/cloud/bin/upgrate_snapshot.sh",snapshotPath, templatePath] txt = util.pread2(cmd) except: txt = '10#failed' @@ -75,7 +78,7 @@ def copy_vhd_to_secondarystorage(session, args): vdiuuid = args['vdiuuid'] sruuid = args['sruuid'] try: - cmd = ["bash", "/opt/xensource/bin/copy_vhd_to_secondarystorage.sh", mountpoint, vdiuuid, sruuid] + cmd = ["bash", "/opt/cloud/bin/copy_vhd_to_secondarystorage.sh", mountpoint, vdiuuid, sruuid] txt = util.pread2(cmd) except: txt = '10#failed' @@ -87,7 +90,7 @@ def copy_vhd_from_secondarystorage(session, args): sruuid = args['sruuid'] namelabel = args['namelabel'] try: - cmd = ["bash", "/opt/xensource/bin/copy_vhd_from_secondarystorage.sh", mountpoint, sruuid, namelabel] + cmd = ["bash", "/opt/cloud/bin/copy_vhd_from_secondarystorage.sh", mountpoint, sruuid, namelabel] txt = util.pread2(cmd) except: txt = '10#failed' @@ -98,7 +101,7 @@ def setup_heartbeat_sr(session, args): host = args['host'] sr = args['sr'] try: - cmd = ["bash", "/opt/xensource/bin/setup_heartbeat_sr.sh", host, sr] + cmd = ["bash", "/opt/cloud/bin/setup_heartbeat_sr.sh", host, sr] txt = util.pread2(cmd) except: txt = '' @@ -110,7 +113,7 @@ def setup_heartbeat_file(session, args): sr = args['sr'] add = args['add'] try: - cmd = ["bash", "/opt/xensource/bin/setup_heartbeat_file.sh", host, sr, add] + cmd = ["bash", "/opt/cloud/bin/setup_heartbeat_file.sh", host, sr, add] txt = util.pread2(cmd) except: txt = '' @@ -121,7 +124,7 @@ def check_heartbeat(session, args): host = args['host'] interval = args['interval'] try: - cmd = ["bash", "/opt/xensource/bin/check_heartbeat.sh", host, interval] + cmd = ["bash", "/opt/cloud/bin/check_heartbeat.sh", host, interval] txt = util.pread2(cmd) except: txt='' @@ -133,7 +136,7 @@ def heartbeat(session, args): host = args['host'] interval = args['interval'] try: - cmd = ["/bin/bash", "/opt/xensource/bin/launch_hb.sh", host, interval] + cmd = ["/bin/bash", "/opt/cloud/bin/launch_hb.sh", host, interval] txt = util.pread2(cmd) except: txt='fail' diff --git a/scripts/vm/hypervisor/xenserver/xcposs/copy_vhd_from_secondarystorage.sh b/scripts/vm/hypervisor/xenserver/xcposs/copy_vhd_from_secondarystorage.sh deleted file mode 100755 index a4e977bdd59..00000000000 --- a/scripts/vm/hypervisor/xenserver/xcposs/copy_vhd_from_secondarystorage.sh +++ /dev/null @@ -1,188 +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. - -#set -x - -usage() { - printf "Usage: %s [vhd file in secondary storage] [uuid of the source sr] [name label] \n" $(basename $0) -} - -cleanup() -{ - if [ ! -z $localmp ]; then - umount -fl $localmp - if [ $? -eq 0 ]; then - rmdir $localmp - fi - fi -} - -if [ -z $1 ]; then - usage - echo "2#no mountpoint" - exit 0 -else - mountpoint=${1%/*} - vhdfilename=${1##*/} -fi - -if [ -z $2 ]; then - usage - echo "3#no uuid of the source sr" - exit 0 -else - sruuid=$2 -fi - -type=$(xe sr-param-get uuid=$sruuid param-name=type) -if [ $? -ne 0 ]; then - echo "4#sr $sruuid doesn't exist" - exit 0 -fi - -if [ -z $3 ]; then - usage - echo "3#no namelabel" - exit 0 -else - namelabel=$3 -fi - -localmp=/var/run/cloud_mount/$(uuidgen -r) - -mkdir -p $localmp -if [ $? -ne 0 ]; then - echo "5#can't make dir $localmp" - exit 0 -fi - -mount -o tcp,soft,ro,timeo=133,retrans=1 $mountpoint $localmp -if [ $? -ne 0 ]; then - echo "6#can't mount $mountpoint to $localmp" - exit 0 -fi - -vhdfile=$localmp/$vhdfilename -if [ ${vhdfile%.vhd} == ${vhdfile} ] ; then - vhdfile=$(ls $vhdfile/*.vhd) - if [ $? -ne 0 ]; then - echo "7#There is no vhd file under $mountpoint" - cleanup - exit 0 - fi -fi - - - -VHDUTIL="/usr/bin/vhd-util" - -copyvhd() -{ - local desvhd=$1 - local srcvhd=$2 - local vsize=$3 - local type=$4 - local parent=`$VHDUTIL query -p -n $srcvhd` - if [ $? -ne 0 ]; then - echo "30#failed to query $srcvhd" - cleanup - exit 0 - fi - if [ "${parent##*vhd has}" = " no parent" ]; then - dd if=$srcvhd of=$desvhd bs=2M - if [ $? -ne 0 ]; then - echo "31#failed to dd $srcvhd to $desvhd" - cleanup - exit 0 - fi - if [ $type != "nfs" -a $type != "ext" -a $type != "file" ]; then - dd if=$srcvhd of=$desvhd bs=512 seek=$(($(($vsize/512))-1)) count=1 - $VHDUTIL modify -s $vsize -n $desvhd - if [ $? -ne 0 ]; then - echo "32#failed to set new vhd physical size for vdi vdi $uuid" - cleanup - exit 0 - fi - fi - else - copyvhd $desvhd $parent $vsize $type - $VHDUTIL coalesce -p $desvhd -n $srcvhd - if [ $? -ne 0 ]; then - echo "32#failed to coalesce $desvhd to $srcvhd" - cleanup - exit 0 - fi - fi -} - -size=$($VHDUTIL query -v -n $vhdfile) -uuid=$(xe vdi-create sr-uuid=$sruuid virtual-size=${size}MiB type=user name-label=$namelabel) -if [ $? -ne 0 ]; then - echo "9#can not create vdi in sr $sruuid" - cleanup - exit 0 -fi - - -if [ $type == "nfs" -o $type == "ext" ]; then - desvhd=/run/sr-mount/$sruuid/$uuid.vhd - copyvhd $desvhd $vhdfile 0 $type - -elif [ $type == "lvmoiscsi" -o $type == "lvm" -o $type == "lvmohba" ]; then - lvsize=$(xe vdi-param-get uuid=$uuid param-name=physical-utilisation) - if [ $? -ne 0 ]; then - echo "12#failed to get physical size of vdi $uuid" - cleanup - exit 0 - fi - desvhd=/dev/VG_XenStorage-$sruuid/VHD-$uuid - lvchange -ay $desvhd - if [ $? -ne 0 ]; then - echo "10#lvm can not make VDI $uuid visible" - cleanup - exit 0 - fi - copyvhd $desvhd $vhdfile $lvsize $type -elif [ $type == "file" ]; then - pbd=`xe sr-param-list uuid=$sruuid |grep PBDs | awk '{print $3}'` - path=`xe pbd-param-list uuid=$pbd |grep device-config |awk '{print $4}'` - desvhd=$path/$uuid.vhd - copyvhd $desvhd $vhdfile 0 $type - -else - echo "15#doesn't support sr type $type" - cleanup - exit 0 -fi - -$VHDUTIL set -n $desvhd -f "hidden" -v "0" > /dev/null -if [ $? -ne 0 ]; then - echo "21#failed to set hidden to 0 $desvhd" - cleanup - exit 0 -fi -xe sr-scan uuid=$sruuid -if [ $? -ne 0 ]; then - echo "14#failed to scan sr $sruuid" - cleanup - exit 0 -fi - -echo "0#$uuid" -cleanup -exit 0 diff --git a/scripts/vm/hypervisor/xenserver/xcposs/copy_vhd_to_secondarystorage.sh b/scripts/vm/hypervisor/xenserver/xcposs/copy_vhd_to_secondarystorage.sh deleted file mode 100755 index b315c07b356..00000000000 --- a/scripts/vm/hypervisor/xenserver/xcposs/copy_vhd_to_secondarystorage.sh +++ /dev/null @@ -1,130 +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. - -#set -x - -usage() { - printf "Usage: %s [mountpoint in secondary storage] [uuid of the source vdi] [uuid of the source sr]\n" $(basename $0) -} - -cleanup() -{ - if [ ! -z $localmp ]; then - umount $localmp - if [ $? -eq 0 ]; then - rmdir $localmp - fi - fi -} - -if [ -z $1 ]; then - usage - echo "1#no mountpoint" - exit 0 -else - mountpoint=$1 -fi - -if [ -z $2 ]; then - usage - echo "2#no uuid of the source sr" - exit 0 -else - vdiuuid=$2 -fi - - -if [ -z $3 ]; then - usage - echo "3#no uuid of the source sr" - exit 0 -else - sruuid=$3 -fi - -type=$(xe sr-param-get uuid=$sruuid param-name=type) -if [ $? -ne 0 ]; then - echo "4#sr $sruuid doesn't exist" - exit 0 -fi - -localmp=/var/run/cloud_mount/$(uuidgen -r) - -mkdir -p $localmp -if [ $? -ne 0 ]; then - echo "5#can't make dir $localmp" - exit 0 -fi - -mount -o tcp,soft,timeo=133,retrans=1 $mountpoint $localmp -if [ $? -ne 0 ]; then - echo "6#can't mount $mountpoint to $localmp" - exit 0 -fi - -vhdfile=$localmp/${vdiuuid}.vhd - -if [ $type == "nfs" -o $type == "ext" ]; then - dd if=/var/run/sr-mount/$sruuid/${vdiuuid}.vhd of=$vhdfile bs=2M - if [ $? -ne 0 ]; then - rm -f $vhdfile - echo "8#failed to copy /var/run/sr-mount/$sruuid/${vdiuuid}.vhd to secondarystorage" - cleanup - exit 0 - fi -elif [ $type == "lvmoiscsi" -o $type == "lvm" -o $type == "lvmohba" ]; then - lvchange -ay /dev/VG_XenStorage-$sruuid/VHD-$vdiuuid - if [ $? -ne 0 ]; then - echo "9#lvm can not make VDI $vdiuuid visible" - cleanup - exit 0 - fi - size=$(vhd-util query -s -n /dev/VG_XenStorage-$sruuid/VHD-$vdiuuid) - if [ $? -ne 0 ]; then - echo "10#can not get physical size of /dev/VG_XenStorage-$sruuid/VHD-$vdiuuid" - cleanup - exit 0 - fi -#in 2M unit - size=$((size>>21)) - size=$((size+1)) - dd if=/dev/VG_XenStorage-$sruuid/VHD-$vdiuuid of=$vhdfile bs=2M count=$size - if [ $? -ne 0 ]; then - rm -f $vhdfile - echo "8#failed to copy /dev/VG_XenStorage-$sruuid/VHD-$vdiuuid to secondarystorage" - cleanup - exit 0 - fi -#in byte unit - size=$((size<<21)) - vhd-util modify -s $size -n $vhdfile - if [ $? -ne 0 ]; then - rm -f $vhdfile - echo "11#failed to change $vhdfile physical size" - cleanup - exit 0 - fi -else - echo "15#doesn't support sr type $type" - cleanup - exit 0 -fi - -echo "0#$vdiuuid" -cleanup -exit 0 diff --git a/scripts/vm/hypervisor/xenserver/xcposs/create_privatetemplate_from_snapshot.sh b/scripts/vm/hypervisor/xenserver/xcposs/create_privatetemplate_from_snapshot.sh deleted file mode 100755 index 4213efcc43e..00000000000 --- a/scripts/vm/hypervisor/xenserver/xcposs/create_privatetemplate_from_snapshot.sh +++ /dev/null @@ -1,138 +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. - -#set -x - -usage() { - printf "Usage: %s [vhd file in secondary storage] [template directory in secondary storage] [template local dir] \n" $(basename $0) -} -options='tcp,soft,timeo=133,retrans=1' -cleanup() -{ - if [ ! -z $snapshotdir ]; then - umount $snapshotdir - if [ $? -eq 0 ]; then - rmdir $snapshotdir - fi - fi - if [ ! -z $templatedir ]; then - umount $templatedir - if [ $? -eq 0 ]; then - rmdir $templatedir - fi - fi -} - -if [ -z $1 ]; then - usage - echo "2#no vhd file path" - exit 0 -else - snapshoturl=${1%/*} - vhdfilename=${1##*/} -fi - -if [ -z $2 ]; then - usage - echo "3#no template path" - exit 0 -else - templateurl=$2 -fi - -if [ -z $3 ]; then - usage - echo "3#no template local dir" - exit 0 -else - tmpltLocalDir=$3 -fi - - -snapshotdir=/run/cloud_mount/$(uuidgen -r) -mkdir -p $snapshotdir -if [ $? -ne 0 ]; then - echo "4#cann't make dir $snapshotdir" - exit 0 -fi - -mount -o $options $snapshoturl $snapshotdir -if [ $? -ne 0 ]; then - rmdir $snapshotdir - echo "5#can not mount $snapshoturl to $snapshotdir" - exit 0 -fi - -templatedir=/run/cloud_mount/$tmpltLocalDir -mkdir -p $templatedir -if [ $? -ne 0 ]; then - templatedir="" - cleanup - echo "6#cann't make dir $templatedir" - exit 0 -fi - -mount -o $options $templateurl $templatedir -if [ $? -ne 0 ]; then - rmdir $templatedir - templatedir="" - cleanup - echo "7#can not mount $templateurl to $templatedir" - exit 0 -fi - -VHDUTIL="vhd-util" - -copyvhd() -{ - local desvhd=$1 - local srcvhd=$2 - local parent= - parent=`$VHDUTIL query -p -n $srcvhd` - if [ $? -ne 0 ]; then - echo "30#failed to query $srcvhd" - cleanup - exit 0 - fi - if [[ "${parent}" =~ " no parent" ]]; then - dd if=$srcvhd of=$desvhd bs=2M - if [ $? -ne 0 ]; then - echo "31#failed to dd $srcvhd to $desvhd" - cleanup - exit 0 - fi - else - copyvhd $desvhd $parent - $VHDUTIL coalesce -p $desvhd -n $srcvhd - if [ $? -ne 0 ]; then - echo "32#failed to coalesce $desvhd to $srcvhd" - cleanup - exit 0 - fi - fi -} - -templateuuid=$(uuidgen -r) -desvhd=$templatedir/$templateuuid.vhd -srcvhd=$snapshotdir/$vhdfilename -copyvhd $desvhd $srcvhd -virtualSize=`$VHDUTIL query -v -n $desvhd` -physicalSize=`ls -l $desvhd | awk '{print $5}'` -cleanup -echo "0#$templateuuid#$physicalSize#$virtualSize" -exit 0 diff --git a/scripts/vm/hypervisor/xenserver/xcposs/patch b/scripts/vm/hypervisor/xenserver/xcposs/patch index 6e1002ea1f1..aa551de264a 100644 --- a/scripts/vm/hypervisor/xenserver/xcposs/patch +++ b/scripts/vm/hypervisor/xenserver/xcposs/patch @@ -27,42 +27,42 @@ # If [source path] starts with '~', then it is path relative to management server home directory. # If [source path] does not start with '/' or '~', then it is relative path to the location of the patch file. NFSSR.py=/usr/lib/xcp/sm -vmops=.,0755,/usr/lib/xcp/plugins +vmops=..,0755,/usr/lib/xcp/plugins ovsgre=..,0755,/usr/lib/xcp/plugins ovstunnel=..,0755,/usr/lib/xcp/plugins -vmopsSnapshot=.,0755,/usr/lib/xcp/plugins +vmopsSnapshot=..,0755,/usr/lib/xcp/plugins hostvmstats.py=..,0755,/usr/lib/xcp/sm systemvm.iso=../../../../../vms,0644,/usr/share/xcp/packages/iso/ id_rsa.cloud=../../../systemvm,0600,/root/.ssh -network_info.sh=..,0755,/usr/lib/xcp/bin -setupxenserver.sh=..,0755,/usr/lib/xcp/bin -make_migratable.sh=..,0755,/usr/lib/xcp/bin -setup_iscsi.sh=..,0755,/usr/lib/xcp/bin -pingtest.sh=../../..,0755,/usr/lib/xcp/bin -dhcp_entry.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin -ipassoc.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin -save_password_to_domr.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin -networkUsage.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin -call_firewall.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin -call_loadbalancer.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin -l2tp_vpn.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin -cloud-setup-bonding.sh=..,0755,/usr/lib/xcp/bin -copy_vhd_to_secondarystorage.sh=.,0755,/usr/lib/xcp/bin -copy_vhd_from_secondarystorage.sh=.,0755,/usr/lib/xcp/bin -setup_heartbeat_sr.sh=..,0755,/usr/lib/xcp/bin -setup_heartbeat_file.sh=..,0755,/usr/lib/xcp/bin -check_heartbeat.sh=..,0755,/usr/lib/xcp/bin -xenheartbeat.sh=..,0755,/usr/lib/xcp/bin -launch_hb.sh=..,0755,/usr/lib/xcp/bin -vhd-util=..,0755,/usr/lib/xcp/bin -vmopspremium=.,0755,/usr/lib/xcp/plugins -create_privatetemplate_from_snapshot.sh=.,0755,/usr/lib/xcp/bin -upgrade_snapshot.sh=..,0755,/usr/lib/xcp/bin -cloud-clean-vlan.sh=..,0755,/usr/lib/xcp/bin -cloud-prepare-upgrade.sh=..,0755,/usr/lib/xcp/bin -getRouterStatus.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin -bumpUpPriority.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin -getDomRVersion.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin -router_proxy.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin -createipAlias.sh=..,0755,/usr/lib/xcp/bin -deleteipAlias.sh=..,0755,/usr/lib/xcp/bin +network_info.sh=..,0755,/opt/cloud/bin +setupxenserver.sh=..,0755,/opt/cloud/bin +make_migratable.sh=..,0755,/opt/cloud/bin +setup_iscsi.sh=..,0755,/opt/cloud/bin +pingtest.sh=../../..,0755,/opt/cloud/bin +dhcp_entry.sh=../../../../network/domr/,0755,/opt/cloud/bin +ipassoc.sh=../../../../network/domr/,0755,/opt/cloud/bin +save_password_to_domr.sh=../../../../network/domr/,0755,/opt/cloud/bin +networkUsage.sh=../../../../network/domr/,0755,/opt/cloud/bin +call_firewall.sh=../../../../network/domr/,0755,/opt/cloud/bin +call_loadbalancer.sh=../../../../network/domr/,0755,/opt/cloud/bin +l2tp_vpn.sh=../../../../network/domr/,0755,/opt/cloud/bin +cloud-setup-bonding.sh=..,0755,/opt/cloud/bin +copy_vhd_to_secondarystorage.sh=..,0755,/opt/cloud/bin +copy_vhd_from_secondarystorage.sh=..,0755,/opt/cloud/bin +setup_heartbeat_sr.sh=..,0755,/opt/cloud/bin +setup_heartbeat_file.sh=..,0755,/opt/cloud/bin +check_heartbeat.sh=..,0755,/opt/cloud/bin +xenheartbeat.sh=..,0755,/opt/cloud/bin +launch_hb.sh=..,0755,/opt/cloud/bin +vhd-util=..,0755,/opt/cloud/bin +vmopspremium=..,0755,/usr/lib/xcp/plugins +create_privatetemplate_from_snapshot.sh=..,0755,/opt/cloud/bin +upgrade_snapshot.sh=..,0755,/opt/cloud/bin +cloud-clean-vlan.sh=..,0755,/opt/cloud/bin +cloud-prepare-upgrade.sh=..,0755,/opt/cloud/bin +getRouterStatus.sh=../../../../network/domr/,0755,/opt/cloud/bin +bumpUpPriority.sh=../../../../network/domr/,0755,/opt/cloud/bin +getDomRVersion.sh=../../../../network/domr/,0755,/opt/cloud/bin +router_proxy.sh=../../../../network/domr/,0755,/opt/cloud/bin +createipAlias.sh=..,0755,/opt/cloud/bin +deleteipAlias.sh=..,0755,/opt/cloud/bin diff --git a/scripts/vm/hypervisor/xenserver/xcposs/vmops b/scripts/vm/hypervisor/xenserver/xcposs/vmops deleted file mode 100644 index 20725e4ec85..00000000000 --- a/scripts/vm/hypervisor/xenserver/xcposs/vmops +++ /dev/null @@ -1,1493 +0,0 @@ -#!/usr/bin/python -# 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. - -# Version @VERSION@ -# -# A plugin for executing script needed by vmops cloud - -import os, sys, time -import XenAPIPlugin -sys.path.extend(["/usr/lib/xcp/sm/", "/usr/local/sbin/", "/sbin/"]) -import base64 -import hostvmstats -import socket -import stat -import tempfile -import util -import subprocess -import zlib -from util import CommandException - -def echo(fn): - def wrapped(*v, **k): - name = fn.__name__ - util.SMlog("#### VMOPS enter %s ####" % name ) - res = fn(*v, **k) - util.SMlog("#### VMOPS exit %s ####" % name ) - return res - return wrapped - -@echo -def gethostvmstats(session, args): - collect_host_stats = args['collectHostStats'] - consolidation_function = args['consolidationFunction'] - interval = args['interval'] - start_time = args['startTime'] - result = hostvmstats.get_stats(session, collect_host_stats, consolidation_function, interval, start_time) - return result - -@echo -def setup_iscsi(session, args): - uuid=args['uuid'] - try: - cmd = ["bash", "/usr/lib/xcp/bin/setup_iscsi.sh", uuid] - txt = util.pread2(cmd) - except: - txt = '' - return '> DONE <' - - -@echo -def getgateway(session, args): - mgmt_ip = args['mgmtIP'] - try: - cmd = ["bash", "/usr/lib/xcp/bin/network_info.sh", "-g", mgmt_ip] - txt = util.pread2(cmd) - except: - txt = '' - - return txt - -@echo -def preparemigration(session, args): - uuid = args['uuid'] - try: - cmd = ["/usr/lib/xcp/bin/make_migratable.sh", uuid] - util.pread2(cmd) - txt = 'success' - except: - util.SMlog("Catch prepare migration exception" ) - txt = '' - - return txt - -@echo -def setIptables(session, args): - try: - '''cmd = ["/bin/bash", "/usr/lib/xcp/bin/setupxenserver.sh"] - txt = util.pread2(cmd)''' - txt = 'success' - except: - util.SMlog(" setIptables execution failed " ) - txt = '' - - return txt - -@echo -def pingdomr(session, args): - host = args['host'] - port = args['port'] - socket.setdefaulttimeout(3) - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - try: - s.connect((host,int(port))) - txt = 'success' - except: - txt = '' - - s.close() - - return txt - -@echo -def kill_copy_process(session, args): - namelabel = args['namelabel'] - try: - cmd = ["bash", "/usr/lib/xcp/bin/kill_copy_process.sh", namelabel] - txt = util.pread2(cmd) - except: - txt = 'false' - return txt - -@echo -def pingxenserver(session, args): - txt = 'success' - return txt - -@echo -def ipassoc(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/usr/lib/xcp/bin/ipassoc.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - txt = 'success' - except: - util.SMlog(" ip associate failed " ) - txt = '' - - return txt - -def pingtest(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/usr/lib/xcp/bin/pingtest.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - txt = 'success' - except: - util.SMlog(" pingtest failed " ) - txt = '' - - return txt - -@echo -def savePassword(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/usr/lib/xcp/bin/save_password_to_domr.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - txt = 'success' - except: - util.SMlog(" save password to domr failed " ) - txt = '' - - return txt - -@echo -def saveDhcpEntry(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/usr/lib/xcp/bin/dhcp_entry.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - txt = 'success' - except: - util.SMlog(" save dhcp entry failed " ) - txt = '' - - return txt - -@echo -def lt2p_vpn(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/usr/lib/xcp/bin/l2tp_vpn.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - txt = 'success' - except: - util.SMlog("l2tp vpn failed " ) - txt = '' - - return txt - -@echo -def setLinkLocalIP(session, args): - brName = args['brName'] - try: - cmd = ["ip", "route", "del", "169.254.0.0/16"] - txt = util.pread2(cmd) - except: - txt = '' - try: - cmd = ["ifconfig", brName, "169.254.0.1", "netmask", "255.255.0.0"] - txt = util.pread2(cmd) - except: - - try: - cmd = ["brctl", "addbr", brName] - txt = util.pread2(cmd) - except: - pass - - try: - cmd = ["ifconfig", brName, "169.254.0.1", "netmask", "255.255.0.0"] - txt = util.pread2(cmd) - except: - pass - try: - cmd = ["ip", "route", "add", "169.254.0.0/16", "dev", brName, "src", "169.254.0.1"] - txt = util.pread2(cmd) - except: - txt = '' - txt = 'success' - return txt - -@echo -def setFirewallRule(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/usr/lib/xcp/bin/call_firewall.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - txt = 'success' - except: - util.SMlog(" set firewall rule failed " ) - txt = '' - - return txt - -@echo -def setLoadBalancerRule(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/usr/lib/xcp/bin/call_loadbalancer.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - txt = 'success' - except: - util.SMlog(" set loadbalancer rule failed " ) - txt = '' - - return txt - -@echo -def createFile(session, args): - file_path = args['filepath'] - file_contents = args['filecontents'] - - try: - f = open(file_path, "w") - f.write(file_contents) - f.close() - txt = 'success' - except: - util.SMlog(" failed to create HA proxy cfg file ") - txt = '' - - return txt - -@echo -def deleteFile(session, args): - file_path = args["filepath"] - - try: - if os.path.isfile(file_path): - os.remove(file_path) - txt = 'success' - except: - util.SMlog(" failed to remove HA proxy cfg file ") - txt = '' - - return txt - - -@echo -def networkUsage(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/usr/lib/xcp/bin/networkUsage.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - except: - util.SMlog(" network usage error " ) - txt = '' - - return txt - -def get_private_nic(session, args): - vms = session.xenapi.VM.get_all() - host_uuid = args.get('host_uuid') - host = session.xenapi.host.get_by_uuid(host_uuid) - piflist = session.xenapi.host.get_PIFs(host) - mgmtnic = 'eth0' - for pif in piflist: - pifrec = session.xenapi.PIF.get_record(pif) - network = pifrec.get('network') - nwrec = session.xenapi.network.get_record(network) - if nwrec.get('name_label') == 'cloud-guest': - return pifrec.get('device') - if pifrec.get('management'): - mgmtnic = pifrec.get('device') - - return mgmtnic - -def chain_name(vm_name): - if vm_name.startswith('i-') or vm_name.startswith('r-'): - if vm_name.endswith('untagged'): - return '-'.join(vm_name.split('-')[:-1]) - return vm_name - -def chain_name_def(vm_name): - if vm_name.startswith('i-'): - if vm_name.endswith('untagged'): - return '-'.join(vm_name.split('-')[:-2]) + "-def" - return '-'.join(vm_name.split('-')[:-1]) + "-def" - return vm_name - -def egress_chain_name(vm_name): - return chain_name(vm_name) + "-eg" - -@echo -def can_bridge_firewall(session, args): - try: - util.pread2(['ebtables', '-V']) - util.pread2(['ipset', '-V']) - except: - return 'false' - - host_uuid = args.get('host_uuid') - try: - util.pread2(['iptables', '-N', 'BRIDGE-FIREWALL']) - util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '-m', 'state', '--state', 'RELATED,ESTABLISHED', '-j', 'ACCEPT']) - util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '-p', 'udp', '--dport', '67', '--sport', '68', '-j', 'ACCEPT']) - util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '-p', 'udp', '--dport', '68', '--sport', '67', '-j', 'ACCEPT']) - util.pread2(['iptables', '-D', 'FORWARD', '-j', 'RH-Firewall-1-INPUT']) - except: - util.SMlog('Chain BRIDGE-FIREWALL already exists') - privnic = get_private_nic(session, args) - result = 'true' - try: - util.pread2(['/bin/bash', '-c', 'iptables -n -L FORWARD | grep BRIDGE-FIREWALL']) - except: - try: - util.pread2(['iptables', '-I', 'FORWARD', '-m', 'physdev', '--physdev-is-bridged', '-j', 'BRIDGE-FIREWALL']) - util.pread2(['iptables', '-A', 'FORWARD', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', privnic, '-j', 'ACCEPT']) - util.pread2(['iptables', '-A', 'FORWARD', '-j', 'DROP']) - except: - return 'false' - default_ebtables_rules() - allow_egress_traffic(session) - if not os.path.exists('/var/run/cloud'): - os.makedirs('/var/run/cloud') - if not os.path.exists('/var/cache/cloud'): - os.makedirs('/var/cache/cloud') - #get_ipset_keyword() - - cleanup_rules_for_dead_vms(session) - cleanup_rules(session, args) - - return result - -@echo -def default_ebtables_rules(): - try: - util.pread2(['ebtables', '-N', 'DEFAULT_EBTABLES']) - util.pread2(['ebtables', '-A', 'FORWARD', '-j' 'DEFAULT_EBTABLES']) - util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '--ip-dst', '255.255.255.255', '--ip-proto', 'udp', '--ip-dport', '67', '-j', 'ACCEPT']) - util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'ARP', '--arp-op', 'Request', '-j', 'ACCEPT']) - util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'ARP', '--arp-op', 'Reply', '-j', 'ACCEPT']) - # deny mac broadcast and multicast - util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '-d', 'Broadcast', '-j', 'DROP']) - util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '-d', 'Multicast', '-j', 'DROP']) - # deny ip broadcast and multicast - util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '--ip-dst', '255.255.255.255', '-j', 'DROP']) - util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '--ip-dst', '224.0.0.0/4', '-j', 'DROP']) - util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '-j', 'RETURN']) - # deny ipv6 - util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv6', '-j', 'DROP']) - # deny vlan - util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', '802_1Q', '-j', 'DROP']) - # deny all others (e.g., 802.1d, CDP) - util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-j', 'DROP']) - except: - util.SMlog('Chain DEFAULT_EBTABLES already exists') - - -@echo -def allow_egress_traffic(session): - devs = [] - for pif in session.xenapi.PIF.get_all(): - pif_rec = session.xenapi.PIF.get_record(pif) - vlan = pif_rec.get('VLAN') - dev = pif_rec.get('device') - if vlan == '-1': - devs.append(dev) - else: - devs.append(dev + "." + vlan) - for d in devs: - try: - util.pread2(['/bin/bash', '-c', "iptables -n -L FORWARD | grep '%s '" % d]) - except: - try: - util.pread2(['iptables', '-I', 'FORWARD', '2', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', d, '-j', 'ACCEPT']) - except: - util.SMlog("Failed to add FORWARD rule through to %s" % d) - return 'false' - return 'true' - - -def ipset(ipsetname, proto, start, end, ips): - try: - util.pread2(['ipset', '-N', ipsetname, 'iptreemap']) - except: - util.SMlog("ipset chain already exists" + ipsetname) - - result = True - ipsettmp = ''.join(''.join(ipsetname.split('-')).split('_')) + str(int(time.time()) % 1000) - - try: - util.pread2(['ipset', '-N', ipsettmp, 'iptreemap']) - except: - util.SMlog("Failed to create temp ipset, reusing old name= " + ipsettmp) - try: - util.pread2(['ipset', '-F', ipsettmp]) - except: - util.SMlog("Failed to clear old temp ipset name=" + ipsettmp) - return False - - try: - for ip in ips: - try: - util.pread2(['ipset', '-A', ipsettmp, ip]) - except CommandException, cex: - if cex.reason.rfind('already in set') == -1: - raise - except: - util.SMlog("Failed to program ipset " + ipsetname) - util.pread2(['ipset', '-F', ipsettmp]) - util.pread2(['ipset', '-X', ipsettmp]) - return False - - try: - util.pread2(['ipset', '-W', ipsettmp, ipsetname]) - except: - util.SMlog("Failed to swap ipset " + ipsetname) - result = False - - try: - util.pread2(['ipset', '-F', ipsettmp]) - util.pread2(['ipset', '-X', ipsettmp]) - except: - # if the temporary name clashes next time we'll just reuse it - util.SMlog("Failed to delete temp ipset " + ipsettmp) - - return result - -@echo -def destroy_network_rules_for_vm(session, args): - vm_name = args.pop('vmName') - vmchain = chain_name(vm_name) - vmchain_egress = egress_chain_name(vm_name) - vmchain_default = chain_name_def(vm_name) - - delete_rules_for_vm_in_bridge_firewall_chain(vm_name) - if vm_name.startswith('i-') or vm_name.startswith('r-') or vm_name.startswith('l-'): - try: - util.pread2(['iptables', '-F', vmchain_default]) - util.pread2(['iptables', '-X', vmchain_default]) - except: - util.SMlog("Ignoring failure to delete chain " + vmchain_default) - - destroy_ebtables_rules(vmchain) - - try: - util.pread2(['iptables', '-F', vmchain]) - util.pread2(['iptables', '-X', vmchain]) - except: - util.SMlog("Ignoring failure to delete ingress chain " + vmchain) - - - try: - util.pread2(['iptables', '-F', vmchain_egress]) - util.pread2(['iptables', '-X', vmchain_egress]) - except: - util.SMlog("Ignoring failure to delete egress chain " + vmchain_egress) - - remove_rule_log_for_vm(vm_name) - - if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-', 'l-'] ]: - return 'true' - - try: - setscmd = "ipset --save | grep " + vmchain + " | grep '^-N' | awk '{print $2}'" - setsforvm = util.pread2(['/bin/bash', '-c', setscmd]).split('\n') - for set in setsforvm: - if set != '': - util.pread2(['ipset', '-F', set]) - util.pread2(['ipset', '-X', set]) - except: - util.SMlog("Failed to destroy ipsets for %" % vm_name) - - - return 'true' - -@echo -def destroy_ebtables_rules(vm_chain): - - delcmd = "ebtables-save | grep " + vm_chain + " | sed 's/-A/-D/'" - delcmds = util.pread2(['/bin/bash', '-c', delcmd]).split('\n') - delcmds.pop() - for cmd in delcmds: - try: - dc = cmd.split(' ') - dc.insert(0, 'ebtables') - util.pread2(dc) - except: - util.SMlog("Ignoring failure to delete ebtables rules for vm " + vm_chain) - try: - util.pread2(['ebtables', '-F', vm_chain]) - util.pread2(['ebtables', '-X', vm_chain]) - except: - util.SMlog("Ignoring failure to delete ebtables chain for vm " + vm_chain) - -@echo -def destroy_arptables_rules(vm_chain): - delcmd = "arptables -vL FORWARD | grep " + vm_chain + " | sed 's/-i any//' | sed 's/-o any//' | awk '{print $1,$2,$3,$4}' " - delcmds = util.pread2(['/bin/bash', '-c', delcmd]).split('\n') - delcmds.pop() - for cmd in delcmds: - try: - dc = cmd.split(' ') - dc.insert(0, 'arptables') - dc.insert(1, '-D') - dc.insert(2, 'FORWARD') - util.pread2(dc) - except: - util.SMlog("Ignoring failure to delete arptables rules for vm " + vm_chain) - - try: - util.pread2(['arptables', '-F', vm_chain]) - util.pread2(['arptables', '-X', vm_chain]) - except: - util.SMlog("Ignoring failure to delete arptables chain for vm " + vm_chain) - -@echo -def default_ebtables_antispoof_rules(vm_chain, vifs, vm_ip, vm_mac): - if vm_mac == 'ff:ff:ff:ff:ff:ff': - util.SMlog("Ignoring since mac address is not valid") - return 'true' - - try: - util.pread2(['ebtables', '-N', vm_chain]) - except: - try: - util.pread2(['ebtables', '-F', vm_chain]) - except: - util.SMlog("Failed to create ebtables antispoof chain, skipping") - return 'true' - - # note all rules for packets into the bridge (-i) precede all output rules (-o) - # always start after the first rule in the FORWARD chain that jumps to DEFAULT_EBTABLES chain - try: - for vif in vifs: - util.pread2(['ebtables', '-I', 'FORWARD', '2', '-i', vif, '-j', vm_chain]) - util.pread2(['ebtables', '-A', 'FORWARD', '-o', vif, '-j', vm_chain]) - except: - util.SMlog("Failed to program default ebtables FORWARD rules for %s" % vm_chain) - return 'false' - - try: - for vif in vifs: - # only allow source mac that belongs to the vm - util.pread2(['ebtables', '-A', vm_chain, '-i', vif, '-s', '!', vm_mac, '-j', 'DROP']) - # do not allow fake dhcp responses - util.pread2(['ebtables', '-A', vm_chain, '-i', vif, '-p', 'IPv4', '--ip-proto', 'udp', '--ip-dport', '68', '-j', 'DROP']) - # do not allow snooping of dhcp requests - util.pread2(['ebtables', '-A', vm_chain, '-o', vif, '-p', 'IPv4', '--ip-proto', 'udp', '--ip-dport', '67', '-j', 'DROP']) - except: - util.SMlog("Failed to program default ebtables antispoof rules for %s" % vm_chain) - return 'false' - - return 'true' - -@echo -def default_arp_antispoof(vm_chain, vifs, vm_ip, vm_mac): - if vm_mac == 'ff:ff:ff:ff:ff:ff': - util.SMlog("Ignoring since mac address is not valid") - return 'true' - - try: - util.pread2(['arptables', '-N', vm_chain]) - except: - try: - util.pread2(['arptables', '-F', vm_chain]) - except: - util.SMlog("Failed to create arptables rule, skipping") - return 'true' - - # note all rules for packets into the bridge (-i) precede all output rules (-o) - try: - for vif in vifs: - util.pread2(['arptables', '-I', 'FORWARD', '-i', vif, '-j', vm_chain]) - util.pread2(['arptables', '-A', 'FORWARD', '-o', vif, '-j', vm_chain]) - except: - util.SMlog("Failed to program default arptables rules in FORWARD chain vm=" + vm_chain) - return 'false' - - try: - for vif in vifs: - #accept arp replies into the bridge as long as the source mac and ips match the vm - util.pread2(['arptables', '-A', vm_chain, '-i', vif, '--opcode', 'Reply', '--source-mac', vm_mac, '--source-ip', vm_ip, '-j', 'ACCEPT']) - #accept any arp requests from this vm. In the future this can be restricted to deny attacks on hosts - #also important to restrict source ip and src mac in these requests as they can be used to update arp tables on destination - util.pread2(['arptables', '-A', vm_chain, '-i', vif, '--opcode', 'Request', '--source-mac', vm_mac, '--source-ip', vm_ip, '-j', 'RETURN']) - #accept any arp requests to this vm as long as the request is for this vm's ip - util.pread2(['arptables', '-A', vm_chain, '-o', vif, '--opcode', 'Request', '--destination-ip', vm_ip, '-j', 'ACCEPT']) - #accept any arp replies to this vm as long as the mac and ip matches - util.pread2(['arptables', '-A', vm_chain, '-o', vif, '--opcode', 'Reply', '--destination-mac', vm_mac, '--destination-ip', vm_ip, '-j', 'ACCEPT']) - util.pread2(['arptables', '-A', vm_chain, '-j', 'DROP']) - - except: - util.SMlog("Failed to program default arptables rules") - return 'false' - - return 'true' - -@echo -def default_network_rules_systemvm(session, args): - vm_name = args.pop('vmName') - try: - vm = session.xenapi.VM.get_by_name_label(vm_name) - if len(vm) != 1: - return 'false' - vm_rec = session.xenapi.VM.get_record(vm[0]) - vm_vifs = vm_rec.get('VIFs') - vifnums = [session.xenapi.VIF.get_record(vif).get('device') for vif in vm_vifs] - domid = vm_rec.get('domid') - except: - util.SMlog("### Failed to get domid or vif list for vm ##" + vm_name) - return 'false' - - if domid == '-1': - util.SMlog("### Failed to get domid for vm (-1): " + vm_name) - return 'false' - - vifs = ["vif" + domid + "." + v for v in vifnums] - #vm_name = '-'.join(vm_name.split('-')[:-1]) - vmchain = chain_name(vm_name) - - - delete_rules_for_vm_in_bridge_firewall_chain(vm_name) - - try: - util.pread2(['iptables', '-N', vmchain]) - except: - util.pread2(['iptables', '-F', vmchain]) - - allow_egress_traffic(session) - - for vif in vifs: - try: - util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', vif, '-j', vmchain]) - util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '4', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', vif, '-j', vmchain]) - util.pread2(['iptables', '-I', vmchain, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', vif, '-j', 'RETURN']) - except: - util.SMlog("Failed to program default rules") - return 'false' - - - util.pread2(['iptables', '-A', vmchain, '-j', 'ACCEPT']) - - if write_rule_log_for_vm(vm_name, '-1', '_ignore_', domid, '_initial_', '-1') == False: - util.SMlog("Failed to log default network rules for systemvm, ignoring") - return 'true' - - -@echo -def default_network_rules(session, args): - vm_name = args.pop('vmName') - vm_ip = args.pop('vmIP') - vm_id = args.pop('vmID') - vm_mac = args.pop('vmMAC') - - try: - vm = session.xenapi.VM.get_by_name_label(vm_name) - if len(vm) != 1: - util.SMlog("### Failed to get record for vm " + vm_name) - return 'false' - vm_rec = session.xenapi.VM.get_record(vm[0]) - domid = vm_rec.get('domid') - except: - util.SMlog("### Failed to get domid for vm " + vm_name) - return 'false' - if domid == '-1': - util.SMlog("### Failed to get domid for vm (-1): " + vm_name) - return 'false' - - vif = "vif" + domid + ".0" - tap = "tap" + domid + ".0" - vifs = [vif] - try: - util.pread2(['ifconfig', tap]) - vifs.append(tap) - except: - pass - - delete_rules_for_vm_in_bridge_firewall_chain(vm_name) - - - vmchain = chain_name(vm_name) - vmchain_egress = egress_chain_name(vm_name) - vmchain_default = chain_name_def(vm_name) - - destroy_ebtables_rules(vmchain) - - - try: - util.pread2(['iptables', '-N', vmchain]) - except: - util.pread2(['iptables', '-F', vmchain]) - - try: - util.pread2(['iptables', '-N', vmchain_egress]) - except: - util.pread2(['iptables', '-F', vmchain_egress]) - - try: - util.pread2(['iptables', '-N', vmchain_default]) - except: - util.pread2(['iptables', '-F', vmchain_default]) - - try: - for v in vifs: - util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain_default]) - util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '2', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-j', vmchain_default]) - util.pread2(['iptables', '-A', vmchain_default, '-m', 'state', '--state', 'RELATED,ESTABLISHED', '-j', 'ACCEPT']) - #allow dhcp - for v in vifs: - util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-p', 'udp', '--dport', '67', '--sport', '68', '-j', 'ACCEPT']) - util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-p', 'udp', '--dport', '68', '--sport', '67', '-j', 'ACCEPT']) - - #don't let vm spoof its ip address - for v in vifs: - util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip,'-p', 'udp', '--dport', '53', '-j', 'RETURN']) - util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', '!', vm_ip, '-j', 'DROP']) - util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '--destination', '!', vm_ip, '-j', 'DROP']) - util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip, '-j', vmchain_egress]) - - for v in vifs: - util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain]) - except: - util.SMlog("Failed to program default rules for vm " + vm_name) - return 'false' - - default_arp_antispoof(vmchain, vifs, vm_ip, vm_mac) - default_ebtables_antispoof_rules(vmchain, vifs, vm_ip, vm_mac) - - if write_rule_log_for_vm(vm_name, vm_id, vm_ip, domid, '_initial_', '-1', vm_mac) == False: - util.SMlog("Failed to log default network rules, ignoring") - - util.SMlog("Programmed default rules for vm " + vm_name) - return 'true' - -@echo -def check_domid_changed(session, vmName): - curr_domid = '-1' - try: - vm = session.xenapi.VM.get_by_name_label(vmName) - if len(vm) != 1: - util.SMlog("### Could not get record for vm ## " + vmName) - else: - vm_rec = session.xenapi.VM.get_record(vm[0]) - curr_domid = vm_rec.get('domid') - except: - util.SMlog("### Failed to get domid for vm ## " + vmName) - - - logfilename = "/var/run/cloud/" + vmName +".log" - if not os.path.exists(logfilename): - return ['-1', curr_domid] - - lines = (line.rstrip() for line in open(logfilename)) - - [_vmName,_vmID,_vmIP,old_domid,_signature,_seqno, _vmMac] = ['_', '-1', '_', '-1', '_', '-1', 'ff:ff:ff:ff:ff:ff'] - for line in lines: - try: - [_vmName,_vmID,_vmIP,old_domid,_signature,_seqno,_vmMac] = line.split(',') - except ValueError,v: - [_vmName,_vmID,_vmIP,old_domid,_signature,_seqno] = line.split(',') - break - - return [curr_domid, old_domid] - -@echo -def delete_rules_for_vm_in_bridge_firewall_chain(vmName): - vm_name = vmName - vmchain = chain_name_def(vm_name) - - delcmd = "iptables-save | grep '\-A BRIDGE-FIREWALL' | grep " + vmchain + " | sed 's/-A/-D/'" - delcmds = util.pread2(['/bin/bash', '-c', delcmd]).split('\n') - delcmds.pop() - for cmd in delcmds: - try: - dc = cmd.split(' ') - dc.insert(0, 'iptables') - dc.pop() - util.pread2(filter(None, dc)) - except: - util.SMlog("Ignoring failure to delete rules for vm " + vmName) - - -@echo -def network_rules_for_rebooted_vm(session, vmName): - vm_name = vmName - [curr_domid, old_domid] = check_domid_changed(session, vm_name) - - if curr_domid == old_domid: - return True - - if old_domid == '-1': - return True - - if curr_domid == '-1': - return True - - util.SMlog("Found a rebooted VM -- reprogramming rules for " + vm_name) - - delete_rules_for_vm_in_bridge_firewall_chain(vm_name) - if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-', 'l-'] ]: - default_network_rules_systemvm(session, {"vmName":vm_name}) - return True - - vif = "vif" + curr_domid + ".0" - tap = "tap" + curr_domid + ".0" - vifs = [vif] - try: - util.pread2(['ifconfig', tap]) - vifs.append(tap) - except: - pass - vmchain = chain_name(vm_name) - vmchain_default = chain_name_def(vm_name) - - for v in vifs: - util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain_default]) - util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '2', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-j', vmchain_default]) - - #change antispoof rule in vmchain - try: - delcmd = "iptables-save | grep '\-A " + vmchain_default + "' | grep physdev-in | sed 's/-A/-D/'" - delcmd2 = "iptables-save | grep '\-A " + vmchain_default + "' | grep physdev-out | sed 's/-A/-D/'" - inscmd = "iptables-save | grep '\-A " + vmchain_default + "' | grep physdev-in | grep vif | sed -r 's/vif[0-9]+.0/" + vif + "/' " - inscmd2 = "iptables-save| grep '\-A " + vmchain_default + "' | grep physdev-in | grep tap | sed -r 's/tap[0-9]+.0/" + tap + "/' " - inscmd3 = "iptables-save | grep '\-A " + vmchain_default + "' | grep physdev-out | grep vif | sed -r 's/vif[0-9]+.0/" + vif + "/' " - inscmd4 = "iptables-save| grep '\-A " + vmchain_default + "' | grep physdev-out | grep tap | sed -r 's/tap[0-9]+.0/" + tap + "/' " - - ipts = [] - for cmd in [delcmd, delcmd2, inscmd, inscmd2, inscmd3, inscmd4]: - cmds = util.pread2(['/bin/bash', '-c', cmd]).split('\n') - cmds.pop() - for c in cmds: - ipt = c.split(' ') - ipt.insert(0, 'iptables') - ipt.pop() - ipts.append(ipt) - - for ipt in ipts: - try: - util.pread2(filter(None,ipt)) - except: - util.SMlog("Failed to rewrite antispoofing rules for vm " + vm_name) - - util.pread2(['/bin/bash', '-c', 'iptables -D ' + vmchain_default + " -j " + vmchain]) - util.pread2(['/bin/bash', '-c', 'iptables -A ' + vmchain_default + " -j " + vmchain]) - except: - util.SMlog("No rules found for vm " + vm_name) - - destroy_ebtables_rules(vmchain) - destroy_arptables_rules(vmchain) - [vm_ip, vm_mac] = get_vm_mac_ip_from_log(vmchain) - default_arp_antispoof(vmchain, vifs, vm_ip, vm_mac) - default_ebtables_antispoof_rules(vmchain, vifs, vm_ip, vm_mac) - rewrite_rule_log_for_vm(vm_name, curr_domid) - return True - -def rewrite_rule_log_for_vm(vm_name, new_domid): - logfilename = "/var/run/cloud/" + vm_name +".log" - if not os.path.exists(logfilename): - return - lines = (line.rstrip() for line in open(logfilename)) - - [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = ['_', '-1', '_', '-1', '_', '-1','ff:ff:ff:ff:ff:ff'] - for line in lines: - try: - [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = line.split(',') - break - except ValueError,v: - [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',') - - write_rule_log_for_vm(_vmName, _vmID, _vmIP, new_domid, _signature, '-1', _vmMac) - -def get_rule_log_for_vm(session, vmName): - vm_name = vmName; - logfilename = "/var/run/cloud/" + vm_name +".log" - if not os.path.exists(logfilename): - return '' - - lines = (line.rstrip() for line in open(logfilename)) - - [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = ['_', '-1', '_', '-1', '_', '-1', 'ff:ff:ff:ff:ff:ff'] - for line in lines: - try: - [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = line.split(',') - break - except ValueError,v: - [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',') - - return ','.join([_vmName, _vmID, _vmIP, _domID, _signature, _seqno]) - -@echo -def get_vm_mac_ip_from_log(vm_name): - [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = ['_', '-1', '0.0.0.0', '-1', '_', '-1','ff:ff:ff:ff:ff:ff'] - logfilename = "/var/run/cloud/" + vm_name +".log" - if not os.path.exists(logfilename): - return ['_', '_'] - - lines = (line.rstrip() for line in open(logfilename)) - for line in lines: - try: - [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = line.split(',') - break - except ValueError,v: - [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',') - - return [ _vmIP, _vmMac] - -@echo -def get_rule_logs_for_vms(session, args): - host_uuid = args.pop('host_uuid') - try: - thishost = session.xenapi.host.get_by_uuid(host_uuid) - hostrec = session.xenapi.host.get_record(thishost) - vms = hostrec.get('resident_VMs') - except: - util.SMlog("Failed to get host from uuid " + host_uuid) - return ' ' - - result = [] - try: - for name in [session.xenapi.VM.get_name_label(x) for x in vms]: - if 1 not in [ name.startswith(c) for c in ['r-', 's-', 'v-', 'i-', 'l-'] ]: - continue - network_rules_for_rebooted_vm(session, name) - if name.startswith('i-'): - log = get_rule_log_for_vm(session, name) - result.append(log) - except: - util.SMlog("Failed to get rule logs, better luck next time!") - - return ";".join(result) - -@echo -def cleanup_rules_for_dead_vms(session): - try: - vms = session.xenapi.VM.get_all() - cleaned = 0 - for vm_name in [session.xenapi.VM.get_name_label(x) for x in vms]: - if 1 in [ vm_name.startswith(c) for c in ['r-', 'i-', 's-', 'v-', 'l-'] ]: - vm = session.xenapi.VM.get_by_name_label(vm_name) - if len(vm) != 1: - continue - vm_rec = session.xenapi.VM.get_record(vm[0]) - state = vm_rec.get('power_state') - if state != 'Running' and state != 'Paused': - util.SMlog("vm " + vm_name + " is not running, cleaning up") - destroy_network_rules_for_vm(session, {'vmName':vm_name}) - cleaned = cleaned+1 - - util.SMlog("Cleaned up rules for " + str(cleaned) + " vms") - except: - util.SMlog("Failed to cleanup rules for dead vms!") - - -@echo -def cleanup_rules(session, args): - instance = args.get('instance') - if not instance: - instance = 'VM' - resident_vms = [] - try: - hostname = util.pread2(['/bin/bash', '-c', 'hostname']).split('\n') - if len(hostname) < 1: - raise Exception('Could not find hostname of this host') - thishost = session.xenapi.host.get_by_name_label(hostname[0]) - if len(thishost) < 1: - raise Exception("Could not find host record from hostname %s of this host"%hostname[0]) - hostrec = session.xenapi.host.get_record(thishost[0]) - vms = hostrec.get('resident_VMs') - resident_vms = [session.xenapi.VM.get_name_label(x) for x in vms] - util.SMlog('cleanup_rules: found %s resident vms on this host %s' % (len(resident_vms)-1, hostname[0])) - - chainscmd = "iptables-save | grep '^:' | awk '{print $1}' | cut -d':' -f2 | sed 's/-def/-%s/'| sed 's/-eg//' | sort|uniq" % instance - chains = util.pread2(['/bin/bash', '-c', chainscmd]).split('\n') - vmchains = [ch for ch in chains if 1 in [ ch.startswith(c) for c in ['r-', 'i-', 's-', 'v-', 'l-']]] - util.SMlog('cleanup_rules: found %s iptables chains for vms on this host %s' % (len(vmchains), hostname[0])) - cleaned = 0 - cleanup = [] - for chain in vmchains: - vm = session.xenapi.VM.get_by_name_label(chain) - if len(vm) != 1: - vm = session.xenapi.VM.get_by_name_label(chain + "-untagged") - if len(vm) != 1: - util.SMlog("chain " + chain + " does not correspond to a vm, cleaning up") - cleanup.append(chain) - continue - if chain not in resident_vms: - util.SMlog("vm " + chain + " is not running, cleaning up") - cleanup.append(chain) - - for vm_name in cleanup: - destroy_network_rules_for_vm(session, {'vmName':vm_name}) - - util.SMlog("Cleaned up rules for " + str(len(cleanup)) + " chains") - return str(len(cleanup)) - except Exception, ex: - util.SMlog("Failed to cleanup rules, reason= " + str(ex)) - return '-1'; - -@echo -def check_rule_log_for_vm(vmName, vmID, vmIP, domID, signature, seqno): - vm_name = vmName; - logfilename = "/var/run/cloud/" + vm_name +".log" - if not os.path.exists(logfilename): - util.SMlog("Failed to find logfile %s" %logfilename) - return [True, True, True] - - lines = (line.rstrip() for line in open(logfilename)) - - [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = ['_', '-1', '_', '-1', '_', '-1', 'ff:ff:ff:ff:ff:ff'] - try: - for line in lines: - try: - [_vmName,_vmID,_vmIP,_domID,_signature,_seqno, _vmMac] = line.split(',') - except ValueError,v: - [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',') - break - except: - util.SMlog("Failed to parse log file for vm " + vmName) - remove_rule_log_for_vm(vmName) - return [True, True, True] - - reprogramDefault = False - if (domID != _domID) or (vmID != _vmID) or (vmIP != _vmIP): - util.SMlog("Change in default info set of vm %s" % vmName) - return [True, True, True] - else: - util.SMlog("No change in default info set of vm %s" % vmName) - - reprogramChain = False - rewriteLog = True - if (int(seqno) > int(_seqno)): - if (_signature != signature): - reprogramChain = True - util.SMlog("Seqno increased from %s to %s: reprogamming "\ - "ingress rules for vm %s" % (_seqno, seqno, vmName)) - else: - util.SMlog("Seqno increased from %s to %s: but no change "\ - "in signature for vm: skip programming ingress "\ - "rules %s" % (_seqno, seqno, vmName)) - elif (int(seqno) < int(_seqno)): - util.SMlog("Seqno decreased from %s to %s: ignoring these "\ - "ingress rules for vm %s" % (_seqno, seqno, vmName)) - rewriteLog = False - elif (signature != _signature): - util.SMlog("Seqno %s stayed the same but signature changed from "\ - "%s to %s for vm %s" % (seqno, _signature, signature, vmName)) - rewriteLog = True - reprogramChain = True - else: - util.SMlog("Seqno and signature stayed the same: %s : ignoring these "\ - "ingress rules for vm %s" % (seqno, vmName)) - rewriteLog = False - - return [reprogramDefault, reprogramChain, rewriteLog] - - -@echo -def write_rule_log_for_vm(vmName, vmID, vmIP, domID, signature, seqno, vmMac='ff:ff:ff:ff:ff:ff'): - vm_name = vmName - logfilename = "/var/run/cloud/" + vm_name +".log" - util.SMlog("Writing log to " + logfilename) - logf = open(logfilename, 'w') - output = ','.join([vmName, vmID, vmIP, domID, signature, seqno, vmMac]) - result = True - try: - logf.write(output) - logf.write('\n') - except: - util.SMlog("Failed to write to rule log file " + logfilename) - result = False - - logf.close() - - return result - -@echo -def remove_rule_log_for_vm(vmName): - vm_name = vmName - logfilename = "/var/run/cloud/" + vm_name +".log" - - result = True - try: - os.remove(logfilename) - except: - util.SMlog("Failed to delete rule log file " + logfilename) - result = False - - return result - -@echo -def inflate_rules (zipped): - return zlib.decompress(base64.b64decode(zipped)) - -@echo -def cache_ipset_keyword(): - tmpname = 'ipsetqzvxtmp' - try: - util.pread2(['/bin/bash', '-c', 'ipset -N ' + tmpname + ' iptreemap']) - except: - util.pread2(['/bin/bash', '-c', 'ipset -F ' + tmpname]) - - try: - util.pread2(['/bin/bash', '-c', 'iptables -A INPUT -m set --set ' + tmpname + ' src' + ' -j ACCEPT']) - util.pread2(['/bin/bash', '-c', 'iptables -D INPUT -m set --set ' + tmpname + ' src' + ' -j ACCEPT']) - keyword = 'set' - except: - keyword = 'match-set' - - try: - util.pread2(['/bin/bash', '-c', 'ipset -X ' + tmpname]) - except: - pass - - cachefile = "/var/cache/cloud/ipset.keyword" - util.SMlog("Writing ipset keyword to " + cachefile) - cachef = open(cachefile, 'w') - try: - cachef.write(keyword) - cachef.write('\n') - except: - util.SMlog("Failed to write to cache file " + cachef) - - cachef.close() - return keyword - -@echo -def get_ipset_keyword(): - cachefile = "/var/cache/cloud/ipset.keyword" - keyword = 'match-set' - - if not os.path.exists(cachefile): - util.SMlog("Failed to find ipset keyword cachefile %s" %cachefile) - keyword = cache_ipset_keyword() - else: - lines = (line.rstrip() for line in open(cachefile)) - for line in lines: - keyword = line - break - - return keyword - -@echo -def network_rules(session, args): - try: - vm_name = args.get('vmName') - vm_ip = args.get('vmIP') - vm_id = args.get('vmID') - vm_mac = args.get('vmMAC') - signature = args.pop('signature') - seqno = args.pop('seqno') - deflated = 'false' - if 'deflated' in args: - deflated = args.pop('deflated') - - try: - vm = session.xenapi.VM.get_by_name_label(vm_name) - if len(vm) != 1: - util.SMlog("### Could not get record for vm ## " + vm_name) - return 'false' - vm_rec = session.xenapi.VM.get_record(vm[0]) - domid = vm_rec.get('domid') - except: - util.SMlog("### Failed to get domid for vm ## " + vm_name) - return 'false' - if domid == '-1': - util.SMlog("### Failed to get domid for vm (-1): " + vm_name) - return 'false' - - vif = "vif" + domid + ".0" - tap = "tap" + domid + ".0" - vifs = [vif] - try: - util.pread2(['ifconfig', tap]) - vifs.append(tap) - except: - pass - - - reason = 'seqno_change_or_sig_change' - [reprogramDefault, reprogramChain, rewriteLog] = \ - check_rule_log_for_vm (vm_name, vm_id, vm_ip, domid, signature, seqno) - - if not reprogramDefault and not reprogramChain: - util.SMlog("No changes detected between current state and received state") - reason = 'seqno_same_sig_same' - if rewriteLog: - reason = 'seqno_increased_sig_same' - write_rule_log_for_vm(vm_name, vm_id, vm_ip, domid, signature, seqno, vm_mac) - util.SMlog("Programming network rules for vm %s seqno=%s signature=%s guestIp=%s,"\ - " do nothing, reason=%s" % (vm_name, seqno, signature, vm_ip, reason)) - return 'true' - - if not reprogramChain: - util.SMlog("###Not programming any ingress rules since no changes detected?") - return 'true' - - if reprogramDefault: - util.SMlog("Change detected in vmId or vmIp or domId, resetting default rules") - default_network_rules(session, args) - reason = 'domid_change' - - rules = args.pop('rules') - if deflated.lower() == 'true': - rules = inflate_rules (rules) - keyword = '--' + get_ipset_keyword() - lines = rules.split(' ') - - util.SMlog("Programming network rules for vm %s seqno=%s numrules=%s signature=%s guestIp=%s,"\ - " update iptables, reason=%s" % (vm_name, seqno, len(lines), signature, vm_ip, reason)) - - cmds = [] - egressrules = 0 - for line in lines: - tokens = line.split(':') - if len(tokens) != 5: - continue - type = tokens[0] - protocol = tokens[1] - start = tokens[2] - end = tokens[3] - cidrs = tokens.pop(); - ips = cidrs.split(",") - ips.pop() - allow_any = False - - if type == 'E': - vmchain = egress_chain_name(vm_name) - action = "RETURN" - direction = "dst" - egressrules = egressrules + 1 - else: - vmchain = chain_name(vm_name) - action = "ACCEPT" - direction = "src" - if '0.0.0.0/0' in ips: - i = ips.index('0.0.0.0/0') - del ips[i] - allow_any = True - range = start + ":" + end - if ips: - ipsetname = vmchain + "_" + protocol + "_" + start + "_" + end - if start == "-1": - ipsetname = vmchain + "_" + protocol + "_any" - - if ipset(ipsetname, protocol, start, end, ips) == False: - util.SMlog(" failed to create ipset for rule " + str(tokens)) - - if protocol == 'all': - iptables = ['iptables', '-I', vmchain, '-m', 'state', '--state', 'NEW', '-m', 'set', keyword, ipsetname, direction, '-j', action] - elif protocol != 'icmp': - iptables = ['iptables', '-I', vmchain, '-p', protocol, '-m', protocol, '--dport', range, '-m', 'state', '--state', 'NEW', '-m', 'set', keyword, ipsetname, direction, '-j', action] - else: - range = start + "/" + end - if start == "-1": - range = "any" - iptables = ['iptables', '-I', vmchain, '-p', 'icmp', '--icmp-type', range, '-m', 'set', keyword, ipsetname, direction, '-j', action] - - cmds.append(iptables) - util.SMlog(iptables) - - if allow_any and protocol != 'all': - if protocol != 'icmp': - iptables = ['iptables', '-I', vmchain, '-p', protocol, '-m', protocol, '--dport', range, '-m', 'state', '--state', 'NEW', '-j', action] - else: - range = start + "/" + end - if start == "-1": - range = "any" - iptables = ['iptables', '-I', vmchain, '-p', 'icmp', '--icmp-type', range, '-j', action] - cmds.append(iptables) - util.SMlog(iptables) - - vmchain = chain_name(vm_name) - util.pread2(['iptables', '-F', vmchain]) - egress_vmchain = egress_chain_name(vm_name) - util.pread2(['iptables', '-F', egress_vmchain]) - - for cmd in cmds: - util.pread2(cmd) - - if egressrules == 0 : - util.pread2(['iptables', '-A', egress_vmchain, '-j', 'RETURN']) - else: - util.pread2(['iptables', '-A', egress_vmchain, '-j', 'DROP']) - - util.pread2(['iptables', '-A', vmchain, '-j', 'DROP']) - - if write_rule_log_for_vm(vm_name, vm_id, vm_ip, domid, signature, seqno, vm_mac) == False: - return 'false' - - return 'true' - except: - util.SMlog("Failed to network rule !") - -@echo -def checkRouter(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/usr/lib/xcp/bin/getRouterStatus.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - except: - util.SMlog(" check router status fail! ") - txt = '' - - return txt - -@echo -def bumpUpPriority(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/usr/lib/xcp/bin/bumpUpPriority.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - txt = 'success' - except: - util.SMlog("bump up priority fail! ") - txt = '' - - return txt - -@echo -def setDNATRule(session, args): - add = args["add"] - if add == "false": - util.pread2(["iptables", "-t", "nat", "-F"]) - else: - ip = args["ip"] - port = args["port"] - util.pread2(["iptables", "-t", "nat", "-F"]) - util.pread2(["iptables", "-t", "nat", "-A", "PREROUTING", "-i", "xenbr0", "-p", "tcp", "--dport", port, "-m", "state", "--state", "NEW", "-j", "DNAT", "--to-destination", ip +":443"]) - return "" - -@echo -def createISOVHD(session, args): - # Should not create the VDI if the systemvm.iso does not exist - if not os.path.exists('/usr/share/xcp/packages/iso/systemvm.iso'): - return "Failed" - #hack for XCP on ubuntu 12.04, as can't attach iso to a vm - vdis = session.xenapi.VDI.get_by_name_label("systemvm-vdi"); - util.SMlog(vdis) - if len(vdis) > 0: - vdi_record = session.xenapi.VDI.get_record(vdis[0]) - vdi_uuid = vdi_record['uuid'] - return vdi_uuid - localsrUUid = args['uuid']; - sr = session.xenapi.SR.get_by_uuid(localsrUUid) - data = {'name_label': "systemvm-vdi", - 'SR': sr, - 'virtual_size': '50000000', - 'type': 'user', - 'sharable':False, - 'read_only':False, - 'other_config':{}, - } - vdi = session.xenapi.VDI.create(data); - vdi_record = session.xenapi.VDI.get_record(vdi) - - vdi_uuid = vdi_record['uuid'] - - vms = session.xenapi.VM.get_all() - ctrldom = None - for vm in vms: - dom0 = session.xenapi.VM.get_is_control_domain(vm) - if dom0 is False: - continue - else: - ctrldom = vm - - if ctrldom is None: - return "Failed" - - vbds = session.xenapi.VM.get_VBDs(ctrldom) - if len(vbds) == 0: - vbd = session.xenapi.VBD.create({"VDI": vdi, "VM": ctrldom, "type":"Disk", "device": "xvda4", "bootable": False, "mode": "RW", "userdevice": "4", "empty":False, - "other_config":{}, "qos_algorithm_type":"", "qos_algorithm_params":{}}) - else: - vbd = vbds[0] - - vbdr = session.xenapi.VBD.get_record(vbd) - if session.xenapi.VBD.get_currently_attached(vbd) is False: - session.xenapi.VBD.plug(vbd) - vbdr = session.xenapi.VBD.get_record(vbd) - util.pread2(["dd", "if=/usr/share/xcp/packages/iso/systemvm.iso", "of=" + "/dev/" + vbdr["device"]]) - session.xenapi.VBD.unplug(vbd) - session.xenapi.VBD.destroy(vbd) - return vdi_uuid - -@echo -def routerProxy(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/usr/lib/xcp/bin/router_proxy.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - if txt is None or len(txt) == 0 : - txt = 'success' - except: - util.SMlog("routerProxy command " + sargs + " failed " ) - txt = '' - - return txt - -@echo -def getDomRVersion(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/usr/lib/xcp/bin/getDomRVersion.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - except: - util.SMlog(" get domR version fail! ") - txt = '' - - return txt - -if __name__ == "__main__": - XenAPIPlugin.dispatch({"pingtest": pingtest, "setup_iscsi":setup_iscsi, "gethostvmstats": gethostvmstats, - "getgateway": getgateway, "preparemigration": preparemigration, - "setIptables": setIptables, "pingdomr": pingdomr, "pingxenserver": pingxenserver, - "ipassoc": ipassoc, "savePassword": savePassword, - "saveDhcpEntry": saveDhcpEntry, "setFirewallRule": setFirewallRule, - "setLoadBalancerRule": setLoadBalancerRule, "createFile": createFile, "deleteFile": deleteFile, - "networkUsage": networkUsage, "network_rules":network_rules, - "can_bridge_firewall":can_bridge_firewall, "default_network_rules":default_network_rules, - "destroy_network_rules_for_vm":destroy_network_rules_for_vm, - "default_network_rules_systemvm":default_network_rules_systemvm, - "get_rule_logs_for_vms":get_rule_logs_for_vms, - "setLinkLocalIP":setLinkLocalIP, "lt2p_vpn":lt2p_vpn, - "cleanup_rules":cleanup_rules, "checkRouter":checkRouter, - "bumpUpPriority":bumpUpPriority, "getDomRVersion":getDomRVersion, - "kill_copy_process":kill_copy_process, - "createISOVHD":createISOVHD, - "routerProxy":routerProxy, - "setDNATRule":setDNATRule}) diff --git a/scripts/vm/hypervisor/xenserver/xcposs/vmopsSnapshot b/scripts/vm/hypervisor/xenserver/xcposs/vmopsSnapshot deleted file mode 100644 index 53f31a99eed..00000000000 --- a/scripts/vm/hypervisor/xenserver/xcposs/vmopsSnapshot +++ /dev/null @@ -1,601 +0,0 @@ -#!/usr/bin/python -# 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. - -# Version @VERSION@ -# -# A plugin for executing script needed by vmops cloud - -import os, sys, time -import XenAPIPlugin -sys.path.append("/usr/lib/xcp/sm/") -import SR, VDI, SRCommand, util, lvutil -from util import CommandException -import vhdutil -import shutil -import lvhdutil -import errno -import subprocess -import xs_errors -import cleanup -import stat -import random - -VHD_UTIL = 'vhd-util' -VHD_PREFIX = 'VHD-' -CLOUD_DIR = '/run/cloud_mount' - -def echo(fn): - def wrapped(*v, **k): - name = fn.__name__ - util.SMlog("#### VMOPS enter %s ####" % name ) - res = fn(*v, **k) - util.SMlog("#### VMOPS exit %s ####" % name ) - return res - return wrapped - - -@echo -def create_secondary_storage_folder(session, args): - local_mount_path = None - - util.SMlog("create_secondary_storage_folder, args: " + str(args)) - - try: - try: - # Mount the remote resource folder locally - remote_mount_path = args["remoteMountPath"] - local_mount_path = os.path.join(CLOUD_DIR, util.gen_uuid()) - mount(remote_mount_path, local_mount_path) - - # Create the new folder - new_folder = local_mount_path + "/" + args["newFolder"] - if not os.path.isdir(new_folder): - current_umask = os.umask(0) - os.makedirs(new_folder) - os.umask(current_umask) - except OSError, (errno, strerror): - errMsg = "create_secondary_storage_folder failed: errno: " + str(errno) + ", strerr: " + strerror - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - except: - errMsg = "create_secondary_storage_folder failed." - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - finally: - if local_mount_path != None: - # Unmount the local folder - umount(local_mount_path) - # Remove the local folder - os.system("rmdir " + local_mount_path) - - return "1" - -@echo -def delete_secondary_storage_folder(session, args): - local_mount_path = None - - util.SMlog("delete_secondary_storage_folder, args: " + str(args)) - - try: - try: - # Mount the remote resource folder locally - remote_mount_path = args["remoteMountPath"] - local_mount_path = os.path.join(CLOUD_DIR, util.gen_uuid()) - mount(remote_mount_path, local_mount_path) - - # Delete the specified folder - folder = local_mount_path + "/" + args["folder"] - if os.path.isdir(folder): - os.system("rm -f " + folder + "/*") - os.system("rmdir " + folder) - except OSError, (errno, strerror): - errMsg = "delete_secondary_storage_folder failed: errno: " + str(errno) + ", strerr: " + strerror - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - except: - errMsg = "delete_secondary_storage_folder failed." - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - finally: - if local_mount_path != None: - # Unmount the local folder - umount(local_mount_path) - # Remove the local folder - os.system("rmdir " + local_mount_path) - - return "1" - -@echo -def post_create_private_template(session, args): - local_mount_path = None - try: - try: - # get local template folder - templatePath = args["templatePath"] - local_mount_path = os.path.join(CLOUD_DIR, util.gen_uuid()) - mount(templatePath, local_mount_path) - # Retrieve args - filename = args["templateFilename"] - name = args["templateName"] - description = args["templateDescription"] - checksum = args["checksum"] - file_size = args["size"] - virtual_size = args["virtualSize"] - template_id = args["templateId"] - - # Create the template.properties file - template_properties_install_path = local_mount_path + "/template.properties" - f = open(template_properties_install_path, "w") - f.write("filename=" + filename + "\n") - f.write("vhd=true\n") - f.write("id=" + template_id + "\n") - f.write("vhd.filename=" + filename + "\n") - f.write("public=false\n") - f.write("uniquename=" + name + "\n") - f.write("vhd.virtualsize=" + virtual_size + "\n") - f.write("virtualsize=" + virtual_size + "\n") - f.write("checksum=" + checksum + "\n") - f.write("hvm=true\n") - f.write("description=" + description + "\n") - f.write("vhd.size=" + str(file_size) + "\n") - f.write("size=" + str(file_size) + "\n") - f.close() - util.SMlog("Created template.properties file") - - # Set permissions - permissions = stat.S_IREAD | stat.S_IWRITE | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH | stat.S_IWOTH - os.chmod(template_properties_install_path, permissions) - util.SMlog("Set permissions on template and template.properties") - - except: - errMsg = "post_create_private_template failed." - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - - finally: - if local_mount_path != None: - # Unmount the local folder - umount(local_mount_path) - # Remove the local folder - os.system("rmdir " + local_mount_path) - return "1" - -def isfile(path, isISCSI): - errMsg = '' - exists = True - if isISCSI: - exists = checkVolumeAvailablility(path) - else: - exists = os.path.isfile(path) - - if not exists: - errMsg = "File " + path + " does not exist." - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - return errMsg - -def copyfile(fromFile, toFile, isISCSI): - util.SMlog("Starting to copy " + fromFile + " to " + toFile) - errMsg = '' - try: - cmd = ['dd', 'if=' + fromFile, 'of=' + toFile, 'bs=4M'] - txt = util.pread2(cmd) - except: - try: - os.system("rm -f " + toFile) - except: - txt = '' - txt = '' - errMsg = "Error while copying " + fromFile + " to " + toFile + " in secondary storage" - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - - util.SMlog("Successfully copied " + fromFile + " to " + toFile) - return errMsg - -def chdir(path): - try: - os.chdir(path) - except OSError, (errno, strerror): - errMsg = "Unable to chdir to " + path + " because of OSError with errno: " + str(errno) + " and strerr: " + strerror - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - util.SMlog("Chdired to " + path) - return - -def scanParent(path): - # Do a scan for the parent for ISCSI volumes - # Note that the parent need not be visible on the XenServer - parentUUID = '' - try: - lvName = os.path.basename(path) - dirname = os.path.dirname(path) - vgName = os.path.basename(dirname) - vhdInfo = vhdutil.getVHDInfoLVM(lvName, lvhdutil.extractUuid, vgName) - parentUUID = vhdInfo.parentUuid - except: - errMsg = "Could not get vhd parent of " + path - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - return parentUUID - -def getParent(path, isISCSI): - parentUUID = '' - try : - if isISCSI: - parentUUID = vhdutil.getParent(path, lvhdutil.extractUuid) - else: - parentUUID = vhdutil.getParent(path, cleanup.FileVDI.extractUuid) - except: - errMsg = "Could not get vhd parent of " + path - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - return parentUUID - -def getParentOfSnapshot(snapshotUuid, primarySRPath, isISCSI): - snapshotVHD = getVHD(snapshotUuid, isISCSI) - snapshotPath = os.path.join(primarySRPath, snapshotVHD) - - baseCopyUuid = '' - if isISCSI: - checkVolumeAvailablility(snapshotPath) - baseCopyUuid = scanParent(snapshotPath) - else: - baseCopyUuid = getParent(snapshotPath, isISCSI) - - util.SMlog("Base copy of snapshotUuid: " + snapshotUuid + " is " + baseCopyUuid) - return baseCopyUuid - -def setParent(parent, child): - try: - cmd = [VHD_UTIL, "modify", "-p", parent, "-n", child] - txt = util.pread2(cmd) - except: - errMsg = "Unexpected error while trying to set parent of " + child + " to " + parent - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - util.SMlog("Successfully set parent of " + child + " to " + parent) - return - -def rename(originalVHD, newVHD): - try: - os.rename(originalVHD, newVHD) - except OSError, (errno, strerror): - errMsg = "OSError while renaming " + origiinalVHD + " to " + newVHD + "with errno: " + str(errno) + " and strerr: " + strerror - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - return - -def makedirs(path): - if not os.path.isdir(path): - try: - os.makedirs(path) - except OSError, (errno, strerror): - umount(path) - if os.path.isdir(path): - return - errMsg = "OSError while creating " + path + " with errno: " + str(errno) + " and strerr: " + strerror - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - return - -def mount(remoteDir, localDir): - makedirs(localDir) - options = "soft,tcp,timeo=133,retrans=1" - try: - cmd = ['mount', '-o', options, remoteDir, localDir] - txt = util.pread2(cmd) - except: - txt = '' - errMsg = "Unexpected error while trying to mount " + remoteDir + " to " + localDir - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - util.SMlog("Successfully mounted " + remoteDir + " to " + localDir) - - return - -def umount(localDir): - try: - cmd = ['umount', localDir] - util.pread2(cmd) - except CommandException: - errMsg = "CommandException raised while trying to umount " + localDir - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - - util.SMlog("Successfully unmounted " + localDir) - return - -def mountSnapshotsDir(secondaryStorageMountPath, localMountPointPath, path): - # The aim is to mount secondaryStorageMountPath on - # And create / dir on it, if it doesn't exist already. - # Assuming that secondaryStorageMountPath exists remotely - - # Just mount secondaryStorageMountPath//SecondaryStorageHost/ everytime - # Never unmount. - # path is like "snapshots/account/volumeId", we mount secondary_storage:/snapshots - relativeDir = path.split("/")[0] - restDir = "/".join(path.split("/")[1:]) - snapshotsDir = os.path.join(secondaryStorageMountPath, relativeDir) - - makedirs(localMountPointPath) - # if something is not mounted already on localMountPointPath, - # mount secondaryStorageMountPath on localMountPath - if os.path.ismount(localMountPointPath): - # There is more than one secondary storage per zone. - # And we are mounting each sec storage under a zone-specific directory - # So two secondary storage snapshot dirs will never get mounted on the same point on the same XenServer. - util.SMlog("The remote snapshots directory has already been mounted on " + localMountPointPath) - else: - mount(snapshotsDir, localMountPointPath) - - # Create accountId/instanceId dir on localMountPointPath, if it doesn't exist - backupsDir = os.path.join(localMountPointPath, restDir) - makedirs(backupsDir) - return backupsDir - -def unmountAll(path): - try: - for dir in os.listdir(path): - if dir.isdigit(): - util.SMlog("Unmounting Sub-Directory: " + dir) - localMountPointPath = os.path.join(path, dir) - umount(localMountPointPath) - except: - util.SMlog("Ignoring the error while trying to unmount the snapshots dir") - -@echo -def unmountSnapshotsDir(session, args): - dcId = args['dcId'] - localMountPointPath = os.path.join(CLOUD_DIR, dcId) - localMountPointPath = os.path.join(localMountPointPath, "snapshots") - unmountAll(localMountPointPath) - try: - umount(localMountPointPath) - except: - util.SMlog("Ignoring the error while trying to unmount the snapshots dir.") - - return "1" - -def getPrimarySRPath(session, primaryStorageSRUuid, isISCSI): - sr = session.xenapi.SR.get_by_uuid(primaryStorageSRUuid) - srrec = session.xenapi.SR.get_record(sr) - srtype = srrec["type"] - if srtype == "file": - pbd = session.xenapi.SR.get_PBDs(sr)[0] - pbdrec = session.xenapi.PBD.get_record(pbd) - primarySRPath = pbdrec["device_config"]["location"] - return primarySRPath - elif isISCSI: - primarySRDir = lvhdutil.VG_PREFIX + primaryStorageSRUuid - return os.path.join(lvhdutil.VG_LOCATION, primarySRDir) - else: - return os.path.join(SR.MOUNT_BASE, primaryStorageSRUuid) - -def getBackupVHD(UUID): - return UUID + '.' + SR.DEFAULT_TAP - -def getVHD(UUID, isISCSI): - if isISCSI: - return VHD_PREFIX + UUID - else: - return UUID + '.' + SR.DEFAULT_TAP - -def getIsTrueString(stringValue): - booleanValue = False - if (stringValue and stringValue == 'true'): - booleanValue = True - return booleanValue - -def makeUnavailable(uuid, primarySRPath, isISCSI): - if not isISCSI: - return - VHD = getVHD(uuid, isISCSI) - path = os.path.join(primarySRPath, VHD) - manageAvailability(path, '-an') - return - -def manageAvailability(path, value): - if path.__contains__("/var/run/sr-mount"): - return - util.SMlog("Setting availability of " + path + " to " + value) - try: - cmd = ['/usr/sbin/lvchange', value, path] - util.pread2(cmd) - except: #CommandException, (rc, cmdListStr, stderr): - #errMsg = "CommandException thrown while executing: " + cmdListStr + " with return code: " + str(rc) + " and stderr: " + stderr - errMsg = "Unexpected exception thrown by lvchange" - util.SMlog(errMsg) - if value == "-ay": - # Raise an error only if we are trying to make it available. - # Just warn if we are trying to make it unavailable after the - # snapshot operation is done. - raise xs_errors.XenError(errMsg) - return - - -def checkVolumeAvailablility(path): - try: - if not isVolumeAvailable(path): - # The VHD file is not available on XenSever. The volume is probably - # inactive or detached. - # Do lvchange -ay to make it available on XenServer - manageAvailability(path, '-ay') - except: - errMsg = "Could not determine status of ISCSI path: " + path - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - - success = False - i = 0 - while i < 6: - i = i + 1 - # Check if the vhd is actually visible by checking for the link - # set isISCSI to true - success = isVolumeAvailable(path) - if success: - util.SMlog("Made vhd: " + path + " available and confirmed that it is visible") - break - - # Sleep for 10 seconds before checking again. - time.sleep(10) - - # If not visible within 1 min fail - if not success: - util.SMlog("Could not make vhd: " + path + " available despite waiting for 1 minute. Does it exist?") - - return success - -def isVolumeAvailable(path): - # Check if iscsi volume is available on this XenServer. - status = "0" - try: - p = subprocess.Popen(["/bin/bash", "-c", "if [ -L " + path + " ]; then echo 1; else echo 0;fi"], stdout=subprocess.PIPE) - status = p.communicate()[0].strip("\n") - except: - errMsg = "Could not determine status of ISCSI path: " + path - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - - return (status == "1") - -def getVhdParent(session, args): - util.SMlog("getParent with " + str(args)) - primaryStorageSRUuid = args['primaryStorageSRUuid'] - snapshotUuid = args['snapshotUuid'] - isISCSI = getIsTrueString(args['isISCSI']) - - primarySRPath = getPrimarySRPath(session, primaryStorageSRUuid, isISCSI) - util.SMlog("primarySRPath: " + primarySRPath) - - baseCopyUuid = getParentOfSnapshot(snapshotUuid, primarySRPath, isISCSI) - - return baseCopyUuid - - -def backupSnapshot(session, args): - util.SMlog("Called backupSnapshot with " + str(args)) - primaryStorageSRUuid = args['primaryStorageSRUuid'] - secondaryStorageMountPath = args['secondaryStorageMountPath'] - snapshotUuid = args['snapshotUuid'] - prevBackupUuid = args['prevBackupUuid'] - backupUuid = args['backupUuid'] - isISCSI = getIsTrueString(args['isISCSI']) - path = args['path'] - localMountPoint = args['localMountPoint'] - primarySRPath = getPrimarySRPath(session, primaryStorageSRUuid, isISCSI) - util.SMlog("primarySRPath: " + primarySRPath) - - baseCopyUuid = getParentOfSnapshot(snapshotUuid, primarySRPath, isISCSI) - baseCopyVHD = getVHD(baseCopyUuid, isISCSI) - baseCopyPath = os.path.join(primarySRPath, baseCopyVHD) - util.SMlog("Base copy path: " + baseCopyPath) - - - # Mount secondary storage mount path on XenServer along the path - # /var/run/sr-mount//snapshots/ and create / dir - # on it. - backupsDir = mountSnapshotsDir(secondaryStorageMountPath, localMountPoint, path) - util.SMlog("Backups dir " + backupsDir) - prevBackupUuid = prevBackupUuid.split("/")[-1] - # Check existence of snapshot on primary storage - isfile(baseCopyPath, isISCSI) - if prevBackupUuid: - # Check existence of prevBackupFile - prevBackupVHD = getBackupVHD(prevBackupUuid) - prevBackupFile = os.path.join(backupsDir, prevBackupVHD) - isfile(prevBackupFile, False) - - # copy baseCopyPath to backupsDir with new uuid - backupVHD = getBackupVHD(backupUuid) - backupFile = os.path.join(backupsDir, backupVHD) - util.SMlog("Back up " + baseCopyUuid + " to Secondary Storage as " + backupUuid) - copyfile(baseCopyPath, backupFile, isISCSI) - vhdutil.setHidden(backupFile, False) - - # Because the primary storage is always scanned, the parent of this base copy is always the first base copy. - # We don't want that, we want a chain of VHDs each of which is a delta from the previous. - # So set the parent of the current baseCopyVHD to prevBackupVHD - if prevBackupUuid: - # If there was a previous snapshot - setParent(prevBackupFile, backupFile) - - txt = "1#" + backupUuid - return txt - -@echo -def deleteSnapshotBackup(session, args): - util.SMlog("Calling deleteSnapshotBackup with " + str(args)) - secondaryStorageMountPath = args['secondaryStorageMountPath'] - backupUUID = args['backupUUID'] - path = args['path'] - localMountPoint = args['localMountPoint'] - - backupsDir = mountSnapshotsDir(secondaryStorageMountPath, localMountPoint, path) - # chdir to the backupsDir for convenience - chdir(backupsDir) - - backupVHD = getBackupVHD(backupUUID) - util.SMlog("checking existence of " + backupVHD) - - # The backupVHD is on secondary which is NFS and not ISCSI. - if not os.path.isfile(backupVHD): - util.SMlog("backupVHD " + backupVHD + "does not exist. Not trying to delete it") - return "1" - util.SMlog("backupVHD " + backupVHD + " exists.") - - # Just delete the backupVHD - try: - os.remove(backupVHD) - except OSError, (errno, strerror): - errMsg = "OSError while removing " + backupVHD + " with errno: " + str(errno) + " and strerr: " + strerror - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - - return "1" - -@echo -def revert_memory_snapshot(session, args): - util.SMlog("Calling revert_memory_snapshot with " + str(args)) - vmName = args['vmName'] - snapshotUUID = args['snapshotUUID'] - oldVmUuid = args['oldVmUuid'] - snapshotMemory = args['snapshotMemory'] - hostUUID = args['hostUUID'] - try: - cmd = '''xe vbd-list vm-uuid=%s | grep 'vdi-uuid' | grep -v 'not in database' | sed -e 's/vdi-uuid ( RO)://g' ''' % oldVmUuid - vdiUuids = os.popen(cmd).read().split() - cmd2 = '''xe vm-param-get param-name=power-state uuid=''' + oldVmUuid - if os.popen(cmd2).read().split()[0] != 'halted': - os.system("xe vm-shutdown force=true vm=" + vmName) - os.system("xe vm-destroy uuid=" + oldVmUuid) - os.system("xe snapshot-revert snapshot-uuid=" + snapshotUUID) - if snapshotMemory == 'true': - os.system("xe vm-resume vm=" + vmName + " on=" + hostUUID) - for vdiUuid in vdiUuids: - os.system("xe vdi-destroy uuid=" + vdiUuid) - except OSError, (errno, strerror): - errMsg = "OSError while reverting vm " + vmName + " to snapshot " + snapshotUUID + " with errno: " + str(errno) + " and strerr: " + strerror - util.SMlog(errMsg) - raise xs_errors.XenError(errMsg) - return "0" - -if __name__ == "__main__": - XenAPIPlugin.dispatch({"getVhdParent":getVhdParent, "create_secondary_storage_folder":create_secondary_storage_folder, "delete_secondary_storage_folder":delete_secondary_storage_folder, "post_create_private_template":post_create_private_template, "backupSnapshot": backupSnapshot, "deleteSnapshotBackup": deleteSnapshotBackup, "unmountSnapshotsDir": unmountSnapshotsDir, "revert_memory_snapshot":revert_memory_snapshot}) - - diff --git a/scripts/vm/hypervisor/xenserver/xcposs/vmopspremium b/scripts/vm/hypervisor/xenserver/xcposs/vmopspremium deleted file mode 100644 index 9066ee0e2f8..00000000000 --- a/scripts/vm/hypervisor/xenserver/xcposs/vmopspremium +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/python -# 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. - -# Version @VERSION@ -# -# A plugin for executing script needed by vmops cloud - -import os, sys, time -import XenAPIPlugin -sys.path.append("/usr/lib/xcp/sm/") -import util -import socket - -def echo(fn): - def wrapped(*v, **k): - name = fn.__name__ - util.SMlog("#### VMOPS enter %s ####" % name ) - res = fn(*v, **k) - util.SMlog("#### VMOPS exit %s ####" % name ) - return res - return wrapped - -@echo -def forceShutdownVM(session, args): - domId = args['domId'] - try: - cmd = ["/usr/lib/xcp/debug/xenops", "destroy_domain", "-domid", domId] - txt = util.pread2(cmd) - except: - txt = '10#failed' - return txt - - -@echo -def create_privatetemplate_from_snapshot(session, args): - templatePath = args['templatePath'] - snapshotPath = args['snapshotPath'] - tmpltLocalDir = args['tmpltLocalDir'] - try: - cmd = ["bash", "/usr/lib/xcp/bin/create_privatetemplate_from_snapshot.sh",snapshotPath, templatePath, tmpltLocalDir] - txt = util.pread2(cmd) - except: - txt = '10#failed' - return txt - -@echo -def upgrade_snapshot(session, args): - templatePath = args['templatePath'] - snapshotPath = args['snapshotPath'] - try: - cmd = ["bash", "/usr/lib/xcp/bin/upgrate_snapshot.sh",snapshotPath, templatePath] - txt = util.pread2(cmd) - except: - txt = '10#failed' - return txt - -@echo -def copy_vhd_to_secondarystorage(session, args): - mountpoint = args['mountpoint'] - vdiuuid = args['vdiuuid'] - sruuid = args['sruuid'] - try: - cmd = ["bash", "/usr/lib/xcp/bin/copy_vhd_to_secondarystorage.sh", mountpoint, vdiuuid, sruuid] - txt = util.pread2(cmd) - except: - txt = '10#failed' - return txt - -@echo -def copy_vhd_from_secondarystorage(session, args): - mountpoint = args['mountpoint'] - sruuid = args['sruuid'] - namelabel = args['namelabel'] - try: - cmd = ["bash", "/usr/lib/xcp/bin/copy_vhd_from_secondarystorage.sh", mountpoint, sruuid, namelabel] - txt = util.pread2(cmd) - except: - txt = '10#failed' - return txt - -@echo -def setup_heartbeat_sr(session, args): - host = args['host'] - sr = args['sr'] - try: - cmd = ["bash", "/usr/lib/xcp/bin/setup_heartbeat_sr.sh", host, sr] - txt = util.pread2(cmd) - except: - txt = '' - return txt - -@echo -def setup_heartbeat_file(session, args): - host = args['host'] - sr = args['sr'] - add = args['add'] - try: - cmd = ["bash", "/usr/lib/xcp/bin/setup_heartbeat_file.sh", host, sr, add] - txt = util.pread2(cmd) - except: - txt = '' - return txt - -@echo -def check_heartbeat(session, args): - host = args['host'] - interval = args['interval'] - try: - cmd = ["bash", "/usr/lib/xcp/bin/check_heartbeat.sh", host, interval] - txt = util.pread2(cmd) - except: - txt='' - return txt - - -@echo -def heartbeat(session, args): - ''' - host = args['host'] - interval = args['interval'] - try: - cmd = ["/bin/bash", "/usr/lib/xcp/bin/launch_hb.sh", host, interval] - txt = util.pread2(cmd) - except: - txt='fail' - ''' - return '> DONE <' - -if __name__ == "__main__": - XenAPIPlugin.dispatch({"forceShutdownVM":forceShutdownVM, "upgrade_snapshot":upgrade_snapshot, "create_privatetemplate_from_snapshot":create_privatetemplate_from_snapshot, "copy_vhd_to_secondarystorage":copy_vhd_to_secondarystorage, "copy_vhd_from_secondarystorage":copy_vhd_from_secondarystorage, "setup_heartbeat_sr":setup_heartbeat_sr, "setup_heartbeat_file":setup_heartbeat_file, "check_heartbeat":check_heartbeat, "heartbeat": heartbeat}) - diff --git a/scripts/vm/hypervisor/xenserver/xcpserver/patch b/scripts/vm/hypervisor/xenserver/xcpserver/patch index 443abc19417..478807f491a 100644 --- a/scripts/vm/hypervisor/xenserver/xcpserver/patch +++ b/scripts/vm/hypervisor/xenserver/xcpserver/patch @@ -34,33 +34,33 @@ vmopsSnapshot=..,0755,/etc/xapi.d/plugins hostvmstats.py=..,0755,/opt/xensource/sm systemvm.iso=../../../../../vms,0644,/opt/xensource/packages/iso id_rsa.cloud=../../../systemvm,0600,/root/.ssh -network_info.sh=..,0755,/opt/xensource/bin -setupxenserver.sh=..,0755,/opt/xensource/bin -make_migratable.sh=..,0755,/opt/xensource/bin -setup_iscsi.sh=..,0755,/opt/xensource/bin -pingtest.sh=../../..,0755,/opt/xensource/bin -dhcp_entry.sh=../../../../network/domr/,0755,/opt/xensource/bin -createipAlias.sh=..,0755,/opt/xensource/bin -deleteipAlias.sh=..,0755,/opt/xensource/bin -router_proxy.sh=../../../../network/domr/,0755,/opt/xensource/bin -save_password_to_domr.sh=../../../../network/domr/,0755,/opt/xensource/bin -call_firewall.sh=../../../../network/domr/,0755,/opt/xensource/bin -call_loadbalancer.sh=../../../../network/domr/,0755,/opt/xensource/bin -cloud-setup-bonding.sh=..,0755,/opt/xensource/bin -copy_vhd_to_secondarystorage.sh=..,0755,/opt/xensource/bin -copy_vhd_from_secondarystorage.sh=..,0755,/opt/xensource/bin -setup_heartbeat_sr.sh=..,0755,/opt/xensource/bin -setup_heartbeat_file.sh=..,0755,/opt/xensource/bin -check_heartbeat.sh=..,0755,/opt/xensource/bin -xenheartbeat.sh=..,0755,/opt/xensource/bin -launch_hb.sh=..,0755,/opt/xensource/bin -vhd-util=..,0755,/opt/xensource/bin +network_info.sh=..,0755,/opt/cloud/bin +setupxenserver.sh=..,0755,/opt/cloud/bin +make_migratable.sh=..,0755,/opt/cloud/bin +setup_iscsi.sh=..,0755,/opt/cloud/bin +pingtest.sh=../../..,0755,/opt/cloud/bin +dhcp_entry.sh=../../../../network/domr/,0755,/opt/cloud/bin +createipAlias.sh=..,0755,/opt/cloud/bin +deleteipAlias.sh=..,0755,/opt/cloud/bin +router_proxy.sh=../../../../network/domr/,0755,/opt/cloud/bin +save_password_to_domr.sh=../../../../network/domr/,0755,/opt/cloud/bin +call_firewall.sh=../../../../network/domr/,0755,/opt/cloud/bin +call_loadbalancer.sh=../../../../network/domr/,0755,/opt/cloud/bin +cloud-setup-bonding.sh=..,0755,/opt/cloud/bin +copy_vhd_to_secondarystorage.sh=..,0755,/opt/cloud/bin +copy_vhd_from_secondarystorage.sh=..,0755,/opt/cloud/bin +setup_heartbeat_sr.sh=..,0755,/opt/cloud/bin +setup_heartbeat_file.sh=..,0755,/opt/cloud/bin +check_heartbeat.sh=..,0755,/opt/cloud/bin +xenheartbeat.sh=..,0755,/opt/cloud/bin +launch_hb.sh=..,0755,/opt/cloud/bin +vhd-util=..,0755,/opt/cloud/bin vmopspremium=..,0755,/etc/xapi.d/plugins -create_privatetemplate_from_snapshot.sh=..,0755,/opt/xensource/bin -upgrade_snapshot.sh=..,0755,/opt/xensource/bin -cloud-clean-vlan.sh=..,0755,/opt/xensource/bin -cloud-prepare-upgrade.sh=..,0755,/opt/xensource/bin -getRouterStatus.sh=../../../../network/domr/,0755,/opt/xensource/bin -bumpUpPriority.sh=../../../../network/domr/,0755,/opt/xensource/bin -getDomRVersion.sh=../../../../network/domr/,0755,/opt/xensource/bin -add_to_vcpus_params_live.sh=..,0755,/opt/xensource/bin +create_privatetemplate_from_snapshot.sh=..,0755,/opt/cloud/bin +upgrade_snapshot.sh=..,0755,/opt/cloud/bin +cloud-clean-vlan.sh=..,0755,/opt/cloud/bin +cloud-prepare-upgrade.sh=..,0755,/opt/cloud/bin +getRouterStatus.sh=../../../../network/domr/,0755,/opt/cloud/bin +bumpUpPriority.sh=../../../../network/domr/,0755,/opt/cloud/bin +getDomRVersion.sh=../../../../network/domr/,0755,/opt/cloud/bin +add_to_vcpus_params_live.sh=..,0755,/opt/cloud/bin diff --git a/scripts/vm/hypervisor/xenserver/xenheartbeat.sh b/scripts/vm/hypervisor/xenserver/xenheartbeat.sh index dd876ba4b79..d5a5d862c71 100755 --- a/scripts/vm/hypervisor/xenserver/xenheartbeat.sh +++ b/scripts/vm/hypervisor/xenserver/xenheartbeat.sh @@ -44,7 +44,7 @@ if [ $interval -gt $2 ]; then exit 3 fi -file=/opt/xensource/bin/heartbeat +file=/opt/cloud/bin/heartbeat lastdate=$(($(date +%s) + $interval)) while [ $(date +%s) -lt $(($lastdate + $2)) ] diff --git a/scripts/vm/hypervisor/xenserver/xenserver56/patch b/scripts/vm/hypervisor/xenserver/xenserver56/patch index 87b3937a867..e593a5c112c 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver56/patch +++ b/scripts/vm/hypervisor/xenserver/xenserver56/patch @@ -32,37 +32,37 @@ vmopsSnapshot=..,0755,/etc/xapi.d/plugins hostvmstats.py=..,0755,/opt/xensource/sm systemvm.iso=../../../../../vms,0644,/opt/xensource/packages/iso id_rsa.cloud=../../../systemvm,0600,/root/.ssh -network_info.sh=..,0755,/opt/xensource/bin -setupxenserver.sh=..,0755,/opt/xensource/bin -make_migratable.sh=..,0755,/opt/xensource/bin -setup_iscsi.sh=..,0755,/opt/xensource/bin -cloud-setup-bonding.sh=..,0755,/opt/xensource/bin -pingtest.sh=../../..,0755,/opt/xensource/bin -createipAlias.sh=..,0755,/opt/xensource/bin -deleteipAlias.sh=..,0755,/opt/xensource/bin -dhcp_entry.sh=../../../../network/domr/,0755,/opt/xensource/bin -save_password_to_domr.sh=../../../../network/domr/,0755,/opt/xensource/bin -call_firewall.sh=../../../../network/domr/,0755,/opt/xensource/bin -call_loadbalancer.sh=../../../../network/domr/,0755,/opt/xensource/bin -router_proxy.sh=../../../../network/domr/,0755,/opt/xensource/bin -copy_vhd_to_secondarystorage.sh=..,0755,/opt/xensource/bin -copy_vhd_from_secondarystorage.sh=..,0755,/opt/xensource/bin -kill_copy_process.sh=..,0755,/opt/xensource/bin -setup_heartbeat_sr.sh=..,0755,/opt/xensource/bin -setup_heartbeat_file.sh=..,0755,/opt/xensource/bin -check_heartbeat.sh=..,0755,/opt/xensource/bin -xenheartbeat.sh=..,0755,/opt/xensource/bin -launch_hb.sh=..,0755,/opt/xensource/bin -vhd-util=..,0755,/opt/xensource/bin +network_info.sh=..,0755,/opt/cloud/bin +setupxenserver.sh=..,0755,/opt/cloud/bin +make_migratable.sh=..,0755,/opt/cloud/bin +setup_iscsi.sh=..,0755,/opt/cloud/bin +cloud-setup-bonding.sh=..,0755,/opt/cloud/bin +pingtest.sh=../../..,0755,/opt/cloud/bin +createipAlias.sh=..,0755,/opt/cloud/bin +deleteipAlias.sh=..,0755,/opt/cloud/bin +dhcp_entry.sh=../../../../network/domr/,0755,/opt/cloud/bin +save_password_to_domr.sh=../../../../network/domr/,0755,/opt/cloud/bin +call_firewall.sh=../../../../network/domr/,0755,/opt/cloud/bin +call_loadbalancer.sh=../../../../network/domr/,0755,/opt/cloud/bin +router_proxy.sh=../../../../network/domr/,0755,/opt/cloud/bin +copy_vhd_to_secondarystorage.sh=..,0755,/opt/cloud/bin +copy_vhd_from_secondarystorage.sh=..,0755,/opt/cloud/bin +kill_copy_process.sh=..,0755,/opt/cloud/bin +setup_heartbeat_sr.sh=..,0755,/opt/cloud/bin +setup_heartbeat_file.sh=..,0755,/opt/cloud/bin +check_heartbeat.sh=..,0755,/opt/cloud/bin +xenheartbeat.sh=..,0755,/opt/cloud/bin +launch_hb.sh=..,0755,/opt/cloud/bin +vhd-util=..,0755,/opt/cloud/bin vmopspremium=..,0755,/etc/xapi.d/plugins InterfaceReconfigure.py=.,0755,/opt/xensource/libexec -create_privatetemplate_from_snapshot.sh=..,0755,/opt/xensource/bin -upgrade_snapshot.sh=..,0755,/opt/xensource/bin -cloud-clean-vlan.sh=..,0755,/opt/xensource/bin -cloud-prepare-upgrade.sh=..,0755,/opt/xensource/bin -bumpUpPriority.sh=../../../../network/domr/,0755,/opt/xensource/bin -swift=..,0755,/opt/xensource/bin +create_privatetemplate_from_snapshot.sh=..,0755,/opt/cloud/bin +upgrade_snapshot.sh=..,0755,/opt/cloud/bin +cloud-clean-vlan.sh=..,0755,/opt/cloud/bin +cloud-prepare-upgrade.sh=..,0755,/opt/cloud/bin +bumpUpPriority.sh=../../../../network/domr/,0755,/opt/cloud/bin +swift=..,0755,/opt/cloud/bin swiftxen=..,0755,/etc/xapi.d/plugins s3xen=..,0755,/etc/xapi.d/plugins -add_to_vcpus_params_live.sh=..,0755,/opt/xensource/bin +add_to_vcpus_params_live.sh=..,0755,/opt/cloud/bin diff --git a/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch b/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch index 6dc9b0562fd..b210a8895ea 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch +++ b/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch @@ -32,36 +32,36 @@ vmopsSnapshot=..,0755,/etc/xapi.d/plugins hostvmstats.py=..,0755,/opt/xensource/sm systemvm.iso=../../../../../vms,0644,/opt/xensource/packages/iso id_rsa.cloud=../../../systemvm,0600,/root/.ssh -network_info.sh=..,0755,/opt/xensource/bin -setupxenserver.sh=..,0755,/opt/xensource/bin -make_migratable.sh=..,0755,/opt/xensource/bin -setup_iscsi.sh=..,0755,/opt/xensource/bin -pingtest.sh=../../..,0755,/opt/xensource/bin -createipAlias.sh=..,0755,/opt/xensource/bin -deleteipAlias.sh=..,0755,/opt/xensource/bin -dhcp_entry.sh=../../../../network/domr/,0755,/opt/xensource/bin -save_password_to_domr.sh=../../../../network/domr/,0755,/opt/xensource/bin -call_firewall.sh=../../../../network/domr/,0755,/opt/xensource/bin -call_loadbalancer.sh=../../../../network/domr/,0755,/opt/xensource/bin -router_proxy.sh=../../../../network/domr/,0755,/opt/xensource/bin -cloud-setup-bonding.sh=..,0755,/opt/xensource/bin -copy_vhd_to_secondarystorage.sh=..,0755,/opt/xensource/bin -copy_vhd_from_secondarystorage.sh=..,0755,/opt/xensource/bin -kill_copy_process.sh=..,0755,/opt/xensource/bin -setup_heartbeat_sr.sh=..,0755,/opt/xensource/bin -setup_heartbeat_file.sh=..,0755,/opt/xensource/bin -check_heartbeat.sh=..,0755,/opt/xensource/bin -xenheartbeat.sh=..,0755,/opt/xensource/bin -launch_hb.sh=..,0755,/opt/xensource/bin -vhd-util=..,0755,/opt/xensource/bin +network_info.sh=..,0755,/opt/cloud/bin +setupxenserver.sh=..,0755,/opt/cloud/bin +make_migratable.sh=..,0755,/opt/cloud/bin +setup_iscsi.sh=..,0755,/opt/cloud/bin +pingtest.sh=../../..,0755,/opt/cloud/bin +createipAlias.sh=..,0755,/opt/cloud/bin +deleteipAlias.sh=..,0755,/opt/cloud/bin +dhcp_entry.sh=../../../../network/domr/,0755,/opt/cloud/bin +save_password_to_domr.sh=../../../../network/domr/,0755,/opt/cloud/bin +call_firewall.sh=../../../../network/domr/,0755,/opt/cloud/bin +call_loadbalancer.sh=../../../../network/domr/,0755,/opt/cloud/bin +router_proxy.sh=../../../../network/domr/,0755,/opt/cloud/bin +cloud-setup-bonding.sh=..,0755,/opt/cloud/bin +copy_vhd_to_secondarystorage.sh=..,0755,/opt/cloud/bin +copy_vhd_from_secondarystorage.sh=..,0755,/opt/cloud/bin +kill_copy_process.sh=..,0755,/opt/cloud/bin +setup_heartbeat_sr.sh=..,0755,/opt/cloud/bin +setup_heartbeat_file.sh=..,0755,/opt/cloud/bin +check_heartbeat.sh=..,0755,/opt/cloud/bin +xenheartbeat.sh=..,0755,/opt/cloud/bin +launch_hb.sh=..,0755,/opt/cloud/bin +vhd-util=..,0755,/opt/cloud/bin vmopspremium=..,0755,/etc/xapi.d/plugins -create_privatetemplate_from_snapshot.sh=..,0755,/opt/xensource/bin -upgrade_snapshot.sh=..,0755,/opt/xensource/bin -cloud-clean-vlan.sh=..,0755,/opt/xensource/bin -cloud-prepare-upgrade.sh=..,0755,/opt/xensource/bin -bumpUpPriority.sh=../../../../network/domr/,0755,/opt/xensource/bin -swift=..,0755,/opt/xensource/bin +create_privatetemplate_from_snapshot.sh=..,0755,/opt/cloud/bin +upgrade_snapshot.sh=..,0755,/opt/cloud/bin +cloud-clean-vlan.sh=..,0755,/opt/cloud/bin +cloud-prepare-upgrade.sh=..,0755,/opt/cloud/bin +bumpUpPriority.sh=../../../../network/domr/,0755,/opt/cloud/bin +swift=..,0755,/opt/cloud/bin swiftxen=..,0755,/etc/xapi.d/plugins s3xen=..,0755,/etc/xapi.d/plugins -add_to_vcpus_params_live.sh=..,0755,/opt/xensource/bin +add_to_vcpus_params_live.sh=..,0755,/opt/cloud/bin diff --git a/scripts/vm/hypervisor/xenserver/xenserver60/patch b/scripts/vm/hypervisor/xenserver/xenserver60/patch index 60a0643bcec..8a0448a2009 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver60/patch +++ b/scripts/vm/hypervisor/xenserver/xenserver60/patch @@ -37,41 +37,41 @@ vmopsSnapshot=..,0755,/etc/xapi.d/plugins hostvmstats.py=..,0755,/opt/xensource/sm systemvm.iso=../../../../../vms,0644,/opt/xensource/packages/iso id_rsa.cloud=../../../systemvm,0600,/root/.ssh -network_info.sh=..,0755,/opt/xensource/bin -setupxenserver.sh=..,0755,/opt/xensource/bin -make_migratable.sh=..,0755,/opt/xensource/bin -createipAlias.sh=..,0755,/opt/xensource/bin -deleteipAlias.sh=..,0755,/opt/xensource/bin -setup_iscsi.sh=..,0755,/opt/xensource/bin -pingtest.sh=../../..,0755,/opt/xensource/bin -dhcp_entry.sh=../../../../network/domr/,0755,/opt/xensource/bin -save_password_to_domr.sh=../../../../network/domr/,0755,/opt/xensource/bin -call_firewall.sh=../../../../network/domr/,0755,/opt/xensource/bin -call_loadbalancer.sh=../../../../network/domr/,0755,/opt/xensource/bin -router_proxy.sh=../../../../network/domr/,0755,/opt/xensource/bin -cloud-setup-bonding.sh=..,0755,/opt/xensource/bin -copy_vhd_to_secondarystorage.sh=..,0755,/opt/xensource/bin -copy_vhd_from_secondarystorage.sh=..,0755,/opt/xensource/bin -kill_copy_process.sh=..,0755,/opt/xensource/bin -setup_heartbeat_sr.sh=..,0755,/opt/xensource/bin -setup_heartbeat_file.sh=..,0755,/opt/xensource/bin -check_heartbeat.sh=..,0755,/opt/xensource/bin -xenheartbeat.sh=..,0755,/opt/xensource/bin -launch_hb.sh=..,0755,/opt/xensource/bin -vhd-util=..,0755,/opt/xensource/bin +network_info.sh=..,0755,/opt/cloud/bin +setupxenserver.sh=..,0755,/opt/cloud/bin +make_migratable.sh=..,0755,/opt/cloud/bin +createipAlias.sh=..,0755,/opt/cloud/bin +deleteipAlias.sh=..,0755,/opt/cloud/bin +setup_iscsi.sh=..,0755,/opt/cloud/bin +pingtest.sh=../../..,0755,/opt/cloud/bin +dhcp_entry.sh=../../../../network/domr/,0755,/opt/cloud/bin +save_password_to_domr.sh=../../../../network/domr/,0755,/opt/cloud/bin +call_firewall.sh=../../../../network/domr/,0755,/opt/cloud/bin +call_loadbalancer.sh=../../../../network/domr/,0755,/opt/cloud/bin +router_proxy.sh=../../../../network/domr/,0755,/opt/cloud/bin +cloud-setup-bonding.sh=..,0755,/opt/cloud/bin +copy_vhd_to_secondarystorage.sh=..,0755,/opt/cloud/bin +copy_vhd_from_secondarystorage.sh=..,0755,/opt/cloud/bin +kill_copy_process.sh=..,0755,/opt/cloud/bin +setup_heartbeat_sr.sh=..,0755,/opt/cloud/bin +setup_heartbeat_file.sh=..,0755,/opt/cloud/bin +check_heartbeat.sh=..,0755,/opt/cloud/bin +xenheartbeat.sh=..,0755,/opt/cloud/bin +launch_hb.sh=..,0755,/opt/cloud/bin +vhd-util=..,0755,/opt/cloud/bin vmopspremium=..,0755,/etc/xapi.d/plugins -create_privatetemplate_from_snapshot.sh=..,0755,/opt/xensource/bin -upgrade_snapshot.sh=..,0755,/opt/xensource/bin -cloud-clean-vlan.sh=..,0755,/opt/xensource/bin -cloud-prepare-upgrade.sh=..,0755,/opt/xensource/bin -bumpUpPriority.sh=../../../../network/domr/,0755,/opt/xensource/bin -swift=..,0755,/opt/xensource/bin +create_privatetemplate_from_snapshot.sh=..,0755,/opt/cloud/bin +upgrade_snapshot.sh=..,0755,/opt/cloud/bin +cloud-clean-vlan.sh=..,0755,/opt/cloud/bin +cloud-prepare-upgrade.sh=..,0755,/opt/cloud/bin +bumpUpPriority.sh=../../../../network/domr/,0755,/opt/cloud/bin +swift=..,0755,/opt/cloud/bin swiftxen=..,0755,/etc/xapi.d/plugins s3xen=..,0755,/etc/xapi.d/plugins -add_to_vcpus_params_live.sh=..,0755,/opt/xensource/bin +add_to_vcpus_params_live.sh=..,0755,/opt/cloud/bin ovs-pvlan=..,0755,/etc/xapi.d/plugins -ovs-pvlan-dhcp-host.sh=../../../network,0755,/opt/xensource/bin -ovs-pvlan-vm.sh=../../../network,0755,/opt/xensource/bin -ovs-pvlan-cleanup.sh=../../../network,0755,/opt/xensource/bin -ovs-get-dhcp-iface.sh=..,0755,/opt/xensource/bin -ovs-get-bridge.sh=..,0755,/opt/xensource/bin +ovs-pvlan-dhcp-host.sh=../../../network,0755,/opt/cloud/bin +ovs-pvlan-vm.sh=../../../network,0755,/opt/cloud/bin +ovs-pvlan-cleanup.sh=../../../network,0755,/opt/cloud/bin +ovs-get-dhcp-iface.sh=..,0755,/opt/cloud/bin +ovs-get-bridge.sh=..,0755,/opt/cloud/bin From cc86599c4d72367709c42ea8485a5e06447bfddc Mon Sep 17 00:00:00 2001 From: Anshul Gangwar Date: Tue, 3 Dec 2013 15:23:06 +0530 Subject: [PATCH 072/170] adding missing license headers for cs files --- .../AgentShell/ProjectInstaller.Designer.cs | 20 +++++++++++++++++-- .../AgentShell/ProjectInstaller.cs | 18 ++++++++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.Designer.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.Designer.cs index 9b9dbb6edb9..a10cbb002fd 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.Designer.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.Designer.cs @@ -1,4 +1,20 @@ -namespace CloudStack.Plugin.AgentShell +// 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. +namespace CloudStack.Plugin.AgentShell { partial class ProjectInstaller { @@ -57,4 +73,4 @@ private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1; private System.ServiceProcess.ServiceInstaller serviceInstaller1; } -} \ No newline at end of file +} diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.cs index c3a225f540a..78356c64848 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.cs @@ -1,4 +1,20 @@ -using System; +// 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. +using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; From d2bf5c9d5e5977120b3218707ee479d2c8f760ab Mon Sep 17 00:00:00 2001 From: lafferty Date: Tue, 3 Dec 2013 01:29:26 +0000 Subject: [PATCH 073/170] bug CLOUDSTACK-5339 --- server/src/com/cloud/storage/VolumeApiServiceImpl.java | 6 ++++++ .../src/com/cloud/template/HypervisorTemplateAdapter.java | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index 0fd0ab0872d..e60d204c29f 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -382,6 +382,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic userSpecifiedName = getRandomVolumeName(); } if ((!url.toLowerCase().endsWith("vhd")) && (!url.toLowerCase().endsWith("vhd.zip")) && (!url.toLowerCase().endsWith("vhd.bz2")) && + (!url.toLowerCase().endsWith("vhdx")) && (!url.toLowerCase().endsWith("vhdx.zip")) && + (!url.toLowerCase().endsWith("vhdx.gz")) && (!url.toLowerCase().endsWith("vhdx.bz2")) && (!url.toLowerCase().endsWith("vhd.gz")) && (!url.toLowerCase().endsWith("qcow2")) && (!url.toLowerCase().endsWith("qcow2.zip")) && (!url.toLowerCase().endsWith("qcow2.bz2")) && (!url.toLowerCase().endsWith("qcow2.gz")) && (!url.toLowerCase().endsWith("ova")) && (!url.toLowerCase().endsWith("ova.zip")) && (!url.toLowerCase().endsWith("ova.bz2")) && (!url.toLowerCase().endsWith("ova.gz")) && @@ -391,6 +393,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic if ((format.equalsIgnoreCase("vhd") && (!url.toLowerCase().endsWith(".vhd") && !url.toLowerCase().endsWith("vhd.zip") && !url.toLowerCase().endsWith("vhd.bz2") && !url.toLowerCase() .endsWith("vhd.gz"))) || + (format.equalsIgnoreCase("vhdx") && (!url.toLowerCase().endsWith(".vhdx") && !url.toLowerCase().endsWith("vhdx.zip") && !url.toLowerCase().endsWith("vhdx.bz2") && !url.toLowerCase() + .endsWith("vhdx.gz"))) || (format.equalsIgnoreCase("qcow2") && (!url.toLowerCase().endsWith(".qcow2") && !url.toLowerCase().endsWith("qcow2.zip") && !url.toLowerCase().endsWith("qcow2.bz2") && !url.toLowerCase().endsWith("qcow2.gz"))) || (format.equalsIgnoreCase("ova") && (!url.toLowerCase().endsWith(".ova") && !url.toLowerCase().endsWith("ova.zip") && !url.toLowerCase().endsWith("ova.bz2") && !url.toLowerCase() @@ -1565,6 +1569,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic return "vhd"; } else if (cluster.getHypervisorType() == HypervisorType.KVM) { return "qcow2"; + } else if (cluster.getHypervisorType() == HypervisorType.Hyperv) { + return "vhdx"; } else if (cluster.getHypervisorType() == HypervisorType.VMware) { return "ova"; } else if (cluster.getHypervisorType() == HypervisorType.Ovm) { diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 32da8230163..542e675d127 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -145,6 +145,8 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase { private void checkFormat(String format, String url) { if ((!url.toLowerCase().endsWith("vhd")) && (!url.toLowerCase().endsWith("vhd.zip")) && (!url.toLowerCase().endsWith("vhd.bz2")) && + (!url.toLowerCase().endsWith("vhdx")) && (!url.toLowerCase().endsWith("vhdx.gz")) && + (!url.toLowerCase().endsWith("vhdx.bz2")) && (!url.toLowerCase().endsWith("vhdx.zip")) && (!url.toLowerCase().endsWith("vhd.gz")) && (!url.toLowerCase().endsWith("qcow2")) && (!url.toLowerCase().endsWith("qcow2.zip")) && (!url.toLowerCase().endsWith("qcow2.bz2")) && (!url.toLowerCase().endsWith("qcow2.gz")) && (!url.toLowerCase().endsWith("ova")) && (!url.toLowerCase().endsWith("ova.zip")) && (!url.toLowerCase().endsWith("ova.bz2")) && (!url.toLowerCase().endsWith("ova.gz")) && @@ -155,6 +157,8 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase { if ((format.equalsIgnoreCase("vhd") && (!url.toLowerCase().endsWith("vhd") && !url.toLowerCase().endsWith("vhd.zip") && !url.toLowerCase().endsWith("vhd.bz2") && !url.toLowerCase() .endsWith("vhd.gz"))) || + (format.equalsIgnoreCase("vhdx") && (!url.toLowerCase().endsWith("vhdx") && !url.toLowerCase().endsWith("vhdx.zip") && !url.toLowerCase().endsWith("vhdx.bz2") && !url.toLowerCase() + .endsWith("vhdx.gz"))) || (format.equalsIgnoreCase("qcow2") && (!url.toLowerCase().endsWith("qcow2") && !url.toLowerCase().endsWith("qcow2.zip") && !url.toLowerCase().endsWith("qcow2.bz2") && !url.toLowerCase().endsWith("qcow2.gz"))) || (format.equalsIgnoreCase("ova") && (!url.toLowerCase().endsWith("ova") && !url.toLowerCase().endsWith("ova.zip") && !url.toLowerCase().endsWith("ova.bz2") && !url.toLowerCase() From c39bc04be6f310cc684dec9923fdcefe95ac53d0 Mon Sep 17 00:00:00 2001 From: Girish Shilamkar Date: Tue, 3 Dec 2013 15:59:42 +0530 Subject: [PATCH 074/170] CLOUDSTACK-5337: Trimming account name (username) to 99 characters --- tools/marvin/marvin/integration/lib/base.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/marvin/marvin/integration/lib/base.py b/tools/marvin/marvin/integration/lib/base.py index bce13272afe..86f962ad9ad 100755 --- a/tools/marvin/marvin/integration/lib/base.py +++ b/tools/marvin/marvin/integration/lib/base.py @@ -98,7 +98,10 @@ class Account: cmd.lastname = services["lastname"] cmd.password = services["password"] - cmd.username = "-".join([services["username"], random_gen(id=apiclient.id)]) + + username = "-".join([services["username"], random_gen(id=apiclient.id)]) + # Trim username to 99 characters to prevent failure + cmd.username = username[:99] if len(username) > 99 else username if "accountUUID" in services: cmd.accountid = "-".join([services["accountUUID"],random_gen()]) From d97345f0a254be412fde2c7bc0fdc2969dd588dc Mon Sep 17 00:00:00 2001 From: Murali Reddy Date: Tue, 3 Dec 2013 16:14:26 +0530 Subject: [PATCH 075/170] fixing copy paste error in getting alert type in alert manager --- server/src/com/cloud/alert/AlertManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/com/cloud/alert/AlertManagerImpl.java b/server/src/com/cloud/alert/AlertManagerImpl.java index 05ed03a036d..fd24c02034a 100755 --- a/server/src/com/cloud/alert/AlertManagerImpl.java +++ b/server/src/com/cloud/alert/AlertManagerImpl.java @@ -262,7 +262,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi if (alertType == ALERT_TYPE_MEMORY) { return "ALERT.MEMORY"; } else if (alertType == ALERT_TYPE_CPU) { - return "ALERT.MEMORY"; + return "ALERT.CPU"; } else if (alertType == ALERT_TYPE_STORAGE) { return "ALERT.STORAGE"; } else if (alertType == ALERT_TYPE_STORAGE_ALLOCATED) { From b4dd3747f34948c8b859a2b9791a175c7b38a53c Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 3 Dec 2013 12:30:59 -0800 Subject: [PATCH 076/170] Dialog list view: Fix toolbar/header positioning --- ui/css/cloudstack3.css | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 2acc6b44043..949e8c3052c 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -7498,16 +7498,16 @@ div.detail-group td.view-all div.view-all div.end { } .ui-dialog .list-view .toolbar { - top: 33px; - width: 824px; + top: 50px; + width: 854px; } div.panel.ui-dialog div.list-view div.fixed-header { - top: 42px; - left: 20px; + top: 55px; + left: 35px; width: 759px; height: 49px; - background-color: #EAECEF; + background-color: #FFFFFF; margin: 0; z-index: 1; } From af3add9353c46a77c933d1c704412cf25a8127b5 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 3 Dec 2013 12:32:26 -0800 Subject: [PATCH 077/170] CLOUDSTACK-5114: Remove checkbox column from dialog list view --- ui/scripts/ui-custom/enableStaticNAT.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/scripts/ui-custom/enableStaticNAT.js b/ui/scripts/ui-custom/enableStaticNAT.js index e46ae1923b4..e469ca9b7cc 100644 --- a/ui/scripts/ui-custom/enableStaticNAT.js +++ b/ui/scripts/ui-custom/enableStaticNAT.js @@ -33,6 +33,8 @@ uiCustom: true }); + instances.listView.multiSelect = false; + instances.listView.actions = { select: { label: _l('label.select.instance'), From bd1c28573ea076a3ff815fd443867a16f7d7c2c1 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 3 Dec 2013 12:02:43 -0800 Subject: [PATCH 078/170] Zone wizard UI: Fix CSS for progress box at end of flow --- ui/css/cloudstack3.css | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 949e8c3052c..96196a011fa 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -6453,15 +6453,20 @@ label.error { left: 0; top: 0; margin: 23px 0 0px 6px; + font-weight: 100; + font-size: 14px; + color: #424242; } .multi-wizard.zone-wizard .review .main-desc.pre-setup { - width: 100%; + width: 90%; font-size: 18px; color: #2C4159; background: url(../images/icons.png) no-repeat 74px -224px; - padding: 6px 0 1px; + padding: 1px 0 1px 20px; text-align: center; + margin-left: 50px; + font-weight: 100; /*+placement:shift 0px 153px;*/ position: relative; left: 0px; @@ -7362,18 +7367,22 @@ label.error { overflow: auto; overflow-x: hidden; float: left; - background: #FFFFFF; + background: #ECECEC 0px -12px; + background: #F7F7F7; + background: -moz-linear-gradient(top, #f7f7f7 0%, #eaeaea 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f7f7f7), color-stop(100%,#eaeaea)); + background: -webkit-linear-gradient(top, #f7f7f7 0%,#eaeaea 100%); + background: -o-linear-gradient(top, #f7f7f7 0%,#eaeaea 100%); + background: -ms-linear-gradient(top, #f7f7f7 0%,#eaeaea 100%); + background: linear-gradient(to bottom, #f7f7f7 0%,#eaeaea 100%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f7f7f7', endColorstr='#eaeaea',GradientType=0 ); margin: 11px 0 0 7px; - /*+box-shadow:inset 0px 1px 4px #979797;*/ - -moz-box-shadow: inset 0px 1px 4px #979797; - -webkit-box-shadow: inset 0px 1px 4px #979797; - -o-box-shadow: inset 0px 1px 4px #979797; - box-shadow: inset 0px 1px 4px #979797; /*+border-radius:4px;*/ -moz-border-radius: 4px; -webkit-border-radius: 4px; -khtml-border-radius: 4px; border-radius: 4px; + border: 1px solid #CACACA; border-radius: 4px 4px 4px 4px; } From 2cbaf04b9751f57f6937c87a1cfe2396c2e53910 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 3 Dec 2013 13:11:48 -0800 Subject: [PATCH 079/170] CLOUDSTACK-4738: UI > VM Wizard > deployVM API has been changed to take in one new parameter CUSTOM_PARAMETERS instead of 3 parameters CPU_NUMBER/CPU_SPEED/MEMORY. Here is corresponding UI change. --- ui/scripts/instanceWizard.js | 147 +++++++++++++++++++++++------------ 1 file changed, 98 insertions(+), 49 deletions(-) diff --git a/ui/scripts/instanceWizard.js b/ui/scripts/instanceWizard.js index 5f08218c638..c83080cb0d1 100644 --- a/ui/scripts/instanceWizard.js +++ b/ui/scripts/instanceWizard.js @@ -581,41 +581,64 @@ ], action: function(args) { // Create a new VM!!!! - var array1 = []; + var deployVmData = {}; - //step 1 : select zone - array1.push("&zoneId=" + args.data.zoneid); + //step 1 : select zone + $.extend(deployVmData, { + zoneid : args.data.zoneid + }); - //step 2: select template - array1.push("&templateId=" + args.data.templateid); - array1.push("&hypervisor=" + selectedHypervisor); + //step 2: select template + $.extend(deployVmData, { + templateid : args.data.templateid + }); + + $.extend(deployVmData, { + hypervisor : selectedHypervisor + }); if (args.$wizard.find('input[name=rootDiskSize]').parent().css('display') != 'none') { - if (args.$wizard.find('input[name=rootDiskSize]').val().length > 0) { - array1.push("&rootdisksize=" + args.$wizard.find('input[name=rootDiskSize]').val()); + if (args.$wizard.find('input[name=rootDiskSize]').val().length > 0) { + $.extend(deployVmData, { + rootdisksize : args.$wizard.find('input[name=rootDiskSize]').val() + }); } } - //step 3: select service offering - array1.push("&serviceOfferingId=" + args.data.serviceofferingid); + //step 3: select service offering + $.extend(deployVmData, { + serviceofferingid : args.data.serviceofferingid + }); if (args.$wizard.find('input[name=compute-cpu-cores]').parent().parent().css('display') != 'none') { - if (args.$wizard.find('input[name=compute-cpu-cores]').val().length > 0) { - array1.push("&cpunumber=" + args.$wizard.find('input[name=compute-cpu-cores]').val()); + if (args.$wizard.find('input[name=compute-cpu-cores]').val().length > 0) { + $.extend(deployVmData, { + 'customparameters[0].cpuNumber' : args.$wizard.find('input[name=compute-cpu-cores]').val() + }); } - if (args.$wizard.find('input[name=compute-cpu]').val().length > 0) { - array1.push("&cpuspeed=" + args.$wizard.find('input[name=compute-cpu]').val()); + if (args.$wizard.find('input[name=compute-cpu]').val().length > 0) { + $.extend(deployVmData, { + 'customparameters[0].cpuSpeed' : args.$wizard.find('input[name=compute-cpu]').val() + }); } - if (args.$wizard.find('input[name=compute-memory]').val().length > 0) { - array1.push("&memory=" + args.$wizard.find('input[name=compute-memory]').val()); + if (args.$wizard.find('input[name=compute-memory]').val().length > 0) { + $.extend(deployVmData, { + 'customparameters[0].memory' : args.$wizard.find('input[name=compute-memory]').val() + }); } } //step 4: select disk offering - if (args.data.diskofferingid != null && args.data.diskofferingid != "0") { - array1.push("&diskOfferingId=" + args.data.diskofferingid); - if (selectedDiskOfferingObj.iscustomized == true) - array1.push("&size=" + args.data.size); + if (args.data.diskofferingid != null && args.data.diskofferingid != "0") { + $.extend(deployVmData, { + diskofferingid : args.data.diskofferingid + }); + + if (selectedDiskOfferingObj.iscustomized == true) { + $.extend(deployVmData, { + size : args.data.size + }); + } } //step 5: select an affinity group @@ -629,8 +652,11 @@ checkedAffinityGroupIdArray = []; } - if (checkedAffinityGroupIdArray.length > 0) - array1.push("&affinitygroupids=" + checkedAffinityGroupIdArray.join(",")); + if (checkedAffinityGroupIdArray.length > 0) { + $.extend(deployVmData, { + affinitygroupids : checkedAffinityGroupIdArray.join(",") + }); + } //step 6: select network if (step6ContainerType == 'select-network' || step6ContainerType == 'select-advanced-sg') { @@ -651,7 +677,7 @@ if (args.data["new-network"] == "create-new-network") { var isCreateNetworkSuccessful = true; - var data = { + var createNetworkData = { networkOfferingId: args.data["new-network-networkofferingid"], name: args.data["new-network-name"], displayText: args.data["new-network-name"], @@ -660,7 +686,7 @@ $.ajax({ url: createURL('createNetwork'), - data: data, + data: createNetworkData, async: false, success: function(json) { newNetwork = json.createnetworkresponse.network; @@ -681,8 +707,9 @@ //create new network ends here //add default network first - if (defaultNetworkId != null && defaultNetworkId.length > 0) + if (defaultNetworkId != null && defaultNetworkId.length > 0) { array2.push(defaultNetworkId); + } //then, add other checked networks if (checkedNetworkIdArray.length > 0) { @@ -691,8 +718,11 @@ array2.push(checkedNetworkIdArray[i]); } } - - array1.push("&networkIds=" + array2.join(",")); + + $.extend(deployVmData, { + networkids : array2.join(",") + }); + } else if (step6ContainerType == 'select-security-group') { var checkedSecurityGroupIdArray; if (typeof(args.data["security-groups"]) == "object" && args.data["security-groups"].length != null) { //args.data["security-groups"] is an array of string, e.g. ["2375f8cc-8a73-4b8d-9b26-50885a25ffe0", "27c60d2a-de7f-4bb7-96e5-a602cec681df","c6301d77-99b5-4e8a-85e2-3ea2ab31c342"], @@ -704,8 +734,11 @@ checkedSecurityGroupIdArray = []; } - if (checkedSecurityGroupIdArray.length > 0) - array1.push("&securitygroupids=" + checkedSecurityGroupIdArray.join(",")); + if (checkedSecurityGroupIdArray.length > 0) { + $.extend(deployVmData, { + securitygroupids : checkedSecurityGroupIdArray.join(",") + }); + } if (selectedZoneObj.networktype == "Advanced" && selectedZoneObj.securitygroupsenabled == true) { // Advanced SG-enabled zone var array2 = []; @@ -723,8 +756,9 @@ } //add default network first - if (defaultNetworkId != null && defaultNetworkId.length > 0 && defaultNetworkId != 'new-network') + if (defaultNetworkId != null && defaultNetworkId.length > 0 && defaultNetworkId != 'new-network') { array2.push(defaultNetworkId); + } //then, add other checked networks if (checkedNetworkIdArray.length > 0) { @@ -733,36 +767,51 @@ array2.push(checkedNetworkIdArray[i]); } } - - array1.push("&networkIds=" + array2.join(",")); + + $.extend(deployVmData, { + networkids : array2.join(",") + }); } } else if (step6ContainerType == 'nothing-to-select') { - if (args.context.networks != null) { //from VPC tier - array1.push("&networkIds=" + args.context.networks[0].id); - array1.push("&domainid=" + args.context.vpc[0].domainid); - - if (args.context.vpc[0].account != null) - array1.push("&account=" + args.context.vpc[0].account); - else if (args.context.vpc[0].projectid != null) - array1.push("&projectid=" + args.context.vpc[0].projectid); + if (args.context.networks != null) { //from VPC tier + $.extend(deployVmData, { + networkids : args.context.networks[0].id + }); + $.extend(deployVmData, { + domainid : args.context.vpc[0].domainid + }); + if (args.context.vpc[0].account != null) { + $.extend(deployVmData, { + account : args.context.vpc[0].account + }); + } else if (args.context.vpc[0].projectid != null) { + $.extend(deployVmData, { + projectid : args.context.vpc[0].projectid + }); + } } } var displayname = args.data.displayname; - if (displayname != null && displayname.length > 0) { - array1.push("&displayname=" + todb(displayname)); - array1.push("&name=" + todb(displayname)); + if (displayname != null && displayname.length > 0) { + $.extend(deployVmData, { + displayname : displayname + }); + $.extend(deployVmData, { + name : displayname + }); } var group = args.data.groupname; - if (group != null && group.length > 0) - array1.push("&group=" + todb(group)); - - //array1.push("&startVm=false"); //for testing only, comment it out before checking in + if (group != null && group.length > 0) { + $.extend(deployVmData, { + group : group + }); + } $.ajax({ - url: createURL("deployVirtualMachine" + array1.join("")), - dataType: "json", + url: createURL('deployVirtualMachine'), + data: deployVmData, success: function(json) { var jid = json.deployvirtualmachineresponse.jobid; var vmid = json.deployvirtualmachineresponse.id; From 03c78247ccb8dd260350b8102d6ec415d30e892f Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Tue, 3 Dec 2013 14:54:59 -0800 Subject: [PATCH 080/170] CLOUDSTACK-3364: change updateIsoPermissions API to accept isextractable paramter from normal user --- .../cloud/template/TemplateManagerImpl.java | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index b3da060f9ed..f2fdcee6540 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -1264,18 +1264,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, updatedTemplate.setFeatured(isFeatured.booleanValue()); } - if (isExtractable != null && caller.getType() == Account.ACCOUNT_TYPE_ADMIN) {// Only - // ROOT - // admins - // allowed - // to - // change - // this - // powerful - // attribute - updatedTemplate.setExtractable(isExtractable.booleanValue()); - } else if (isExtractable != null && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { - throw new InvalidParameterValueException("Only ROOT admins are allowed to modify this attribute."); + if(isExtractable != null){ + // Only Root admins allowed to change it for templates + if(!template.getFormat().equals(ImageFormat.ISO) && caller.getType() != Account.ACCOUNT_TYPE_ADMIN){ + throw new InvalidParameterValueException("Only ROOT admins are allowed to modify this attribute."); + }else{ + // For Isos normal user can change it, as their are no derivatives. + updatedTemplate.setExtractable(isExtractable.booleanValue()); + } } _tmpltDao.update(template.getId(), updatedTemplate); From b84f5791c3bf013c634031fbb1d1c6cf526275a6 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 3 Dec 2013 15:20:16 -0800 Subject: [PATCH 081/170] Dashboard, alerts: Fix width of title --- ui/css/cloudstack3.css | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 96196a011fa..c60e722c945 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -4455,6 +4455,7 @@ Dialogs*/ } .dashboard.admin .dashboard-container.sub.alerts ul li span.title { + width: 100%; font-weight: bold; font-size: 14px; font-weight: 100; From c77dca2d3e9a662cd8cbd4822976e4743fb16964 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 3 Dec 2013 15:36:15 -0800 Subject: [PATCH 082/170] CLOUDSTACK-5301: Show VPC routers on main VR page, to support upgrade feature --- ui/scripts/system.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 8f1572a91e7..7e4bb61b34f 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -7601,7 +7601,7 @@ } var data2 = { - forvpc: false + // forvpc: false }; var routers = []; From 1c4f1deaa88584850c31e1012c7c48aaf3ed7b48 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 3 Dec 2013 15:45:35 -0800 Subject: [PATCH 083/170] CLOUDSTACK-4061: Fix wrapping text with ja ui --- ui/css/cloudstack3.css | 1 + ui/css/cloudstack3.ja.css | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index c60e722c945..7b1dde0ab9f 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -214,6 +214,7 @@ table thead th.quick-view { width: 58px !important; height: 14px !important; text-indent: 2px; + white-space: nowrap; } table tbody td.quick-view { diff --git a/ui/css/cloudstack3.ja.css b/ui/css/cloudstack3.ja.css index 85c23a17c40..1d53e6e4d91 100644 --- a/ui/css/cloudstack3.ja.css +++ b/ui/css/cloudstack3.ja.css @@ -1,3 +1,4 @@ +/*[fmt]1C20-1C0D-E*/ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -6,9 +7,9 @@ * 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 @@ -16,7 +17,6 @@ * specific language governing permissions and limitations * under the License. */ -/*[fmt]1C20-1C0D-E*/ #header div.view-switcher { font-size: 9px; } @@ -50,3 +50,17 @@ div.toolbar div.filters select { font-size: 11px; } +div.toolbar div.button.add, +div.toolbar div.button.refresh, +div.toolbar div.button.add, +div.toolbar div.button.main-action, +.toolbar div.button.header-action, +.detail-group .button.add { + font-size: 10px; +} + +table tbody td.quick-view, +table thead th.quick-view { + font-size: 8px; +} + From f420b748903eb261e7721512da0168733d82d202 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 3 Dec 2013 15:42:38 -0800 Subject: [PATCH 084/170] CLOUDSTACK-5355: addImageStore should not log password in clear text in the log. --- .../lifecycle/CloudStackImageStoreLifeCycleImpl.java | 6 ++++-- utils/src/com/cloud/utils/StringUtils.java | 4 ++-- utils/test/com/cloud/utils/StringUtilsTest.java | 8 ++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java index fa07eb8a971..95c90349a03 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java @@ -26,6 +26,8 @@ import javax.inject.Inject; import org.apache.log4j.Logger; +import com.ibm.wsdl.util.StringUtils; + import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; @@ -84,13 +86,13 @@ public class CloudStackImageStoreLifeCycleImpl implements ImageStoreLifeCycle { DataStoreRole role = (DataStoreRole)dsInfos.get("role"); Map details = (Map)dsInfos.get("details"); - s_logger.info("Trying to add a new data store at " + url + " to data center " + dcId); + s_logger.info("Trying to add a new data store at " + StringUtils.cleanString(url) + " to data center " + dcId); URI uri = null; try { uri = new URI(UriUtils.encodeURIComponent(url)); if (uri.getScheme() == null) { - throw new InvalidParameterValueException("uri.scheme is null " + url + ", add nfs:// (or cifs://) as a prefix"); + throw new InvalidParameterValueException("uri.scheme is null " + StringUtils.cleanString(url) + ", add nfs:// (or cifs://) as a prefix"); } else if (uri.getScheme().equalsIgnoreCase("nfs")) { if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) { throw new InvalidParameterValueException("Your host and/or path is wrong. Make sure it's of the format nfs://hostname/path"); diff --git a/utils/src/com/cloud/utils/StringUtils.java b/utils/src/com/cloud/utils/StringUtils.java index fef96f9e9c0..ddd09de2a50 100644 --- a/utils/src/com/cloud/utils/StringUtils.java +++ b/utils/src/com/cloud/utils/StringUtils.java @@ -152,8 +152,8 @@ public class StringUtils { return sb.toString(); } - // removes a password request param and it's value - private static final Pattern REGEX_PASSWORD_QUERYSTRING = Pattern.compile("&?(password|accesskey|secretkey)=.*?(?=[&'\"])"); + // removes a password request param and it's value, also considering password is in query parameter value which has been url encoded + private static final Pattern REGEX_PASSWORD_QUERYSTRING = Pattern.compile("(&|%26)?(password|accesskey|secretkey)(=|%3D).*?(?=(%26|[&'\"]))"); // removes a password/accesskey/ property from a response json object private static final Pattern REGEX_PASSWORD_JSON = Pattern.compile("\"(password|accesskey|secretkey)\":\".*?\",?"); diff --git a/utils/test/com/cloud/utils/StringUtilsTest.java b/utils/test/com/cloud/utils/StringUtilsTest.java index 28da7e89f29..cc22f9db7a9 100644 --- a/utils/test/com/cloud/utils/StringUtilsTest.java +++ b/utils/test/com/cloud/utils/StringUtilsTest.java @@ -71,6 +71,14 @@ public class StringUtilsTest { assertEquals(result, expected); } + @Test + public void testCleanPasswordFromEncodedRequestString() { + String input = "name=SS1&provider=SMB&zoneid=5a60af2b-3025-4f2a-9ecc-8e33bf2b94e3&url=cifs%3A%2F%2F10.102.192.150%2FSMB-Share%2Fsowmya%2Fsecondary%3Fuser%3Dsowmya%26password%3DXXXXX%40123%26domain%3DBLR"; + String expected = "name=SS1&provider=SMB&zoneid=5a60af2b-3025-4f2a-9ecc-8e33bf2b94e3&url=cifs%3A%2F%2F10.102.192.150%2FSMB-Share%2Fsowmya%2Fsecondary%3Fuser%3Dsowmya%26domain%3DBLR"; + String result = StringUtils.cleanString(input); + assertEquals(result, expected); + } + @Test public void testCleanPasswordFromRequestStringWithMultiplePasswords() { String input = "username=foo&password=bar&url=foobar&password=bar2&test=4"; From 5a96307fbf81ce42b3ad82a56bc6a1b2434cb396 Mon Sep 17 00:00:00 2001 From: Devdeep Singh Date: Tue, 3 Dec 2013 17:27:24 +0530 Subject: [PATCH 085/170] Changes for allowing migration of a vm on hyperv. Migration was blocked in cloudstack for hyperv. Enabled it. Also updated the agent code to allow hyperv migration. --- .../HypervResource/CloudStackTypes.cs | 1 + .../HypervResourceController.cs | 10 +- .../HypervResource/IWmiCallsV2.cs | 1 + .../HypervResource/WmiCallsV2.cs | 98 +- ...OOT.virtualization.v2.Msvm_MigrationJob.cs | 1867 +++++++++++++++++ ...n.v2.Msvm_VirtualSystemMigrationService.cs | 1581 ++++++++++++++ ....Msvm_VirtualSystemMigrationSettingData.cs | 915 ++++++++ .../WmiWrappers/WmiWrappers.csproj | 11 +- .../cloud/server/ManagementServerImpl.java | 10 +- .../src/com/cloud/vm/UserVmManagerImpl.java | 15 +- 10 files changed, 4495 insertions(+), 14 deletions(-) create mode 100644 plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/ROOT.virtualization.v2.Msvm_MigrationJob.cs create mode 100644 plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/ROOT.virtualization.v2.Msvm_VirtualSystemMigrationService.cs create mode 100644 plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/ROOT.virtualization.v2.Msvm_VirtualSystemMigrationSettingData.cs diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs index af8c61f20f5..7a373a410ad 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs @@ -160,6 +160,7 @@ namespace HypervResource else { fileName = @"\\" + this.primaryDataStore.uri.Host + this.primaryDataStore.uri.LocalPath + @"\" + this.name; + fileName = fileName.Replace(@"/", @"\"); } if (this.format != null) diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index fd6fe9f5583..fc4dea5748d 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -1477,14 +1477,15 @@ namespace HypervResource logger.Info(CloudStackTypes.PrepareForMigrationCommand + cmd.ToString()); string details = null; - bool result = false; + bool result = true; try { - details = "NOP - failure"; + details = "NOP - success"; } catch (Exception sysEx) { + result = false; details = CloudStackTypes.PrepareForMigrationCommand + " failed due to " + sysEx.Message; logger.Error(details, sysEx); } @@ -1514,7 +1515,10 @@ namespace HypervResource try { - details = "NOP - failure"; + string vm = (string)cmd.vmName; + string destination = (string)cmd.destIp; + wmiCallsV2.MigrateVm(vm, destination); + result = true; } catch (Exception sysEx) { diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs index 223f7481071..99ce35276b7 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs @@ -38,6 +38,7 @@ namespace HypervResource ComputerSystem DeployVirtualMachine(dynamic jsonObj, string systemVmIso); void DestroyVm(dynamic jsonObj); void DestroyVm(string displayName); + void MigrateVm(string vmName, string destination); void DetachDisk(string displayName, string diskFileName); ComputerSystem GetComputerSystem(string displayName); string GetDefaultDataRoot(); diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs index e2d4f6c4b91..c0201682cb0 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs @@ -36,6 +36,26 @@ namespace HypervResource { public static String CloudStackUserDataKey = "cloudstack-vm-userdata"; + /// + /// Defines the migration types. + /// + public enum MigrationType + { + VirtualSystem = 32768, + Storage = 32769, + Staged = 32770, + VirtualSystemAndStorage = 32771 + }; + + /// + /// Defines migration transport types. + /// + public enum TransportType + { + TCP = 5, + SMB = 32768 + }; + public static void Initialize() { // Trigger assembly load into curren appdomain @@ -858,7 +878,42 @@ namespace HypervResource } while (vm != null); } - + + /// + /// Migrates a vm to the given destination host + /// + /// + /// + public void MigrateVm(string vmName, string destination) + { + ComputerSystem vm = GetComputerSystem(vmName); + VirtualSystemMigrationSettingData migrationSettingData = VirtualSystemMigrationSettingData.CreateInstance(); + VirtualSystemMigrationService service = GetVirtualisationSystemMigrationService(); + + migrationSettingData.LateBoundObject["MigrationType"] = MigrationType.VirtualSystem; + migrationSettingData.LateBoundObject["TransportType"] = TransportType.TCP; + string migrationSettings = migrationSettingData.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20); + + ManagementPath jobPath; + string destinationHost = "band-cloud153.blr.cloudstack.org"; + var ret_val = service.MigrateVirtualSystemToHost(vm.Path, destinationHost, migrationSettings, null, null, out jobPath); + if (ret_val == ReturnCode.Started) + { + MigrationJobCompleted(jobPath); + } + else if (ret_val != ReturnCode.Completed) + { + var errMsg = string.Format( + "Failed migrating VM {0} (GUID {1}) due to {2}", + vm.ElementName, + vm.Name, + ReturnCode.ToString(ret_val)); + var ex = new WmiException(errMsg); + logger.Error(errMsg, ex); + throw ex; + } + } + /// /// Create new storage media resources, e.g. hard disk images and ISO disk images /// see http://msdn.microsoft.com/en-us/library/hh859775(v=vs.85).aspx @@ -1475,6 +1530,21 @@ namespace HypervResource throw ex; } + public VirtualSystemMigrationService GetVirtualisationSystemMigrationService() + { + + var virtSysMigSvcCollection = VirtualSystemMigrationService.GetInstances(); + foreach (VirtualSystemMigrationService item in virtSysMigSvcCollection) + { + return item; + } + + var errMsg = string.Format("No Hyper-V migration service subsystem on server"); + var ex = new WmiException(errMsg); + logger.Error(errMsg, ex); + throw ex; + } + /// /// Similar to http://msdn.microsoft.com/en-us/library/hh850031%28v=vs.85%29.aspx /// @@ -1508,6 +1578,32 @@ namespace HypervResource logger.DebugFormat("WMI job succeeded: {0}, Elapsed={1}", jobObj.Description, jobObj.ElapsedTime); } + private static void MigrationJobCompleted(ManagementPath jobPath) + { + MigrationJob jobObj = null; + for (;;) + { + jobObj = new MigrationJob(jobPath); + if (jobObj.JobState != JobState.Starting && jobObj.JobState != JobState.Running) + { + break; + } + logger.InfoFormat("In progress... {0}% completed.", jobObj.PercentComplete); + System.Threading.Thread.Sleep(1000); + } + + if (jobObj.JobState != JobState.Completed) + { + var errMsg = string.Format( + "Hyper-V Job failed, Error Code:{0}, Description: {1}", + jobObj.ErrorCode, + jobObj.ErrorDescription); + var ex = new WmiException(errMsg); + logger.Error(errMsg, ex); + throw ex; + } + } + public void GetProcessorResources(out uint cores, out uint mhz) { // Processor processors diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/ROOT.virtualization.v2.Msvm_MigrationJob.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/ROOT.virtualization.v2.Msvm_MigrationJob.cs new file mode 100644 index 00000000000..7b7e5f1d088 --- /dev/null +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/ROOT.virtualization.v2.Msvm_MigrationJob.cs @@ -0,0 +1,1867 @@ +// 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. + +namespace CloudStack.Plugin.WmiWrappers.ROOT.VIRTUALIZATION.V2 { + using System; + using System.ComponentModel; + using System.Management; + using System.Collections; + using System.Globalization; + using System.ComponentModel.Design.Serialization; + using System.Reflection; + + + // Functions ShouldSerialize are functions used by VS property browser to check if a particular property has to be serialized. These functions are added for all ValueType properties ( properties of type Int32, BOOL etc.. which cannot be set to null). These functions use IsNull function. These functions are also used in the TypeConverter implementation for the properties to check for NULL value of property so that an empty value can be shown in Property browser in case of Drag and Drop in Visual studio. + // Functions IsNull() are used to check if a property is NULL. + // Functions Reset are added for Nullable Read/Write properties. These functions are used by VS designer in property browser to set a property to NULL. + // Every property added to the class for WMI property has attributes set to define its behavior in Visual Studio designer and also to define a TypeConverter to be used. + // Datetime conversion functions ToDateTime and ToDmtfDateTime are added to the class to convert DMTF datetime to System.DateTime and vice-versa. + // An Early Bound class generated for the WMI class.Msvm_MigrationJob + public class MigrationJob : System.ComponentModel.Component { + + // Private property to hold the WMI namespace in which the class resides. + private static string CreatedWmiNamespace = "ROOT\\virtualization\\v2"; + + // Private property to hold the name of WMI class which created this class. + public static string CreatedClassName = "Msvm_MigrationJob"; + + // Private member variable to hold the ManagementScope which is used by the various methods. + private static System.Management.ManagementScope statMgmtScope = null; + + private ManagementSystemProperties PrivateSystemProperties; + + // Underlying lateBound WMI object. + private System.Management.ManagementObject PrivateLateBoundObject; + + // Member variable to store the 'automatic commit' behavior for the class. + private bool AutoCommitProp; + + // Private variable to hold the embedded property representing the instance. + private System.Management.ManagementBaseObject embeddedObj; + + // The current WMI object used + private System.Management.ManagementBaseObject curObj; + + // Flag to indicate if the instance is an embedded object. + private bool isEmbedded; + + // Below are different overloads of constructors to initialize an instance of the class with a WMI object. + public MigrationJob() { + this.InitializeObject(null, null, null); + } + + public MigrationJob(string keyInstanceID) { + this.InitializeObject(null, new System.Management.ManagementPath(MigrationJob.ConstructPath(keyInstanceID)), null); + } + + public MigrationJob(System.Management.ManagementScope mgmtScope, string keyInstanceID) { + this.InitializeObject(((System.Management.ManagementScope)(mgmtScope)), new System.Management.ManagementPath(MigrationJob.ConstructPath(keyInstanceID)), null); + } + + public MigrationJob(System.Management.ManagementPath path, System.Management.ObjectGetOptions getOptions) { + this.InitializeObject(null, path, getOptions); + } + + public MigrationJob(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path) { + this.InitializeObject(mgmtScope, path, null); + } + + public MigrationJob(System.Management.ManagementPath path) { + this.InitializeObject(null, path, null); + } + + public MigrationJob(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path, System.Management.ObjectGetOptions getOptions) { + this.InitializeObject(mgmtScope, path, getOptions); + } + + public MigrationJob(System.Management.ManagementObject theObject) { + Initialize(); + if ((CheckIfProperClass(theObject) == true)) { + PrivateLateBoundObject = theObject; + PrivateSystemProperties = new ManagementSystemProperties(PrivateLateBoundObject); + curObj = PrivateLateBoundObject; + } + else { + throw new System.ArgumentException("Class name does not match."); + } + } + + public MigrationJob(System.Management.ManagementBaseObject theObject) { + Initialize(); + if ((CheckIfProperClass(theObject) == true)) { + embeddedObj = theObject; + PrivateSystemProperties = new ManagementSystemProperties(theObject); + curObj = embeddedObj; + isEmbedded = true; + } + else { + throw new System.ArgumentException("Class name does not match."); + } + } + + // Property returns the namespace of the WMI class. + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string OriginatingNamespace { + get { + return "ROOT\\virtualization\\v2"; + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string ManagementClassName { + get { + string strRet = CreatedClassName; + if ((curObj != null)) { + if ((curObj.ClassPath != null)) { + strRet = ((string)(curObj["__CLASS"])); + if (((strRet == null) + || (strRet == string.Empty))) { + strRet = CreatedClassName; + } + } + } + return strRet; + } + } + + // Property pointing to an embedded object to get System properties of the WMI object. + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ManagementSystemProperties SystemProperties { + get { + return PrivateSystemProperties; + } + } + + // Property returning the underlying lateBound object. + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public System.Management.ManagementBaseObject LateBoundObject { + get { + return curObj; + } + } + + // ManagementScope of the object. + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public System.Management.ManagementScope Scope { + get { + if ((isEmbedded == false)) { + return PrivateLateBoundObject.Scope; + } + else { + return null; + } + } + set { + if ((isEmbedded == false)) { + PrivateLateBoundObject.Scope = value; + } + } + } + + // Property to show the commit behavior for the WMI object. If true, WMI object will be automatically saved after each property modification.(ie. Put() is called after modification of a property). + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool AutoCommit { + get { + return AutoCommitProp; + } + set { + AutoCommitProp = value; + } + } + + // The ManagementPath of the underlying WMI object. + [Browsable(true)] + public System.Management.ManagementPath Path { + get { + if ((isEmbedded == false)) { + return PrivateLateBoundObject.Path; + } + else { + return null; + } + } + set { + if ((isEmbedded == false)) { + if ((CheckIfProperClass(null, value, null) != true)) { + throw new System.ArgumentException("Class name does not match."); + } + PrivateLateBoundObject.Path = value; + } + } + } + + // Public static scope property which is used by the various methods. + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public static System.Management.ManagementScope StaticScope { + get { + return statMgmtScope; + } + set { + statMgmtScope = value; + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsCancellableNull { + get { + if ((curObj["Cancellable"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates whether the job can be cancelled. The value of this property does not g" + + "uarantee that a request to cancel the job will succeed.")] + [TypeConverter(typeof(WMIValueTypeConverter))] + public bool Cancellable { + get { + if ((curObj["Cancellable"] == null)) { + return System.Convert.ToBoolean(0); + } + return ((bool)(curObj["Cancellable"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Caption { + get { + return ((string)(curObj["Caption"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsCommunicationStatusNull { + get { + if ((curObj["CommunicationStatus"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort CommunicationStatus { + get { + if ((curObj["CommunicationStatus"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["CommunicationStatus"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsDeleteOnCompletionNull { + get { + if ((curObj["DeleteOnCompletion"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public bool DeleteOnCompletion { + get { + if ((curObj["DeleteOnCompletion"] == null)) { + return System.Convert.ToBoolean(0); + } + return ((bool)(curObj["DeleteOnCompletion"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Description { + get { + return ((string)(curObj["Description"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Hostname the destination virtualization platform where the virtual system is migr" + + "ating. It will be NULL for storage migration.")] + public string DestinationHost { + get { + return ((string)(curObj["DestinationHost"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsDetailedStatusNull { + get { + if ((curObj["DetailedStatus"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort DetailedStatus { + get { + if ((curObj["DetailedStatus"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["DetailedStatus"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsElapsedTimeNull { + get { + if ((curObj["ElapsedTime"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime ElapsedTime { + get { + if ((curObj["ElapsedTime"] != null)) { + return ToDateTime(((string)(curObj["ElapsedTime"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string ElementName { + get { + return ((string)(curObj["ElementName"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsErrorCodeNull { + get { + if ((curObj["ErrorCode"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort ErrorCode { + get { + if ((curObj["ErrorCode"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["ErrorCode"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string ErrorDescription { + get { + return ((string)(curObj["ErrorDescription"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string ErrorSummaryDescription { + get { + return ((string)(curObj["ErrorSummaryDescription"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsHealthStateNull { + get { + if ((curObj["HealthState"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort HealthState { + get { + if ((curObj["HealthState"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["HealthState"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsInstallDateNull { + get { + if ((curObj["InstallDate"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime InstallDate { + get { + if ((curObj["InstallDate"] != null)) { + return ToDateTime(((string)(curObj["InstallDate"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string InstanceID { + get { + return ((string)(curObj["InstanceID"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsJobRunTimesNull { + get { + if ((curObj["JobRunTimes"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public uint JobRunTimes { + get { + if ((curObj["JobRunTimes"] == null)) { + return System.Convert.ToUInt32(0); + } + return ((uint)(curObj["JobRunTimes"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsJobStateNull { + get { + if ((curObj["JobState"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort JobState { + get { + if ((curObj["JobState"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["JobState"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string JobStatus { + get { + return ((string)(curObj["JobStatus"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsJobTypeNull { + get { + if ((curObj["JobType"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates the type of Job being tracked by this object.")] + [TypeConverter(typeof(WMIValueTypeConverter))] + public JobTypeValues JobType { + get { + if ((curObj["JobType"] == null)) { + return ((JobTypeValues)(System.Convert.ToInt32(308))); + } + return ((JobTypeValues)(System.Convert.ToInt32(curObj["JobType"]))); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsLocalOrUtcTimeNull { + get { + if ((curObj["LocalOrUtcTime"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort LocalOrUtcTime { + get { + if ((curObj["LocalOrUtcTime"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["LocalOrUtcTime"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsMigrationTypeNull { + get { + if ((curObj["MigrationType"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("The migration type as defined in Msvm_VirtualSystemMigrationSettingData.Migration" + + "Type. This can beused to identify the type of migration the job represents.")] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort MigrationType { + get { + if ((curObj["MigrationType"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["MigrationType"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Name { + get { + return ((string)(curObj["Name"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description(@"For Live Migration this must be set to NULL. For Storage Migration, it will specify the virtual machine's virtual hard drives which moved and where they moved. If not NULL, NewResourceSettingData will contain an array of embedded instances of resource allocation setting data (RASD) which represent VHDs. Destination location will be provided using Connection property of RASD.")] + public string[] NewResourceSettingData { + get { + return ((string[])(curObj["NewResourceSettingData"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description(@"For Live Migration this will be set to NULL. For Storage Migration, it will indicate the new path for virtual machine data (ExternalDataRoot, SnapshotDataRoot and SwapFileDataRoot). This being NULL indicates that virtual machine's data roots are not moving. Otherwise NewSystemSettingData will be instance of Msvm_VirtualSystemGlobalSettingData containing properties ExternalDataRoot, SnapshotDataRoot and SwapFileDataRoot. If not NULL, ExternalDataRoot property will specify new location of virtual machine's current configuration and saved state. If not NULL, SnapshotDataRoot property will specify new location for snapshots data. If not NULL, SwapFileDataRoot property will specify new location of virtual machine's smart paging files ")] + public string NewSystemSettingData { + get { + return ((string)(curObj["NewSystemSettingData"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Notify { + get { + return ((string)(curObj["Notify"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsOperatingStatusNull { + get { + if ((curObj["OperatingStatus"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort OperatingStatus { + get { + if ((curObj["OperatingStatus"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["OperatingStatus"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ushort[] OperationalStatus { + get { + return ((ushort[])(curObj["OperationalStatus"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string OtherRecoveryAction { + get { + return ((string)(curObj["OtherRecoveryAction"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Owner { + get { + return ((string)(curObj["Owner"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsPercentCompleteNull { + get { + if ((curObj["PercentComplete"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort PercentComplete { + get { + if ((curObj["PercentComplete"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["PercentComplete"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsPrimaryStatusNull { + get { + if ((curObj["PrimaryStatus"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort PrimaryStatus { + get { + if ((curObj["PrimaryStatus"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["PrimaryStatus"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsPriorityNull { + get { + if ((curObj["Priority"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public uint Priority { + get { + if ((curObj["Priority"] == null)) { + return System.Convert.ToUInt32(0); + } + return ((uint)(curObj["Priority"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsRecoveryActionNull { + get { + if ((curObj["RecoveryAction"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort RecoveryAction { + get { + if ((curObj["RecoveryAction"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["RecoveryAction"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsRunDayNull { + get { + if ((curObj["RunDay"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public sbyte RunDay { + get { + if ((curObj["RunDay"] == null)) { + return System.Convert.ToSByte(0); + } + return ((sbyte)(curObj["RunDay"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsRunDayOfWeekNull { + get { + if ((curObj["RunDayOfWeek"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public sbyte RunDayOfWeek { + get { + if ((curObj["RunDayOfWeek"] == null)) { + return System.Convert.ToSByte(0); + } + return ((sbyte)(curObj["RunDayOfWeek"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsRunMonthNull { + get { + if ((curObj["RunMonth"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public byte RunMonth { + get { + if ((curObj["RunMonth"] == null)) { + return System.Convert.ToByte(0); + } + return ((byte)(curObj["RunMonth"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsRunStartIntervalNull { + get { + if ((curObj["RunStartInterval"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime RunStartInterval { + get { + if ((curObj["RunStartInterval"] != null)) { + return ToDateTime(((string)(curObj["RunStartInterval"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsScheduledStartTimeNull { + get { + if ((curObj["ScheduledStartTime"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime ScheduledStartTime { + get { + if ((curObj["ScheduledStartTime"] != null)) { + return ToDateTime(((string)(curObj["ScheduledStartTime"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsStartTimeNull { + get { + if ((curObj["StartTime"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime StartTime { + get { + if ((curObj["StartTime"] != null)) { + return ToDateTime(((string)(curObj["StartTime"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Status { + get { + return ((string)(curObj["Status"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string[] StatusDescriptions { + get { + return ((string[])(curObj["StatusDescriptions"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsTimeBeforeRemovalNull { + get { + if ((curObj["TimeBeforeRemoval"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime TimeBeforeRemoval { + get { + if ((curObj["TimeBeforeRemoval"] != null)) { + return ToDateTime(((string)(curObj["TimeBeforeRemoval"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsTimeOfLastStateChangeNull { + get { + if ((curObj["TimeOfLastStateChange"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime TimeOfLastStateChange { + get { + if ((curObj["TimeOfLastStateChange"] != null)) { + return ToDateTime(((string)(curObj["TimeOfLastStateChange"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsTimeSubmittedNull { + get { + if ((curObj["TimeSubmitted"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime TimeSubmitted { + get { + if ((curObj["TimeSubmitted"] != null)) { + return ToDateTime(((string)(curObj["TimeSubmitted"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsUntilTimeNull { + get { + if ((curObj["UntilTime"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime UntilTime { + get { + if ((curObj["UntilTime"] != null)) { + return ToDateTime(((string)(curObj["UntilTime"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("GUID of the affected virtual system.")] + public string VirtualSystemName { + get { + return ((string)(curObj["VirtualSystemName"])); + } + } + + private bool CheckIfProperClass(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path, System.Management.ObjectGetOptions OptionsParam) { + if (((path != null) + && (string.Compare(path.ClassName, this.ManagementClassName, true, System.Globalization.CultureInfo.InvariantCulture) == 0))) { + return true; + } + else { + return CheckIfProperClass(new System.Management.ManagementObject(mgmtScope, path, OptionsParam)); + } + } + + private bool CheckIfProperClass(System.Management.ManagementBaseObject theObj) { + if (((theObj != null) + && (string.Compare(((string)(theObj["__CLASS"])), this.ManagementClassName, true, System.Globalization.CultureInfo.InvariantCulture) == 0))) { + return true; + } + else { + System.Array parentClasses = ((System.Array)(theObj["__DERIVATION"])); + if ((parentClasses != null)) { + int count = 0; + for (count = 0; (count < parentClasses.Length); count = (count + 1)) { + if ((string.Compare(((string)(parentClasses.GetValue(count))), this.ManagementClassName, true, System.Globalization.CultureInfo.InvariantCulture) == 0)) { + return true; + } + } + } + } + return false; + } + + private bool ShouldSerializeCancellable() { + if ((this.IsCancellableNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeCommunicationStatus() { + if ((this.IsCommunicationStatusNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeDeleteOnCompletion() { + if ((this.IsDeleteOnCompletionNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeDetailedStatus() { + if ((this.IsDetailedStatusNull == false)) { + return true; + } + return false; + } + + // Converts a given datetime in DMTF format to System.DateTime object. + static System.DateTime ToDateTime(string dmtfDate) { + System.DateTime initializer = System.DateTime.MinValue; + int year = initializer.Year; + int month = initializer.Month; + int day = initializer.Day; + int hour = initializer.Hour; + int minute = initializer.Minute; + int second = initializer.Second; + long ticks = 0; + string dmtf = dmtfDate; + System.DateTime datetime = System.DateTime.MinValue; + string tempString = string.Empty; + if ((dmtf == null)) { + throw new System.ArgumentOutOfRangeException(); + } + if ((dmtf.Length == 0)) { + throw new System.ArgumentOutOfRangeException(); + } + if ((dmtf.Length != 25)) { + throw new System.ArgumentOutOfRangeException(); + } + try { + tempString = dmtf.Substring(0, 4); + if (("****" != tempString)) { + year = int.Parse(tempString); + } + tempString = dmtf.Substring(4, 2); + if (("**" != tempString)) { + month = int.Parse(tempString); + } + tempString = dmtf.Substring(6, 2); + if (("**" != tempString)) { + day = int.Parse(tempString); + } + tempString = dmtf.Substring(8, 2); + if (("**" != tempString)) { + hour = int.Parse(tempString); + } + tempString = dmtf.Substring(10, 2); + if (("**" != tempString)) { + minute = int.Parse(tempString); + } + tempString = dmtf.Substring(12, 2); + if (("**" != tempString)) { + second = int.Parse(tempString); + } + tempString = dmtf.Substring(15, 6); + if (("******" != tempString)) { + ticks = (long.Parse(tempString) * ((long)((System.TimeSpan.TicksPerMillisecond / 1000)))); + } + if (((((((((year < 0) + || (month < 0)) + || (day < 0)) + || (hour < 0)) + || (minute < 0)) + || (minute < 0)) + || (second < 0)) + || (ticks < 0))) { + throw new System.ArgumentOutOfRangeException(); + } + } + catch (System.Exception e) { + throw new System.ArgumentOutOfRangeException(null, e.Message); + } + datetime = new System.DateTime(year, month, day, hour, minute, second, 0); + datetime = datetime.AddTicks(ticks); + System.TimeSpan tickOffset = System.TimeZone.CurrentTimeZone.GetUtcOffset(datetime); + int UTCOffset = 0; + int OffsetToBeAdjusted = 0; + long OffsetMins = ((long)((tickOffset.Ticks / System.TimeSpan.TicksPerMinute))); + tempString = dmtf.Substring(22, 3); + if ((tempString != "******")) { + tempString = dmtf.Substring(21, 4); + try { + UTCOffset = int.Parse(tempString); + } + catch (System.Exception e) { + throw new System.ArgumentOutOfRangeException(null, e.Message); + } + OffsetToBeAdjusted = ((int)((OffsetMins - UTCOffset))); + datetime = datetime.AddMinutes(((double)(OffsetToBeAdjusted))); + } + return datetime; + } + + // Converts a given System.DateTime object to DMTF datetime format. + static string ToDmtfDateTime(System.DateTime date) { + string utcString = string.Empty; + System.TimeSpan tickOffset = System.TimeZone.CurrentTimeZone.GetUtcOffset(date); + long OffsetMins = ((long)((tickOffset.Ticks / System.TimeSpan.TicksPerMinute))); + if ((System.Math.Abs(OffsetMins) > 999)) { + date = date.ToUniversalTime(); + utcString = "+000"; + } + else { + if ((tickOffset.Ticks >= 0)) { + utcString = string.Concat("+", ((long)((tickOffset.Ticks / System.TimeSpan.TicksPerMinute))).ToString().PadLeft(3, '0')); + } + else { + string strTemp = ((long)(OffsetMins)).ToString(); + utcString = string.Concat("-", strTemp.Substring(1, (strTemp.Length - 1)).PadLeft(3, '0')); + } + } + string dmtfDateTime = ((int)(date.Year)).ToString().PadLeft(4, '0'); + dmtfDateTime = string.Concat(dmtfDateTime, ((int)(date.Month)).ToString().PadLeft(2, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, ((int)(date.Day)).ToString().PadLeft(2, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, ((int)(date.Hour)).ToString().PadLeft(2, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, ((int)(date.Minute)).ToString().PadLeft(2, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, ((int)(date.Second)).ToString().PadLeft(2, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, "."); + System.DateTime dtTemp = new System.DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, 0); + long microsec = ((long)((((date.Ticks - dtTemp.Ticks) + * 1000) + / System.TimeSpan.TicksPerMillisecond))); + string strMicrosec = ((long)(microsec)).ToString(); + if ((strMicrosec.Length > 6)) { + strMicrosec = strMicrosec.Substring(0, 6); + } + dmtfDateTime = string.Concat(dmtfDateTime, strMicrosec.PadLeft(6, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, utcString); + return dmtfDateTime; + } + + private bool ShouldSerializeElapsedTime() { + if ((this.IsElapsedTimeNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeErrorCode() { + if ((this.IsErrorCodeNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeHealthState() { + if ((this.IsHealthStateNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeInstallDate() { + if ((this.IsInstallDateNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeJobRunTimes() { + if ((this.IsJobRunTimesNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeJobState() { + if ((this.IsJobStateNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeJobType() { + if ((this.IsJobTypeNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeLocalOrUtcTime() { + if ((this.IsLocalOrUtcTimeNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeMigrationType() { + if ((this.IsMigrationTypeNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeOperatingStatus() { + if ((this.IsOperatingStatusNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializePercentComplete() { + if ((this.IsPercentCompleteNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializePrimaryStatus() { + if ((this.IsPrimaryStatusNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializePriority() { + if ((this.IsPriorityNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeRecoveryAction() { + if ((this.IsRecoveryActionNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeRunDay() { + if ((this.IsRunDayNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeRunDayOfWeek() { + if ((this.IsRunDayOfWeekNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeRunMonth() { + if ((this.IsRunMonthNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeRunStartInterval() { + if ((this.IsRunStartIntervalNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeScheduledStartTime() { + if ((this.IsScheduledStartTimeNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeStartTime() { + if ((this.IsStartTimeNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeTimeBeforeRemoval() { + if ((this.IsTimeBeforeRemovalNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeTimeOfLastStateChange() { + if ((this.IsTimeOfLastStateChangeNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeTimeSubmitted() { + if ((this.IsTimeSubmittedNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeUntilTime() { + if ((this.IsUntilTimeNull == false)) { + return true; + } + return false; + } + + [Browsable(true)] + public void CommitObject() { + if ((isEmbedded == false)) { + PrivateLateBoundObject.Put(); + } + } + + [Browsable(true)] + public void CommitObject(System.Management.PutOptions putOptions) { + if ((isEmbedded == false)) { + PrivateLateBoundObject.Put(putOptions); + } + } + + private void Initialize() { + AutoCommitProp = true; + isEmbedded = false; + } + + private static string ConstructPath(string keyInstanceID) { + string strPath = "ROOT\\virtualization\\v2:Msvm_MigrationJob"; + strPath = string.Concat(strPath, string.Concat(".InstanceID=", string.Concat("\"", string.Concat(keyInstanceID, "\"")))); + return strPath; + } + + private void InitializeObject(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path, System.Management.ObjectGetOptions getOptions) { + Initialize(); + if ((path != null)) { + if ((CheckIfProperClass(mgmtScope, path, getOptions) != true)) { + throw new System.ArgumentException("Class name does not match."); + } + } + PrivateLateBoundObject = new System.Management.ManagementObject(mgmtScope, path, getOptions); + PrivateSystemProperties = new ManagementSystemProperties(PrivateLateBoundObject); + curObj = PrivateLateBoundObject; + } + + // Different overloads of GetInstances() help in enumerating instances of the WMI class. + public static MigrationJobCollection GetInstances() { + return GetInstances(null, null, null); + } + + public static MigrationJobCollection GetInstances(string condition) { + return GetInstances(null, condition, null); + } + + public static MigrationJobCollection GetInstances(string[] selectedProperties) { + return GetInstances(null, null, selectedProperties); + } + + public static MigrationJobCollection GetInstances(string condition, string[] selectedProperties) { + return GetInstances(null, condition, selectedProperties); + } + + public static MigrationJobCollection GetInstances(System.Management.ManagementScope mgmtScope, System.Management.EnumerationOptions enumOptions) { + if ((mgmtScope == null)) { + if ((statMgmtScope == null)) { + mgmtScope = new System.Management.ManagementScope(); + mgmtScope.Path.NamespacePath = "root\\virtualization\\v2"; + } + else { + mgmtScope = statMgmtScope; + } + } + System.Management.ManagementPath pathObj = new System.Management.ManagementPath(); + pathObj.ClassName = "Msvm_MigrationJob"; + pathObj.NamespacePath = "root\\virtualization\\v2"; + System.Management.ManagementClass clsObject = new System.Management.ManagementClass(mgmtScope, pathObj, null); + if ((enumOptions == null)) { + enumOptions = new System.Management.EnumerationOptions(); + enumOptions.EnsureLocatable = true; + } + return new MigrationJobCollection(clsObject.GetInstances(enumOptions)); + } + + public static MigrationJobCollection GetInstances(System.Management.ManagementScope mgmtScope, string condition) { + return GetInstances(mgmtScope, condition, null); + } + + public static MigrationJobCollection GetInstances(System.Management.ManagementScope mgmtScope, string[] selectedProperties) { + return GetInstances(mgmtScope, null, selectedProperties); + } + + public static MigrationJobCollection GetInstances(System.Management.ManagementScope mgmtScope, string condition, string[] selectedProperties) { + if ((mgmtScope == null)) { + if ((statMgmtScope == null)) { + mgmtScope = new System.Management.ManagementScope(); + mgmtScope.Path.NamespacePath = "root\\virtualization\\v2"; + } + else { + mgmtScope = statMgmtScope; + } + } + System.Management.ManagementObjectSearcher ObjectSearcher = new System.Management.ManagementObjectSearcher(mgmtScope, new SelectQuery("Msvm_MigrationJob", condition, selectedProperties)); + System.Management.EnumerationOptions enumOptions = new System.Management.EnumerationOptions(); + enumOptions.EnsureLocatable = true; + ObjectSearcher.Options = enumOptions; + return new MigrationJobCollection(ObjectSearcher.Get()); + } + + [Browsable(true)] + public static MigrationJob CreateInstance() { + System.Management.ManagementScope mgmtScope = null; + if ((statMgmtScope == null)) { + mgmtScope = new System.Management.ManagementScope(); + mgmtScope.Path.NamespacePath = CreatedWmiNamespace; + } + else { + mgmtScope = statMgmtScope; + } + System.Management.ManagementPath mgmtPath = new System.Management.ManagementPath(CreatedClassName); + System.Management.ManagementClass tmpMgmtClass = new System.Management.ManagementClass(mgmtScope, mgmtPath, null); + return new MigrationJob(tmpMgmtClass.CreateInstance()); + } + + [Browsable(true)] + public void Delete() { + PrivateLateBoundObject.Delete(); + } + + public uint GetError(out string Error) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("GetError", inParams, null); + Error = System.Convert.ToString(outParams.Properties["Error"].Value); + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + Error = null; + return System.Convert.ToUInt32(0); + } + } + + public uint GetErrorEx(out string[] Errors) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("GetErrorEx", inParams, null); + Errors = ((string[])(outParams.Properties["Errors"].Value)); + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + Errors = null; + return System.Convert.ToUInt32(0); + } + } + + public uint KillJob(bool DeleteOnKill) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + inParams = PrivateLateBoundObject.GetMethodParameters("KillJob"); + inParams["DeleteOnKill"] = ((bool)(DeleteOnKill)); + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("KillJob", inParams, null); + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + return System.Convert.ToUInt32(0); + } + } + + public uint RequestStateChange(ushort RequestedState, System.DateTime TimeoutPeriod) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + inParams = PrivateLateBoundObject.GetMethodParameters("RequestStateChange"); + inParams["RequestedState"] = ((ushort)(RequestedState)); + inParams["TimeoutPeriod"] = ToDmtfDateTime(((System.DateTime)(TimeoutPeriod))); + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("RequestStateChange", inParams, null); + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + return System.Convert.ToUInt32(0); + } + } + + public enum JobTypeValues { + + Unknown0 = 0, + + Creating_Remote_Virtual_Machine = 300, + + Checking_Virtual_Machine_Compatibility = 301, + + Checking_Virtual_Machine_and_Storage_Compatibility = 302, + + Checking_Storage_Compatibility = 303, + + Checking_Storage_Migration = 304, + + Moving_Virtual_Machine = 305, + + Moving_Virtual_Machine_and_Storage = 306, + + Moving_Storage = 307, + + NULL_ENUM_VALUE = 308, + } + + // Enumerator implementation for enumerating instances of the class. + public class MigrationJobCollection : object, ICollection { + + private ManagementObjectCollection privColObj; + + public MigrationJobCollection(ManagementObjectCollection objCollection) { + privColObj = objCollection; + } + + public virtual int Count { + get { + return privColObj.Count; + } + } + + public virtual bool IsSynchronized { + get { + return privColObj.IsSynchronized; + } + } + + public virtual object SyncRoot { + get { + return this; + } + } + + public virtual void CopyTo(System.Array array, int index) { + privColObj.CopyTo(array, index); + int nCtr; + for (nCtr = 0; (nCtr < array.Length); nCtr = (nCtr + 1)) { + array.SetValue(new MigrationJob(((System.Management.ManagementObject)(array.GetValue(nCtr)))), nCtr); + } + } + + public virtual System.Collections.IEnumerator GetEnumerator() { + return new MigrationJobEnumerator(privColObj.GetEnumerator()); + } + + public class MigrationJobEnumerator : object, System.Collections.IEnumerator { + + private ManagementObjectCollection.ManagementObjectEnumerator privObjEnum; + + public MigrationJobEnumerator(ManagementObjectCollection.ManagementObjectEnumerator objEnum) { + privObjEnum = objEnum; + } + + public virtual object Current { + get { + return new MigrationJob(((System.Management.ManagementObject)(privObjEnum.Current))); + } + } + + public virtual bool MoveNext() { + return privObjEnum.MoveNext(); + } + + public virtual void Reset() { + privObjEnum.Reset(); + } + } + } + + // TypeConverter to handle null values for ValueType properties + public class WMIValueTypeConverter : TypeConverter { + + private TypeConverter baseConverter; + + private System.Type baseType; + + public WMIValueTypeConverter(System.Type inBaseType) { + baseConverter = TypeDescriptor.GetConverter(inBaseType); + baseType = inBaseType; + } + + public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type srcType) { + return baseConverter.CanConvertFrom(context, srcType); + } + + public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Type destinationType) { + return baseConverter.CanConvertTo(context, destinationType); + } + + public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { + return baseConverter.ConvertFrom(context, culture, value); + } + + public override object CreateInstance(System.ComponentModel.ITypeDescriptorContext context, System.Collections.IDictionary dictionary) { + return baseConverter.CreateInstance(context, dictionary); + } + + public override bool GetCreateInstanceSupported(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetCreateInstanceSupported(context); + } + + public override PropertyDescriptorCollection GetProperties(System.ComponentModel.ITypeDescriptorContext context, object value, System.Attribute[] attributeVar) { + return baseConverter.GetProperties(context, value, attributeVar); + } + + public override bool GetPropertiesSupported(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetPropertiesSupported(context); + } + + public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetStandardValues(context); + } + + public override bool GetStandardValuesExclusive(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetStandardValuesExclusive(context); + } + + public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetStandardValuesSupported(context); + } + + public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) { + if ((baseType.BaseType == typeof(System.Enum))) { + if ((value.GetType() == destinationType)) { + return value; + } + if ((((value == null) + && (context != null)) + && (context.PropertyDescriptor.ShouldSerializeValue(context.Instance) == false))) { + return "NULL_ENUM_VALUE" ; + } + return baseConverter.ConvertTo(context, culture, value, destinationType); + } + if (((baseType == typeof(bool)) + && (baseType.BaseType == typeof(System.ValueType)))) { + if ((((value == null) + && (context != null)) + && (context.PropertyDescriptor.ShouldSerializeValue(context.Instance) == false))) { + return ""; + } + return baseConverter.ConvertTo(context, culture, value, destinationType); + } + if (((context != null) + && (context.PropertyDescriptor.ShouldSerializeValue(context.Instance) == false))) { + return ""; + } + return baseConverter.ConvertTo(context, culture, value, destinationType); + } + } + + // Embedded class to represent WMI system Properties. + [TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))] + public class ManagementSystemProperties { + + private System.Management.ManagementBaseObject PrivateLateBoundObject; + + public ManagementSystemProperties(System.Management.ManagementBaseObject ManagedObject) { + PrivateLateBoundObject = ManagedObject; + } + + [Browsable(true)] + public int GENUS { + get { + return ((int)(PrivateLateBoundObject["__GENUS"])); + } + } + + [Browsable(true)] + public string CLASS { + get { + return ((string)(PrivateLateBoundObject["__CLASS"])); + } + } + + [Browsable(true)] + public string SUPERCLASS { + get { + return ((string)(PrivateLateBoundObject["__SUPERCLASS"])); + } + } + + [Browsable(true)] + public string DYNASTY { + get { + return ((string)(PrivateLateBoundObject["__DYNASTY"])); + } + } + + [Browsable(true)] + public string RELPATH { + get { + return ((string)(PrivateLateBoundObject["__RELPATH"])); + } + } + + [Browsable(true)] + public int PROPERTY_COUNT { + get { + return ((int)(PrivateLateBoundObject["__PROPERTY_COUNT"])); + } + } + + [Browsable(true)] + public string[] DERIVATION { + get { + return ((string[])(PrivateLateBoundObject["__DERIVATION"])); + } + } + + [Browsable(true)] + public string SERVER { + get { + return ((string)(PrivateLateBoundObject["__SERVER"])); + } + } + + [Browsable(true)] + public string NAMESPACE { + get { + return ((string)(PrivateLateBoundObject["__NAMESPACE"])); + } + } + + [Browsable(true)] + public string PATH { + get { + return ((string)(PrivateLateBoundObject["__PATH"])); + } + } + } + } +} diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/ROOT.virtualization.v2.Msvm_VirtualSystemMigrationService.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/ROOT.virtualization.v2.Msvm_VirtualSystemMigrationService.cs new file mode 100644 index 00000000000..89592b1b900 --- /dev/null +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/ROOT.virtualization.v2.Msvm_VirtualSystemMigrationService.cs @@ -0,0 +1,1581 @@ +// 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. + +namespace CloudStack.Plugin.WmiWrappers.ROOT.VIRTUALIZATION.V2 { + using System; + using System.ComponentModel; + using System.Management; + using System.Collections; + using System.Globalization; + using System.ComponentModel.Design.Serialization; + using System.Reflection; + + + // Functions ShouldSerialize are functions used by VS property browser to check if a particular property has to be serialized. These functions are added for all ValueType properties ( properties of type Int32, BOOL etc.. which cannot be set to null). These functions use IsNull function. These functions are also used in the TypeConverter implementation for the properties to check for NULL value of property so that an empty value can be shown in Property browser in case of Drag and Drop in Visual studio. + // Functions IsNull() are used to check if a property is NULL. + // Functions Reset are added for Nullable Read/Write properties. These functions are used by VS designer in property browser to set a property to NULL. + // Every property added to the class for WMI property has attributes set to define its behavior in Visual Studio designer and also to define a TypeConverter to be used. + // Datetime conversion functions ToDateTime and ToDmtfDateTime are added to the class to convert DMTF datetime to System.DateTime and vice-versa. + // An Early Bound class generated for the WMI class.Msvm_VirtualSystemMigrationService + public class VirtualSystemMigrationService : System.ComponentModel.Component { + + // Private property to hold the WMI namespace in which the class resides. + private static string CreatedWmiNamespace = "ROOT\\virtualization\\v2"; + + // Private property to hold the name of WMI class which created this class. + public static string CreatedClassName = "Msvm_VirtualSystemMigrationService"; + + // Private member variable to hold the ManagementScope which is used by the various methods. + private static System.Management.ManagementScope statMgmtScope = null; + + private ManagementSystemProperties PrivateSystemProperties; + + // Underlying lateBound WMI object. + private System.Management.ManagementObject PrivateLateBoundObject; + + // Member variable to store the 'automatic commit' behavior for the class. + private bool AutoCommitProp; + + // Private variable to hold the embedded property representing the instance. + private System.Management.ManagementBaseObject embeddedObj; + + // The current WMI object used + private System.Management.ManagementBaseObject curObj; + + // Flag to indicate if the instance is an embedded object. + private bool isEmbedded; + + // Below are different overloads of constructors to initialize an instance of the class with a WMI object. + public VirtualSystemMigrationService() { + this.InitializeObject(null, null, null); + } + + public VirtualSystemMigrationService(string keyCreationClassName, string keyName, string keySystemCreationClassName, string keySystemName) { + this.InitializeObject(null, new System.Management.ManagementPath(VirtualSystemMigrationService.ConstructPath(keyCreationClassName, keyName, keySystemCreationClassName, keySystemName)), null); + } + + public VirtualSystemMigrationService(System.Management.ManagementScope mgmtScope, string keyCreationClassName, string keyName, string keySystemCreationClassName, string keySystemName) { + this.InitializeObject(((System.Management.ManagementScope)(mgmtScope)), new System.Management.ManagementPath(VirtualSystemMigrationService.ConstructPath(keyCreationClassName, keyName, keySystemCreationClassName, keySystemName)), null); + } + + public VirtualSystemMigrationService(System.Management.ManagementPath path, System.Management.ObjectGetOptions getOptions) { + this.InitializeObject(null, path, getOptions); + } + + public VirtualSystemMigrationService(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path) { + this.InitializeObject(mgmtScope, path, null); + } + + public VirtualSystemMigrationService(System.Management.ManagementPath path) { + this.InitializeObject(null, path, null); + } + + public VirtualSystemMigrationService(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path, System.Management.ObjectGetOptions getOptions) { + this.InitializeObject(mgmtScope, path, getOptions); + } + + public VirtualSystemMigrationService(System.Management.ManagementObject theObject) { + Initialize(); + if ((CheckIfProperClass(theObject) == true)) { + PrivateLateBoundObject = theObject; + PrivateSystemProperties = new ManagementSystemProperties(PrivateLateBoundObject); + curObj = PrivateLateBoundObject; + } + else { + throw new System.ArgumentException("Class name does not match."); + } + } + + public VirtualSystemMigrationService(System.Management.ManagementBaseObject theObject) { + Initialize(); + if ((CheckIfProperClass(theObject) == true)) { + embeddedObj = theObject; + PrivateSystemProperties = new ManagementSystemProperties(theObject); + curObj = embeddedObj; + isEmbedded = true; + } + else { + throw new System.ArgumentException("Class name does not match."); + } + } + + // Property returns the namespace of the WMI class. + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string OriginatingNamespace { + get { + return "ROOT\\virtualization\\v2"; + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string ManagementClassName { + get { + string strRet = CreatedClassName; + if ((curObj != null)) { + if ((curObj.ClassPath != null)) { + strRet = ((string)(curObj["__CLASS"])); + if (((strRet == null) + || (strRet == string.Empty))) { + strRet = CreatedClassName; + } + } + } + return strRet; + } + } + + // Property pointing to an embedded object to get System properties of the WMI object. + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ManagementSystemProperties SystemProperties { + get { + return PrivateSystemProperties; + } + } + + // Property returning the underlying lateBound object. + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public System.Management.ManagementBaseObject LateBoundObject { + get { + return curObj; + } + } + + // ManagementScope of the object. + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public System.Management.ManagementScope Scope { + get { + if ((isEmbedded == false)) { + return PrivateLateBoundObject.Scope; + } + else { + return null; + } + } + set { + if ((isEmbedded == false)) { + PrivateLateBoundObject.Scope = value; + } + } + } + + // Property to show the commit behavior for the WMI object. If true, WMI object will be automatically saved after each property modification.(ie. Put() is called after modification of a property). + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool AutoCommit { + get { + return AutoCommitProp; + } + set { + AutoCommitProp = value; + } + } + + // The ManagementPath of the underlying WMI object. + [Browsable(true)] + public System.Management.ManagementPath Path { + get { + if ((isEmbedded == false)) { + return PrivateLateBoundObject.Path; + } + else { + return null; + } + } + set { + if ((isEmbedded == false)) { + if ((CheckIfProperClass(null, value, null) != true)) { + throw new System.ArgumentException("Class name does not match."); + } + PrivateLateBoundObject.Path = value; + } + } + } + + // Public static scope property which is used by the various methods. + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public static System.Management.ManagementScope StaticScope { + get { + return statMgmtScope; + } + set { + statMgmtScope = value; + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsActiveStorageMigrationCountNull { + get { + if ((curObj["ActiveStorageMigrationCount"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("The number of currently in-flight storage migrations.")] + [TypeConverter(typeof(WMIValueTypeConverter))] + public uint ActiveStorageMigrationCount { + get { + if ((curObj["ActiveStorageMigrationCount"] == null)) { + return System.Convert.ToUInt32(0); + } + return ((uint)(curObj["ActiveStorageMigrationCount"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsActiveVirtualSystemMigrationCountNull { + get { + if ((curObj["ActiveVirtualSystemMigrationCount"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("The number of currently in-flight virtual system migrations.")] + [TypeConverter(typeof(WMIValueTypeConverter))] + public uint ActiveVirtualSystemMigrationCount { + get { + if ((curObj["ActiveVirtualSystemMigrationCount"] == null)) { + return System.Convert.ToUInt32(0); + } + return ((uint)(curObj["ActiveVirtualSystemMigrationCount"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ushort[] AvailableRequestedStates { + get { + return ((ushort[])(curObj["AvailableRequestedStates"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Caption { + get { + return ((string)(curObj["Caption"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsCommunicationStatusNull { + get { + if ((curObj["CommunicationStatus"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort CommunicationStatus { + get { + if ((curObj["CommunicationStatus"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["CommunicationStatus"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string CreationClassName { + get { + return ((string)(curObj["CreationClassName"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Description { + get { + return ((string)(curObj["Description"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsDetailedStatusNull { + get { + if ((curObj["DetailedStatus"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort DetailedStatus { + get { + if ((curObj["DetailedStatus"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["DetailedStatus"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string ElementName { + get { + return ((string)(curObj["ElementName"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEnabledDefaultNull { + get { + if ((curObj["EnabledDefault"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort EnabledDefault { + get { + if ((curObj["EnabledDefault"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["EnabledDefault"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEnabledStateNull { + get { + if ((curObj["EnabledState"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort EnabledState { + get { + if ((curObj["EnabledState"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["EnabledState"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsHealthStateNull { + get { + if ((curObj["HealthState"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort HealthState { + get { + if ((curObj["HealthState"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["HealthState"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsInstallDateNull { + get { + if ((curObj["InstallDate"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime InstallDate { + get { + if ((curObj["InstallDate"] != null)) { + return ToDateTime(((string)(curObj["InstallDate"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string InstanceID { + get { + return ((string)(curObj["InstanceID"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("The list of IP addresses of the host, which can be used for virtual system migra" + + "tion.")] + public string[] MigrationServiceListenerIPAddressList { + get { + return ((string[])(curObj["MigrationServiceListenerIPAddressList"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Name { + get { + return ((string)(curObj["Name"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsOperatingStatusNull { + get { + if ((curObj["OperatingStatus"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort OperatingStatus { + get { + if ((curObj["OperatingStatus"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["OperatingStatus"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ushort[] OperationalStatus { + get { + return ((ushort[])(curObj["OperationalStatus"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string OtherEnabledState { + get { + return ((string)(curObj["OtherEnabledState"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string PrimaryOwnerContact { + get { + return ((string)(curObj["PrimaryOwnerContact"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string PrimaryOwnerName { + get { + return ((string)(curObj["PrimaryOwnerName"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsPrimaryStatusNull { + get { + if ((curObj["PrimaryStatus"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort PrimaryStatus { + get { + if ((curObj["PrimaryStatus"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["PrimaryStatus"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsRequestedStateNull { + get { + if ((curObj["RequestedState"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort RequestedState { + get { + if ((curObj["RequestedState"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["RequestedState"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsStartedNull { + get { + if ((curObj["Started"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public bool Started { + get { + if ((curObj["Started"] == null)) { + return System.Convert.ToBoolean(0); + } + return ((bool)(curObj["Started"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string StartMode { + get { + return ((string)(curObj["StartMode"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Status { + get { + return ((string)(curObj["Status"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string[] StatusDescriptions { + get { + return ((string[])(curObj["StatusDescriptions"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string SystemCreationClassName { + get { + return ((string)(curObj["SystemCreationClassName"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string SystemName { + get { + return ((string)(curObj["SystemName"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsTimeOfLastStateChangeNull { + get { + if ((curObj["TimeOfLastStateChange"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime TimeOfLastStateChange { + get { + if ((curObj["TimeOfLastStateChange"] != null)) { + return ToDateTime(((string)(curObj["TimeOfLastStateChange"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsTransitioningToStateNull { + get { + if ((curObj["TransitioningToState"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort TransitioningToState { + get { + if ((curObj["TransitioningToState"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["TransitioningToState"])); + } + } + + private bool CheckIfProperClass(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path, System.Management.ObjectGetOptions OptionsParam) { + if (((path != null) + && (string.Compare(path.ClassName, this.ManagementClassName, true, System.Globalization.CultureInfo.InvariantCulture) == 0))) { + return true; + } + else { + return CheckIfProperClass(new System.Management.ManagementObject(mgmtScope, path, OptionsParam)); + } + } + + private bool CheckIfProperClass(System.Management.ManagementBaseObject theObj) { + if (((theObj != null) + && (string.Compare(((string)(theObj["__CLASS"])), this.ManagementClassName, true, System.Globalization.CultureInfo.InvariantCulture) == 0))) { + return true; + } + else { + System.Array parentClasses = ((System.Array)(theObj["__DERIVATION"])); + if ((parentClasses != null)) { + int count = 0; + for (count = 0; (count < parentClasses.Length); count = (count + 1)) { + if ((string.Compare(((string)(parentClasses.GetValue(count))), this.ManagementClassName, true, System.Globalization.CultureInfo.InvariantCulture) == 0)) { + return true; + } + } + } + } + return false; + } + + private bool ShouldSerializeActiveStorageMigrationCount() { + if ((this.IsActiveStorageMigrationCountNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeActiveVirtualSystemMigrationCount() { + if ((this.IsActiveVirtualSystemMigrationCountNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeCommunicationStatus() { + if ((this.IsCommunicationStatusNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeDetailedStatus() { + if ((this.IsDetailedStatusNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeEnabledDefault() { + if ((this.IsEnabledDefaultNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeEnabledState() { + if ((this.IsEnabledStateNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeHealthState() { + if ((this.IsHealthStateNull == false)) { + return true; + } + return false; + } + + // Converts a given datetime in DMTF format to System.DateTime object. + static System.DateTime ToDateTime(string dmtfDate) { + System.DateTime initializer = System.DateTime.MinValue; + int year = initializer.Year; + int month = initializer.Month; + int day = initializer.Day; + int hour = initializer.Hour; + int minute = initializer.Minute; + int second = initializer.Second; + long ticks = 0; + string dmtf = dmtfDate; + System.DateTime datetime = System.DateTime.MinValue; + string tempString = string.Empty; + if ((dmtf == null)) { + throw new System.ArgumentOutOfRangeException(); + } + if ((dmtf.Length == 0)) { + throw new System.ArgumentOutOfRangeException(); + } + if ((dmtf.Length != 25)) { + throw new System.ArgumentOutOfRangeException(); + } + try { + tempString = dmtf.Substring(0, 4); + if (("****" != tempString)) { + year = int.Parse(tempString); + } + tempString = dmtf.Substring(4, 2); + if (("**" != tempString)) { + month = int.Parse(tempString); + } + tempString = dmtf.Substring(6, 2); + if (("**" != tempString)) { + day = int.Parse(tempString); + } + tempString = dmtf.Substring(8, 2); + if (("**" != tempString)) { + hour = int.Parse(tempString); + } + tempString = dmtf.Substring(10, 2); + if (("**" != tempString)) { + minute = int.Parse(tempString); + } + tempString = dmtf.Substring(12, 2); + if (("**" != tempString)) { + second = int.Parse(tempString); + } + tempString = dmtf.Substring(15, 6); + if (("******" != tempString)) { + ticks = (long.Parse(tempString) * ((long)((System.TimeSpan.TicksPerMillisecond / 1000)))); + } + if (((((((((year < 0) + || (month < 0)) + || (day < 0)) + || (hour < 0)) + || (minute < 0)) + || (minute < 0)) + || (second < 0)) + || (ticks < 0))) { + throw new System.ArgumentOutOfRangeException(); + } + } + catch (System.Exception e) { + throw new System.ArgumentOutOfRangeException(null, e.Message); + } + datetime = new System.DateTime(year, month, day, hour, minute, second, 0); + datetime = datetime.AddTicks(ticks); + System.TimeSpan tickOffset = System.TimeZone.CurrentTimeZone.GetUtcOffset(datetime); + int UTCOffset = 0; + int OffsetToBeAdjusted = 0; + long OffsetMins = ((long)((tickOffset.Ticks / System.TimeSpan.TicksPerMinute))); + tempString = dmtf.Substring(22, 3); + if ((tempString != "******")) { + tempString = dmtf.Substring(21, 4); + try { + UTCOffset = int.Parse(tempString); + } + catch (System.Exception e) { + throw new System.ArgumentOutOfRangeException(null, e.Message); + } + OffsetToBeAdjusted = ((int)((OffsetMins - UTCOffset))); + datetime = datetime.AddMinutes(((double)(OffsetToBeAdjusted))); + } + return datetime; + } + + // Converts a given System.DateTime object to DMTF datetime format. + static string ToDmtfDateTime(System.DateTime date) { + string utcString = string.Empty; + System.TimeSpan tickOffset = System.TimeZone.CurrentTimeZone.GetUtcOffset(date); + long OffsetMins = ((long)((tickOffset.Ticks / System.TimeSpan.TicksPerMinute))); + if ((System.Math.Abs(OffsetMins) > 999)) { + date = date.ToUniversalTime(); + utcString = "+000"; + } + else { + if ((tickOffset.Ticks >= 0)) { + utcString = string.Concat("+", ((long)((tickOffset.Ticks / System.TimeSpan.TicksPerMinute))).ToString().PadLeft(3, '0')); + } + else { + string strTemp = ((long)(OffsetMins)).ToString(); + utcString = string.Concat("-", strTemp.Substring(1, (strTemp.Length - 1)).PadLeft(3, '0')); + } + } + string dmtfDateTime = ((int)(date.Year)).ToString().PadLeft(4, '0'); + dmtfDateTime = string.Concat(dmtfDateTime, ((int)(date.Month)).ToString().PadLeft(2, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, ((int)(date.Day)).ToString().PadLeft(2, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, ((int)(date.Hour)).ToString().PadLeft(2, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, ((int)(date.Minute)).ToString().PadLeft(2, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, ((int)(date.Second)).ToString().PadLeft(2, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, "."); + System.DateTime dtTemp = new System.DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, 0); + long microsec = ((long)((((date.Ticks - dtTemp.Ticks) + * 1000) + / System.TimeSpan.TicksPerMillisecond))); + string strMicrosec = ((long)(microsec)).ToString(); + if ((strMicrosec.Length > 6)) { + strMicrosec = strMicrosec.Substring(0, 6); + } + dmtfDateTime = string.Concat(dmtfDateTime, strMicrosec.PadLeft(6, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, utcString); + return dmtfDateTime; + } + + private bool ShouldSerializeInstallDate() { + if ((this.IsInstallDateNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeOperatingStatus() { + if ((this.IsOperatingStatusNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializePrimaryStatus() { + if ((this.IsPrimaryStatusNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeRequestedState() { + if ((this.IsRequestedStateNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeStarted() { + if ((this.IsStartedNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeTimeOfLastStateChange() { + if ((this.IsTimeOfLastStateChangeNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeTransitioningToState() { + if ((this.IsTransitioningToStateNull == false)) { + return true; + } + return false; + } + + [Browsable(true)] + public void CommitObject() { + if ((isEmbedded == false)) { + PrivateLateBoundObject.Put(); + } + } + + [Browsable(true)] + public void CommitObject(System.Management.PutOptions putOptions) { + if ((isEmbedded == false)) { + PrivateLateBoundObject.Put(putOptions); + } + } + + private void Initialize() { + AutoCommitProp = true; + isEmbedded = false; + } + + private static string ConstructPath(string keyCreationClassName, string keyName, string keySystemCreationClassName, string keySystemName) { + string strPath = "ROOT\\virtualization\\v2:Msvm_VirtualSystemMigrationService"; + strPath = string.Concat(strPath, string.Concat(".CreationClassName=", string.Concat("\"", string.Concat(keyCreationClassName, "\"")))); + strPath = string.Concat(strPath, string.Concat(",Name=", string.Concat("\"", string.Concat(keyName, "\"")))); + strPath = string.Concat(strPath, string.Concat(",SystemCreationClassName=", string.Concat("\"", string.Concat(keySystemCreationClassName, "\"")))); + strPath = string.Concat(strPath, string.Concat(",SystemName=", string.Concat("\"", string.Concat(keySystemName, "\"")))); + return strPath; + } + + private void InitializeObject(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path, System.Management.ObjectGetOptions getOptions) { + Initialize(); + if ((path != null)) { + if ((CheckIfProperClass(mgmtScope, path, getOptions) != true)) { + throw new System.ArgumentException("Class name does not match."); + } + } + PrivateLateBoundObject = new System.Management.ManagementObject(mgmtScope, path, getOptions); + PrivateSystemProperties = new ManagementSystemProperties(PrivateLateBoundObject); + curObj = PrivateLateBoundObject; + } + + // Different overloads of GetInstances() help in enumerating instances of the WMI class. + public static VirtualSystemMigrationServiceCollection GetInstances() { + return GetInstances(null, null, null); + } + + public static VirtualSystemMigrationServiceCollection GetInstances(string condition) { + return GetInstances(null, condition, null); + } + + public static VirtualSystemMigrationServiceCollection GetInstances(string[] selectedProperties) { + return GetInstances(null, null, selectedProperties); + } + + public static VirtualSystemMigrationServiceCollection GetInstances(string condition, string[] selectedProperties) { + return GetInstances(null, condition, selectedProperties); + } + + public static VirtualSystemMigrationServiceCollection GetInstances(System.Management.ManagementScope mgmtScope, System.Management.EnumerationOptions enumOptions) { + if ((mgmtScope == null)) { + if ((statMgmtScope == null)) { + mgmtScope = new System.Management.ManagementScope(); + mgmtScope.Path.NamespacePath = "root\\virtualization\\v2"; + } + else { + mgmtScope = statMgmtScope; + } + } + System.Management.ManagementPath pathObj = new System.Management.ManagementPath(); + pathObj.ClassName = "Msvm_VirtualSystemMigrationService"; + pathObj.NamespacePath = "root\\virtualization\\v2"; + System.Management.ManagementClass clsObject = new System.Management.ManagementClass(mgmtScope, pathObj, null); + if ((enumOptions == null)) { + enumOptions = new System.Management.EnumerationOptions(); + enumOptions.EnsureLocatable = true; + } + return new VirtualSystemMigrationServiceCollection(clsObject.GetInstances(enumOptions)); + } + + public static VirtualSystemMigrationServiceCollection GetInstances(System.Management.ManagementScope mgmtScope, string condition) { + return GetInstances(mgmtScope, condition, null); + } + + public static VirtualSystemMigrationServiceCollection GetInstances(System.Management.ManagementScope mgmtScope, string[] selectedProperties) { + return GetInstances(mgmtScope, null, selectedProperties); + } + + public static VirtualSystemMigrationServiceCollection GetInstances(System.Management.ManagementScope mgmtScope, string condition, string[] selectedProperties) { + if ((mgmtScope == null)) { + if ((statMgmtScope == null)) { + mgmtScope = new System.Management.ManagementScope(); + mgmtScope.Path.NamespacePath = "root\\virtualization\\v2"; + } + else { + mgmtScope = statMgmtScope; + } + } + System.Management.ManagementObjectSearcher ObjectSearcher = new System.Management.ManagementObjectSearcher(mgmtScope, new SelectQuery("Msvm_VirtualSystemMigrationService", condition, selectedProperties)); + System.Management.EnumerationOptions enumOptions = new System.Management.EnumerationOptions(); + enumOptions.EnsureLocatable = true; + ObjectSearcher.Options = enumOptions; + return new VirtualSystemMigrationServiceCollection(ObjectSearcher.Get()); + } + + [Browsable(true)] + public static VirtualSystemMigrationService CreateInstance() { + System.Management.ManagementScope mgmtScope = null; + if ((statMgmtScope == null)) { + mgmtScope = new System.Management.ManagementScope(); + mgmtScope.Path.NamespacePath = CreatedWmiNamespace; + } + else { + mgmtScope = statMgmtScope; + } + System.Management.ManagementPath mgmtPath = new System.Management.ManagementPath(CreatedClassName); + System.Management.ManagementClass tmpMgmtClass = new System.Management.ManagementClass(mgmtScope, mgmtPath, null); + return new VirtualSystemMigrationService(tmpMgmtClass.CreateInstance()); + } + + [Browsable(true)] + public void Delete() { + PrivateLateBoundObject.Delete(); + } + + public uint AddNetworkSettings(string[] NetworkSettings, out System.Management.ManagementPath Job) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + inParams = PrivateLateBoundObject.GetMethodParameters("AddNetworkSettings"); + inParams["NetworkSettings"] = ((string[])(NetworkSettings)); + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("AddNetworkSettings", inParams, null); + Job = null; + if ((outParams.Properties["Job"] != null)) { + Job = new System.Management.ManagementPath(outParams.Properties["Job"].ToString()); + } + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + Job = null; + return System.Convert.ToUInt32(0); + } + } + + public uint CheckSystemCompatibilityInfo(byte[] CompatibilityInfo, out string[] Reasons) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + inParams = PrivateLateBoundObject.GetMethodParameters("CheckSystemCompatibilityInfo"); + inParams["CompatibilityInfo"] = ((byte[])(CompatibilityInfo)); + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("CheckSystemCompatibilityInfo", inParams, null); + Reasons = ((string[])(outParams.Properties["Reasons"].Value)); + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + Reasons = null; + return System.Convert.ToUInt32(0); + } + } + + public uint CheckVirtualSystemIsMigratable(System.Management.ManagementPath ComputerSystem, string DestinationHost, string MigrationSettingData, string[] NewResourceSettingData, string NewSystemSettingData, out System.Management.ManagementPath Job) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + inParams = PrivateLateBoundObject.GetMethodParameters("CheckVirtualSystemIsMigratable"); + inParams["ComputerSystem"] = ((System.Management.ManagementPath)(ComputerSystem)).Path; + inParams["DestinationHost"] = ((string)(DestinationHost)); + inParams["MigrationSettingData"] = ((string)(MigrationSettingData)); + inParams["NewResourceSettingData"] = ((string[])(NewResourceSettingData)); + inParams["NewSystemSettingData"] = ((string)(NewSystemSettingData)); + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("CheckVirtualSystemIsMigratable", inParams, null); + Job = null; + if ((outParams.Properties["Job"] != null)) { + Job = new System.Management.ManagementPath(outParams.Properties["Job"].ToString()); + } + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + Job = null; + return System.Convert.ToUInt32(0); + } + } + + public uint CheckVirtualSystemIsMigratableToHost(System.Management.ManagementPath ComputerSystem, string DestinationHost, string MigrationSettingData, string[] NewResourceSettingData, string NewSystemSettingData, out bool IsMigratable) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + inParams = PrivateLateBoundObject.GetMethodParameters("CheckVirtualSystemIsMigratableToHost"); + inParams["ComputerSystem"] = ((System.Management.ManagementPath)(ComputerSystem)).Path; + inParams["DestinationHost"] = ((string)(DestinationHost)); + inParams["MigrationSettingData"] = ((string)(MigrationSettingData)); + inParams["NewResourceSettingData"] = ((string[])(NewResourceSettingData)); + inParams["NewSystemSettingData"] = ((string)(NewSystemSettingData)); + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("CheckVirtualSystemIsMigratableToHost", inParams, null); + IsMigratable = System.Convert.ToBoolean(outParams.Properties["IsMigratable"].Value); + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + IsMigratable = System.Convert.ToBoolean(0); + return System.Convert.ToUInt32(0); + } + } + + public uint CheckVirtualSystemIsMigratableToSystem(System.Management.ManagementPath ComputerSystem, System.Management.ManagementPath DestinationSystem, string MigrationSettingData, string[] NewResourceSettingData, string NewSystemSettingData, out bool IsMigratable) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + inParams = PrivateLateBoundObject.GetMethodParameters("CheckVirtualSystemIsMigratableToSystem"); + inParams["ComputerSystem"] = ((System.Management.ManagementPath)(ComputerSystem)).Path; + inParams["DestinationSystem"] = ((System.Management.ManagementPath)(DestinationSystem)).Path; + inParams["MigrationSettingData"] = ((string)(MigrationSettingData)); + inParams["NewResourceSettingData"] = ((string[])(NewResourceSettingData)); + inParams["NewSystemSettingData"] = ((string)(NewSystemSettingData)); + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("CheckVirtualSystemIsMigratableToSystem", inParams, null); + IsMigratable = System.Convert.ToBoolean(outParams.Properties["IsMigratable"].Value); + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + IsMigratable = System.Convert.ToBoolean(0); + return System.Convert.ToUInt32(0); + } + } + + public uint GetSystemCompatibilityInfo(System.Management.ManagementPath ComputerSystem, out byte[] CompatibilityInfo) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + inParams = PrivateLateBoundObject.GetMethodParameters("GetSystemCompatibilityInfo"); + inParams["ComputerSystem"] = ((System.Management.ManagementPath)(ComputerSystem)).Path; + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("GetSystemCompatibilityInfo", inParams, null); + CompatibilityInfo = ((byte[])(outParams.Properties["CompatibilityInfo"].Value)); + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + CompatibilityInfo = null; + return System.Convert.ToUInt32(0); + } + } + + public uint MigrateVirtualSystemToHost(System.Management.ManagementPath ComputerSystem, string DestinationHost, string MigrationSettingData, string[] NewResourceSettingData, string NewSystemSettingData, out System.Management.ManagementPath Job) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + inParams = PrivateLateBoundObject.GetMethodParameters("MigrateVirtualSystemToHost"); + inParams["ComputerSystem"] = ((System.Management.ManagementPath)(ComputerSystem)).Path; + inParams["DestinationHost"] = ((string)(DestinationHost)); + inParams["MigrationSettingData"] = ((string)(MigrationSettingData)); + inParams["NewResourceSettingData"] = ((string[])(NewResourceSettingData)); + inParams["NewSystemSettingData"] = ((string)(NewSystemSettingData)); + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("MigrateVirtualSystemToHost", inParams, null); + Job = null; + if ((outParams.Properties["Job"] != null) && outParams.Properties["Job"].Value != null) + { + Job = new System.Management.ManagementPath((string)outParams.Properties["Job"].Value); + } + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + Job = null; + return System.Convert.ToUInt32(0); + } + } + + public uint MigrateVirtualSystemToSystem(System.Management.ManagementPath ComputerSystem, System.Management.ManagementPath DestinationSystem, string MigrationSettingData, string[] NewResourceSettingData, string NewSystemSettingData, out System.Management.ManagementPath Job, out System.Management.ManagementPath NewComputerSystem) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + inParams = PrivateLateBoundObject.GetMethodParameters("MigrateVirtualSystemToSystem"); + inParams["ComputerSystem"] = ((System.Management.ManagementPath)(ComputerSystem)).Path; + inParams["DestinationSystem"] = ((System.Management.ManagementPath)(DestinationSystem)).Path; + inParams["MigrationSettingData"] = ((string)(MigrationSettingData)); + inParams["NewResourceSettingData"] = ((string[])(NewResourceSettingData)); + inParams["NewSystemSettingData"] = ((string)(NewSystemSettingData)); + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("MigrateVirtualSystemToSystem", inParams, null); + Job = null; + if ((outParams.Properties["Job"] != null)) { + Job = new System.Management.ManagementPath(outParams.Properties["Job"].ToString()); + } + NewComputerSystem = null; + if ((outParams.Properties["NewComputerSystem"] != null)) { + NewComputerSystem = new System.Management.ManagementPath(outParams.Properties["NewComputerSystem"].ToString()); + } + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + Job = null; + NewComputerSystem = null; + return System.Convert.ToUInt32(0); + } + } + + public uint ModifyNetworkSettings(string[] NetworkSettings, out System.Management.ManagementPath Job) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + inParams = PrivateLateBoundObject.GetMethodParameters("ModifyNetworkSettings"); + inParams["NetworkSettings"] = ((string[])(NetworkSettings)); + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("ModifyNetworkSettings", inParams, null); + Job = null; + if ((outParams.Properties["Job"] != null)) { + Job = new System.Management.ManagementPath(outParams.Properties["Job"].ToString()); + } + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + Job = null; + return System.Convert.ToUInt32(0); + } + } + + public uint ModifyServiceSettings(string ServiceSettingData, out System.Management.ManagementPath Job) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + inParams = PrivateLateBoundObject.GetMethodParameters("ModifyServiceSettings"); + inParams["ServiceSettingData"] = ((string)(ServiceSettingData)); + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("ModifyServiceSettings", inParams, null); + Job = null; + if ((outParams.Properties["Job"] != null)) { + Job = new System.Management.ManagementPath(outParams.Properties["Job"].ToString()); + } + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + Job = null; + return System.Convert.ToUInt32(0); + } + } + + public uint RemoveNetworkSettings(System.Management.ManagementPath[] NetworkSettings, out System.Management.ManagementPath Job) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + inParams = PrivateLateBoundObject.GetMethodParameters("RemoveNetworkSettings"); + if ((NetworkSettings != null)) { + int len = ((System.Array)(NetworkSettings)).Length; + string[] arrProp = new string[len]; + for (int iCounter = 0; (iCounter < len); iCounter = (iCounter + 1)) { + arrProp[iCounter] = ((System.Management.ManagementPath)(((System.Array)(NetworkSettings)).GetValue(iCounter))).Path; + } + inParams["NetworkSettings"] = arrProp; + } + else { + inParams["NetworkSettings"] = null; + } + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("RemoveNetworkSettings", inParams, null); + Job = null; + if ((outParams.Properties["Job"] != null)) { + Job = new System.Management.ManagementPath(outParams.Properties["Job"].ToString()); + } + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + Job = null; + return System.Convert.ToUInt32(0); + } + } + + public uint RequestStateChange(ushort RequestedState, System.DateTime TimeoutPeriod, out System.Management.ManagementPath Job) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + inParams = PrivateLateBoundObject.GetMethodParameters("RequestStateChange"); + inParams["RequestedState"] = ((ushort)(RequestedState)); + inParams["TimeoutPeriod"] = ToDmtfDateTime(((System.DateTime)(TimeoutPeriod))); + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("RequestStateChange", inParams, null); + Job = null; + if ((outParams.Properties["Job"] != null)) { + Job = new System.Management.ManagementPath(outParams.Properties["Job"].ToString()); + } + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + Job = null; + return System.Convert.ToUInt32(0); + } + } + + public uint StartService() { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("StartService", inParams, null); + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + return System.Convert.ToUInt32(0); + } + } + + public uint StopService() { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("StopService", inParams, null); + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + return System.Convert.ToUInt32(0); + } + } + + // Enumerator implementation for enumerating instances of the class. + public class VirtualSystemMigrationServiceCollection : object, ICollection { + + private ManagementObjectCollection privColObj; + + public VirtualSystemMigrationServiceCollection(ManagementObjectCollection objCollection) { + privColObj = objCollection; + } + + public virtual int Count { + get { + return privColObj.Count; + } + } + + public virtual bool IsSynchronized { + get { + return privColObj.IsSynchronized; + } + } + + public virtual object SyncRoot { + get { + return this; + } + } + + public virtual void CopyTo(System.Array array, int index) { + privColObj.CopyTo(array, index); + int nCtr; + for (nCtr = 0; (nCtr < array.Length); nCtr = (nCtr + 1)) { + array.SetValue(new VirtualSystemMigrationService(((System.Management.ManagementObject)(array.GetValue(nCtr)))), nCtr); + } + } + + public virtual System.Collections.IEnumerator GetEnumerator() { + return new VirtualSystemMigrationServiceEnumerator(privColObj.GetEnumerator()); + } + + public class VirtualSystemMigrationServiceEnumerator : object, System.Collections.IEnumerator { + + private ManagementObjectCollection.ManagementObjectEnumerator privObjEnum; + + public VirtualSystemMigrationServiceEnumerator(ManagementObjectCollection.ManagementObjectEnumerator objEnum) { + privObjEnum = objEnum; + } + + public virtual object Current { + get { + return new VirtualSystemMigrationService(((System.Management.ManagementObject)(privObjEnum.Current))); + } + } + + public virtual bool MoveNext() { + return privObjEnum.MoveNext(); + } + + public virtual void Reset() { + privObjEnum.Reset(); + } + } + } + + // TypeConverter to handle null values for ValueType properties + public class WMIValueTypeConverter : TypeConverter { + + private TypeConverter baseConverter; + + private System.Type baseType; + + public WMIValueTypeConverter(System.Type inBaseType) { + baseConverter = TypeDescriptor.GetConverter(inBaseType); + baseType = inBaseType; + } + + public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type srcType) { + return baseConverter.CanConvertFrom(context, srcType); + } + + public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Type destinationType) { + return baseConverter.CanConvertTo(context, destinationType); + } + + public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { + return baseConverter.ConvertFrom(context, culture, value); + } + + public override object CreateInstance(System.ComponentModel.ITypeDescriptorContext context, System.Collections.IDictionary dictionary) { + return baseConverter.CreateInstance(context, dictionary); + } + + public override bool GetCreateInstanceSupported(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetCreateInstanceSupported(context); + } + + public override PropertyDescriptorCollection GetProperties(System.ComponentModel.ITypeDescriptorContext context, object value, System.Attribute[] attributeVar) { + return baseConverter.GetProperties(context, value, attributeVar); + } + + public override bool GetPropertiesSupported(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetPropertiesSupported(context); + } + + public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetStandardValues(context); + } + + public override bool GetStandardValuesExclusive(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetStandardValuesExclusive(context); + } + + public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetStandardValuesSupported(context); + } + + public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) { + if ((baseType.BaseType == typeof(System.Enum))) { + if ((value.GetType() == destinationType)) { + return value; + } + if ((((value == null) + && (context != null)) + && (context.PropertyDescriptor.ShouldSerializeValue(context.Instance) == false))) { + return "NULL_ENUM_VALUE" ; + } + return baseConverter.ConvertTo(context, culture, value, destinationType); + } + if (((baseType == typeof(bool)) + && (baseType.BaseType == typeof(System.ValueType)))) { + if ((((value == null) + && (context != null)) + && (context.PropertyDescriptor.ShouldSerializeValue(context.Instance) == false))) { + return ""; + } + return baseConverter.ConvertTo(context, culture, value, destinationType); + } + if (((context != null) + && (context.PropertyDescriptor.ShouldSerializeValue(context.Instance) == false))) { + return ""; + } + return baseConverter.ConvertTo(context, culture, value, destinationType); + } + } + + // Embedded class to represent WMI system Properties. + [TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))] + public class ManagementSystemProperties { + + private System.Management.ManagementBaseObject PrivateLateBoundObject; + + public ManagementSystemProperties(System.Management.ManagementBaseObject ManagedObject) { + PrivateLateBoundObject = ManagedObject; + } + + [Browsable(true)] + public int GENUS { + get { + return ((int)(PrivateLateBoundObject["__GENUS"])); + } + } + + [Browsable(true)] + public string CLASS { + get { + return ((string)(PrivateLateBoundObject["__CLASS"])); + } + } + + [Browsable(true)] + public string SUPERCLASS { + get { + return ((string)(PrivateLateBoundObject["__SUPERCLASS"])); + } + } + + [Browsable(true)] + public string DYNASTY { + get { + return ((string)(PrivateLateBoundObject["__DYNASTY"])); + } + } + + [Browsable(true)] + public string RELPATH { + get { + return ((string)(PrivateLateBoundObject["__RELPATH"])); + } + } + + [Browsable(true)] + public int PROPERTY_COUNT { + get { + return ((int)(PrivateLateBoundObject["__PROPERTY_COUNT"])); + } + } + + [Browsable(true)] + public string[] DERIVATION { + get { + return ((string[])(PrivateLateBoundObject["__DERIVATION"])); + } + } + + [Browsable(true)] + public string SERVER { + get { + return ((string)(PrivateLateBoundObject["__SERVER"])); + } + } + + [Browsable(true)] + public string NAMESPACE { + get { + return ((string)(PrivateLateBoundObject["__NAMESPACE"])); + } + } + + [Browsable(true)] + public string PATH { + get { + return ((string)(PrivateLateBoundObject["__PATH"])); + } + } + } + } +} diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/ROOT.virtualization.v2.Msvm_VirtualSystemMigrationSettingData.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/ROOT.virtualization.v2.Msvm_VirtualSystemMigrationSettingData.cs new file mode 100644 index 00000000000..de5bea5d8b8 --- /dev/null +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/ROOT.virtualization.v2.Msvm_VirtualSystemMigrationSettingData.cs @@ -0,0 +1,915 @@ +// 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. + +namespace CloudStack.Plugin.WmiWrappers.ROOT.VIRTUALIZATION.V2 { + using System; + using System.ComponentModel; + using System.Management; + using System.Collections; + using System.Globalization; + using System.ComponentModel.Design.Serialization; + using System.Reflection; + + + // Functions ShouldSerialize are functions used by VS property browser to check if a particular property has to be serialized. These functions are added for all ValueType properties ( properties of type Int32, BOOL etc.. which cannot be set to null). These functions use IsNull function. These functions are also used in the TypeConverter implementation for the properties to check for NULL value of property so that an empty value can be shown in Property browser in case of Drag and Drop in Visual studio. + // Functions IsNull() are used to check if a property is NULL. + // Functions Reset are added for Nullable Read/Write properties. These functions are used by VS designer in property browser to set a property to NULL. + // Every property added to the class for WMI property has attributes set to define its behavior in Visual Studio designer and also to define a TypeConverter to be used. + // An Early Bound class generated for the WMI class.Msvm_VirtualSystemMigrationSettingData + public class VirtualSystemMigrationSettingData : System.ComponentModel.Component { + + // Private property to hold the WMI namespace in which the class resides. + private static string CreatedWmiNamespace = "ROOT\\virtualization\\v2"; + + // Private property to hold the name of WMI class which created this class. + public static string CreatedClassName = "Msvm_VirtualSystemMigrationSettingData"; + + // Private member variable to hold the ManagementScope which is used by the various methods. + private static System.Management.ManagementScope statMgmtScope = null; + + private ManagementSystemProperties PrivateSystemProperties; + + // Underlying lateBound WMI object. + private System.Management.ManagementObject PrivateLateBoundObject; + + // Member variable to store the 'automatic commit' behavior for the class. + private bool AutoCommitProp; + + // Private variable to hold the embedded property representing the instance. + private System.Management.ManagementBaseObject embeddedObj; + + // The current WMI object used + private System.Management.ManagementBaseObject curObj; + + // Flag to indicate if the instance is an embedded object. + private bool isEmbedded; + + // Below are different overloads of constructors to initialize an instance of the class with a WMI object. + public VirtualSystemMigrationSettingData() { + this.InitializeObject(null, null, null); + } + + public VirtualSystemMigrationSettingData(string keyInstanceID) { + this.InitializeObject(null, new System.Management.ManagementPath(VirtualSystemMigrationSettingData.ConstructPath(keyInstanceID)), null); + } + + public VirtualSystemMigrationSettingData(System.Management.ManagementScope mgmtScope, string keyInstanceID) { + this.InitializeObject(((System.Management.ManagementScope)(mgmtScope)), new System.Management.ManagementPath(VirtualSystemMigrationSettingData.ConstructPath(keyInstanceID)), null); + } + + public VirtualSystemMigrationSettingData(System.Management.ManagementPath path, System.Management.ObjectGetOptions getOptions) { + this.InitializeObject(null, path, getOptions); + } + + public VirtualSystemMigrationSettingData(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path) { + this.InitializeObject(mgmtScope, path, null); + } + + public VirtualSystemMigrationSettingData(System.Management.ManagementPath path) { + this.InitializeObject(null, path, null); + } + + public VirtualSystemMigrationSettingData(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path, System.Management.ObjectGetOptions getOptions) { + this.InitializeObject(mgmtScope, path, getOptions); + } + + public VirtualSystemMigrationSettingData(System.Management.ManagementObject theObject) { + Initialize(); + if ((CheckIfProperClass(theObject) == true)) { + PrivateLateBoundObject = theObject; + PrivateSystemProperties = new ManagementSystemProperties(PrivateLateBoundObject); + curObj = PrivateLateBoundObject; + } + else { + throw new System.ArgumentException("Class name does not match."); + } + } + + public VirtualSystemMigrationSettingData(System.Management.ManagementBaseObject theObject) { + Initialize(); + if ((CheckIfProperClass(theObject) == true)) { + embeddedObj = theObject; + PrivateSystemProperties = new ManagementSystemProperties(theObject); + curObj = embeddedObj; + isEmbedded = true; + } + else { + throw new System.ArgumentException("Class name does not match."); + } + } + + // Property returns the namespace of the WMI class. + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string OriginatingNamespace { + get { + return "ROOT\\virtualization\\v2"; + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string ManagementClassName { + get { + string strRet = CreatedClassName; + if ((curObj != null)) { + if ((curObj.ClassPath != null)) { + strRet = ((string)(curObj["__CLASS"])); + if (((strRet == null) + || (strRet == string.Empty))) { + strRet = CreatedClassName; + } + } + } + return strRet; + } + } + + // Property pointing to an embedded object to get System properties of the WMI object. + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ManagementSystemProperties SystemProperties { + get { + return PrivateSystemProperties; + } + } + + // Property returning the underlying lateBound object. + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public System.Management.ManagementBaseObject LateBoundObject { + get { + return curObj; + } + } + + // ManagementScope of the object. + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public System.Management.ManagementScope Scope { + get { + if ((isEmbedded == false)) { + return PrivateLateBoundObject.Scope; + } + else { + return null; + } + } + set { + if ((isEmbedded == false)) { + PrivateLateBoundObject.Scope = value; + } + } + } + + // Property to show the commit behavior for the WMI object. If true, WMI object will be automatically saved after each property modification.(ie. Put() is called after modification of a property). + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool AutoCommit { + get { + return AutoCommitProp; + } + set { + AutoCommitProp = value; + } + } + + // The ManagementPath of the underlying WMI object. + [Browsable(true)] + public System.Management.ManagementPath Path { + get { + if ((isEmbedded == false)) { + return PrivateLateBoundObject.Path; + } + else { + return null; + } + } + set { + if ((isEmbedded == false)) { + if ((CheckIfProperClass(null, value, null) != true)) { + throw new System.ArgumentException("Class name does not match."); + } + PrivateLateBoundObject.Path = value; + } + } + } + + // Public static scope property which is used by the various methods. + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public static System.Management.ManagementScope StaticScope { + get { + return statMgmtScope; + } + set { + statMgmtScope = value; + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsBandwidthNull { + get { + if ((curObj["Bandwidth"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort Bandwidth { + get { + if ((curObj["Bandwidth"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["Bandwidth"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string BandwidthUnit { + get { + return ((string)(curObj["BandwidthUnit"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Caption { + get { + return ((string)(curObj["Caption"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Description { + get { + return ((string)(curObj["Description"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("For storage migration it will be NULL. For virtual system \nmigration, client can " + + "provide a list of IP addresses of the \ndestination host.")] + public string[] DestinationIPAddressList { + get { + return ((string[])(curObj["DestinationIPAddressList"])); + } + set { + curObj["DestinationIPAddressList"] = value; + if (((isEmbedded == false) + && (AutoCommitProp == true))) { + PrivateLateBoundObject.Put(); + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description(@"If we have a planned computer system at migration destination then DestinationPlannedVirtualSystemId could be set to +the GUID of the destination Planned VM where the VM needs to +migrate. This is useful for cases where user has created a +planned VM at the destination along with resource fixup, and +wants a VM from source to migrate into this planned VM.")] + public string DestinationPlannedVirtualSystemId { + get { + return ((string)(curObj["DestinationPlannedVirtualSystemId"])); + } + set { + curObj["DestinationPlannedVirtualSystemId"] = value; + if (((isEmbedded == false) + && (AutoCommitProp == true))) { + PrivateLateBoundObject.Put(); + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string ElementName { + get { + return ((string)(curObj["ElementName"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string InstanceID { + get { + return ((string)(curObj["InstanceID"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsMigrationTypeNull { + get { + if ((curObj["MigrationType"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("MigrationType describes the type of migration operation to \nbe performed.\n")] + [TypeConverter(typeof(WMIValueTypeConverter))] + public MigrationTypeValues MigrationType { + get { + if ((curObj["MigrationType"] == null)) { + return ((MigrationTypeValues)(System.Convert.ToInt32(32773))); + } + return ((MigrationTypeValues)(System.Convert.ToInt32(curObj["MigrationType"]))); + } + set { + if ((MigrationTypeValues.NULL_ENUM_VALUE == value)) { + curObj["MigrationType"] = null; + } + else { + curObj["MigrationType"] = value; + } + if (((isEmbedded == false) + && (AutoCommitProp == true))) { + PrivateLateBoundObject.Put(); + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string OtherTransportType { + get { + return ((string)(curObj["OtherTransportType"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsPriorityNull { + get { + if ((curObj["Priority"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort Priority { + get { + if ((curObj["Priority"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["Priority"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsRetainVhdCopiesOnSourceNull { + get { + if ((curObj["RetainVhdCopiesOnSource"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("For storage migration, this could be set to TRUE or FALSE\nto determine wheither, " + + "at the end of a storage migration, when the\nsource host is beeing clean up, the " + + "read only VHDs should be removedor not.")] + [TypeConverter(typeof(WMIValueTypeConverter))] + public bool RetainVhdCopiesOnSource { + get { + if ((curObj["RetainVhdCopiesOnSource"] == null)) { + return System.Convert.ToBoolean(0); + } + return ((bool)(curObj["RetainVhdCopiesOnSource"])); + } + set { + curObj["RetainVhdCopiesOnSource"] = value; + if (((isEmbedded == false) + && (AutoCommitProp == true))) { + PrivateLateBoundObject.Put(); + } + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsTransportTypeNull { + get { + if ((curObj["TransportType"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort TransportType { + get { + if ((curObj["TransportType"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["TransportType"])); + } + } + + private bool CheckIfProperClass(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path, System.Management.ObjectGetOptions OptionsParam) { + if (((path != null) + && (string.Compare(path.ClassName, this.ManagementClassName, true, System.Globalization.CultureInfo.InvariantCulture) == 0))) { + return true; + } + else { + return CheckIfProperClass(new System.Management.ManagementObject(mgmtScope, path, OptionsParam)); + } + } + + private bool CheckIfProperClass(System.Management.ManagementBaseObject theObj) { + if (((theObj != null) + && (string.Compare(((string)(theObj["__CLASS"])), this.ManagementClassName, true, System.Globalization.CultureInfo.InvariantCulture) == 0))) { + return true; + } + else { + System.Array parentClasses = ((System.Array)(theObj["__DERIVATION"])); + if ((parentClasses != null)) { + int count = 0; + for (count = 0; (count < parentClasses.Length); count = (count + 1)) { + if ((string.Compare(((string)(parentClasses.GetValue(count))), this.ManagementClassName, true, System.Globalization.CultureInfo.InvariantCulture) == 0)) { + return true; + } + } + } + } + return false; + } + + private bool ShouldSerializeBandwidth() { + if ((this.IsBandwidthNull == false)) { + return true; + } + return false; + } + + private void ResetDestinationIPAddressList() { + curObj["DestinationIPAddressList"] = null; + if (((isEmbedded == false) + && (AutoCommitProp == true))) { + PrivateLateBoundObject.Put(); + } + } + + private void ResetDestinationPlannedVirtualSystemId() { + curObj["DestinationPlannedVirtualSystemId"] = null; + if (((isEmbedded == false) + && (AutoCommitProp == true))) { + PrivateLateBoundObject.Put(); + } + } + + private bool ShouldSerializeMigrationType() { + if ((this.IsMigrationTypeNull == false)) { + return true; + } + return false; + } + + private void ResetMigrationType() { + curObj["MigrationType"] = null; + if (((isEmbedded == false) + && (AutoCommitProp == true))) { + PrivateLateBoundObject.Put(); + } + } + + private bool ShouldSerializePriority() { + if ((this.IsPriorityNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeRetainVhdCopiesOnSource() { + if ((this.IsRetainVhdCopiesOnSourceNull == false)) { + return true; + } + return false; + } + + private void ResetRetainVhdCopiesOnSource() { + curObj["RetainVhdCopiesOnSource"] = null; + if (((isEmbedded == false) + && (AutoCommitProp == true))) { + PrivateLateBoundObject.Put(); + } + } + + private bool ShouldSerializeTransportType() { + if ((this.IsTransportTypeNull == false)) { + return true; + } + return false; + } + + [Browsable(true)] + public void CommitObject() { + if ((isEmbedded == false)) { + PrivateLateBoundObject.Put(); + } + } + + [Browsable(true)] + public void CommitObject(System.Management.PutOptions putOptions) { + if ((isEmbedded == false)) { + PrivateLateBoundObject.Put(putOptions); + } + } + + private void Initialize() { + AutoCommitProp = true; + isEmbedded = false; + } + + private static string ConstructPath(string keyInstanceID) { + string strPath = "ROOT\\virtualization\\v2:Msvm_VirtualSystemMigrationSettingData"; + strPath = string.Concat(strPath, string.Concat(".InstanceID=", string.Concat("\"", string.Concat(keyInstanceID, "\"")))); + return strPath; + } + + private void InitializeObject(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path, System.Management.ObjectGetOptions getOptions) { + Initialize(); + if ((path != null)) { + if ((CheckIfProperClass(mgmtScope, path, getOptions) != true)) { + throw new System.ArgumentException("Class name does not match."); + } + } + PrivateLateBoundObject = new System.Management.ManagementObject(mgmtScope, path, getOptions); + PrivateSystemProperties = new ManagementSystemProperties(PrivateLateBoundObject); + curObj = PrivateLateBoundObject; + } + + // Different overloads of GetInstances() help in enumerating instances of the WMI class. + public static VirtualSystemMigrationSettingDataCollection GetInstances() { + return GetInstances(null, null, null); + } + + public static VirtualSystemMigrationSettingDataCollection GetInstances(string condition) { + return GetInstances(null, condition, null); + } + + public static VirtualSystemMigrationSettingDataCollection GetInstances(string[] selectedProperties) { + return GetInstances(null, null, selectedProperties); + } + + public static VirtualSystemMigrationSettingDataCollection GetInstances(string condition, string[] selectedProperties) { + return GetInstances(null, condition, selectedProperties); + } + + public static VirtualSystemMigrationSettingDataCollection GetInstances(System.Management.ManagementScope mgmtScope, System.Management.EnumerationOptions enumOptions) { + if ((mgmtScope == null)) { + if ((statMgmtScope == null)) { + mgmtScope = new System.Management.ManagementScope(); + mgmtScope.Path.NamespacePath = "root\\virtualization\\v2"; + } + else { + mgmtScope = statMgmtScope; + } + } + System.Management.ManagementPath pathObj = new System.Management.ManagementPath(); + pathObj.ClassName = "Msvm_VirtualSystemMigrationSettingData"; + pathObj.NamespacePath = "root\\virtualization\\v2"; + System.Management.ManagementClass clsObject = new System.Management.ManagementClass(mgmtScope, pathObj, null); + if ((enumOptions == null)) { + enumOptions = new System.Management.EnumerationOptions(); + enumOptions.EnsureLocatable = true; + } + return new VirtualSystemMigrationSettingDataCollection(clsObject.GetInstances(enumOptions)); + } + + public static VirtualSystemMigrationSettingDataCollection GetInstances(System.Management.ManagementScope mgmtScope, string condition) { + return GetInstances(mgmtScope, condition, null); + } + + public static VirtualSystemMigrationSettingDataCollection GetInstances(System.Management.ManagementScope mgmtScope, string[] selectedProperties) { + return GetInstances(mgmtScope, null, selectedProperties); + } + + public static VirtualSystemMigrationSettingDataCollection GetInstances(System.Management.ManagementScope mgmtScope, string condition, string[] selectedProperties) { + if ((mgmtScope == null)) { + if ((statMgmtScope == null)) { + mgmtScope = new System.Management.ManagementScope(); + mgmtScope.Path.NamespacePath = "root\\virtualization\\v2"; + } + else { + mgmtScope = statMgmtScope; + } + } + System.Management.ManagementObjectSearcher ObjectSearcher = new System.Management.ManagementObjectSearcher(mgmtScope, new SelectQuery("Msvm_VirtualSystemMigrationSettingData", condition, selectedProperties)); + System.Management.EnumerationOptions enumOptions = new System.Management.EnumerationOptions(); + enumOptions.EnsureLocatable = true; + ObjectSearcher.Options = enumOptions; + return new VirtualSystemMigrationSettingDataCollection(ObjectSearcher.Get()); + } + + [Browsable(true)] + public static VirtualSystemMigrationSettingData CreateInstance() { + System.Management.ManagementScope mgmtScope = null; + if ((statMgmtScope == null)) { + mgmtScope = new System.Management.ManagementScope(); + mgmtScope.Path.NamespacePath = CreatedWmiNamespace; + } + else { + mgmtScope = statMgmtScope; + } + System.Management.ManagementPath mgmtPath = new System.Management.ManagementPath(CreatedClassName); + System.Management.ManagementClass tmpMgmtClass = new System.Management.ManagementClass(mgmtScope, mgmtPath, null); + return new VirtualSystemMigrationSettingData(tmpMgmtClass.CreateInstance()); + } + + [Browsable(true)] + public void Delete() { + PrivateLateBoundObject.Delete(); + } + + public enum MigrationTypeValues { + + Unknown0 = 0, + + VirtualSystem = 32768, + + Storage = 32769, + + Staged = 32770, + + VirtualSystemAndStorage = 32771, + + StorageDeepCheck = 32772, + + NULL_ENUM_VALUE = 32773, + } + + // Enumerator implementation for enumerating instances of the class. + public class VirtualSystemMigrationSettingDataCollection : object, ICollection { + + private ManagementObjectCollection privColObj; + + public VirtualSystemMigrationSettingDataCollection(ManagementObjectCollection objCollection) { + privColObj = objCollection; + } + + public virtual int Count { + get { + return privColObj.Count; + } + } + + public virtual bool IsSynchronized { + get { + return privColObj.IsSynchronized; + } + } + + public virtual object SyncRoot { + get { + return this; + } + } + + public virtual void CopyTo(System.Array array, int index) { + privColObj.CopyTo(array, index); + int nCtr; + for (nCtr = 0; (nCtr < array.Length); nCtr = (nCtr + 1)) { + array.SetValue(new VirtualSystemMigrationSettingData(((System.Management.ManagementObject)(array.GetValue(nCtr)))), nCtr); + } + } + + public virtual System.Collections.IEnumerator GetEnumerator() { + return new VirtualSystemMigrationSettingDataEnumerator(privColObj.GetEnumerator()); + } + + public class VirtualSystemMigrationSettingDataEnumerator : object, System.Collections.IEnumerator { + + private ManagementObjectCollection.ManagementObjectEnumerator privObjEnum; + + public VirtualSystemMigrationSettingDataEnumerator(ManagementObjectCollection.ManagementObjectEnumerator objEnum) { + privObjEnum = objEnum; + } + + public virtual object Current { + get { + return new VirtualSystemMigrationSettingData(((System.Management.ManagementObject)(privObjEnum.Current))); + } + } + + public virtual bool MoveNext() { + return privObjEnum.MoveNext(); + } + + public virtual void Reset() { + privObjEnum.Reset(); + } + } + } + + // TypeConverter to handle null values for ValueType properties + public class WMIValueTypeConverter : TypeConverter { + + private TypeConverter baseConverter; + + private System.Type baseType; + + public WMIValueTypeConverter(System.Type inBaseType) { + baseConverter = TypeDescriptor.GetConverter(inBaseType); + baseType = inBaseType; + } + + public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type srcType) { + return baseConverter.CanConvertFrom(context, srcType); + } + + public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Type destinationType) { + return baseConverter.CanConvertTo(context, destinationType); + } + + public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { + return baseConverter.ConvertFrom(context, culture, value); + } + + public override object CreateInstance(System.ComponentModel.ITypeDescriptorContext context, System.Collections.IDictionary dictionary) { + return baseConverter.CreateInstance(context, dictionary); + } + + public override bool GetCreateInstanceSupported(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetCreateInstanceSupported(context); + } + + public override PropertyDescriptorCollection GetProperties(System.ComponentModel.ITypeDescriptorContext context, object value, System.Attribute[] attributeVar) { + return baseConverter.GetProperties(context, value, attributeVar); + } + + public override bool GetPropertiesSupported(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetPropertiesSupported(context); + } + + public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetStandardValues(context); + } + + public override bool GetStandardValuesExclusive(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetStandardValuesExclusive(context); + } + + public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetStandardValuesSupported(context); + } + + public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) { + if ((baseType.BaseType == typeof(System.Enum))) { + if ((value.GetType() == destinationType)) { + return value; + } + if ((((value == null) + && (context != null)) + && (context.PropertyDescriptor.ShouldSerializeValue(context.Instance) == false))) { + return "NULL_ENUM_VALUE" ; + } + return baseConverter.ConvertTo(context, culture, value, destinationType); + } + if (((baseType == typeof(bool)) + && (baseType.BaseType == typeof(System.ValueType)))) { + if ((((value == null) + && (context != null)) + && (context.PropertyDescriptor.ShouldSerializeValue(context.Instance) == false))) { + return ""; + } + return baseConverter.ConvertTo(context, culture, value, destinationType); + } + if (((context != null) + && (context.PropertyDescriptor.ShouldSerializeValue(context.Instance) == false))) { + return ""; + } + return baseConverter.ConvertTo(context, culture, value, destinationType); + } + } + + // Embedded class to represent WMI system Properties. + [TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))] + public class ManagementSystemProperties { + + private System.Management.ManagementBaseObject PrivateLateBoundObject; + + public ManagementSystemProperties(System.Management.ManagementBaseObject ManagedObject) { + PrivateLateBoundObject = ManagedObject; + } + + [Browsable(true)] + public int GENUS { + get { + return ((int)(PrivateLateBoundObject["__GENUS"])); + } + } + + [Browsable(true)] + public string CLASS { + get { + return ((string)(PrivateLateBoundObject["__CLASS"])); + } + } + + [Browsable(true)] + public string SUPERCLASS { + get { + return ((string)(PrivateLateBoundObject["__SUPERCLASS"])); + } + } + + [Browsable(true)] + public string DYNASTY { + get { + return ((string)(PrivateLateBoundObject["__DYNASTY"])); + } + } + + [Browsable(true)] + public string RELPATH { + get { + return ((string)(PrivateLateBoundObject["__RELPATH"])); + } + } + + [Browsable(true)] + public int PROPERTY_COUNT { + get { + return ((int)(PrivateLateBoundObject["__PROPERTY_COUNT"])); + } + } + + [Browsable(true)] + public string[] DERIVATION { + get { + return ((string[])(PrivateLateBoundObject["__DERIVATION"])); + } + } + + [Browsable(true)] + public string SERVER { + get { + return ((string)(PrivateLateBoundObject["__SERVER"])); + } + } + + [Browsable(true)] + public string NAMESPACE { + get { + return ((string)(PrivateLateBoundObject["__NAMESPACE"])); + } + } + + [Browsable(true)] + public string PATH { + get { + return ((string)(PrivateLateBoundObject["__PATH"])); + } + } + } + } +} diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/WmiWrappers.csproj b/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/WmiWrappers.csproj index da0c0d6ce7c..1a703400bcb 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/WmiWrappers.csproj +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/WmiWrappers.csproj @@ -123,6 +123,9 @@ Component + + Component + Component @@ -153,6 +156,12 @@ Component + + Component + + + Component + Component @@ -172,4 +181,4 @@ --> - + \ No newline at end of file diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 860f1654734..ee9c04a2aa4 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -1067,12 +1067,14 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe throw ex; } - if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && - !vm.getHypervisorType().equals(HypervisorType.KVM) && !vm.getHypervisorType().equals(HypervisorType.Ovm)) { + if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) + && !vm.getHypervisorType().equals(HypervisorType.KVM) && !vm.getHypervisorType().equals(HypervisorType.Ovm) + && !vm.getHypervisorType().equals(HypervisorType.Hyperv)) { if (s_logger.isDebugEnabled()) { - s_logger.debug(vm + " is not XenServer/VMware/KVM/OVM, cannot migrate this VM."); + s_logger.debug(vm + " is not XenServer/VMware/KVM/OVM/Hyperv, cannot migrate this VM."); } - throw new InvalidParameterValueException("Unsupported Hypervisor Type for VM migration, we support " + "XenServer/VMware/KVM/Ovm only"); + throw new InvalidParameterValueException("Unsupported Hypervisor Type for VM migration, we support " + + "XenServer/VMware/KVM/Ovm/Hyperv only"); } long srcHostId = vm.getHostId(); diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index d3dd35663b9..49f4e2e7fdb 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -3873,13 +3873,18 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir ex.addProxyObject(vm.getUuid(), "vmId"); throw ex; } - if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && - !vm.getHypervisorType().equals(HypervisorType.KVM) && !vm.getHypervisorType().equals(HypervisorType.Ovm) && - !vm.getHypervisorType().equals(HypervisorType.Simulator)) { + if (!vm.getHypervisorType().equals(HypervisorType.XenServer) + && !vm.getHypervisorType().equals(HypervisorType.VMware) + && !vm.getHypervisorType().equals(HypervisorType.KVM) + && !vm.getHypervisorType().equals(HypervisorType.Ovm) + && !vm.getHypervisorType().equals(HypervisorType.Hyperv) + && !vm.getHypervisorType().equals(HypervisorType.Simulator)) { if (s_logger.isDebugEnabled()) { - s_logger.debug(vm + " is not XenServer/VMware/KVM/Ovm, cannot migrate this VM."); + s_logger.debug(vm + + " is not XenServer/VMware/KVM/Ovm/Hyperv, cannot migrate this VM."); } - throw new InvalidParameterValueException("Unsupported Hypervisor Type for VM migration, we support XenServer/VMware/KVM only"); + throw new InvalidParameterValueException( + "Unsupported Hypervisor Type for VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv only"); } if (isVMUsingLocalStorage(vm)) { From d26b9ac00e1486dd7ec68e6f2ef03777f007a344 Mon Sep 17 00:00:00 2001 From: Devdeep Singh Date: Wed, 4 Dec 2013 02:27:27 +0530 Subject: [PATCH 086/170] Fix for live migration of vm. Use the host name as the migration destination. Also mapped the vm state corrected in check vm on host answer. --- .../HypervResource/HypervResourceController.cs | 2 +- .../DotNet/ServerResource/HypervResource/WmiCallsV2.cs | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index fc4dea5748d..915816d0a31 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -738,7 +738,7 @@ namespace HypervResource } else { - state = EnabledState.ToString(sys.EnabledState); // TODO: V2 changes? + state = EnabledState.ToCloudStackState(sys.EnabledState); // TODO: V2 changes? result = true; } diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs index c0201682cb0..c69ec38d436 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs @@ -890,13 +890,17 @@ namespace HypervResource VirtualSystemMigrationSettingData migrationSettingData = VirtualSystemMigrationSettingData.CreateInstance(); VirtualSystemMigrationService service = GetVirtualisationSystemMigrationService(); + IPAddress addr = IPAddress.Parse(destination); + IPHostEntry entry = Dns.GetHostEntry(addr); + string[] destinationHost = new string[] { destination }; + migrationSettingData.LateBoundObject["MigrationType"] = MigrationType.VirtualSystem; migrationSettingData.LateBoundObject["TransportType"] = TransportType.TCP; + migrationSettingData.LateBoundObject["DestinationIPAddressList"] = destinationHost; string migrationSettings = migrationSettingData.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20); ManagementPath jobPath; - string destinationHost = "band-cloud153.blr.cloudstack.org"; - var ret_val = service.MigrateVirtualSystemToHost(vm.Path, destinationHost, migrationSettings, null, null, out jobPath); + var ret_val = service.MigrateVirtualSystemToHost(vm.Path, entry.HostName, migrationSettings, null, null, out jobPath); if (ret_val == ReturnCode.Started) { MigrationJobCompleted(jobPath); From f05063f377087d41d9df5bae8680ce5121b6ec94 Mon Sep 17 00:00:00 2001 From: Gaurav Aradhye Date: Wed, 4 Dec 2013 11:25:58 +0530 Subject: [PATCH 087/170] CLOUDSTACK-5346: Fixed shared network cleanup issue --- .../component/test_project_resources.py | 66 +++++++++++++++---- 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/test/integration/component/test_project_resources.py b/test/integration/component/test_project_resources.py index 9b9b2e6ac2e..b7ed60edf11 100644 --- a/test/integration/component/test_project_resources.py +++ b/test/integration/component/test_project_resources.py @@ -17,15 +17,35 @@ """ P1 tests for Resource creation """ #Import Local Modules -import marvin from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * -from marvin.sshClient import SshClient -import datetime +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.integration.lib.base import (VirtualMachine, + Account, + Project, + NATRule, + PublicIPAddress, + Network, + Snapshot, + Template, + FireWallRule, + SecurityGroup, + ServiceOffering, + Domain, + Volume, + DiskOffering, + LoadBalancerRule) + +from marvin.integration.lib.common import (get_zone, + get_template, + get_domain, + list_volumes, + list_network_offerings, + list_lb_rules, + get_free_vlan, + wait_for_cleanup) + +from marvin.integration.lib.utils import cleanup_resources +import random class Services: @@ -98,11 +118,11 @@ class Services: "domain_network": { "name": "Domainwide Network", "displaytext": "Domainwide Network", - "gateway": '192.168.100.1', + "gateway": '', "netmask": '255.255.255.0', - "startip": '192.168.100.200', - "endip": '192.168.100.201', - "vlan": 4001, + "startip": '', + "endip": '', + "vlan": '', "acltype": 'domain' }, "natrule": { @@ -478,6 +498,20 @@ class TestNetwork(cloudstackTestCase): self.debug("creating a shared network in domain: %s" % self.domain.id) + + # Getting physical network and free vlan in it + physical_network, vlan = get_free_vlan(self.apiclient, self.zone.id) + + self.services["domain_network"]["vlan"] = vlan + self.services["domain_network"]["physicalnetworkid"] = physical_network.id + + # Generating random subnet number for shared network creation + shared_network_subnet_number = random.randrange(1,254) + + self.services["domain_network"]["gateway"] = "172.16."+str(shared_network_subnet_number)+".1" + self.services["domain_network"]["startip"] = "172.16."+str(shared_network_subnet_number)+".2" + self.services["domain_network"]["endip"] = "172.16."+str(shared_network_subnet_number)+".20" + domain_network = Network.create( self.apiclient, self.services["domain_network"], @@ -503,6 +537,14 @@ class TestNetwork(cloudstackTestCase): 'Running', "Check VM state is Running or not" ) + + # Delete VM before network gets deleted in cleanup + virtual_machine.delete(self.apiclient) + + # Wait for expunge interval to cleanup VM + wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"]) + + self.cleanup.append(domain_network) return From e5cfe948186b825d2b28c99ce2915a5ca8498aff Mon Sep 17 00:00:00 2001 From: Bharat Kumar Date: Thu, 28 Nov 2013 12:34:16 +0530 Subject: [PATCH 088/170] CLOUDSTACK-5160 add a map to specify the custom compute parameters in the deployvm api. Signed-off-by: Jayapal --- api/src/com/cloud/vm/UserVmService.java | 6 +- .../api/command/user/vm/DeployVMCmd.java | 64 +++++--------- .../src/com/cloud/vm/UserVmManagerImpl.java | 88 +++++++------------ 3 files changed, 59 insertions(+), 99 deletions(-) diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java index ac14da753b1..5306bf92e57 100755 --- a/api/src/com/cloud/vm/UserVmService.java +++ b/api/src/com/cloud/vm/UserVmService.java @@ -202,7 +202,7 @@ public interface UserVmService { UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard, - List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootdisksize, String customId) throws InsufficientCapacityException, + List affinityGroupIdList, Map customParameter, String customId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; /** @@ -276,7 +276,7 @@ public interface UserVmService { UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List networkIdList, List securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, - List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootdisksize, String customId) throws InsufficientCapacityException, + List affinityGroupIdList, Map customParameters, String customId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; /** @@ -348,7 +348,7 @@ public interface UserVmService { UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List networkIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List affinityGroupIdList, - Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootdkisksize, String customId) + Map customParameters, String customId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java index f075082c3f8..fee6db25c87 100755 --- a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java @@ -230,29 +230,11 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd { description = "an optional field, whether to the display the vm to the end user or not.") private Boolean displayVm; - @Parameter(name = ApiConstants.CPU_SPEED, - type = CommandType.INTEGER, - since = "4.3", - description = "optional field to specify the cpu speed when using dynamic compute offering.") - private Integer cpuSpeed; - - @Parameter(name = ApiConstants.MEMORY, - type = CommandType.INTEGER, - since = "4.3", - description = "optional field to specify the memory when using dynamic compute offering") - private Integer memory; - - @Parameter(name = ApiConstants.CPU_NUMBER, - type = CommandType.INTEGER, - since = "4.3", - description = "optional field to specify the number of cpu cores when using dynamic offering.") - private Integer cpuNumber; - - @Parameter(name = ApiConstants.ROOT_DISK_SIZE, - type = CommandType.LONG, - since = "4.3", - description = "optional field to specify the number of cpu cores when using dynamic offering.") - private Long rootdisksize; + @Parameter(name = ApiConstants.CUSTOM_PARAMETERS, + type = CommandType.MAP, + since= "4.3", + description = "used to specify the custom parameters.") + private Map customParameters; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -280,6 +262,21 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd { return domainId; } + public Map getCustomParameters() { + Map customparameterMap = new HashMap(); + if (customParameters != null && customParameters.size() !=0){ + Collection parameterCollection = customParameters.values(); + Iterator iter = parameterCollection.iterator(); + while (iter.hasNext()) { + HashMap value = (HashMap) iter.next(); + for (String key : value.keySet()) { + customparameterMap.put(key, value.get(key)); + } + } + } + return customparameterMap; + } + public String getGroup() { return group; } @@ -292,21 +289,6 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd { return displayVm; } - public Integer getMemory() { - return memory; - } - - public Integer getCpuSpeed() { - return cpuSpeed; - } - - public Integer getCpuNumber() { - return cpuNumber; - } - - public Long getRootdisksize() { - return rootdisksize; - } public List getSecurityGroupIdList() { if (securityGroupNameList != null && securityGroupIdList != null) { @@ -577,14 +559,14 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd { vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(), owner, name, displayName, diskOfferingId, size, group, getHypervisor(), getHttpMethod(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, displayVm, keyboard, - getAffinityGroupIdList(), cpuSpeed, memory, cpuNumber, rootdisksize, getCustomId()); + getAffinityGroupIdList(), getCustomParameters(), getCustomId()); } } else { if (zone.isSecurityGroupEnabled()) { vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, getNetworkIds(), getSecurityGroupIdList(), owner, name, displayName, diskOfferingId, size, group, getHypervisor(), getHttpMethod(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, displayVm, - keyboard, getAffinityGroupIdList(), cpuSpeed, memory, cpuNumber, rootdisksize, getCustomId()); + keyboard, getAffinityGroupIdList(), getCustomParameters(), getCustomId()); } else { if (getSecurityGroupIdList() != null && !getSecurityGroupIdList().isEmpty()) { @@ -593,7 +575,7 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd { vm = _userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, getNetworkIds(), owner, name, displayName, diskOfferingId, size, group, getHypervisor(), getHttpMethod(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, displayVm, keyboard, getAffinityGroupIdList(), - cpuSpeed, memory, cpuNumber, rootdisksize, getCustomId()); + getCustomParameters(), getCustomId()); } } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 49f4e2e7fdb..ff519ead9cb 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -2188,7 +2188,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, - List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootDiskSize, String customId) throws InsufficientCapacityException, + List affinityGroupIdList, Map customParametes, String customId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); @@ -2233,8 +2233,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, - httpmethod, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, cpuSpeed, memory, cpuNumber, - rootDiskSize, customId); + httpmethod, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParametes, customId); } @@ -2243,7 +2242,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List networkIdList, List securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, - List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootDiskSize, String customId) throws InsufficientCapacityException, + List affinityGroupIdList, Map customParameters, String customId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); @@ -2342,8 +2341,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, - httpmethod, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, cpuSpeed, memory, cpuNumber, - rootDiskSize, customId); + httpmethod, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParameters, customId); } @Override @@ -2351,7 +2349,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List networkIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayvm, String keyboard, - List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootDiskSize, String customId) throws InsufficientCapacityException, + List affinityGroupIdList, Map customParametrs, String customId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); @@ -2440,7 +2438,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, null, group, httpmethod, - userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayvm, keyboard, affinityGroupIdList, cpuSpeed, memory, cpuNumber, rootDiskSize, customId); + userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayvm, keyboard, affinityGroupIdList, customParametrs, customId); } public void checkNameForRFCCompliance(String name) { @@ -2454,7 +2452,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir protected UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate tmplt, String hostName, String displayName, Account owner, Long diskOfferingId, Long diskSize, List networkList, List securityGroupIdList, String group, HTTPMethod httpmethod, String userData, String sshKeyPair, HypervisorType hypervisor, Account caller, Map requestedIps, IpAddresses defaultIps, - Boolean isDisplayVmEnabled, String keyboard, List affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootDiskSize, String customId) + Boolean isDisplayVmEnabled, String keyboard, List affinityGroupIdList, Map customParameters, String customId) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException { _accountMgr.checkAccess(caller, null, true, owner); @@ -2489,6 +2487,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } ServiceOfferingVO offering = _serviceOfferingDao.findById(serviceOffering.getId()); + if (offering.isDynamic()) { + offering.setDynamicFlag(true); + validateCustomParameters(offering, customParameters); + offering = _offeringDao.getcomputeOffering(offering, customParameters); + } // check if account/domain is with in resource limits to create a new vm boolean isIso = Storage.ImageFormat.ISO == template.getFormat(); // For baremetal, size can be null @@ -2500,11 +2503,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir if (diskOfferingId != null) { size += _diskOfferingDao.findById(diskOfferingId).getDiskSize(); } - if (!offering.isDynamic()) { - resourceLimitCheck(owner, new Long(offering.getCpu()), new Long(offering.getRamSize())); - } else { - resourceLimitCheck(owner, new Long(cpuSpeed), new Long(memory)); - } + resourceLimitCheck(owner, new Long(offering.getCpu()), new Long(offering.getRamSize())); + _resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, (isIso || diskOfferingId == null ? 1 : 2)); _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, size); @@ -2671,35 +2671,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir long id = _vmDao.getNextInSequence(Long.class, "id"); - List details = new ArrayList(); - if (offering.isDynamic()) { - //insert the custom value of dynamic parameters - if (offering.getCpu() == null) { - if ((cpuNumber != null) && (cpuNumber <= 0)) { - throw new InvalidParameterValueException("Invalid CPU number value, specify a value between 1 and 2147483647"); - } - } - if (offering.getSpeed() == null) { - if ((cpuSpeed != null) && (cpuSpeed <= 0)) { - throw new InvalidParameterValueException("Invalid CPU speed value, specify a value between 1 and 2147483647"); - } - } - - if (offering.getRamSize() == null) { - if ((memory != null) && (memory < 32)) { - throw new InvalidParameterValueException("Invalid memory value, specify a value between 32 and 2147483647 MB"); - } - } - - details.add(new UserVmDetailVO(id, UsageEventVO.DynamicParameters.cpuNumber.toString(), cpuNumber.toString())); - details.add(new UserVmDetailVO(id, UsageEventVO.DynamicParameters.cpuSpeed.toString(), cpuSpeed.toString())); - details.add(new UserVmDetailVO(id, UsageEventVO.DynamicParameters.memory.toString(), memory.toString())); - offering.setCpu(cpuNumber); - offering.setRamSize(memory); - offering.setSpeed(cpuSpeed); - offering.setDynamicFlag(true); - } if (hostName != null) { // Check is hostName is RFC compliant checkNameForRFCCompliance(hostName); @@ -2770,7 +2742,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir UserVmVO vm = commitUserVm(zone, template, hostName, displayName, owner, diskOfferingId, diskSize, userData, hypervisor, caller, isDisplayVmEnabled, keyboard, accountId, - offering, isIso, sshPublicKey, networkNicMap, id, instanceName, uuidName, hypervisorType, rootDiskSize, details); + offering, isIso, sshPublicKey, networkNicMap, id, instanceName, uuidName, hypervisorType, customParameters); // Assign instance to the group try { @@ -2801,7 +2773,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir final Long diskOfferingId, final Long diskSize, final String userData, final HypervisorType hypervisor, final Account caller, final Boolean isDisplayVmEnabled, final String keyboard, final long accountId, final ServiceOfferingVO offering, final boolean isIso, final String sshPublicKey, final LinkedHashMap networkNicMap, final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType, - final Long rootDiskSize, final List vmdetails) throws InsufficientCapacityException { + final Map customParameters) throws InsufficientCapacityException { return Transaction.execute(new TransactionCallbackWithException() { @Override public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCapacityException { @@ -2820,6 +2792,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir if (isIso) { vm.setIsoId(template.getId()); } + Long rootDiskSize = null; + if (customParameters.containsKey("rootdisksize")) { + if (NumbersUtil.parseLong(customParameters.get("rootdisksize"), -1) <=0) { + throw new InvalidParameterValueException("rootdisk size should be a non zero number."); + } + rootDiskSize = Long.parseLong(customParameters.get("rootDisksize")); + customParameters.remove("rootdisksize"); + } if (isDisplayVmEnabled != null) { if (!_accountMgr.isRootAdmin(caller.getType())) { @@ -2864,9 +2844,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } _vmDao.persist(vm); - if (vmdetails != null && vmdetails.size() > 0) { - for (UserVmDetailVO detail : vmdetails) { - vm.setDetail(detail.getName(), detail.getValue()); + if (customParameters != null && customParameters.size() > 0) { + for (String key : customParameters.keySet()) { + vm.setDetail(key, customParameters.get(key)); } } _vmDao.saveDetails(vm); @@ -2896,15 +2876,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir CallContext.current().setEventDetails("Vm Id: " + vm.getId()); if (!offering.isDynamic()) { + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), + vm.getHostName(), offering.getId(), template.getId(), hypervisorType.toString(), + VirtualMachine.class.getName(), vm.getUuid()); + } + else { UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(), - template.getId(), hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid()); - } else { - HashMap vmdetailsMap = new HashMap(); - for (UserVmDetailVO vmdetail : vmdetails) { - vmdetailsMap.put(vmdetail.getName(), vmdetail.getValue()); - } - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(), - template.getId(), hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), vmdetailsMap); + template.getId(), hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), customParameters); } //Update Resource Count for the given account From 6b955958c6165f69de8dbaf6310868d8f5c2a3b1 Mon Sep 17 00:00:00 2001 From: Gaurav Aradhye Date: Wed, 4 Dec 2013 11:29:50 +0530 Subject: [PATCH 089/170] CLOUDSTACK-5333: Code changes related to snapshots listing Signed-off-by: Girish Shilamkar --- .../component/test_project_limits.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/integration/component/test_project_limits.py b/test/integration/component/test_project_limits.py index c497311c94a..7cb29b7d279 100644 --- a/test/integration/component/test_project_limits.py +++ b/test/integration/component/test_project_limits.py @@ -24,6 +24,7 @@ from marvin.cloudstackAPI import * from marvin.integration.lib.utils import * from marvin.integration.lib.base import * from marvin.integration.lib.common import * +from marvin.codes import PASS import datetime @@ -781,15 +782,14 @@ class TestResourceLimitsProject(cloudstackTestCase): projectid=self.project.id ) self.cleanup.append(snapshot_1) - # Verify Snapshot state - self.assertEqual( - snapshot_1.state in [ - 'BackedUp', - 'CreatedOnPrimary' - ], - True, - "Check Snapshot state is Running or not" - ) + + #list snapshots + snapshots = list_snapshots(self.apiclient, projectid=self.project.id) + + self.debug("snapshots list: %s" % snapshots) + + self.assertEqual(validateList(snapshots)[0], PASS, "Snapshots list validation failed") + self.assertEqual(len(snapshots), 1, "Snapshots list should have exactly one entity") # Exception should be raised for second snapshot with self.assertRaises(Exception): From 291eafadaefc66ca030c26e0bbc78256ac8a8dbd Mon Sep 17 00:00:00 2001 From: Gaurav Aradhye Date: Wed, 4 Dec 2013 11:32:36 +0530 Subject: [PATCH 090/170] CLOUDSTACK-5347: Resolved issue related to snapshot state --- test/integration/component/test_project_resources.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/integration/component/test_project_resources.py b/test/integration/component/test_project_resources.py index b7ed60edf11..18382690b90 100644 --- a/test/integration/component/test_project_resources.py +++ b/test/integration/component/test_project_resources.py @@ -905,10 +905,12 @@ class TestSnapshots(cloudstackTestCase): self.assertEqual( snapshot.state in [ 'BackedUp', - 'CreatedOnPrimary' + 'CreatedOnPrimary', + 'Allocated' ], True, - "Check Snapshot state is Running or not" + "Check Snapshot state is in one of the mentioned possible states, \ + It is currently: %s" % snapshot.state ) snapshots = Snapshot.list( From 4b5a0ca4c27f511e48c6cc094ce4bec731c0d8fb Mon Sep 17 00:00:00 2001 From: Ashutosh K Date: Wed, 4 Dec 2013 11:37:22 +0530 Subject: [PATCH 091/170] CLOUDSTACK-5230: Removing test cases' dependency on each other leading to failures --- .../component/test_vpc_vm_life_cycle.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/test/integration/component/test_vpc_vm_life_cycle.py b/test/integration/component/test_vpc_vm_life_cycle.py index aed9f9581f7..5ce94f24945 100644 --- a/test/integration/component/test_vpc_vm_life_cycle.py +++ b/test/integration/component/test_vpc_vm_life_cycle.py @@ -1395,6 +1395,20 @@ class TestVMLifeCycleSharedNwVPC(cloudstackTestCase): """ Test recover an instance in VPC networks """ + self.debug("Deploying vm") + + self.vm_2 = VirtualMachine.create( + self.api_client, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_1.id), + str(self.network_2.id)] + ) + + self.cleanup.append(self.vm_2) + try: self.vm_2.delete(self.apiclient) except Exception as e: @@ -1603,7 +1617,7 @@ class TestVMLifeCycleSharedNwVPC(cloudstackTestCase): self.debug("Delete virtual machines in account: %s" % self.account.name) try: - self.vm_2.delete(self.apiclient) + self.vm_3.delete(self.apiclient) except Exception as e: self.fail("Failed to destroy the virtual instances, %s" % e) @@ -1623,7 +1637,6 @@ class TestVMLifeCycleSharedNwVPC(cloudstackTestCase): self.account.name) try: self.vm_1.delete(self.apiclient) - self.vm_3.delete(self.apiclient) except Exception as e: self.fail("Failed to destroy the virtual instances, %s" % e) From 3f8741a4ece956126f24752b7f1a1e4542cbc5ca Mon Sep 17 00:00:00 2001 From: Donal Lafferty Date: Wed, 4 Dec 2013 12:14:45 +0530 Subject: [PATCH 092/170] Changes for fixing the hyperv agent build on windows using mono. --- .../ServerResource/.nuget/NuGet.targets | 48 +++++++++---------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/.nuget/NuGet.targets b/plugins/hypervisors/hyperv/DotNet/ServerResource/.nuget/NuGet.targets index d0ebc7535f3..c4211a23551 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/.nuget/NuGet.targets +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/.nuget/NuGet.targets @@ -2,7 +2,7 @@ $(MSBuildProjectDirectory)\..\ - + false @@ -11,11 +11,10 @@ true - + false - @@ -25,37 +24,34 @@ --> - + $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) $([System.IO.Path]::Combine($(ProjectDir), "packages.config")) - - + + $(SolutionDir).nuget - packages.config + $(ProjectDir)packages.config - + $(NuGetToolsPath)\NuGet.exe @(PackageSource) - - "$(NuGetExePath)" - mono --runtime=v4.0.30319 $(NuGetExePath) + + "$(NuGetExePath)" + mono --runtime=v4.0.30319 $(NuGetExePath) $(TargetDir.Trim('\\')) - + -RequireConsent -NonInteractive - - "$(SolutionDir) " - "$(SolutionDir)" - $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir) - $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols + $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir "$(SolutionDir) " + $(NuGetCommand) pack "$(ProjectPath)" -Properties Configuration=$(Configuration) $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols @@ -87,22 +83,22 @@ - + Condition="( '$(OS)' != 'Windows_NT' Or '$(BuildWithMono)' == 'true' ) And Exists('$(PackagesConfig)')" /> + + Condition="'$(OS)' == 'Windows_NT' And '$(BuildWithMono)' != 'true' And Exists('$(PackagesConfig)')" /> - - + + + Condition=" '$(OS)' == 'Windows_NT' And '$(BuildWithMono)' != 'true' " /> - + @@ -133,4 +129,4 @@ - \ No newline at end of file + From 9d50b0bb684dbe2dd401f2158960b65fff1516dd Mon Sep 17 00:00:00 2001 From: Rajesh Battala Date: Wed, 4 Dec 2013 15:48:01 +0530 Subject: [PATCH 093/170] Adding cifs support to systemvm 64bit to support Hyperv --- tools/appliance/definitions/systemvm64template/postinstall.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/appliance/definitions/systemvm64template/postinstall.sh b/tools/appliance/definitions/systemvm64template/postinstall.sh index d25ba13c617..c78896569a1 100644 --- a/tools/appliance/definitions/systemvm64template/postinstall.sh +++ b/tools/appliance/definitions/systemvm64template/postinstall.sh @@ -51,6 +51,10 @@ install_packages() { apt-get --no-install-recommends -q -y --force-yes install nfs-common # nfs irqbalance apt-get --no-install-recommends -q -y --force-yes install irqbalance + + # cifs client + apt-get --no-install-recommends -q -y --force-yes install samba-common + apt-get --no-install-recommends -q -y --force-yes install cifs-utils # vpn stuff apt-get --no-install-recommends -q -y --force-yes install xl2tpd bcrelay ppp ipsec-tools tdb-tools From f2c7db99471537942b9d3b1c5966ff35c4a52c6e Mon Sep 17 00:00:00 2001 From: Jayapal Date: Wed, 4 Dec 2013 16:14:48 +0530 Subject: [PATCH 094/170] Corrected parsing vlan tag in JuniperSrx resource --- .../src/com/cloud/network/resource/JuniperSrxResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/network-elements/juniper-srx/src/com/cloud/network/resource/JuniperSrxResource.java b/plugins/network-elements/juniper-srx/src/com/cloud/network/resource/JuniperSrxResource.java index ac3e9ab05be..338e0953249 100644 --- a/plugins/network-elements/juniper-srx/src/com/cloud/network/resource/JuniperSrxResource.java +++ b/plugins/network-elements/juniper-srx/src/com/cloud/network/resource/JuniperSrxResource.java @@ -691,7 +691,7 @@ public class JuniperSrxResource implements ServerResource { Long publicVlanTag = null; if (ip.getBroadcastUri() != null && !ip.getBroadcastUri().equals("untagged")) { try { - publicVlanTag = Long.parseLong(ip.getBroadcastUri()); + publicVlanTag = Long.parseLong(BroadcastDomainType.getValue(ip.getBroadcastUri())); } catch (Exception e) { throw new ExecutionException("Could not parse public VLAN tag: " + ip.getBroadcastUri()); } From b2c89552226bd44b356d5bcd613f14ca3b9c90a7 Mon Sep 17 00:00:00 2001 From: Ashutosh K Date: Wed, 4 Dec 2013 18:41:10 +0530 Subject: [PATCH 095/170] CLOUDSTACK-5364: Resolving network cleanup issue in egress fw rules test cases --- .../integration/component/test_egress_fw_rules.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/test/integration/component/test_egress_fw_rules.py b/test/integration/component/test_egress_fw_rules.py index 6dcc2c4dd87..5f076ab4c5d 100644 --- a/test/integration/component/test_egress_fw_rules.py +++ b/test/integration/component/test_egress_fw_rules.py @@ -376,12 +376,21 @@ class TestEgressFWRules(cloudstackTestCase): self.debug("Cleaning up the resources") self.virtual_machine.delete(self.apiclient) wait_for_cleanup(self.apiclient, ["expunge.interval", "expunge.delay"]) - self.debug("Sleep for VM cleanup to complete.") - #time.sleep(self.services['sleep']) + + retriesCount = 5 + while True: + vms = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) + if vms is None: + break + elif retriesCount == 0: + self.fail("Failed to delete/expunge VM") + + time.sleep(10) + retriesCount -= 1 + self.network.delete(self.apiclient) self.debug("Sleep for Network cleanup to complete.") wait_for_cleanup(self.apiclient, ["network.gc.wait", "network.gc.interval"]) - #time.sleep(self.services['sleep']) cleanup_resources(self.apiclient, reversed(self.cleanup)) self.debug("Cleanup complete!") except Exception as e: From dfff362c116d69aaad52d7e907d19b9e11dac028 Mon Sep 17 00:00:00 2001 From: Girish Shilamkar Date: Wed, 4 Dec 2013 18:54:50 +0530 Subject: [PATCH 096/170] CLOUDSTACK-5351: Fixed a regression where shared_ntwk_vlan was not changed to shared_vlan --- test/integration/component/test_shared_networks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/component/test_shared_networks.py b/test/integration/component/test_shared_networks.py index 9b76702af6e..99cce19488b 100644 --- a/test/integration/component/test_shared_networks.py +++ b/test/integration/component/test_shared_networks.py @@ -1992,8 +1992,8 @@ class TestSharedNetworks(cloudstackTestCase): self.services["network"]["acltype"] = "Domain" self.services["network"]["networkofferingid"] = self.shared_network_offering.id self.services["network"]["physicalnetworkid"] = physical_network.id - self.services["network"]["vlan"] = shared_ntwk_vlan - self.debug("Creating a shared network in non-cloudstack VLAN %s" % shared_ntwk_vlan) + self.services["network"]["vlan"] = shared_vlan + self.debug("Creating a shared network in non-cloudstack VLAN %s" % shared_vlan) self.network = Network.create( self.api_client, self.services["network"], From f37057a215c886369924c81352449bf4f5a27d2c Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Mon, 2 Dec 2013 15:42:25 +0530 Subject: [PATCH 097/170] CLOUDSTACK-5172. Detaching VM volume is not allowed if there are VM snapshots because any changes to the disk layout will break the semantics of VM-based snapshot --- server/src/com/cloud/storage/VolumeApiServiceImpl.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index e60d204c29f..fdd5db5707f 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -1236,6 +1236,12 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic throw new InvalidParameterValueException("Please specify a VM that is either running or stopped."); } + // Don't allow detach if target VM has associated VM snapshots + List vmSnapshots = _vmSnapshotDao.findByVm(vmId); + if (vmSnapshots.size() > 0) { + throw new InvalidParameterValueException("Unable to detach volume, please specify a VM that does not have VM snapshots"); + } + AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (asyncExecutionContext != null) { AsyncJob job = asyncExecutionContext.getJob(); From 13740ac135a3b4769af56690b4d1e82e36a35209 Mon Sep 17 00:00:00 2001 From: Devdeep Singh Date: Thu, 5 Dec 2013 02:59:23 +0530 Subject: [PATCH 098/170] CLOUDSTACK-5178: DeployVm from ISO fails. Fixed the creation of root volume and made sure the iso is attached when a vm is deployed. --- .../HypervResource/CloudStackTypes.cs | 50 +- .../HypervResourceController.cs | 61 +- .../HypervResource/WmiCallsV2.cs | 42 +- .../ROOT.virtualization.v2.Msvm_StorageJob.cs | 1863 +++++++++++++++++ .../WmiWrappers/WmiWrappers.csproj | 3 + 5 files changed, 1996 insertions(+), 23 deletions(-) create mode 100644 plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/ROOT.virtualization.v2.Msvm_StorageJob.cs diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs index 7a373a410ad..ce1b1e8c6eb 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs @@ -176,6 +176,7 @@ namespace HypervResource public string format; public string name; public string uuid; + public ulong size; public PrimaryDataStoreTO primaryDataStore; public static VolumeObjectTO ParseJson(dynamic json) @@ -195,7 +196,8 @@ namespace HypervResource dataStore = volumeObjectTOJson.dataStore, format = ((string)volumeObjectTOJson.format), name = (string)volumeObjectTOJson.name, - uuid = (string)volumeObjectTOJson.uuid + uuid = (string)volumeObjectTOJson.uuid, + size = (ulong)volumeObjectTOJson.size }; result.primaryDataStore = PrimaryDataStoreTO.ParseJson(volumeObjectTOJson.dataStore); @@ -312,20 +314,23 @@ namespace HypervResource public static S3TO ParseJson(dynamic json) { S3TO result = null; - dynamic s3TOJson = json[CloudStackTypes.S3TO]; - if (s3TOJson != null) + if (json != null) { - result = new S3TO() + dynamic s3TOJson = json[CloudStackTypes.S3TO]; + if (s3TOJson != null) { - bucketName = (string)s3TOJson.bucketName, - secretKey = (string)s3TOJson.secretKey, - accessKey = (string)s3TOJson.accessKey, - endpoint = (string)s3TOJson.endPoint, - httpsFlag = (bool)s3TOJson.httpsFlag - }; - // Delete security credentials in original command. Prevents logger from spilling the beans, as it were. - s3TOJson.secretKey = string.Empty; - s3TOJson.accessKey = string.Empty; + result = new S3TO() + { + bucketName = (string)s3TOJson.bucketName, + secretKey = (string)s3TOJson.secretKey, + accessKey = (string)s3TOJson.accessKey, + endpoint = (string)s3TOJson.endPoint, + httpsFlag = (bool)s3TOJson.httpsFlag + }; + // Delete security credentials in original command. Prevents logger from spilling the beans, as it were. + s3TOJson.secretKey = string.Empty; + s3TOJson.accessKey = string.Empty; + } } return result; } @@ -380,16 +385,19 @@ namespace HypervResource public static NFSTO ParseJson(dynamic json) { NFSTO result = null; - dynamic nfsTOJson = json[CloudStackTypes.NFSTO]; - if (nfsTOJson != null) + if (json != null) { - result = new NFSTO() + dynamic nfsTOJson = json[CloudStackTypes.NFSTO]; + if (nfsTOJson != null) { - _role = (string)nfsTOJson._role, - }; - // Delete security credentials in original command. Prevents logger from spilling the beans, as it were. - String uriStr = (String)nfsTOJson._url; - result.uri = new Uri(uriStr); + result = new NFSTO() + { + _role = (string)nfsTOJson._role, + }; + // Delete security credentials in original command. Prevents logger from spilling the beans, as it were. + String uriStr = (String)nfsTOJson._url; + result.uri = new Uri(uriStr); + } } return result; } diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index 915816d0a31..f5008123930 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -1010,6 +1010,66 @@ namespace HypervResource } } + // POST api/HypervResource/CreateObjectCommand + [HttpPost] + [ActionName(CloudStackTypes.CreateObjectCommand)] + public JContainer CreateObjectCommand([FromBody]dynamic cmd) + { + using (log4net.NDC.Push(Guid.NewGuid().ToString())) + { + logger.Info(CloudStackTypes.CreateObjectCommand + cmd.ToString()); + + bool result = false; + string details = null; + + try + { + VolumeObjectTO volume = VolumeObjectTO.ParseJson(cmd.data); + PrimaryDataStoreTO primary = volume.primaryDataStore; + ulong volumeSize = volume.size; + string volumeName = volume.name + ".vhdx"; + string volumePath = null; + + if (primary.isLocal) + { + volumePath = Path.Combine(primary.Path, volumeName); + } + else + { + volumePath = @"\\" + primary.uri.Host + primary.uri.LocalPath + @"\" + volumeName; + volumePath = volumePath.Replace('/', '\\'); + Utils.ConnectToRemote(primary.UncPath, primary.Domain, primary.User, primary.Password); + } + + wmiCallsV2.CreateDynamicVirtualHardDisk(volumeSize, volumePath); + if (File.Exists(volumePath)) + { + result = true; + } + else + { + details = "Failed to create disk with name " + volumePath; + } + } + catch (Exception ex) + { + // Test by providing wrong key + details = CloudStackTypes.CreateObjectCommand + " failed on exception, " + ex.Message; + logger.Error(details, ex); + } + + object ansContent = new + { + result = result, + details = details, + data = cmd.data, + contextMap = contextMap + }; + + return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CreateObjectAnswer); + } + } + // POST api/HypervResource/MaintainCommand // TODO: should this be a NOP? [HttpPost] @@ -1085,7 +1145,6 @@ namespace HypervResource { logger.Info(CloudStackTypes.GetVmStatsCommand + cmd.ToString()); bool result = false; - string details = null; JArray vmNamesJson = cmd.vmNames; string[] vmNames = vmNamesJson.ToObject(); Dictionary vmProcessorInfo = new Dictionary(vmNames.Length); diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs index c69ec38d436..c6c039a9bed 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs @@ -286,7 +286,10 @@ namespace HypervResource { string vhdFile = null; string diskName = null; + string isoPath = null; VolumeObjectTO volInfo = VolumeObjectTO.ParseJson(diskDrive.data); + TemplateObjectTO templateInfo = TemplateObjectTO.ParseJson(diskDrive.data); + if (volInfo != null) { // assert @@ -327,6 +330,13 @@ namespace HypervResource } logger.Debug("Going to create " + vmName + " with attached voluem " + diskName + " at " + vhdFile); } + else if (templateInfo != null && templateInfo.nfsDataStoreTO != null) + { + NFSTO share = templateInfo.nfsDataStoreTO; + Utils.ConnectToRemote(share.UncPath, share.Domain, share.User, share.Password); + // The share is mapped, now attach the iso + isoPath = Path.Combine(share.UncPath.Replace('/', Path.DirectorySeparatorChar), templateInfo.path); + } string driveType = diskDrive.type; @@ -353,6 +363,10 @@ namespace HypervResource logger.DebugFormat("Create disk type {1} (Named: {0}), on vm {2} {3}", diskName, driveResourceType, vmName, string.IsNullOrEmpty(vhdFile) ? " no disk to insert" : ", inserting disk" +vhdFile ); AddDiskDriveToVm(newVm, vhdFile, ideCtrllr, driveResourceType); + if (isoPath != null) + { + AttachIso(vmName, isoPath); + } } String publicIpAddress = ""; @@ -1484,7 +1498,7 @@ namespace HypervResource // If the Job is done asynchronously if (ret_val == ReturnCode.Started) { - JobCompleted(jobPath); + StorageJobCompleted(jobPath); } else if (ret_val != ReturnCode.Completed) { @@ -1608,6 +1622,32 @@ namespace HypervResource } } + private static void StorageJobCompleted(ManagementPath jobPath) + { + StorageJob jobObj = null; + for (; ; ) + { + jobObj = new StorageJob(jobPath); + if (jobObj.JobState != JobState.Starting && jobObj.JobState != JobState.Running) + { + break; + } + logger.InfoFormat("In progress... {0}% completed.", jobObj.PercentComplete); + System.Threading.Thread.Sleep(1000); + } + + if (jobObj.JobState != JobState.Completed) + { + var errMsg = string.Format( + "Hyper-V Job failed, Error Code:{0}, Description: {1}", + jobObj.ErrorCode, + jobObj.ErrorDescription); + var ex = new WmiException(errMsg); + logger.Error(errMsg, ex); + throw ex; + } + } + public void GetProcessorResources(out uint cores, out uint mhz) { // Processor processors diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/ROOT.virtualization.v2.Msvm_StorageJob.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/ROOT.virtualization.v2.Msvm_StorageJob.cs new file mode 100644 index 00000000000..5a101f1bfeb --- /dev/null +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/ROOT.virtualization.v2.Msvm_StorageJob.cs @@ -0,0 +1,1863 @@ +// 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. + +namespace CloudStack.Plugin.WmiWrappers.ROOT.VIRTUALIZATION.V2 { + using System; + using System.ComponentModel; + using System.Management; + using System.Collections; + using System.Globalization; + using System.ComponentModel.Design.Serialization; + using System.Reflection; + + + // Functions ShouldSerialize are functions used by VS property browser to check if a particular property has to be serialized. These functions are added for all ValueType properties ( properties of type Int32, BOOL etc.. which cannot be set to null). These functions use IsNull function. These functions are also used in the TypeConverter implementation for the properties to check for NULL value of property so that an empty value can be shown in Property browser in case of Drag and Drop in Visual studio. + // Functions IsNull() are used to check if a property is NULL. + // Functions Reset are added for Nullable Read/Write properties. These functions are used by VS designer in property browser to set a property to NULL. + // Every property added to the class for WMI property has attributes set to define its behavior in Visual Studio designer and also to define a TypeConverter to be used. + // Datetime conversion functions ToDateTime and ToDmtfDateTime are added to the class to convert DMTF datetime to System.DateTime and vice-versa. + // An Early Bound class generated for the WMI class.Msvm_StorageJob + public class StorageJob : System.ComponentModel.Component { + + // Private property to hold the WMI namespace in which the class resides. + private static string CreatedWmiNamespace = "ROOT\\virtualization\\v2"; + + // Private property to hold the name of WMI class which created this class. + public static string CreatedClassName = "Msvm_StorageJob"; + + // Private member variable to hold the ManagementScope which is used by the various methods. + private static System.Management.ManagementScope statMgmtScope = null; + + private ManagementSystemProperties PrivateSystemProperties; + + // Underlying lateBound WMI object. + private System.Management.ManagementObject PrivateLateBoundObject; + + // Member variable to store the 'automatic commit' behavior for the class. + private bool AutoCommitProp; + + // Private variable to hold the embedded property representing the instance. + private System.Management.ManagementBaseObject embeddedObj; + + // The current WMI object used + private System.Management.ManagementBaseObject curObj; + + // Flag to indicate if the instance is an embedded object. + private bool isEmbedded; + + // Below are different overloads of constructors to initialize an instance of the class with a WMI object. + public StorageJob() { + this.InitializeObject(null, null, null); + } + + public StorageJob(string keyInstanceID) { + this.InitializeObject(null, new System.Management.ManagementPath(StorageJob.ConstructPath(keyInstanceID)), null); + } + + public StorageJob(System.Management.ManagementScope mgmtScope, string keyInstanceID) { + this.InitializeObject(((System.Management.ManagementScope)(mgmtScope)), new System.Management.ManagementPath(StorageJob.ConstructPath(keyInstanceID)), null); + } + + public StorageJob(System.Management.ManagementPath path, System.Management.ObjectGetOptions getOptions) { + this.InitializeObject(null, path, getOptions); + } + + public StorageJob(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path) { + this.InitializeObject(mgmtScope, path, null); + } + + public StorageJob(System.Management.ManagementPath path) { + this.InitializeObject(null, path, null); + } + + public StorageJob(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path, System.Management.ObjectGetOptions getOptions) { + this.InitializeObject(mgmtScope, path, getOptions); + } + + public StorageJob(System.Management.ManagementObject theObject) { + Initialize(); + if ((CheckIfProperClass(theObject) == true)) { + PrivateLateBoundObject = theObject; + PrivateSystemProperties = new ManagementSystemProperties(PrivateLateBoundObject); + curObj = PrivateLateBoundObject; + } + else { + throw new System.ArgumentException("Class name does not match."); + } + } + + public StorageJob(System.Management.ManagementBaseObject theObject) { + Initialize(); + if ((CheckIfProperClass(theObject) == true)) { + embeddedObj = theObject; + PrivateSystemProperties = new ManagementSystemProperties(theObject); + curObj = embeddedObj; + isEmbedded = true; + } + else { + throw new System.ArgumentException("Class name does not match."); + } + } + + // Property returns the namespace of the WMI class. + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string OriginatingNamespace { + get { + return "ROOT\\virtualization\\v2"; + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string ManagementClassName { + get { + string strRet = CreatedClassName; + if ((curObj != null)) { + if ((curObj.ClassPath != null)) { + strRet = ((string)(curObj["__CLASS"])); + if (((strRet == null) + || (strRet == string.Empty))) { + strRet = CreatedClassName; + } + } + } + return strRet; + } + } + + // Property pointing to an embedded object to get System properties of the WMI object. + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ManagementSystemProperties SystemProperties { + get { + return PrivateSystemProperties; + } + } + + // Property returning the underlying lateBound object. + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public System.Management.ManagementBaseObject LateBoundObject { + get { + return curObj; + } + } + + // ManagementScope of the object. + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public System.Management.ManagementScope Scope { + get { + if ((isEmbedded == false)) { + return PrivateLateBoundObject.Scope; + } + else { + return null; + } + } + set { + if ((isEmbedded == false)) { + PrivateLateBoundObject.Scope = value; + } + } + } + + // Property to show the commit behavior for the WMI object. If true, WMI object will be automatically saved after each property modification.(ie. Put() is called after modification of a property). + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool AutoCommit { + get { + return AutoCommitProp; + } + set { + AutoCommitProp = value; + } + } + + // The ManagementPath of the underlying WMI object. + [Browsable(true)] + public System.Management.ManagementPath Path { + get { + if ((isEmbedded == false)) { + return PrivateLateBoundObject.Path; + } + else { + return null; + } + } + set { + if ((isEmbedded == false)) { + if ((CheckIfProperClass(null, value, null) != true)) { + throw new System.ArgumentException("Class name does not match."); + } + PrivateLateBoundObject.Path = value; + } + } + } + + // Public static scope property which is used by the various methods. + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public static System.Management.ManagementScope StaticScope { + get { + return statMgmtScope; + } + set { + statMgmtScope = value; + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsCancellableNull { + get { + if ((curObj["Cancellable"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates whether the job can be cancelled. The value of this property does not g" + + "uarantee that a request to cancel the job will succeed.")] + [TypeConverter(typeof(WMIValueTypeConverter))] + public bool Cancellable { + get { + if ((curObj["Cancellable"] == null)) { + return System.Convert.ToBoolean(0); + } + return ((bool)(curObj["Cancellable"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Caption { + get { + return ((string)(curObj["Caption"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("On failure of the asynchronous operation, this property contains the file path to" + + " the child of the virtual hard drive being affected by this operation.")] + public string Child { + get { + return ((string)(curObj["Child"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsCommunicationStatusNull { + get { + if ((curObj["CommunicationStatus"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort CommunicationStatus { + get { + if ((curObj["CommunicationStatus"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["CommunicationStatus"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsDeleteOnCompletionNull { + get { + if ((curObj["DeleteOnCompletion"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public bool DeleteOnCompletion { + get { + if ((curObj["DeleteOnCompletion"] == null)) { + return System.Convert.ToBoolean(0); + } + return ((bool)(curObj["DeleteOnCompletion"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Description { + get { + return ((string)(curObj["Description"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsDetailedStatusNull { + get { + if ((curObj["DetailedStatus"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort DetailedStatus { + get { + if ((curObj["DetailedStatus"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["DetailedStatus"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsElapsedTimeNull { + get { + if ((curObj["ElapsedTime"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime ElapsedTime { + get { + if ((curObj["ElapsedTime"] != null)) { + return ToDateTime(((string)(curObj["ElapsedTime"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string ElementName { + get { + return ((string)(curObj["ElementName"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsErrorCodeNull { + get { + if ((curObj["ErrorCode"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort ErrorCode { + get { + if ((curObj["ErrorCode"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["ErrorCode"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string ErrorDescription { + get { + return ((string)(curObj["ErrorDescription"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string ErrorSummaryDescription { + get { + return ((string)(curObj["ErrorSummaryDescription"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsHealthStateNull { + get { + if ((curObj["HealthState"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort HealthState { + get { + if ((curObj["HealthState"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["HealthState"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsInstallDateNull { + get { + if ((curObj["InstallDate"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime InstallDate { + get { + if ((curObj["InstallDate"] != null)) { + return ToDateTime(((string)(curObj["InstallDate"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string InstanceID { + get { + return ((string)(curObj["InstanceID"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsJobCompletionStatusCodeNull { + get { + if ((curObj["JobCompletionStatusCode"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("The HRESULT code that describes the completion status for the asynchronous operat" + + "ion.")] + [TypeConverter(typeof(WMIValueTypeConverter))] + public uint JobCompletionStatusCode { + get { + if ((curObj["JobCompletionStatusCode"] == null)) { + return System.Convert.ToUInt32(0); + } + return ((uint)(curObj["JobCompletionStatusCode"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsJobRunTimesNull { + get { + if ((curObj["JobRunTimes"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public uint JobRunTimes { + get { + if ((curObj["JobRunTimes"] == null)) { + return System.Convert.ToUInt32(0); + } + return ((uint)(curObj["JobRunTimes"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsJobStateNull { + get { + if ((curObj["JobState"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort JobState { + get { + if ((curObj["JobState"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["JobState"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string JobStatus { + get { + return ((string)(curObj["JobStatus"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsJobTypeNull { + get { + if ((curObj["JobType"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description(@"The type of asynchronous operation being tracked by this instance of Msvm_StorageJob. +Values are: +Unknown +VHD Creation: Creating a virtual hard disk image (VHD). +Floppy Creation: Creating a virtual floppy disk image (VFD). +Compaction: Compacting the size of a virtual hard disk image. +Expansion: Expanding the size of a virtual hard disk image. +Merging: Merging multiple virtual hard disk images into a single image. +Conversion: Converting the type of a virtual hard disk image. +Loopback Mount: Mounting the virtual hard disk on the parent partition. +Get VHD Info: Retrieving information about a virtual hard disk image (VHD). +Validate VHD Image: Validating a virtual hard disk image (VHD).")] + [TypeConverter(typeof(WMIValueTypeConverter))] + public JobTypeValues JobType { + get { + if ((curObj["JobType"] == null)) { + return ((JobTypeValues)(System.Convert.ToInt32(10))); + } + return ((JobTypeValues)(System.Convert.ToInt32(curObj["JobType"]))); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsLocalOrUtcTimeNull { + get { + if ((curObj["LocalOrUtcTime"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort LocalOrUtcTime { + get { + if ((curObj["LocalOrUtcTime"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["LocalOrUtcTime"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Name { + get { + return ((string)(curObj["Name"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Notify { + get { + return ((string)(curObj["Notify"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsOperatingStatusNull { + get { + if ((curObj["OperatingStatus"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort OperatingStatus { + get { + if ((curObj["OperatingStatus"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["OperatingStatus"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ushort[] OperationalStatus { + get { + return ((ushort[])(curObj["OperationalStatus"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string OtherRecoveryAction { + get { + return ((string)(curObj["OtherRecoveryAction"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Owner { + get { + return ((string)(curObj["Owner"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("On failure of the asynchronous operation, this property contains the file path to" + + " the parent of the virtual hard drive being affected by this operation.")] + public string Parent { + get { + return ((string)(curObj["Parent"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsPercentCompleteNull { + get { + if ((curObj["PercentComplete"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort PercentComplete { + get { + if ((curObj["PercentComplete"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["PercentComplete"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsPrimaryStatusNull { + get { + if ((curObj["PrimaryStatus"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort PrimaryStatus { + get { + if ((curObj["PrimaryStatus"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["PrimaryStatus"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsPriorityNull { + get { + if ((curObj["Priority"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public uint Priority { + get { + if ((curObj["Priority"] == null)) { + return System.Convert.ToUInt32(0); + } + return ((uint)(curObj["Priority"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsRecoveryActionNull { + get { + if ((curObj["RecoveryAction"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public ushort RecoveryAction { + get { + if ((curObj["RecoveryAction"] == null)) { + return System.Convert.ToUInt16(0); + } + return ((ushort)(curObj["RecoveryAction"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsRunDayNull { + get { + if ((curObj["RunDay"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public sbyte RunDay { + get { + if ((curObj["RunDay"] == null)) { + return System.Convert.ToSByte(0); + } + return ((sbyte)(curObj["RunDay"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsRunDayOfWeekNull { + get { + if ((curObj["RunDayOfWeek"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public sbyte RunDayOfWeek { + get { + if ((curObj["RunDayOfWeek"] == null)) { + return System.Convert.ToSByte(0); + } + return ((sbyte)(curObj["RunDayOfWeek"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsRunMonthNull { + get { + if ((curObj["RunMonth"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public byte RunMonth { + get { + if ((curObj["RunMonth"] == null)) { + return System.Convert.ToByte(0); + } + return ((byte)(curObj["RunMonth"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsRunStartIntervalNull { + get { + if ((curObj["RunStartInterval"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime RunStartInterval { + get { + if ((curObj["RunStartInterval"] != null)) { + return ToDateTime(((string)(curObj["RunStartInterval"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsScheduledStartTimeNull { + get { + if ((curObj["ScheduledStartTime"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime ScheduledStartTime { + get { + if ((curObj["ScheduledStartTime"] != null)) { + return ToDateTime(((string)(curObj["ScheduledStartTime"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsStartTimeNull { + get { + if ((curObj["StartTime"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime StartTime { + get { + if ((curObj["StartTime"] != null)) { + return ToDateTime(((string)(curObj["StartTime"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Status { + get { + return ((string)(curObj["Status"])); + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string[] StatusDescriptions { + get { + return ((string[])(curObj["StatusDescriptions"])); + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsTimeBeforeRemovalNull { + get { + if ((curObj["TimeBeforeRemoval"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime TimeBeforeRemoval { + get { + if ((curObj["TimeBeforeRemoval"] != null)) { + return ToDateTime(((string)(curObj["TimeBeforeRemoval"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsTimeOfLastStateChangeNull { + get { + if ((curObj["TimeOfLastStateChange"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime TimeOfLastStateChange { + get { + if ((curObj["TimeOfLastStateChange"] != null)) { + return ToDateTime(((string)(curObj["TimeOfLastStateChange"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsTimeSubmittedNull { + get { + if ((curObj["TimeSubmitted"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime TimeSubmitted { + get { + if ((curObj["TimeSubmitted"] != null)) { + return ToDateTime(((string)(curObj["TimeSubmitted"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsUntilTimeNull { + get { + if ((curObj["UntilTime"] == null)) { + return true; + } + else { + return false; + } + } + } + + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [TypeConverter(typeof(WMIValueTypeConverter))] + public System.DateTime UntilTime { + get { + if ((curObj["UntilTime"] != null)) { + return ToDateTime(((string)(curObj["UntilTime"]))); + } + else { + return System.DateTime.MinValue; + } + } + } + + private bool CheckIfProperClass(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path, System.Management.ObjectGetOptions OptionsParam) { + if (((path != null) + && (string.Compare(path.ClassName, this.ManagementClassName, true, System.Globalization.CultureInfo.InvariantCulture) == 0))) { + return true; + } + else { + return CheckIfProperClass(new System.Management.ManagementObject(mgmtScope, path, OptionsParam)); + } + } + + private bool CheckIfProperClass(System.Management.ManagementBaseObject theObj) { + if (((theObj != null) + && (string.Compare(((string)(theObj["__CLASS"])), this.ManagementClassName, true, System.Globalization.CultureInfo.InvariantCulture) == 0))) { + return true; + } + else { + System.Array parentClasses = ((System.Array)(theObj["__DERIVATION"])); + if ((parentClasses != null)) { + int count = 0; + for (count = 0; (count < parentClasses.Length); count = (count + 1)) { + if ((string.Compare(((string)(parentClasses.GetValue(count))), this.ManagementClassName, true, System.Globalization.CultureInfo.InvariantCulture) == 0)) { + return true; + } + } + } + } + return false; + } + + private bool ShouldSerializeCancellable() { + if ((this.IsCancellableNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeCommunicationStatus() { + if ((this.IsCommunicationStatusNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeDeleteOnCompletion() { + if ((this.IsDeleteOnCompletionNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeDetailedStatus() { + if ((this.IsDetailedStatusNull == false)) { + return true; + } + return false; + } + + // Converts a given datetime in DMTF format to System.DateTime object. + static System.DateTime ToDateTime(string dmtfDate) { + System.DateTime initializer = System.DateTime.MinValue; + int year = initializer.Year; + int month = initializer.Month; + int day = initializer.Day; + int hour = initializer.Hour; + int minute = initializer.Minute; + int second = initializer.Second; + long ticks = 0; + string dmtf = dmtfDate; + System.DateTime datetime = System.DateTime.MinValue; + string tempString = string.Empty; + if ((dmtf == null)) { + throw new System.ArgumentOutOfRangeException(); + } + if ((dmtf.Length == 0)) { + throw new System.ArgumentOutOfRangeException(); + } + if ((dmtf.Length != 25)) { + throw new System.ArgumentOutOfRangeException(); + } + try { + tempString = dmtf.Substring(0, 4); + if (("****" != tempString)) { + year = int.Parse(tempString); + } + tempString = dmtf.Substring(4, 2); + if (("**" != tempString)) { + month = int.Parse(tempString); + } + tempString = dmtf.Substring(6, 2); + if (("**" != tempString)) { + day = int.Parse(tempString); + } + tempString = dmtf.Substring(8, 2); + if (("**" != tempString)) { + hour = int.Parse(tempString); + } + tempString = dmtf.Substring(10, 2); + if (("**" != tempString)) { + minute = int.Parse(tempString); + } + tempString = dmtf.Substring(12, 2); + if (("**" != tempString)) { + second = int.Parse(tempString); + } + tempString = dmtf.Substring(15, 6); + if (("******" != tempString)) { + ticks = (long.Parse(tempString) * ((long)((System.TimeSpan.TicksPerMillisecond / 1000)))); + } + if (((((((((year < 0) + || (month < 0)) + || (day < 0)) + || (hour < 0)) + || (minute < 0)) + || (minute < 0)) + || (second < 0)) + || (ticks < 0))) { + throw new System.ArgumentOutOfRangeException(); + } + } + catch (System.Exception e) { + throw new System.ArgumentOutOfRangeException(null, e.Message); + } + datetime = new System.DateTime(year, month, day, hour, minute, second, 0); + datetime = datetime.AddTicks(ticks); + System.TimeSpan tickOffset = System.TimeZone.CurrentTimeZone.GetUtcOffset(datetime); + int UTCOffset = 0; + int OffsetToBeAdjusted = 0; + long OffsetMins = ((long)((tickOffset.Ticks / System.TimeSpan.TicksPerMinute))); + tempString = dmtf.Substring(22, 3); + if ((tempString != "******")) { + tempString = dmtf.Substring(21, 4); + try { + UTCOffset = int.Parse(tempString); + } + catch (System.Exception e) { + throw new System.ArgumentOutOfRangeException(null, e.Message); + } + OffsetToBeAdjusted = ((int)((OffsetMins - UTCOffset))); + datetime = datetime.AddMinutes(((double)(OffsetToBeAdjusted))); + } + return datetime; + } + + // Converts a given System.DateTime object to DMTF datetime format. + static string ToDmtfDateTime(System.DateTime date) { + string utcString = string.Empty; + System.TimeSpan tickOffset = System.TimeZone.CurrentTimeZone.GetUtcOffset(date); + long OffsetMins = ((long)((tickOffset.Ticks / System.TimeSpan.TicksPerMinute))); + if ((System.Math.Abs(OffsetMins) > 999)) { + date = date.ToUniversalTime(); + utcString = "+000"; + } + else { + if ((tickOffset.Ticks >= 0)) { + utcString = string.Concat("+", ((long)((tickOffset.Ticks / System.TimeSpan.TicksPerMinute))).ToString().PadLeft(3, '0')); + } + else { + string strTemp = ((long)(OffsetMins)).ToString(); + utcString = string.Concat("-", strTemp.Substring(1, (strTemp.Length - 1)).PadLeft(3, '0')); + } + } + string dmtfDateTime = ((int)(date.Year)).ToString().PadLeft(4, '0'); + dmtfDateTime = string.Concat(dmtfDateTime, ((int)(date.Month)).ToString().PadLeft(2, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, ((int)(date.Day)).ToString().PadLeft(2, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, ((int)(date.Hour)).ToString().PadLeft(2, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, ((int)(date.Minute)).ToString().PadLeft(2, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, ((int)(date.Second)).ToString().PadLeft(2, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, "."); + System.DateTime dtTemp = new System.DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, 0); + long microsec = ((long)((((date.Ticks - dtTemp.Ticks) + * 1000) + / System.TimeSpan.TicksPerMillisecond))); + string strMicrosec = ((long)(microsec)).ToString(); + if ((strMicrosec.Length > 6)) { + strMicrosec = strMicrosec.Substring(0, 6); + } + dmtfDateTime = string.Concat(dmtfDateTime, strMicrosec.PadLeft(6, '0')); + dmtfDateTime = string.Concat(dmtfDateTime, utcString); + return dmtfDateTime; + } + + private bool ShouldSerializeElapsedTime() { + if ((this.IsElapsedTimeNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeErrorCode() { + if ((this.IsErrorCodeNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeHealthState() { + if ((this.IsHealthStateNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeInstallDate() { + if ((this.IsInstallDateNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeJobCompletionStatusCode() { + if ((this.IsJobCompletionStatusCodeNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeJobRunTimes() { + if ((this.IsJobRunTimesNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeJobState() { + if ((this.IsJobStateNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeJobType() { + if ((this.IsJobTypeNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeLocalOrUtcTime() { + if ((this.IsLocalOrUtcTimeNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeOperatingStatus() { + if ((this.IsOperatingStatusNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializePercentComplete() { + if ((this.IsPercentCompleteNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializePrimaryStatus() { + if ((this.IsPrimaryStatusNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializePriority() { + if ((this.IsPriorityNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeRecoveryAction() { + if ((this.IsRecoveryActionNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeRunDay() { + if ((this.IsRunDayNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeRunDayOfWeek() { + if ((this.IsRunDayOfWeekNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeRunMonth() { + if ((this.IsRunMonthNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeRunStartInterval() { + if ((this.IsRunStartIntervalNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeScheduledStartTime() { + if ((this.IsScheduledStartTimeNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeStartTime() { + if ((this.IsStartTimeNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeTimeBeforeRemoval() { + if ((this.IsTimeBeforeRemovalNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeTimeOfLastStateChange() { + if ((this.IsTimeOfLastStateChangeNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeTimeSubmitted() { + if ((this.IsTimeSubmittedNull == false)) { + return true; + } + return false; + } + + private bool ShouldSerializeUntilTime() { + if ((this.IsUntilTimeNull == false)) { + return true; + } + return false; + } + + [Browsable(true)] + public void CommitObject() { + if ((isEmbedded == false)) { + PrivateLateBoundObject.Put(); + } + } + + [Browsable(true)] + public void CommitObject(System.Management.PutOptions putOptions) { + if ((isEmbedded == false)) { + PrivateLateBoundObject.Put(putOptions); + } + } + + private void Initialize() { + AutoCommitProp = true; + isEmbedded = false; + } + + private static string ConstructPath(string keyInstanceID) { + string strPath = "ROOT\\virtualization\\v2:Msvm_StorageJob"; + strPath = string.Concat(strPath, string.Concat(".InstanceID=", string.Concat("\"", string.Concat(keyInstanceID, "\"")))); + return strPath; + } + + private void InitializeObject(System.Management.ManagementScope mgmtScope, System.Management.ManagementPath path, System.Management.ObjectGetOptions getOptions) { + Initialize(); + if ((path != null)) { + if ((CheckIfProperClass(mgmtScope, path, getOptions) != true)) { + throw new System.ArgumentException("Class name does not match."); + } + } + PrivateLateBoundObject = new System.Management.ManagementObject(mgmtScope, path, getOptions); + PrivateSystemProperties = new ManagementSystemProperties(PrivateLateBoundObject); + curObj = PrivateLateBoundObject; + } + + // Different overloads of GetInstances() help in enumerating instances of the WMI class. + public static StorageJobCollection GetInstances() { + return GetInstances(null, null, null); + } + + public static StorageJobCollection GetInstances(string condition) { + return GetInstances(null, condition, null); + } + + public static StorageJobCollection GetInstances(string[] selectedProperties) { + return GetInstances(null, null, selectedProperties); + } + + public static StorageJobCollection GetInstances(string condition, string[] selectedProperties) { + return GetInstances(null, condition, selectedProperties); + } + + public static StorageJobCollection GetInstances(System.Management.ManagementScope mgmtScope, System.Management.EnumerationOptions enumOptions) { + if ((mgmtScope == null)) { + if ((statMgmtScope == null)) { + mgmtScope = new System.Management.ManagementScope(); + mgmtScope.Path.NamespacePath = "root\\virtualization\\v2"; + } + else { + mgmtScope = statMgmtScope; + } + } + System.Management.ManagementPath pathObj = new System.Management.ManagementPath(); + pathObj.ClassName = "Msvm_StorageJob"; + pathObj.NamespacePath = "root\\virtualization\\v2"; + System.Management.ManagementClass clsObject = new System.Management.ManagementClass(mgmtScope, pathObj, null); + if ((enumOptions == null)) { + enumOptions = new System.Management.EnumerationOptions(); + enumOptions.EnsureLocatable = true; + } + return new StorageJobCollection(clsObject.GetInstances(enumOptions)); + } + + public static StorageJobCollection GetInstances(System.Management.ManagementScope mgmtScope, string condition) { + return GetInstances(mgmtScope, condition, null); + } + + public static StorageJobCollection GetInstances(System.Management.ManagementScope mgmtScope, string[] selectedProperties) { + return GetInstances(mgmtScope, null, selectedProperties); + } + + public static StorageJobCollection GetInstances(System.Management.ManagementScope mgmtScope, string condition, string[] selectedProperties) { + if ((mgmtScope == null)) { + if ((statMgmtScope == null)) { + mgmtScope = new System.Management.ManagementScope(); + mgmtScope.Path.NamespacePath = "root\\virtualization\\v2"; + } + else { + mgmtScope = statMgmtScope; + } + } + System.Management.ManagementObjectSearcher ObjectSearcher = new System.Management.ManagementObjectSearcher(mgmtScope, new SelectQuery("Msvm_StorageJob", condition, selectedProperties)); + System.Management.EnumerationOptions enumOptions = new System.Management.EnumerationOptions(); + enumOptions.EnsureLocatable = true; + ObjectSearcher.Options = enumOptions; + return new StorageJobCollection(ObjectSearcher.Get()); + } + + [Browsable(true)] + public static StorageJob CreateInstance() { + System.Management.ManagementScope mgmtScope = null; + if ((statMgmtScope == null)) { + mgmtScope = new System.Management.ManagementScope(); + mgmtScope.Path.NamespacePath = CreatedWmiNamespace; + } + else { + mgmtScope = statMgmtScope; + } + System.Management.ManagementPath mgmtPath = new System.Management.ManagementPath(CreatedClassName); + System.Management.ManagementClass tmpMgmtClass = new System.Management.ManagementClass(mgmtScope, mgmtPath, null); + return new StorageJob(tmpMgmtClass.CreateInstance()); + } + + [Browsable(true)] + public void Delete() { + PrivateLateBoundObject.Delete(); + } + + public uint GetError(out string Error) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("GetError", inParams, null); + Error = System.Convert.ToString(outParams.Properties["Error"].Value); + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + Error = null; + return System.Convert.ToUInt32(0); + } + } + + public uint GetErrorEx(out string[] Errors) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("GetErrorEx", inParams, null); + Errors = ((string[])(outParams.Properties["Errors"].Value)); + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + Errors = null; + return System.Convert.ToUInt32(0); + } + } + + public uint KillJob(bool DeleteOnKill) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + inParams = PrivateLateBoundObject.GetMethodParameters("KillJob"); + inParams["DeleteOnKill"] = ((bool)(DeleteOnKill)); + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("KillJob", inParams, null); + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + return System.Convert.ToUInt32(0); + } + } + + public uint RequestStateChange(ushort RequestedState, System.DateTime TimeoutPeriod) { + if ((isEmbedded == false)) { + System.Management.ManagementBaseObject inParams = null; + inParams = PrivateLateBoundObject.GetMethodParameters("RequestStateChange"); + inParams["RequestedState"] = ((ushort)(RequestedState)); + inParams["TimeoutPeriod"] = ToDmtfDateTime(((System.DateTime)(TimeoutPeriod))); + System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("RequestStateChange", inParams, null); + return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value); + } + else { + return System.Convert.ToUInt32(0); + } + } + + public enum JobTypeValues { + + Unknown0 = 0, + + VHD_Creation = 1, + + Floppy_Creation = 2, + + Compaction = 3, + + Expansion = 4, + + Merging = 5, + + Conversion = 6, + + Loopback_Mount = 7, + + Get_VHD_Info = 8, + + Validate_VHD_Image = 9, + + NULL_ENUM_VALUE = 10, + } + + // Enumerator implementation for enumerating instances of the class. + public class StorageJobCollection : object, ICollection { + + private ManagementObjectCollection privColObj; + + public StorageJobCollection(ManagementObjectCollection objCollection) { + privColObj = objCollection; + } + + public virtual int Count { + get { + return privColObj.Count; + } + } + + public virtual bool IsSynchronized { + get { + return privColObj.IsSynchronized; + } + } + + public virtual object SyncRoot { + get { + return this; + } + } + + public virtual void CopyTo(System.Array array, int index) { + privColObj.CopyTo(array, index); + int nCtr; + for (nCtr = 0; (nCtr < array.Length); nCtr = (nCtr + 1)) { + array.SetValue(new StorageJob(((System.Management.ManagementObject)(array.GetValue(nCtr)))), nCtr); + } + } + + public virtual System.Collections.IEnumerator GetEnumerator() { + return new StorageJobEnumerator(privColObj.GetEnumerator()); + } + + public class StorageJobEnumerator : object, System.Collections.IEnumerator { + + private ManagementObjectCollection.ManagementObjectEnumerator privObjEnum; + + public StorageJobEnumerator(ManagementObjectCollection.ManagementObjectEnumerator objEnum) { + privObjEnum = objEnum; + } + + public virtual object Current { + get { + return new StorageJob(((System.Management.ManagementObject)(privObjEnum.Current))); + } + } + + public virtual bool MoveNext() { + return privObjEnum.MoveNext(); + } + + public virtual void Reset() { + privObjEnum.Reset(); + } + } + } + + // TypeConverter to handle null values for ValueType properties + public class WMIValueTypeConverter : TypeConverter { + + private TypeConverter baseConverter; + + private System.Type baseType; + + public WMIValueTypeConverter(System.Type inBaseType) { + baseConverter = TypeDescriptor.GetConverter(inBaseType); + baseType = inBaseType; + } + + public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type srcType) { + return baseConverter.CanConvertFrom(context, srcType); + } + + public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Type destinationType) { + return baseConverter.CanConvertTo(context, destinationType); + } + + public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { + return baseConverter.ConvertFrom(context, culture, value); + } + + public override object CreateInstance(System.ComponentModel.ITypeDescriptorContext context, System.Collections.IDictionary dictionary) { + return baseConverter.CreateInstance(context, dictionary); + } + + public override bool GetCreateInstanceSupported(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetCreateInstanceSupported(context); + } + + public override PropertyDescriptorCollection GetProperties(System.ComponentModel.ITypeDescriptorContext context, object value, System.Attribute[] attributeVar) { + return baseConverter.GetProperties(context, value, attributeVar); + } + + public override bool GetPropertiesSupported(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetPropertiesSupported(context); + } + + public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetStandardValues(context); + } + + public override bool GetStandardValuesExclusive(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetStandardValuesExclusive(context); + } + + public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context) { + return baseConverter.GetStandardValuesSupported(context); + } + + public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) { + if ((baseType.BaseType == typeof(System.Enum))) { + if ((value.GetType() == destinationType)) { + return value; + } + if ((((value == null) + && (context != null)) + && (context.PropertyDescriptor.ShouldSerializeValue(context.Instance) == false))) { + return "NULL_ENUM_VALUE" ; + } + return baseConverter.ConvertTo(context, culture, value, destinationType); + } + if (((baseType == typeof(bool)) + && (baseType.BaseType == typeof(System.ValueType)))) { + if ((((value == null) + && (context != null)) + && (context.PropertyDescriptor.ShouldSerializeValue(context.Instance) == false))) { + return ""; + } + return baseConverter.ConvertTo(context, culture, value, destinationType); + } + if (((context != null) + && (context.PropertyDescriptor.ShouldSerializeValue(context.Instance) == false))) { + return ""; + } + return baseConverter.ConvertTo(context, culture, value, destinationType); + } + } + + // Embedded class to represent WMI system Properties. + [TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))] + public class ManagementSystemProperties { + + private System.Management.ManagementBaseObject PrivateLateBoundObject; + + public ManagementSystemProperties(System.Management.ManagementBaseObject ManagedObject) { + PrivateLateBoundObject = ManagedObject; + } + + [Browsable(true)] + public int GENUS { + get { + return ((int)(PrivateLateBoundObject["__GENUS"])); + } + } + + [Browsable(true)] + public string CLASS { + get { + return ((string)(PrivateLateBoundObject["__CLASS"])); + } + } + + [Browsable(true)] + public string SUPERCLASS { + get { + return ((string)(PrivateLateBoundObject["__SUPERCLASS"])); + } + } + + [Browsable(true)] + public string DYNASTY { + get { + return ((string)(PrivateLateBoundObject["__DYNASTY"])); + } + } + + [Browsable(true)] + public string RELPATH { + get { + return ((string)(PrivateLateBoundObject["__RELPATH"])); + } + } + + [Browsable(true)] + public int PROPERTY_COUNT { + get { + return ((int)(PrivateLateBoundObject["__PROPERTY_COUNT"])); + } + } + + [Browsable(true)] + public string[] DERIVATION { + get { + return ((string[])(PrivateLateBoundObject["__DERIVATION"])); + } + } + + [Browsable(true)] + public string SERVER { + get { + return ((string)(PrivateLateBoundObject["__SERVER"])); + } + } + + [Browsable(true)] + public string NAMESPACE { + get { + return ((string)(PrivateLateBoundObject["__NAMESPACE"])); + } + } + + [Browsable(true)] + public string PATH { + get { + return ((string)(PrivateLateBoundObject["__PATH"])); + } + } + } + } +} diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/WmiWrappers.csproj b/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/WmiWrappers.csproj index 1a703400bcb..b4bf04b7057 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/WmiWrappers.csproj +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/WmiWrappers.csproj @@ -135,6 +135,9 @@ Component + + Component + Component From 4ecf6df5f64cc048cac110dbb73f11c66dc16750 Mon Sep 17 00:00:00 2001 From: Chris Suich Date: Wed, 4 Dec 2013 10:06:05 -0500 Subject: [PATCH 099/170] Fixed issue with ListView 'needsRefresh' overlays not being removed JIRA-5368 --- ui/scripts/ui/widgets/listView.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js index 53b37f187eb..06b8521795c 100644 --- a/ui/scripts/ui/widgets/listView.js +++ b/ui/scripts/ui/widgets/listView.js @@ -370,6 +370,12 @@ } } + if (needsRefresh) { + if (!$listView.closest('.detail-view').size()) { + $loading.remove(); + } + } + if (options.error) options.error(message); if (message) cloudStack.dialog.notice({ From 10cd11637afbc89915df4d22a3eaddecbbfc988e Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Wed, 4 Dec 2013 08:59:59 -0800 Subject: [PATCH 100/170] CLOUDSTACK-5266: Fix quickview not working for VR sections --- ui/scripts/system.js | 29 ++++++++++++++++++----------- ui/scripts/ui/widgets/detailView.js | 3 ++- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 7e4bb61b34f..9dd5190bec7 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -8380,10 +8380,13 @@ args.context.routerGroupByZone[0].routerRequiresUpgrade = 0; } } - }); - args.response.success({ - data: args.context.routerGroupByZone[0] - }) + }); + + setTimeout(function() { + args.response.success({ + data: args.context.routerGroupByZone[0] + }) + }); } } } @@ -8600,9 +8603,11 @@ } } }); - args.response.success({ - data: args.context.routerGroupByPod[0] - }) + setTimeout(function() { + args.response.success({ + data: args.context.routerGroupByPod[0] + }); + }); } } } @@ -8822,9 +8827,11 @@ } } }); - args.response.success({ - data: args.context.routerGroupByCluster[0] - }) + setTimeout(function() { + args.response.success({ + data: args.context.routerGroupByCluster[0] + }); + }); } } } @@ -17887,7 +17894,7 @@ jsonObj["redundantRouterState"] = jsonObj.redundantstate; } else { jsonObj["redundantRouterState"] = ""; - } + } } var refreshNspData = function(nspName) { diff --git a/ui/scripts/ui/widgets/detailView.js b/ui/scripts/ui/widgets/detailView.js index b0ebaa9b279..4c40ec80056 100644 --- a/ui/scripts/ui/widgets/detailView.js +++ b/ui/scripts/ui/widgets/detailView.js @@ -93,7 +93,8 @@ var $detailViewElems = $detailView.find('ul.ui-tabs-nav, .detail-group').remove(); var viewArgs = $detailView.data('view-args'); var context = viewArgs.context; - var activeContextItem = viewArgs.section ? context[viewArgs.section][0] : null; + var activeContextItem = viewArgs.section && context[viewArgs.section] ? + context[viewArgs.section][0] : null; $detailView.tabs('destroy'); $detailView.data('view-args').jsonObj = newData; From 8e06cf5593bc9e4ac523083b4d85a9865f98558b Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Wed, 4 Dec 2013 09:38:47 -0800 Subject: [PATCH 101/170] VR UI actions: Fix incorrect response object referenced on action complete --- ui/scripts/system.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 9dd5190bec7..0d8784f5006 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -2338,7 +2338,7 @@ _custom: { jobId: jid, getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.domainrouter; + return json.queryasyncjobresultresponse.jobresult.router; }, getActionFilter: function() { return routerActionfilter; @@ -2384,7 +2384,7 @@ _custom: { jobId: jid, getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.domainrouter; + return json.queryasyncjobresultresponse.jobresult.router; }, getActionFilter: function() { return routerActionfilter; @@ -3418,7 +3418,7 @@ _custom: { jobId: jid, getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.domainrouter; + return json.queryasyncjobresultresponse.jobresult.router; }, getActionFilter: function() { return routerActionfilter; @@ -3464,7 +3464,7 @@ _custom: { jobId: jid, getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.domainrouter; + return json.queryasyncjobresultresponse.jobresult.router; }, getActionFilter: function() { return routerActionfilter; @@ -3500,7 +3500,7 @@ _custom: { jobId: jid, getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.domainrouter; + return json.queryasyncjobresultresponse.jobresult.router; }, getActionFilter: function() { return routerActionfilter; @@ -7659,7 +7659,7 @@ _custom: { jobId: jid, getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.domainrouter; + return json.queryasyncjobresultresponse.jobresult.router; }, getActionFilter: function() { return routerActionfilter; @@ -7705,7 +7705,7 @@ _custom: { jobId: jid, getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.domainrouter; + return json.queryasyncjobresultresponse.jobresult.router; }, getActionFilter: function() { return routerActionfilter; @@ -7804,7 +7804,7 @@ _custom: { jobId: jid, getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.domainrouter; + return json.queryasyncjobresultresponse.jobresult.router; }, getActionFilter: function() { return routerActionfilter; From 2ed41270ce8b25a05e2a0c0c0ba7e0c909f96061 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Wed, 4 Dec 2013 09:39:52 -0800 Subject: [PATCH 102/170] Detail view: Fix error on refresh from async action Fixes error on detail view actions when list view subsection has a custom ID --- ui/scripts/ui/widgets/detailView.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ui/scripts/ui/widgets/detailView.js b/ui/scripts/ui/widgets/detailView.js index 4c40ec80056..3a3cd798794 100644 --- a/ui/scripts/ui/widgets/detailView.js +++ b/ui/scripts/ui/widgets/detailView.js @@ -46,11 +46,13 @@ // Refresh detail view context if ($detailView) { - $.extend( - $detailView.data('view-args').context[ - $detailView.data('view-args').section - ][0], newData - ); + var detailViewArgs = $detailView.data('view-args'); + var listViewArgs = $listView.data('view-args'); + var contextID = listViewArgs.sections && listViewArgs.sections[detailViewArgs.section].id ? + listViewArgs.sections[detailViewArgs.section].id : + detailViewArgs.section; + + $.extend($detailView.data('view-args').context[contextID][0], newData); } }; From 751d8d196670c8b615abefb3f5298de0514a5469 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Wed, 4 Dec 2013 09:50:30 -0800 Subject: [PATCH 103/170] CLOUDSTACK-2570: Fix duplicate resource name field --- ui/modules/vnmcNetworkProvider/vnmcNetworkProvider.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/ui/modules/vnmcNetworkProvider/vnmcNetworkProvider.js b/ui/modules/vnmcNetworkProvider/vnmcNetworkProvider.js index f1d22d193bc..d618b232d27 100644 --- a/ui/modules/vnmcNetworkProvider/vnmcNetworkProvider.js +++ b/ui/modules/vnmcNetworkProvider/vnmcNetworkProvider.js @@ -250,9 +250,6 @@ }, provider: { label: 'Provider' - }, - RESOURCE_NAME: { - label: 'Resource Name' } }], dataProvider: function (args) { From bd6f706b7261948ff44cffeebab0c7fcddfae857 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Mon, 2 Dec 2013 16:18:08 -0800 Subject: [PATCH 104/170] CLOUDSTACK-5261: added support for Alert publishing via ROOT Admin API Conflicts: engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/discoverer/HypervServerDiscoverer.java plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java server/src/com/cloud/alert/AlertManagerImpl.java server/src/com/cloud/alert/ConsoleProxyAlertAdapter.java server/src/com/cloud/alert/SecondaryStorageVmAlertAdapter.java server/src/com/cloud/configuration/ConfigurationManagerImpl.java server/src/com/cloud/ha/HighAvailabilityManagerExtImpl.java server/src/com/cloud/ha/HighAvailabilityManagerImpl.java server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java server/src/com/cloud/vm/UserVmManagerImpl.java usage/src/com/cloud/usage/UsageAlertManagerImpl.java usage/src/com/cloud/usage/UsageManagerImpl.java listAlerts: introduced new parameter "name" to the alertResponse Conflicts: api/src/org/apache/cloudstack/api/command/admin/resource/ListAlertsCmd.java server/src/com/cloud/alert/AlertManagerImpl.java usage/src/com/cloud/usage/UsageAlertManagerImpl.java Added new Admin API - generateAlert. Available to ROOT admin only Conflicts: api/src/org/apache/cloudstack/alert/AlertService.java api/src/org/apache/cloudstack/api/BaseCmd.java usage/src/com/cloud/usage/UsageAlertManagerImpl.java listAlerts: implemented search by alert name Conflicts: api/src/org/apache/cloudstack/alert/AlertService.java api/src/org/apache/cloudstack/api/command/admin/resource/ListAlertsCmd.java engine/schema/src/com/cloud/alert/AlertVO.java --- api/src/com/cloud/alert/Alert.java | 1 + api/src/com/cloud/event/EventTypes.java | 4 + .../apache/cloudstack/alert/AlertService.java | 103 +++++++++++++ .../org/apache/cloudstack/api/BaseCmd.java | 11 +- .../command/admin/alert/GenerateAlertCmd.java | 123 +++++++++++++++ .../command/admin/resource/ListAlertsCmd.java | 11 +- .../api/response/AlertResponse.java | 7 + client/tomcatconf/commands.properties.in | 1 + .../src/com/cloud/alert/AlertManager.java | 43 +----- .../cloud/agent/manager/AgentManagerImpl.java | 10 +- .../cloud/vm/VirtualMachineManagerImpl.java | 37 +++-- .../orchestration/NetworkOrchestrator.java | 2 +- .../schema/src/com/cloud/alert/AlertVO.java | 18 ++- .../storage/image/TemplateServiceImpl.java | 2 +- .../provider/DefaultHostListener.java | 2 +- .../storage/volume/VolumeServiceImpl.java | 7 +- .../discoverer/HypervServerDiscoverer.java | 5 +- .../vmware/VmwareServerDiscoverer.java | 2 +- .../xen/discoverer/XcpServerDiscoverer.java | 9 +- .../provider/SolidFireHostListener.java | 2 +- .../src/com/cloud/alert/AlertManagerImpl.java | 142 ++++++------------ .../com/cloud/alert/ClusterAlertAdapter.java | 4 +- .../cloud/alert/ConsoleProxyAlertAdapter.java | 14 +- .../alert/SecondaryStorageVmAlertAdapter.java | 14 +- .../ConfigurationManagerImpl.java | 4 +- .../ha/HighAvailabilityManagerExtImpl.java | 4 +- .../cloud/ha/HighAvailabilityManagerImpl.java | 20 +-- .../VirtualNetworkApplianceManagerImpl.java | 14 +- .../ResourceLimitManagerImpl.java | 2 +- .../cloud/server/ManagementServerImpl.java | 7 + .../storage/snapshot/SnapshotManagerImpl.java | 2 +- .../src/com/cloud/vm/UserVmManagerImpl.java | 16 +- .../com/cloud/alert/MockAlertManagerImpl.java | 10 +- setup/db/db/schema-421to430.sql | 4 + .../cloud/usage/UsageAlertManagerImpl.java | 49 +++--- .../src/com/cloud/usage/UsageManagerImpl.java | 8 +- 36 files changed, 465 insertions(+), 249 deletions(-) create mode 100644 api/src/org/apache/cloudstack/alert/AlertService.java create mode 100644 api/src/org/apache/cloudstack/api/command/admin/alert/GenerateAlertCmd.java diff --git a/api/src/com/cloud/alert/Alert.java b/api/src/com/cloud/alert/Alert.java index d835bf84499..6555b6fded1 100644 --- a/api/src/com/cloud/alert/Alert.java +++ b/api/src/com/cloud/alert/Alert.java @@ -39,4 +39,5 @@ public interface Alert extends Identity, InternalIdentity { Date getResolved(); boolean getArchived(); + String getName(); } diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 0554d7aa704..c539066bdaa 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -450,6 +450,10 @@ public class EventTypes { // Object store migration public static final String EVENT_MIGRATE_PREPARE_SECONDARY_STORAGE = "MIGRATE.PREPARE.SS"; + //Alert generation + public static final String ALERT_GENERATE = "ALERT.GENERATE"; + + static { // TODO: need a way to force author adding event types to declare the entity details as well, with out braking diff --git a/api/src/org/apache/cloudstack/alert/AlertService.java b/api/src/org/apache/cloudstack/alert/AlertService.java new file mode 100644 index 00000000000..2143fe8d23f --- /dev/null +++ b/api/src/org/apache/cloudstack/alert/AlertService.java @@ -0,0 +1,103 @@ + +// 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.alert; + +import java.util.HashSet; +import java.util.Set; + +import com.cloud.capacity.Capacity; +import com.cloud.exception.InvalidParameterValueException; + +public interface AlertService { + public static class AlertType { + private static Set defaultAlertTypes = new HashSet(); + private final String name; + private final short type; + + private AlertType(short type, String name, boolean isDefault) { + this.name = name; + this.type = type; + if (isDefault) { + defaultAlertTypes.add(this); + } + } + + public static final AlertType ALERT_TYPE_MEMORY = new AlertType(Capacity.CAPACITY_TYPE_MEMORY, "ALERT.MEMORY", true); + public static final AlertType ALERT_TYPE_CPU = new AlertType(Capacity.CAPACITY_TYPE_CPU, "ALERT.CPU", true); + public static final AlertType ALERT_TYPE_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_STORAGE, "ALERT.STORAGE", true); + public static final AlertType ALERT_TYPE_STORAGE_ALLOCATED = new AlertType(Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED, "ALERT.STORAGE.ALLOCATED", true); + public static final AlertType ALERT_TYPE_VIRTUAL_NETWORK_PUBLIC_IP = new AlertType(Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP, "ALERT.NETWORK.PUBLICIP", true); + public static final AlertType ALERT_TYPE_PRIVATE_IP = new AlertType(Capacity.CAPACITY_TYPE_PRIVATE_IP, "ALERT.NETWORK.PRIVATEIP", true); + public static final AlertType ALERT_TYPE_SECONDARY_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_SECONDARY_STORAGE, "ALERT.STORAGE.SECONDARY", true); + public static final AlertType ALERT_TYPE_HOST = new AlertType((short)7, "ALERT.COMPUTE.HOST", true); + public static final AlertType ALERT_TYPE_USERVM = new AlertType((short)8, "ALERT.USERVM", true); + public static final AlertType ALERT_TYPE_DOMAIN_ROUTER = new AlertType((short)9, "ALERT.SERVICE.DOMAINROUTER", true); + public static final AlertType ALERT_TYPE_CONSOLE_PROXY = new AlertType((short)10, "ALERT.SERVICE.CONSOLEPROXY", true); + public static final AlertType ALERT_TYPE_ROUTING = new AlertType((short)11, "ALERT.NETWORK.ROUTING", true); + public static final AlertType ALERT_TYPE_STORAGE_MISC = new AlertType((short)12, "ALERT.STORAGE.MISC", true); + public static final AlertType ALERT_TYPE_USAGE_SERVER = new AlertType((short)13, "ALERT.USAGE", true); + public static final AlertType ALERT_TYPE_MANAGMENT_NODE = new AlertType((short)14, "ALERT.MANAGEMENT", true); + public static final AlertType ALERT_TYPE_DOMAIN_ROUTER_MIGRATE = new AlertType((short)15, "ALERT.NETWORK.DOMAINROUTERMIGRATE", true); + public static final AlertType ALERT_TYPE_CONSOLE_PROXY_MIGRATE = new AlertType((short)16, "ALERT.SERVICE.CONSOLEPROXYMIGRATE", true); + public static final AlertType ALERT_TYPE_USERVM_MIGRATE = new AlertType((short)17, "ALERT.USERVM.MIGRATE", true); + public static final AlertType ALERT_TYPE_VLAN = new AlertType((short)18, "ALERT.NETWORK.VLAN", true); + public static final AlertType ALERT_TYPE_SSVM = new AlertType((short)19, "ALERT.SERVICE.SSVM", true); + public static final AlertType ALERT_TYPE_USAGE_SERVER_RESULT = new AlertType((short)20, "ALERT.USAGE.RESULT", true); + public static final AlertType ALERT_TYPE_STORAGE_DELETE = new AlertType((short)21, "ALERT.STORAGE.DELETE", true); + public static final AlertType ALERT_TYPE_UPDATE_RESOURCE_COUNT = new AlertType((short)22, "ALERT.RESOURCE.COUNT", true); + public static final AlertType ALERT_TYPE_USAGE_SANITY_RESULT = new AlertType((short)23, "ALERT.USAGE.SANITY", true); + public static final AlertType ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP = new AlertType((short)24, "ALERT.NETWORK.DIRECTPUBLICIP", true); + public static final AlertType ALERT_TYPE_LOCAL_STORAGE = new AlertType((short)25, "ALERT.STORAGE.LOCAL", true); + public static final AlertType ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED = new AlertType((short)26, "ALERT.RESOURCE.EXCEED", true); + public static final AlertType ALERT_TYPE_SYNC = new AlertType((short)27, "ALERT.TYPE.SYNC", true); + + public short getType() { + return type; + } + + public String getName() { + return name; + } + + private static AlertType getAlertType(short type) { + for (AlertType alertType : defaultAlertTypes) { + if (alertType.getType() == type) { + return alertType; + } + } + return null; + } + + @Override + public String toString() { + return String.valueOf(this.getType()); + } + + public static AlertType generateAlert(short type, String name) { + AlertType defaultAlert = getAlertType(type); + if (defaultAlert != null && !defaultAlert.getName().equalsIgnoreCase(name)) { + throw new InvalidParameterValueException("There is a default alert having type " + type + " and name " + defaultAlert.getName()); + } else { + return new AlertType(type, name, false); + } + } + } + + boolean generateAlert(AlertType alertType, long dataCenterId, Long podId, String msg); + +} diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java index b060f43a022..86a7c726d6c 100644 --- a/api/src/org/apache/cloudstack/api/BaseCmd.java +++ b/api/src/org/apache/cloudstack/api/BaseCmd.java @@ -26,14 +26,14 @@ import java.util.regex.Pattern; import javax.inject.Inject; -import org.apache.log4j.Logger; - import org.apache.cloudstack.affinity.AffinityGroupService; +import org.apache.cloudstack.alert.AlertService; import org.apache.cloudstack.network.element.InternalLoadBalancerElementService; import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService; import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService; import org.apache.cloudstack.query.QueryService; import org.apache.cloudstack.usage.UsageService; +import org.apache.log4j.Logger; import com.cloud.configuration.ConfigurationService; import com.cloud.domain.Domain; @@ -191,9 +191,12 @@ public abstract class BaseCmd { public InternalLoadBalancerVMService _internalLbSvc; @Inject public NetworkModel _ntwkModel; - + @Inject + public AlertService _alertSvc; + public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, - ResourceAllocationException, NetworkRuleConflictException; + ResourceAllocationException, NetworkRuleConflictException; + public void configure() { } diff --git a/api/src/org/apache/cloudstack/api/command/admin/alert/GenerateAlertCmd.java b/api/src/org/apache/cloudstack/api/command/admin/alert/GenerateAlertCmd.java new file mode 100644 index 00000000000..b23a3be9dea --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/alert/GenerateAlertCmd.java @@ -0,0 +1,123 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command.admin.alert; + +import org.apache.cloudstack.alert.AlertService; +import org.apache.cloudstack.alert.AlertService.AlertType; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.PodResponse; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.log4j.Logger; + +import com.cloud.event.EventTypes; + +@APICommand(name = "generateAlert", description = "Generates an alert", responseObject = SuccessResponse.class, since="4.3") +public class GenerateAlertCmd extends BaseAsyncCmd { + + public static final Logger s_logger = Logger.getLogger(GenerateAlertCmd.class.getName()); + + private static final String s_name = "generatealertresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.TYPE, type = CommandType.SHORT, description = "Type of the alert", required=true) + private Short type; + + @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "Name of the alert", required=true) + private String name; + + @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, description = "Alert description", required=true) + private String description; + + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class, description="Zone id for which alert is generated") + private Long zoneId; + + @Parameter(name=ApiConstants.POD_ID, type=CommandType.UUID, entityType=PodResponse.class, description="Pod id for which alert is generated") + private Long podId; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + @Override + public String getCommandName() { + return s_name; + } + + public Short getType() { + return type; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public long getZoneId() { + if (zoneId == null) { + return 0L; + } + return zoneId; + } + + public Long getPodId() { + return podId; + } + + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + + + @Override + public void execute() { + AlertType alertType = AlertService.AlertType.generateAlert(getType(), getName()); + if (_alertSvc.generateAlert(alertType, getZoneId(), getPodId(), getDescription())) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate an alert"); + } + } + + @Override + public String getEventType() { + return EventTypes.ALERT_GENERATE; + } + + @Override + public String getEventDescription() { + return "Generating alert of type " + type + "; name " + name; + } + + @Override + public long getEntityOwnerId() { + return 0; + } +} \ No newline at end of file diff --git a/api/src/org/apache/cloudstack/api/command/admin/resource/ListAlertsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/resource/ListAlertsCmd.java index 90ab67ce9b1..2fc4084e0ab 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/resource/ListAlertsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/resource/ListAlertsCmd.java @@ -19,14 +19,13 @@ package org.apache.cloudstack.api.command.admin.resource; import java.util.ArrayList; import java.util.List; -import org.apache.log4j.Logger; - import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.response.AlertResponse; import org.apache.cloudstack.api.response.ListResponse; +import org.apache.log4j.Logger; import com.cloud.alert.Alert; import com.cloud.utils.Pair; @@ -47,6 +46,9 @@ public class ListAlertsCmd extends BaseListCmd { @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "list by alert type") private String type; + + @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "list by alert name", since="4.3") + private String name; // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// @@ -59,6 +61,10 @@ public class ListAlertsCmd extends BaseListCmd { public String getType() { return type; } + + public String getName() { + return name; + } // /////////////////////////////////////////////////// // ///////////// API Implementation/////////////////// @@ -80,6 +86,7 @@ public class ListAlertsCmd extends BaseListCmd { alertResponse.setAlertType(alert.getType()); alertResponse.setDescription(alert.getSubject()); alertResponse.setLastSent(alert.getLastSent()); + alertResponse.setName(alert.getName()); alertResponse.setObjectName("alert"); alertResponseList.add(alertResponse); diff --git a/api/src/org/apache/cloudstack/api/response/AlertResponse.java b/api/src/org/apache/cloudstack/api/response/AlertResponse.java index 5a279157613..a2554c3b095 100644 --- a/api/src/org/apache/cloudstack/api/response/AlertResponse.java +++ b/api/src/org/apache/cloudstack/api/response/AlertResponse.java @@ -42,6 +42,9 @@ public class AlertResponse extends BaseResponse { + "MANAGMENT_NODE = 13: lost connection to default route (to the gateway), " + "DOMAIN_ROUTER_MIGRATE = 14, CONSOLE_PROXY_MIGRATE = 15, USERVM_MIGRATE = 16, VLAN = 17, SSVM = 18, " + "USAGE_SERVER_RESULT = 19") private Short alertType; + + @SerializedName(ApiConstants.NAME) @Param(description="the name of the alert", since="4.3") + private String alertName; @SerializedName(ApiConstants.DESCRIPTION) @Param(description = "description of the alert") @@ -66,4 +69,8 @@ public class AlertResponse extends BaseResponse { public void setLastSent(Date lastSent) { this.lastSent = lastSent; } + + public void setName(String name) { + this.alertName = name; + } } diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 28490a91d77..10afdcc7e63 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -246,6 +246,7 @@ deleteEvents=15 listAlerts=3 archiveAlerts=1 deleteAlerts=1 +generateAlert=1 #### system capacity commands listCapacity=3 diff --git a/engine/components-api/src/com/cloud/alert/AlertManager.java b/engine/components-api/src/com/cloud/alert/AlertManager.java index 5aea465f6ee..56a27df1b42 100755 --- a/engine/components-api/src/com/cloud/alert/AlertManager.java +++ b/engine/components-api/src/com/cloud/alert/AlertManager.java @@ -16,43 +16,13 @@ // under the License. package com.cloud.alert; +import org.apache.cloudstack.alert.AlertService; import org.apache.cloudstack.framework.config.ConfigKey; -import com.cloud.capacity.CapacityVO; import com.cloud.utils.component.Manager; -public interface AlertManager extends Manager { - public static final short ALERT_TYPE_MEMORY = CapacityVO.CAPACITY_TYPE_MEMORY; - public static final short ALERT_TYPE_CPU = CapacityVO.CAPACITY_TYPE_CPU; - public static final short ALERT_TYPE_STORAGE = CapacityVO.CAPACITY_TYPE_STORAGE; - public static final short ALERT_TYPE_STORAGE_ALLOCATED = CapacityVO.CAPACITY_TYPE_STORAGE_ALLOCATED; - public static final short ALERT_TYPE_VIRTUAL_NETWORK_PUBLIC_IP = CapacityVO.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP; - public static final short ALERT_TYPE_PRIVATE_IP = CapacityVO.CAPACITY_TYPE_PRIVATE_IP; - public static final short ALERT_TYPE_SECONDARY_STORAGE = CapacityVO.CAPACITY_TYPE_SECONDARY_STORAGE; - public static final short ALERT_TYPE_HOST = 7; - public static final short ALERT_TYPE_USERVM = 8; - public static final short ALERT_TYPE_DOMAIN_ROUTER = 9; - public static final short ALERT_TYPE_CONSOLE_PROXY = 10; - public static final short ALERT_TYPE_ROUTING = 11; // lost connection to default route (to the gateway) - public static final short ALERT_TYPE_STORAGE_MISC = 12; // lost connection to default route (to the gateway) - public static final short ALERT_TYPE_USAGE_SERVER = 13; // lost connection to default route (to the gateway) - public static final short ALERT_TYPE_MANAGMENT_NODE = 14; // lost connection to default route (to the gateway) - public static final short ALERT_TYPE_DOMAIN_ROUTER_MIGRATE = 15; - public static final short ALERT_TYPE_CONSOLE_PROXY_MIGRATE = 16; - public static final short ALERT_TYPE_USERVM_MIGRATE = 17; - public static final short ALERT_TYPE_VLAN = 18; - public static final short ALERT_TYPE_SSVM = 19; - public static final short ALERT_TYPE_USAGE_SERVER_RESULT = 20; // Usage job result - public static final short ALERT_TYPE_STORAGE_DELETE = 21; - public static final short ALERT_TYPE_UPDATE_RESOURCE_COUNT = 22; // Generated when we fail to update the resource - // count - public static final short ALERT_TYPE_USAGE_SANITY_RESULT = 23; - public static final short ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP = 24; - public static final short ALERT_TYPE_LOCAL_STORAGE = 25; - public static final short ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED = 26; // Generated when the resource limit exceeds the limit. Currently used for recurring snapshots only - - public static final short ALERT_TYPE_SYNC = 27; - +public interface AlertManager extends Manager, AlertService{ + static final ConfigKey StorageCapacityThreshold = new ConfigKey(Double.class, "cluster.storage.capacity.notificationthreshold", "Alert", "0.75", "Percentage (as a value between 0 and 1) of storage utilization above which alerts will be sent about low storage available.", true, ConfigKey.Scope.Cluster, null); @@ -65,9 +35,10 @@ public interface AlertManager extends Manager { "Alert", "0.75", "Percentage (as a value between 0 and 1) of allocated storage utilization above which alerts will be sent about low storage available.", true, ConfigKey.Scope.Cluster, null); - void clearAlert(short alertType, long dataCenterId, long podId); - - void sendAlert(short alertType, long dataCenterId, Long podId, String subject, String body); + void clearAlert(AlertType alertType, long dataCenterId, long podId); void recalculateCapacity(); + + void sendAlert(AlertType alertType, long dataCenterId, Long podId, String subject, String body); + } diff --git a/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java b/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java index 1e8b1488c9c..42648df9a89 100755 --- a/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -818,7 +818,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl HostPodVO podVO = _podDao.findById(host.getPodId()); String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName(); if ((host.getType() != Host.Type.SecondaryStorage) && (host.getType() != Host.Type.ConsoleProxy)) { - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host disconnected, " + hostDesc, + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host disconnected, " + hostDesc, "If the agent for host [" + hostDesc + "] is not restarted within " + AlertWait + " seconds, HA will begin on the VMs"); } event = Status.Event.AgentDisconnected; @@ -828,8 +828,8 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId()); HostPodVO podVO = _podDao.findById(host.getPodId()); String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName(); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host in ALERT state, " + hostDesc, - "In availability zone " + host.getDataCenterId() + ", host is in alert state: " + host.getId() + "-" + host.getName()); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host in ALERT state, " + hostDesc, "In availability zone " + host.getDataCenterId() + + ", host is in alert state: " + host.getId() + "-" + host.getName()); } } else { s_logger.debug("The next status of Agent " + host.getId() + " is not Alert, no need to investigate what happened"); @@ -1201,11 +1201,11 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName(); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_ROUTING, host.getDataCenterId(), host.getPodId(), + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_ROUTING, host.getDataCenterId(), host.getPodId(), "Host lost connection to gateway, " + hostDesc, "Host [" + hostDesc + "] lost connection to gateway (default route) and is possibly having network connection issues."); } else { - _alertMgr.clearAlert(AlertManager.ALERT_TYPE_ROUTING, host.getDataCenterId(), host.getPodId()); + _alertMgr.clearAlert(AlertManager.AlertType.ALERT_TYPE_ROUTING, host.getDataCenterId(), host.getPodId()); } } else { s_logger.debug("Not processing " + PingRoutingCommand.class.getSimpleName() + " for agent id=" + cmdHostId + diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 6b551cc57ec..cbaddc9808f 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -40,8 +40,6 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; - import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -69,6 +67,7 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.cloudstack.utils.identity.ManagementServerNode; +import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; @@ -1676,11 +1675,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac throw new CloudRuntimeException("VM is not Running, unable to migrate the vm currently " + vm + " , current state: " + vm.getState().toString()); } - short alertType = AlertManager.ALERT_TYPE_USERVM_MIGRATE; + AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM_MIGRATE; if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE; + alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE; } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_CONSOLE_PROXY_MIGRATE; + alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY_MIGRATE; } VirtualMachineProfile vmSrc = new VirtualMachineProfileImpl(vm); @@ -1936,11 +1935,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac " doesn't involve migrating the volumes."); } - short alertType = AlertManager.ALERT_TYPE_USERVM_MIGRATE; + AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM_MIGRATE; if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE; + alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE; } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_CONSOLE_PROXY_MIGRATE; + alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY_MIGRATE; } _networkMgr.prepareNicForMigration(profile, destination); @@ -2555,13 +2554,13 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (agentState == State.Error) { agentState = State.Stopped; - short alertType = AlertManager.ALERT_TYPE_USERVM; + AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM; if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_DOMAIN_ROUTER; + alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER; } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_CONSOLE_PROXY; + alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY; } else if (VirtualMachine.Type.SecondaryStorageVm.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_SSVM; + alertType = AlertManager.AlertType.ALERT_TYPE_SSVM; } HostPodVO podVO = _podDao.findById(vm.getPodIdToDeployIn()); @@ -3506,11 +3505,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac throw new CloudRuntimeException("VM is not Running, unable to migrate the vm currently " + vm + " , current state: " + vm.getState().toString()); } - short alertType = AlertManager.ALERT_TYPE_USERVM_MIGRATE; + AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM_MIGRATE; if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE; + alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE; } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_CONSOLE_PROXY_MIGRATE; + alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY_MIGRATE; } VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); @@ -3859,7 +3858,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } // we need to alert admin or user about this risky state transition - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(), + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(), VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName() + ") state is sync-ed (Starting -> Running) from out-of-context transition. VM network environment may need to be reset"); break; @@ -3881,7 +3880,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } catch (NoTransitionException e) { s_logger.warn("Unexpected VM state transition exception, race-condition?", e); } - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(), + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(), VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName() + ") state is sync-ed (" + vm.getState() + " -> Running) from out-of-context transition. VM network environment may need to be reset"); break; @@ -3923,7 +3922,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } catch (NoTransitionException e) { s_logger.warn("Unexpected VM state transition exception, race-condition?", e); } - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(), + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(), VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName() + ") state is sync-ed (" + vm.getState() + " -> Stopped) from out-of-context transition."); // TODO: we need to forcely release all resource allocation @@ -3984,7 +3983,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac VMInstanceVO vm = _vmDao.findById(vmId); // We now only alert administrator about this situation - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(), + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(), VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName() + ") is stuck in " + vm.getState() + " state and its host is unreachable for too long"); } diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 75caabe12d3..b5c1539ba9d 100755 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -2841,7 +2841,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra if (!answer.getResult()) { s_logger.warn("Unable to setup agent " + hostId + " due to " + ((answer != null) ? answer.getDetails() : "return null")); String msg = "Incorrect Network setup on agent, Reinitialize agent after network names are setup, details : " + answer.getDetails(); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, dcId, host.getPodId(), msg, msg); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, dcId, host.getPodId(), msg, msg); throw new ConnectionException(true, msg); } else { if (answer.needReconnect()) { diff --git a/engine/schema/src/com/cloud/alert/AlertVO.java b/engine/schema/src/com/cloud/alert/AlertVO.java index 98d8557d287..ade505d2e3f 100755 --- a/engine/schema/src/com/cloud/alert/AlertVO.java +++ b/engine/schema/src/com/cloud/alert/AlertVO.java @@ -72,16 +72,14 @@ public class AlertVO implements Alert { @Column(name = "archived") private boolean archived; + + @Column(name="name") + private String name; public AlertVO() { this.uuid = UUID.randomUUID().toString(); } - public AlertVO(Long id) { - this.id = id; - this.uuid = UUID.randomUUID().toString(); - } - @Override public long getId() { return id; @@ -184,4 +182,14 @@ public class AlertVO implements Alert { public void setArchived(Boolean archived) { this.archived = archived; } + + @Override + public String getName() { + return name; + } + + + public void setName(String name) { + this.name = name; + } } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index b88460203c8..dbd95e8b35f 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -364,7 +364,7 @@ public class TemplateServiceImpl implements TemplateService { tmpltInfo.getSize() - UriUtils.getRemoteSize(tmplt.getUrl())); } catch (ResourceAllocationException e) { s_logger.warn(e.getMessage()); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, zoneId, null, e.getMessage(), e.getMessage()); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, zoneId, null, e.getMessage(), e.getMessage()); } finally { _resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(), com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java index d2984e20da6..4838bf678e0 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java @@ -63,7 +63,7 @@ public class DefaultHostListener implements HypervisorHostListener { if (!answer.getResult()) { String msg = "Unable to attach storage pool" + poolId + " to the host" + hostId; - alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, pool.getDataCenterId(), pool.getPodId(), msg, msg); + alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, pool.getDataCenterId(), pool.getPodId(), msg, msg); throw new CloudRuntimeException("Unable establish connection from storage head to storage pool " + pool.getId() + " due to " + answer.getDetails() + pool.getId()); } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 284f9932ae8..9f71abd7003 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -25,9 +25,6 @@ import java.util.Map; import javax.inject.Inject; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; @@ -60,6 +57,8 @@ import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.ListVolumeAnswer; @@ -1204,7 +1203,7 @@ public class VolumeServiceImpl implements VolumeService { com.cloud.configuration.Resource.ResourceType.secondary_storage, volInfo.getSize() - volInfo.getPhysicalSize()); } catch (ResourceAllocationException e) { s_logger.warn(e.getMessage()); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), volume.getPodId(), e.getMessage(), + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), volume.getPodId(), e.getMessage(), e.getMessage()); } finally { _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/discoverer/HypervServerDiscoverer.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/discoverer/HypervServerDiscoverer.java index e3dcd8f634f..2a630c7e6db 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/discoverer/HypervServerDiscoverer.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/discoverer/HypervServerDiscoverer.java @@ -339,10 +339,11 @@ public class HypervServerDiscoverer extends DiscovererBase implements Discoverer // TODO: does the resource have to create a connection? return resources; } catch (ConfigurationException e) { - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, dcId, podId, "Unable to add " + uri.getHost(), "Error is " + e.getMessage()); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, dcId, podId, "Unable to add " + uri.getHost(), "Error is " + e.getMessage()); s_logger.warn("Unable to instantiate " + uri.getHost(), e); } catch (UnknownHostException e) { - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, dcId, podId, "Unable to add " + uri.getHost(), "Error is " + e.getMessage()); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, dcId, podId, "Unable to add " + uri.getHost(), "Error is " + e.getMessage()); + s_logger.warn("Unable to instantiate " + uri.getHost(), e); } catch (Exception e) { String msg = " can't setup agent, due to " + e.toString() + " - " + e.getMessage(); diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java index 8ed445f6781..ad3620dd03f 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java @@ -402,7 +402,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer try { resource.configure("VMware", params); } catch (ConfigurationException e) { - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, dcId, podId, "Unable to add " + url.getHost(), "Error is " + e.getMessage()); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, dcId, podId, "Unable to add " + url.getHost(), "Error is " + e.getMessage()); s_logger.warn("Unable to instantiate " + url.getHost(), e); } resource.start(); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java index 6dfc0d4759c..705aa4cd14b 100755 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java @@ -253,7 +253,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L } if (!support_hvm) { String msg = "Unable to add host " + record.address + " because it doesn't support hvm"; - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, dcId, podId, msg, msg); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, dcId, podId, msg, msg); s_logger.debug(msg); throw new RuntimeException(msg); } @@ -331,7 +331,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L try { resource.configure("Xen Server", params); } catch (ConfigurationException e) { - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, dcId, podId, "Unable to add " + record.address, "Error is " + e.getMessage()); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, dcId, podId, "Unable to add " + record.address, "Error is " + e.getMessage()); s_logger.warn("Unable to instantiate " + record.address, e); continue; } @@ -468,7 +468,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L String msg = "Only support XCP 1.0.0, 1.1.0, 1.4.x, 1.5 beta, 1.6.x; XenServer 5.6, XenServer 5.6 FP1, XenServer 5.6 SP2, Xenserver 6.0, 6.0.2, 6.1.0, 6.2.0 but this one is " + prodBrand + " " + prodVersion; - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, dcId, podId, msg, msg); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, dcId, podId, msg, msg); s_logger.debug(msg); throw new RuntimeException(msg); } @@ -741,10 +741,9 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L "Unable to eject host " + host.getGuid() + " due to there is no host up in this cluster, please execute xe pool-eject host-uuid=" + host.getGuid() + "in this host " + host.getPrivateIpAddress(); s_logger.warn(msg); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Unable to eject host " + host.getGuid(), msg); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Unable to eject host " + host.getGuid(), msg); } } - return new DeleteHostAnswer(true); } diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java index 53143141778..d8e4ec61ec8 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java @@ -82,7 +82,7 @@ public class SolidFireHostListener implements HypervisorHostListener { if (!answer.getResult()) { String msg = "Unable to attach storage pool " + storagePoolId + " to host " + hostId; - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, storagePool.getDataCenterId(), storagePool.getPodId(), msg, msg); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, storagePool.getDataCenterId(), storagePool.getPodId(), msg, msg); throw new CloudRuntimeException("Unable to establish a connection from agent to storage pool " + storagePool.getId() + " due to " + answer.getDetails() + " (" + storagePool.getId() + ")"); diff --git a/server/src/com/cloud/alert/AlertManagerImpl.java b/server/src/com/cloud/alert/AlertManagerImpl.java index fd24c02034a..c742813e17e 100755 --- a/server/src/com/cloud/alert/AlertManagerImpl.java +++ b/server/src/com/cloud/alert/AlertManagerImpl.java @@ -40,12 +40,7 @@ import javax.mail.URLName; import javax.mail.internet.InternetAddress; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; - -import com.sun.mail.smtp.SMTPMessage; -import com.sun.mail.smtp.SMTPSSLTransport; -import com.sun.mail.smtp.SMTPTransport; - +import org.apache.cloudstack.alert.AlertService.AlertType; import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; @@ -53,6 +48,7 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.managed.context.ManagedContextTimerTask; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.log4j.Logger; import com.cloud.alert.dao.AlertDao; import com.cloud.api.ApiDBUtils; @@ -73,7 +69,9 @@ import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.DataCenterIpAddressDao; import com.cloud.dc.dao.HostPodDao; +import com.cloud.event.ActionEvent; import com.cloud.event.AlertGenerator; +import com.cloud.event.EventTypes; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.network.dao.IPAddressDao; @@ -85,6 +83,9 @@ import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; import com.cloud.utils.db.SearchCriteria; +import com.sun.mail.smtp.SMTPMessage; +import com.sun.mail.smtp.SMTPSSLTransport; +import com.sun.mail.smtp.SMTPTransport; @Local(value = {AlertManager.class}) public class AlertManagerImpl extends ManagerBase implements AlertManager, Configurable { @@ -228,10 +229,10 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi } @Override - public void clearAlert(short alertType, long dataCenterId, long podId) { + public void clearAlert(AlertType alertType, long dataCenterId, long podId) { try { if (_emailAlert != null) { - _emailAlert.clearAlert(alertType, dataCenterId, podId); + _emailAlert.clearAlert(alertType.getType(), dataCenterId, podId); } } catch (Exception ex) { s_logger.error("Problem clearing email alert", ex); @@ -239,10 +240,10 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi } @Override - public void sendAlert(short alertType, long dataCenterId, Long podId, String subject, String body) { + public void sendAlert(AlertType alertType, long dataCenterId, Long podId, String subject, String body) { // publish alert - AlertGenerator.publishAlertOnEventBus(getAlertType(alertType), dataCenterId, podId, subject, body); + AlertGenerator.publishAlertOnEventBus(alertType.getName(), dataCenterId, podId, subject, body); // TODO: queue up these messages and send them as one set of issues once a certain number of issues is reached? If that's the case, // shouldn't we have a type/severity as part of the API so that severe errors get sent right away? @@ -258,67 +259,6 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi } } - private String getAlertType(short alertType) { - if (alertType == ALERT_TYPE_MEMORY) { - return "ALERT.MEMORY"; - } else if (alertType == ALERT_TYPE_CPU) { - return "ALERT.CPU"; - } else if (alertType == ALERT_TYPE_STORAGE) { - return "ALERT.STORAGE"; - } else if (alertType == ALERT_TYPE_STORAGE_ALLOCATED) { - return "ALERT.STORAGE.ALLOCATED"; - } else if (alertType == ALERT_TYPE_VIRTUAL_NETWORK_PUBLIC_IP) { - return "ALERT.NETWORK.PUBLICIP"; - } else if (alertType == ALERT_TYPE_PRIVATE_IP) { - return "ALERT.NETWORK.PRIVATEIP"; - } else if (alertType == ALERT_TYPE_SECONDARY_STORAGE) { - return "ALERT.STORAGE.SECONDARY"; - } else if (alertType == ALERT_TYPE_HOST) { - return "ALERT.COMPUTE.HOST"; - } else if (alertType == ALERT_TYPE_USERVM) { - return "ALERT.USERVM"; - } else if (alertType == ALERT_TYPE_DOMAIN_ROUTER) { - return "ALERT.SERVICE.DOMAINROUTER"; - } else if (alertType == ALERT_TYPE_CONSOLE_PROXY) { - return "ALERT.SERVICE.CONSOLEPROXY"; - } else if (alertType == ALERT_TYPE_ROUTING) { - return "ALERT.NETWORK.ROUTING"; - } else if (alertType == ALERT_TYPE_STORAGE_MISC) { - return "ALERT.STORAGE.MISC"; - } else if (alertType == ALERT_TYPE_USAGE_SERVER) { - return "ALERT.USAGE"; - } else if (alertType == ALERT_TYPE_MANAGMENT_NODE) { - return "ALERT.MANAGEMENT"; - } else if (alertType == ALERT_TYPE_DOMAIN_ROUTER_MIGRATE) { - return "ALERT.NETWORK.DOMAINROUTERMIGRATE"; - } else if (alertType == ALERT_TYPE_CONSOLE_PROXY_MIGRATE) { - return "ALERT.SERVICE.CONSOLEPROXYMIGRATE"; - } else if (alertType == ALERT_TYPE_USERVM_MIGRATE) { - return "ALERT.USERVM.MIGRATE"; - } else if (alertType == ALERT_TYPE_VLAN) { - return "ALERT.NETWORK.VLAN"; - } else if (alertType == ALERT_TYPE_SSVM) { - return "ALERT.SERVICE.SSVM"; - } else if (alertType == ALERT_TYPE_USAGE_SERVER_RESULT) { - return "ALERT.USAGE.RESULT"; - } else if (alertType == ALERT_TYPE_STORAGE_DELETE) { - return "ALERT.STORAGE.DELETE"; - } else if (alertType == ALERT_TYPE_UPDATE_RESOURCE_COUNT) { - return "ALERT.RESOURCE.COUNT"; - } else if (alertType == ALERT_TYPE_USAGE_SANITY_RESULT) { - return "ALERT.USAGE.SANITY"; - } else if (alertType == ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP) { - return "ALERT.NETWORK.DIRECTPUBLICIP"; - } else if (alertType == ALERT_TYPE_LOCAL_STORAGE) { - return "ALERT.STORAGE.LOCAL"; - } else if (alertType == ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED) { - return "ALERT.RESOURCE.EXCEED"; - } - return "UNKNOWN"; - } - - @Override - @DB public void recalculateCapacity() { // FIXME: the right way to do this is to register a listener (see RouterStatsListener, VMSyncListener) // for the vm sync state. The listener model has connects/disconnects to keep things in sync much better @@ -602,8 +542,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi String msgContent = null; String totalStr; String usedStr; - String pctStr = formatPercent(usedCapacity / totalCapacity); - short alertType = -1; + String pctStr = formatPercent(usedCapacity/totalCapacity); + AlertType alertType = null; Long podId = pod == null ? null : pod.getId(); Long clusterId = cluster == null ? null : cluster.getId(); @@ -615,21 +555,21 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi totalStr = formatBytesToMegabytes(totalCapacity); usedStr = formatBytesToMegabytes(usedCapacity); msgContent = "System memory is low, total: " + totalStr + " MB, used: " + usedStr + " MB (" + pctStr + "%)"; - alertType = ALERT_TYPE_MEMORY; + alertType = AlertManager.AlertType.ALERT_TYPE_MEMORY; break; case Capacity.CAPACITY_TYPE_CPU: msgSubject = "System Alert: Low Unallocated CPU in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + dc.getName(); totalStr = _dfWhole.format(totalCapacity); usedStr = _dfWhole.format(usedCapacity); msgContent = "Unallocated CPU is low, total: " + totalStr + " Mhz, used: " + usedStr + " Mhz (" + pctStr + "%)"; - alertType = ALERT_TYPE_CPU; + alertType = AlertManager.AlertType.ALERT_TYPE_CPU; break; case Capacity.CAPACITY_TYPE_STORAGE: msgSubject = "System Alert: Low Available Storage in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + dc.getName(); totalStr = formatBytesToMegabytes(totalCapacity); usedStr = formatBytesToMegabytes(usedCapacity); msgContent = "Available storage space is low, total: " + totalStr + " MB, used: " + usedStr + " MB (" + pctStr + "%)"; - alertType = ALERT_TYPE_STORAGE; + alertType = AlertManager.AlertType.ALERT_TYPE_STORAGE; break; case Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED: msgSubject = @@ -638,7 +578,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi totalStr = formatBytesToMegabytes(totalCapacity); usedStr = formatBytesToMegabytes(usedCapacity); msgContent = "Unallocated storage space is low, total: " + totalStr + " MB, allocated: " + usedStr + " MB (" + pctStr + "%)"; - alertType = ALERT_TYPE_STORAGE_ALLOCATED; + alertType = AlertManager.AlertType.ALERT_TYPE_STORAGE_ALLOCATED; break; case Capacity.CAPACITY_TYPE_LOCAL_STORAGE: msgSubject = @@ -647,7 +587,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi totalStr = formatBytesToMegabytes(totalCapacity); usedStr = formatBytesToMegabytes(usedCapacity); msgContent = "Unallocated storage space is low, total: " + totalStr + " MB, allocated: " + usedStr + " MB (" + pctStr + "%)"; - alertType = ALERT_TYPE_LOCAL_STORAGE; + alertType = AlertManager.AlertType.ALERT_TYPE_LOCAL_STORAGE; break; //Pod Level @@ -656,7 +596,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi totalStr = Double.toString(totalCapacity); usedStr = Double.toString(usedCapacity); msgContent = "Number of unallocated private IPs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)"; - alertType = ALERT_TYPE_PRIVATE_IP; + alertType = AlertManager.AlertType.ALERT_TYPE_PRIVATE_IP; break; //Zone Level @@ -665,28 +605,28 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi totalStr = formatBytesToMegabytes(totalCapacity); usedStr = formatBytesToMegabytes(usedCapacity); msgContent = "Available secondary storage space is low, total: " + totalStr + " MB, used: " + usedStr + " MB (" + pctStr + "%)"; - alertType = ALERT_TYPE_SECONDARY_STORAGE; + alertType = AlertManager.AlertType.ALERT_TYPE_SECONDARY_STORAGE; break; case Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP: msgSubject = "System Alert: Number of unallocated virtual network public IPs is low in availability zone " + dc.getName(); totalStr = Double.toString(totalCapacity); usedStr = Double.toString(usedCapacity); msgContent = "Number of unallocated public IPs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)"; - alertType = ALERT_TYPE_VIRTUAL_NETWORK_PUBLIC_IP; + alertType = AlertManager.AlertType.ALERT_TYPE_VIRTUAL_NETWORK_PUBLIC_IP; break; case Capacity.CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP: msgSubject = "System Alert: Number of unallocated shared network IPs is low in availability zone " + dc.getName(); totalStr = Double.toString(totalCapacity); usedStr = Double.toString(usedCapacity); msgContent = "Number of unallocated shared network IPs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)"; - alertType = ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP; + alertType = AlertManager.AlertType.ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP; break; case Capacity.CAPACITY_TYPE_VLAN: msgSubject = "System Alert: Number of unallocated VLANs is low in availability zone " + dc.getName(); totalStr = Double.toString(totalCapacity); usedStr = Double.toString(usedCapacity); msgContent = "Number of unallocated VLANs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)"; - alertType = ALERT_TYPE_VLAN; + alertType = AlertManager.AlertType.ALERT_TYPE_VLAN; break; } @@ -805,28 +745,32 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi } // TODO: make sure this handles SSL transport (useAuth is true) and regular - public void sendAlert(short alertType, long dataCenterId, Long podId, Long clusterId, String subject, String content) throws MessagingException, - UnsupportedEncodingException { - s_alertsLogger.warn(" alertType:: " + alertType + " // dataCenterId:: " + dataCenterId + " // podId:: " + podId + " // clusterId:: " + null + - " // message:: " + subject); + public void sendAlert(AlertType alertType, long dataCenterId, Long podId, Long clusterId, String subject, String content) throws MessagingException, UnsupportedEncodingException { + s_alertsLogger.warn(" alertType:: " + alertType + " // dataCenterId:: " + dataCenterId + " // podId:: " + + podId + " // clusterId:: " + null + " // message:: " + subject); AlertVO alert = null; - if ((alertType != AlertManager.ALERT_TYPE_HOST) && (alertType != AlertManager.ALERT_TYPE_USERVM) && (alertType != AlertManager.ALERT_TYPE_DOMAIN_ROUTER) && - (alertType != AlertManager.ALERT_TYPE_CONSOLE_PROXY) && (alertType != AlertManager.ALERT_TYPE_SSVM) && - (alertType != AlertManager.ALERT_TYPE_STORAGE_MISC) && (alertType != AlertManager.ALERT_TYPE_MANAGMENT_NODE) && - (alertType != AlertManager.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED)) { - alert = _alertDao.getLastAlert(alertType, dataCenterId, podId, clusterId); + if ((alertType != AlertManager.AlertType.ALERT_TYPE_HOST) && + (alertType != AlertManager.AlertType.ALERT_TYPE_USERVM) && + (alertType != AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER) && + (alertType != AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY) && + (alertType != AlertManager.AlertType.ALERT_TYPE_SSVM) && + (alertType != AlertManager.AlertType.ALERT_TYPE_STORAGE_MISC) && + (alertType != AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE) && + (alertType != AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED)) { + alert = _alertDao.getLastAlert(alertType.getType(), dataCenterId, podId, clusterId); } if (alert == null) { // set up a new alert AlertVO newAlert = new AlertVO(); - newAlert.setType(alertType); + newAlert.setType(alertType.getType()); newAlert.setSubject(subject); newAlert.setClusterId(clusterId); newAlert.setPodId(podId); newAlert.setDataCenterId(dataCenterId); newAlert.setSentCount(1); // initialize sent count to 1 since we are now sending an alert newAlert.setLastSent(new Date()); + newAlert.setName(alertType.getName()); _alertDao.persist(newAlert); } else { if (s_logger.isDebugEnabled()) { @@ -904,4 +848,16 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi public ConfigKey[] getConfigKeys() { return new ConfigKey[] {CPUCapacityThreshold, MemoryCapacityThreshold, StorageAllocatedCapacityThreshold, StorageCapacityThreshold}; } + + @Override + @ActionEvent(eventType = EventTypes.ALERT_GENERATE, eventDescription = "generating alert", async=true) + public boolean generateAlert(AlertType alertType, long dataCenterId, Long podId, String msg) { + try { + sendAlert(alertType, dataCenterId, podId, msg, msg); + return true; + } catch (Exception ex) { + s_logger.warn("Failed to generate an alert of type=" + alertType + "; msg=" + msg); + return false; + } + } } diff --git a/server/src/com/cloud/alert/ClusterAlertAdapter.java b/server/src/com/cloud/alert/ClusterAlertAdapter.java index a06800e688e..568fc0fb5c6 100644 --- a/server/src/com/cloud/alert/ClusterAlertAdapter.java +++ b/server/src/com/cloud/alert/ClusterAlertAdapter.java @@ -72,7 +72,7 @@ public class ClusterAlertAdapter extends AdapterBase implements AlertAdapter { s_logger.debug("Management server node " + mshost.getServiceIP() + " is up, send alert"); } - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0), "Management server node " + mshost.getServiceIP() + " is up", ""); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0), "Management server node " + mshost.getServiceIP() + " is up", ""); break; } } @@ -92,7 +92,7 @@ public class ClusterAlertAdapter extends AdapterBase implements AlertAdapter { if (s_logger.isDebugEnabled()) { s_logger.debug("Detected management server node " + mshost.getServiceIP() + " is down, send alert"); } - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0), "Management server node " + mshost.getServiceIP() + " is down", ""); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0), "Management server node " + mshost.getServiceIP() + " is down", ""); } else { if (s_logger.isDebugEnabled()) { s_logger.debug("Detected management server node " + mshost.getServiceIP() + " is down, but alert has already been set"); diff --git a/server/src/com/cloud/alert/ConsoleProxyAlertAdapter.java b/server/src/com/cloud/alert/ConsoleProxyAlertAdapter.java index 1c04b229ea6..86f7fc1e101 100644 --- a/server/src/com/cloud/alert/ConsoleProxyAlertAdapter.java +++ b/server/src/com/cloud/alert/ConsoleProxyAlertAdapter.java @@ -68,7 +68,7 @@ public class ConsoleProxyAlertAdapter extends AdapterBase implements AlertAdapte s_logger.debug("Console proxy is up, zone: " + dc.getName() + ", proxy: " + proxy.getHostName() + ", public IP: " + proxy.getPublicIpAddress() + ", private IP: " + proxy.getPrivateIpAddress()); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_CONSOLE_PROXY, args.getZoneId(), proxy.getPodIdToDeployIn(), "Console proxy up in zone: " + dc.getName() + + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY, args.getZoneId(), proxy.getPodIdToDeployIn(), "Console proxy up in zone: " + dc.getName() + ", proxy: " + proxy.getHostName() + ", public IP: " + proxy.getPublicIpAddress() + ", private IP: " + (proxy.getPrivateIpAddress() == null ? "N/A" : proxy.getPrivateIpAddress()), "Console proxy up (zone " + dc.getName() + ")"); break; @@ -78,7 +78,7 @@ public class ConsoleProxyAlertAdapter extends AdapterBase implements AlertAdapte s_logger.debug("Console proxy is down, zone: " + dc.getName() + ", proxy: " + proxy.getHostName() + ", public IP: " + proxy.getPublicIpAddress() + ", private IP: " + (proxy.getPrivateIpAddress() == null ? "N/A" : proxy.getPrivateIpAddress())); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_CONSOLE_PROXY, args.getZoneId(), proxy.getPodIdToDeployIn(), "Console proxy down in zone: " + dc.getName() + + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY, args.getZoneId(), proxy.getPodIdToDeployIn(), "Console proxy down in zone: " + dc.getName() + ", proxy: " + proxy.getHostName() + ", public IP: " + proxy.getPublicIpAddress() + ", private IP: " + (proxy.getPrivateIpAddress() == null ? "N/A" : proxy.getPrivateIpAddress()), "Console proxy down (zone " + dc.getName() + ")"); break; @@ -88,7 +88,7 @@ public class ConsoleProxyAlertAdapter extends AdapterBase implements AlertAdapte s_logger.debug("Console proxy is rebooted, zone: " + dc.getName() + ", proxy: " + proxy.getHostName() + ", public IP: " + proxy.getPublicIpAddress() + ", private IP: " + (proxy.getPrivateIpAddress() == null ? "N/A" : proxy.getPrivateIpAddress())); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_CONSOLE_PROXY, args.getZoneId(), proxy.getPodIdToDeployIn(), + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY, args.getZoneId(), proxy.getPodIdToDeployIn(), "Console proxy rebooted in zone: " + dc.getName() + ", proxy: " + proxy.getHostName() + ", public IP: " + proxy.getPublicIpAddress() + ", private IP: " + (proxy.getPrivateIpAddress() == null ? "N/A" : proxy.getPrivateIpAddress()), "Console proxy rebooted (zone " + dc.getName() + ")"); @@ -99,7 +99,7 @@ public class ConsoleProxyAlertAdapter extends AdapterBase implements AlertAdapte s_logger.debug("Console proxy creation failure, zone: " + dc.getName() + ", proxy: " + proxy.getHostName() + ", public IP: " + proxy.getPublicIpAddress() + ", private IP: " + (proxy.getPrivateIpAddress() == null ? "N/A" : proxy.getPrivateIpAddress())); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_CONSOLE_PROXY, args.getZoneId(), proxy.getPodIdToDeployIn(), + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY, args.getZoneId(), proxy.getPodIdToDeployIn(), "Console proxy creation failure. zone: " + dc.getName() + ", proxy: " + proxy.getHostName() + ", public IP: " + proxy.getPublicIpAddress() + ", private IP: " + (proxy.getPrivateIpAddress() == null ? "N/A" : proxy.getPrivateIpAddress()) + ", error details: " + args.getMessage(), "Console proxy creation failure (zone " + dc.getName() + ")"); @@ -110,7 +110,7 @@ public class ConsoleProxyAlertAdapter extends AdapterBase implements AlertAdapte s_logger.debug("Console proxy startup failure, zone: " + dc.getName() + ", proxy: " + proxy.getHostName() + ", public IP: " + proxy.getPublicIpAddress() + ", private IP: " + (proxy.getPrivateIpAddress() == null ? "N/A" : proxy.getPrivateIpAddress())); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_CONSOLE_PROXY, args.getZoneId(), proxy.getPodIdToDeployIn(), + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY, args.getZoneId(), proxy.getPodIdToDeployIn(), "Console proxy startup failure. zone: " + dc.getName() + ", proxy: " + proxy.getHostName() + ", public IP: " + proxy.getPublicIpAddress() + ", private IP: " + (proxy.getPrivateIpAddress() == null ? "N/A" : proxy.getPrivateIpAddress()) + ", error details: " + args.getMessage(), "Console proxy startup failure (zone " + dc.getName() + ")"); @@ -122,7 +122,7 @@ public class ConsoleProxyAlertAdapter extends AdapterBase implements AlertAdapte proxy.getPublicIpAddress() + ", private IP: " + (proxy.getPrivateIpAddress() == null ? "N/A" : proxy.getPrivateIpAddress())); _alertMgr.sendAlert( - AlertManager.ALERT_TYPE_CONSOLE_PROXY, + AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY, args.getZoneId(), proxy.getPodIdToDeployIn(), "Failed to open console proxy firewall port. zone: " + dc.getName() + ", proxy: " + proxy.getHostName() + ", public IP: " + @@ -135,7 +135,7 @@ public class ConsoleProxyAlertAdapter extends AdapterBase implements AlertAdapte s_logger.debug("Console proxy storage alert, zone: " + dc.getName() + ", proxy: " + proxy.getHostName() + ", public IP: " + proxy.getPublicIpAddress() + ", private IP: " + proxy.getPrivateIpAddress() + ", message: " + args.getMessage()); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_STORAGE_MISC, args.getZoneId(), proxy.getPodIdToDeployIn(), + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_STORAGE_MISC, args.getZoneId(), proxy.getPodIdToDeployIn(), "Console proxy storage issue. zone: " + dc.getName() + ", message: " + args.getMessage(), "Console proxy alert (zone " + dc.getName() + ")"); break; } diff --git a/server/src/com/cloud/alert/SecondaryStorageVmAlertAdapter.java b/server/src/com/cloud/alert/SecondaryStorageVmAlertAdapter.java index 91744567596..9d4de55f579 100644 --- a/server/src/com/cloud/alert/SecondaryStorageVmAlertAdapter.java +++ b/server/src/com/cloud/alert/SecondaryStorageVmAlertAdapter.java @@ -68,7 +68,7 @@ public class SecondaryStorageVmAlertAdapter extends AdapterBase implements Alert s_logger.debug("Secondary Storage Vm is up, zone: " + dc.getName() + ", secStorageVm: " + secStorageVm.getHostName() + ", public IP: " + secStorageVm.getPublicIpAddress() + ", private IP: " + secStorageVm.getPrivateIpAddress()); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_SSVM, args.getZoneId(), secStorageVm.getPodIdToDeployIn(), "Secondary Storage Vm up in zone: " + + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SSVM, args.getZoneId(), secStorageVm.getPodIdToDeployIn(), "Secondary Storage Vm up in zone: " + dc.getName() + ", secStorageVm: " + secStorageVm.getHostName() + ", public IP: " + secStorageVm.getPublicIpAddress() + ", private IP: " + (secStorageVm.getPrivateIpAddress() == null ? "N/A" : secStorageVm.getPrivateIpAddress()), "Secondary Storage Vm up (zone " + dc.getName() + ")"); break; @@ -79,7 +79,7 @@ public class SecondaryStorageVmAlertAdapter extends AdapterBase implements Alert secStorageVm.getPublicIpAddress() + ", private IP: " + (secStorageVm.getPrivateIpAddress() == null ? "N/A" : secStorageVm.getPrivateIpAddress())); _alertMgr.sendAlert( - AlertManager.ALERT_TYPE_SSVM, + AlertManager.AlertType.ALERT_TYPE_SSVM, args.getZoneId(), secStorageVm.getPodIdToDeployIn(), "Secondary Storage Vm down in zone: " + dc.getName() + ", secStorageVm: " + secStorageVm.getHostName() + ", public IP: " + @@ -93,7 +93,7 @@ public class SecondaryStorageVmAlertAdapter extends AdapterBase implements Alert secStorageVm.getPublicIpAddress() + ", private IP: " + (secStorageVm.getPrivateIpAddress() == null ? "N/A" : secStorageVm.getPrivateIpAddress())); _alertMgr.sendAlert( - AlertManager.ALERT_TYPE_SSVM, + AlertManager.AlertType.ALERT_TYPE_SSVM, args.getZoneId(), secStorageVm.getPodIdToDeployIn(), "Secondary Storage Vm rebooted in zone: " + dc.getName() + ", secStorageVm: " + secStorageVm.getHostName() + ", public IP: " + @@ -106,7 +106,7 @@ public class SecondaryStorageVmAlertAdapter extends AdapterBase implements Alert s_logger.debug("Secondary Storage Vm creation failure, zone: " + dc.getName() + ", secStorageVm: " + secStorageVm.getHostName() + ", public IP: " + secStorageVm.getPublicIpAddress() + ", private IP: " + (secStorageVm.getPrivateIpAddress() == null ? "N/A" : secStorageVm.getPrivateIpAddress())); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_SSVM, args.getZoneId(), secStorageVm.getPodIdToDeployIn(), "Secondary Storage Vm creation failure. zone: " + + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SSVM, args.getZoneId(), secStorageVm.getPodIdToDeployIn(), "Secondary Storage Vm creation failure. zone: " + dc.getName() + ", secStorageVm: " + secStorageVm.getHostName() + ", public IP: " + secStorageVm.getPublicIpAddress() + ", private IP: " + (secStorageVm.getPrivateIpAddress() == null ? "N/A" : secStorageVm.getPrivateIpAddress()) + ", error details: " + args.getMessage(), "Secondary Storage Vm creation failure (zone " + dc.getName() + ")"); @@ -117,7 +117,7 @@ public class SecondaryStorageVmAlertAdapter extends AdapterBase implements Alert s_logger.debug("Secondary Storage Vm startup failure, zone: " + dc.getName() + ", secStorageVm: " + secStorageVm.getHostName() + ", public IP: " + secStorageVm.getPublicIpAddress() + ", private IP: " + (secStorageVm.getPrivateIpAddress() == null ? "N/A" : secStorageVm.getPrivateIpAddress())); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_SSVM, args.getZoneId(), secStorageVm.getPodIdToDeployIn(), "Secondary Storage Vm startup failure. zone: " + + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SSVM, args.getZoneId(), secStorageVm.getPodIdToDeployIn(), "Secondary Storage Vm startup failure. zone: " + dc.getName() + ", secStorageVm: " + secStorageVm.getHostName() + ", public IP: " + secStorageVm.getPublicIpAddress() + ", private IP: " + (secStorageVm.getPrivateIpAddress() == null ? "N/A" : secStorageVm.getPrivateIpAddress()) + ", error details: " + args.getMessage(), "Secondary Storage Vm startup failure (zone " + dc.getName() + ")"); @@ -128,7 +128,7 @@ public class SecondaryStorageVmAlertAdapter extends AdapterBase implements Alert s_logger.debug("Secondary Storage Vm firewall alert, zone: " + dc.getName() + ", secStorageVm: " + secStorageVm.getHostName() + ", public IP: " + secStorageVm.getPublicIpAddress() + ", private IP: " + (secStorageVm.getPrivateIpAddress() == null ? "N/A" : secStorageVm.getPrivateIpAddress())); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_SSVM, args.getZoneId(), secStorageVm.getPodIdToDeployIn(), + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SSVM, args.getZoneId(), secStorageVm.getPodIdToDeployIn(), "Failed to open secondary storage vm firewall port. zone: " + dc.getName() + ", secStorageVm: " + secStorageVm.getHostName() + ", public IP: " + secStorageVm.getPublicIpAddress() + ", private IP: " + (secStorageVm.getPrivateIpAddress() == null ? "N/A" : secStorageVm.getPrivateIpAddress()), "Secondary Storage Vm alert (zone " + dc.getName() + ")"); @@ -139,7 +139,7 @@ public class SecondaryStorageVmAlertAdapter extends AdapterBase implements Alert s_logger.debug("Secondary Storage Vm storage alert, zone: " + dc.getName() + ", secStorageVm: " + secStorageVm.getHostName() + ", public IP: " + secStorageVm.getPublicIpAddress() + ", private IP: " + secStorageVm.getPrivateIpAddress() + ", message: " + args.getMessage()); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_STORAGE_MISC, args.getZoneId(), secStorageVm.getPodIdToDeployIn(), + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_STORAGE_MISC, args.getZoneId(), secStorageVm.getPodIdToDeployIn(), "Secondary Storage Vm storage issue. zone: " + dc.getName() + ", message: " + args.getMessage(), "Secondary Storage Vm alert (zone " + dc.getName() + ")"); break; diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 854c089f497..a2c0204438c 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -403,12 +403,12 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if (localCidrs.length > 0) { s_logger.warn("Management network CIDR is not configured originally. Set it default to " + localCidrs[0]); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0), "Management network CIDR is not configured originally. Set it default to " + + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0), "Management network CIDR is not configured originally. Set it default to " + localCidrs[0], ""); _configDao.update(Config.ManagementNetwork.key(), Config.ManagementNetwork.getCategory(), localCidrs[0]); } else { s_logger.warn("Management network CIDR is not properly configured and we are not able to find a default setting"); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0), + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0), "Management network CIDR is not properly configured and we are not able to find a default setting", ""); } } diff --git a/server/src/com/cloud/ha/HighAvailabilityManagerExtImpl.java b/server/src/com/cloud/ha/HighAvailabilityManagerExtImpl.java index 5d975fe0feb..56db8ef2f26 100644 --- a/server/src/com/cloud/ha/HighAvailabilityManagerExtImpl.java +++ b/server/src/com/cloud/ha/HighAvailabilityManagerExtImpl.java @@ -92,10 +92,10 @@ public class HighAvailabilityManagerExtImpl extends HighAvailabilityManagerImpl } if (!isRunning) { - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USAGE_SERVER, 0, new Long(0), "No usage server process running", + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USAGE_SERVER, 0, new Long(0), "No usage server process running", "No usage server process has been detected, some attention is required"); } else { - _alertMgr.clearAlert(AlertManager.ALERT_TYPE_USAGE_SERVER, 0, 0); + _alertMgr.clearAlert(AlertManager.AlertType.ALERT_TYPE_USAGE_SERVER, 0, 0); } } catch (Exception ex) { s_logger.warn("Error while monitoring usage job", ex); diff --git a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java index fc65a215c97..aec1b8dd2b7 100755 --- a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java +++ b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java @@ -36,6 +36,8 @@ import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationSer import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.managed.context.ManagedContext; import org.apache.cloudstack.managed.context.ManagedContextRunnable; +import org.apache.log4j.Logger; +import org.apache.log4j.NDC; import com.cloud.agent.AgentManager; import com.cloud.alert.AlertManager; @@ -243,7 +245,7 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai HostPodVO podVO = _podDao.findById(host.getPodId()); String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName(); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host is down, " + hostDesc, "Host [" + hostDesc + "] is down." + + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host is down, " + hostDesc, "Host [" + hostDesc + "] is down." + ((sb != null) ? sb.toString() : "")); for (final VMInstanceVO vm : vms) { @@ -317,13 +319,13 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai s_logger.debug("VM does not require investigation so I'm marking it as Stopped: " + vm.toString()); } - short alertType = AlertManager.ALERT_TYPE_USERVM; + AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM; if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_DOMAIN_ROUTER; + alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER; } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_CONSOLE_PROXY; + alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY; } else if (VirtualMachine.Type.SecondaryStorageVm.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_SSVM; + alertType = AlertManager.AlertType.ALERT_TYPE_SSVM; } if (!(_forceHA || vm.isHaEnabled())) { @@ -415,13 +417,13 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai return null; } - short alertType = AlertManager.ALERT_TYPE_USERVM; + AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM; if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_DOMAIN_ROUTER; + alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER; } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_CONSOLE_PROXY; + alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY; } else if (VirtualMachine.Type.SecondaryStorageVm.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_SSVM; + alertType = AlertManager.AlertType.ALERT_TYPE_SSVM; } HostVO host = _hostDao.findById(work.getHostId()); diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index d5b9d3cf038..2e8cde3bad7 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1109,7 +1109,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V "Site-to-site Vpn Connection to " + gw.getName() + " on router " + router.getHostName() + "(id: " + router.getId() + ") " + " just switch from " + oldState + " to " + conn.getState(); s_logger.info(context); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), title, context); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), title, context); } } finally { _s2sVpnConnectionDao.releaseFromLockTable(lock.getId()); @@ -1170,7 +1170,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V "Redundant virtual router (name: " + router.getHostName() + ", id: " + router.getId() + ") " + " just switch from " + prevState + " to " + currState; s_logger.info(context); if (currState == RedundantState.MASTER) { - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), title, context); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), title, context); } } } @@ -1186,7 +1186,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V if (s_logger.isDebugEnabled()) { s_logger.debug(title); } - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, backupRouter.getDataCenterId(), backupRouter.getPodIdToDeployIn(), title, title); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, backupRouter.getDataCenterId(), backupRouter.getPodIdToDeployIn(), title, title); try { rebootRouter(backupRouter.getId(), true); } catch (ConcurrentOperationException e) { @@ -1277,8 +1277,8 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V String context = "Virtual router (name: " + router.getHostName() + ", id: " + router.getId() + " and router (name: " + dupRouter.getHostName() + ", id: " + router.getId() + ") are both in MASTER state! If the problem persist, restart both of routers. "; - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), title, context); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, dupRouter.getDataCenterId(), dupRouter.getPodIdToDeployIn(), title, context); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), title, context); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, dupRouter.getDataCenterId(), dupRouter.getPodIdToDeployIn(), title, context); s_logger.warn(context); } else { networkRouterMaps.put(routerGuestNtwkId, router); @@ -3571,7 +3571,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V String context = "Virtual router (name: " + disconnectedRouter.getInstanceName() + ", id: " + disconnectedRouter.getId() + ") would be stopped after connecting back, due to: " + reason; - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, disconnectedRouter.getDataCenterId(), disconnectedRouter.getPodIdToDeployIn(), title, context); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, disconnectedRouter.getDataCenterId(), disconnectedRouter.getPodIdToDeployIn(), title, context); disconnectedRouter.setStopPending(true); disconnectedRouter = _routerDao.persist(disconnectedRouter); @@ -3589,7 +3589,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } } else { String t = "Can't bump up virtual router " + connectedRouter.getInstanceName() + "'s priority due to it's already bumped up!"; - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, connectedRouter.getDataCenterId(), connectedRouter.getPodIdToDeployIn(), t, t); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, connectedRouter.getDataCenterId(), connectedRouter.getPodIdToDeployIn(), t, t); } } } diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index 70e8cdf3c4f..6e5dce6bd3f 100755 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -253,7 +253,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim long numToDecrement = (delta.length == 0) ? 1 : delta[0].longValue(); if (!updateResourceCountForAccount(accountId, type, false, numToDecrement)) { - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, "Failed to decrement resource count of type " + type + " for account id=" + + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, "Failed to decrement resource count of type " + type + " for account id=" + accountId, "Failed to decrement resource count of type " + type + " for account id=" + accountId + "; use updateResourceCount API to recalculate/fix the problem"); } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index ee9c04a2aa4..dbb36476e70 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -59,6 +59,7 @@ import org.apache.cloudstack.api.command.admin.account.DisableAccountCmd; import org.apache.cloudstack.api.command.admin.account.EnableAccountCmd; import org.apache.cloudstack.api.command.admin.account.LockAccountCmd; import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd; +import org.apache.cloudstack.api.command.admin.alert.GenerateAlertCmd; import org.apache.cloudstack.api.command.admin.autoscale.CreateCounterCmd; import org.apache.cloudstack.api.command.admin.autoscale.DeleteCounterCmd; import org.apache.cloudstack.api.command.admin.cluster.AddClusterCmd; @@ -2254,6 +2255,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe Object id = cmd.getId(); Object type = cmd.getType(); Object keyword = cmd.getKeyword(); + Object name = cmd.getName(); Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), null); if (id != null) { @@ -2273,6 +2275,10 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe if (type != null) { sc.addAnd("type", SearchCriteria.Op.EQ, type); } + + if (name != null) { + sc.addAnd("name", SearchCriteria.Op.EQ, name); + } sc.addAnd("archived", SearchCriteria.Op.EQ, false); Pair, Integer> result = _alertDao.searchAndCount(sc, searchFilter); @@ -2857,6 +2863,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe cmdList.add(ListSslCertsCmd.class); cmdList.add(AssignCertToLoadBalancerCmd.class); cmdList.add(RemoveCertFromLoadBalancerCmd.class); + cmdList.add(GenerateAlertCmd.class); return cmdList; } diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 3c5e6a4d753..ef89fe21c9e 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -1077,7 +1077,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, if (snapshotType != Type.MANUAL) { String msg = "Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots"; s_logger.warn(msg); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, msg, "Snapshot resource limit exceeded for account id : " + owner.getId() + + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, msg, "Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots; please use updateResourceLimit to increase the limit"); } throw e; diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index ff519ead9cb..4e78ba14313 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -1756,7 +1756,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } } String msg = "Failed to deploy Vm with Id: " + vmId + ", on Host with Id: " + hostId; - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); // Get serviceOffering for Virtual Machine ServiceOfferingVO offering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId()); @@ -3977,14 +3977,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir if (srcExplDedicated && !destExplDedicated) { //raise an alert String msg = "VM is being migrated from a explicitly dedicated host " + srcHost.getName() + " to non-dedicated host " + destHost.getName(); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); s_logger.warn(msg); } //if srcHost is non dedicated but destination Host is explicitly dedicated if (!srcExplDedicated && destExplDedicated) { //raise an alert String msg = "VM is being migrated from a non dedicated host " + srcHost.getName() + " to a explicitly dedicated host " + destHost.getName(); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); s_logger.warn(msg); } @@ -3994,14 +3994,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(srcHost) + " to host " + destHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(destHost); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); s_logger.warn(msg); } if ((domainOfDedicatedHost(srcHost) != null) && (domainOfDedicatedHost(srcHost) != domainOfDedicatedHost(destHost))) { String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(srcHost) + " to host " + destHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(destHost); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); s_logger.warn(msg); } } @@ -4041,7 +4041,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } } } - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); s_logger.warn(msg); } else { @@ -4064,12 +4064,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } else { msg = "VM is being migrated from implicitly dedicated host " + srcHost.getName() + " to shared host " + destHost.getName(); } - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); s_logger.warn(msg); } else { if (destImplDedicated) { msg = "VM is being migrated from shared host " + srcHost.getName() + " to implicitly dedicated host " + destHost.getName(); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); s_logger.warn(msg); } } diff --git a/server/test/com/cloud/alert/MockAlertManagerImpl.java b/server/test/com/cloud/alert/MockAlertManagerImpl.java index f0c67f9ed70..597d479e6ca 100644 --- a/server/test/com/cloud/alert/MockAlertManagerImpl.java +++ b/server/test/com/cloud/alert/MockAlertManagerImpl.java @@ -63,7 +63,7 @@ public class MockAlertManagerImpl extends ManagerBase implements AlertManager { * @see com.cloud.alert.AlertManager#clearAlert(short, long, long) */ @Override - public void clearAlert(short alertType, long dataCenterId, long podId) { + public void clearAlert(AlertType alertType, long dataCenterId, long podId) { // TODO Auto-generated method stub } @@ -72,7 +72,7 @@ public class MockAlertManagerImpl extends ManagerBase implements AlertManager { * @see com.cloud.alert.AlertManager#sendAlert(short, long, java.lang.Long, java.lang.String, java.lang.String) */ @Override - public void sendAlert(short alertType, long dataCenterId, Long podId, String subject, String body) { + public void sendAlert(AlertType alertType, long dataCenterId, Long podId, String subject, String body) { // TODO Auto-generated method stub } @@ -86,4 +86,10 @@ public class MockAlertManagerImpl extends ManagerBase implements AlertManager { } + @Override + public boolean generateAlert(AlertType alertType, long dataCenterId, Long podId, String msg) { + // TODO Auto-generated method stub + return false; + } + } diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql index 45f874cfca5..6fbe288c9e9 100644 --- a/setup/db/db/schema-421to430.sql +++ b/setup/db/db/schema-421to430.sql @@ -799,3 +799,7 @@ CREATE TABLE `cloud`.`network_acl_item_details` ( PRIMARY KEY (`id`), CONSTRAINT `fk_network_acl_item_details__network_acl_item_id` FOREIGN KEY `fk_network_acl_item_details__network_acl_item_id`(`network_acl_item_id`) REFERENCES `network_acl_item`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +ALTER TABLE `cloud`.`alert` ADD COLUMN `name` varchar(255) DEFAULT NULL COMMENT 'name of the alert'; + diff --git a/usage/src/com/cloud/usage/UsageAlertManagerImpl.java b/usage/src/com/cloud/usage/UsageAlertManagerImpl.java index 640adb9d6ad..0f86e857c5a 100644 --- a/usage/src/com/cloud/usage/UsageAlertManagerImpl.java +++ b/usage/src/com/cloud/usage/UsageAlertManagerImpl.java @@ -32,20 +32,18 @@ import javax.mail.URLName; import javax.mail.internet.InternetAddress; import javax.naming.ConfigurationException; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.sun.mail.smtp.SMTPMessage; -import com.sun.mail.smtp.SMTPSSLTransport; -import com.sun.mail.smtp.SMTPTransport; - -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; - import com.cloud.alert.AlertManager; import com.cloud.alert.AlertVO; import com.cloud.alert.dao.AlertDao; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.ManagerBase; +import com.sun.mail.smtp.SMTPMessage; +import com.sun.mail.smtp.SMTPSSLTransport; +import com.sun.mail.smtp.SMTPTransport; @Component @Local(value = {AlertManager.class}) @@ -88,10 +86,10 @@ public class UsageAlertManagerImpl extends ManagerBase implements AlertManager { } @Override - public void clearAlert(short alertType, long dataCenterId, long podId) { + public void clearAlert(AlertType alertType, long dataCenterId, long podId) { try { if (_emailAlert != null) { - _emailAlert.clearAlert(alertType, dataCenterId, podId); + _emailAlert.clearAlert(alertType.getType(), dataCenterId, podId); } } catch (Exception ex) { s_logger.error("Problem clearing email alert", ex); @@ -99,7 +97,7 @@ public class UsageAlertManagerImpl extends ManagerBase implements AlertManager { } @Override - public void sendAlert(short alertType, long dataCenterId, Long podId, String subject, String body) { + public void sendAlert(AlertType alertType, long dataCenterId, Long podId, String subject, String body) { // TODO: queue up these messages and send them as one set of issues once a certain number of issues is reached? If that's the case, // shouldn't we have a type/severity as part of the API so that severe errors get sent right away? try { @@ -177,25 +175,30 @@ public class UsageAlertManagerImpl extends ManagerBase implements AlertManager { } // TODO: make sure this handles SSL transport (useAuth is true) and regular - public void sendAlert(short alertType, long dataCenterId, Long podId, String subject, String content) throws MessagingException, UnsupportedEncodingException { - s_alertsLogger.warn(" alertType:: " + alertType + " // dataCenterId:: " + dataCenterId + " // podId:: " + podId + " // clusterId:: " + null + - " // message:: " + subject); + protected void sendAlert(AlertType alertType, long dataCenterId, Long podId, String subject, String content) throws MessagingException, UnsupportedEncodingException { + s_alertsLogger.warn(" alertType:: " + alertType + " // dataCenterId:: " + dataCenterId + " // podId:: " + + podId + " // clusterId:: " + null + " // message:: " + subject); AlertVO alert = null; - if ((alertType != AlertManager.ALERT_TYPE_HOST) && (alertType != AlertManager.ALERT_TYPE_USERVM) && (alertType != AlertManager.ALERT_TYPE_DOMAIN_ROUTER) && - (alertType != AlertManager.ALERT_TYPE_CONSOLE_PROXY) && (alertType != AlertManager.ALERT_TYPE_SSVM) && - (alertType != AlertManager.ALERT_TYPE_STORAGE_MISC) && (alertType != AlertManager.ALERT_TYPE_MANAGMENT_NODE)) { - alert = _alertDao.getLastAlert(alertType, dataCenterId, podId); + if ((alertType != AlertManager.AlertType.ALERT_TYPE_HOST) && + (alertType != AlertManager.AlertType.ALERT_TYPE_USERVM) && + (alertType != AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER) && + (alertType != AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY) && + (alertType != AlertManager.AlertType.ALERT_TYPE_SSVM) && + (alertType != AlertManager.AlertType.ALERT_TYPE_STORAGE_MISC) && + (alertType != AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE)) { + alert = _alertDao.getLastAlert(alertType.getType(), dataCenterId, podId); } if (alert == null) { // set up a new alert AlertVO newAlert = new AlertVO(); - newAlert.setType(alertType); + newAlert.setType(alertType.getType()); newAlert.setSubject(subject); newAlert.setPodId(podId); newAlert.setDataCenterId(dataCenterId); newAlert.setSentCount(1); // initialize sent count to 1 since we are now sending an alert newAlert.setLastSent(new Date()); + newAlert.setName(alertType.getName()); _alertDao.persist(newAlert); } else { if (s_logger.isDebugEnabled()) { @@ -245,4 +248,16 @@ public class UsageAlertManagerImpl extends ManagerBase implements AlertManager { // TODO Auto-generated method stub } + + + @Override + public boolean generateAlert(AlertType alertType, long dataCenterId, Long podId, String msg) { + try { + sendAlert(alertType, dataCenterId, podId, msg, msg); + return true; + } catch (Exception ex) { + s_logger.warn("Failed to generate an alert of type=" + alertType + "; msg=" + msg); + return false; + } + } } diff --git a/usage/src/com/cloud/usage/UsageManagerImpl.java b/usage/src/com/cloud/usage/UsageManagerImpl.java index 3da7d48618a..b6c9ea6d064 100644 --- a/usage/src/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/com/cloud/usage/UsageManagerImpl.java @@ -818,10 +818,10 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna // switch back to CLOUD_DB TransactionLegacy swap = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); if (!success) { - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USAGE_SERVER_RESULT, 0, new Long(0), "Usage job failed. Job id: " + job.getId(), + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USAGE_SERVER_RESULT, 0, new Long(0), "Usage job failed. Job id: " + job.getId(), "Usage job failed. Job id: " + job.getId()); } else { - _alertMgr.clearAlert(AlertManager.ALERT_TYPE_USAGE_SERVER_RESULT, 0, 0); + _alertMgr.clearAlert(AlertManager.AlertType.ALERT_TYPE_USAGE_SERVER_RESULT, 0, 0); } swap.close(); @@ -1863,9 +1863,9 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna try { String errors = usc.runSanityCheck(); if (errors.length() > 0) { - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USAGE_SANITY_RESULT, 0, new Long(0), "Usage Sanity Check failed", errors); + _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USAGE_SANITY_RESULT, 0, new Long(0), "Usage Sanity Check failed", errors); } else { - _alertMgr.clearAlert(AlertManager.ALERT_TYPE_USAGE_SANITY_RESULT, 0, 0); + _alertMgr.clearAlert(AlertManager.AlertType.ALERT_TYPE_USAGE_SANITY_RESULT, 0, 0); } } catch (SQLException e) { s_logger.error("Error in sanity check", e); From b0a1528c5a73271ed862e307c9d43a8e6766158d Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Wed, 4 Dec 2013 11:01:33 -0800 Subject: [PATCH 105/170] CLOUDSTACK-5349: Volume create usage event and resource count werent getting registered. Check its type rather than it is UserVm since the code is coming from VirtualMachineManager. --- .../orchestration/VolumeOrchestrator.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java index fdc2d2393e3..a10dc66650e 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java @@ -524,10 +524,17 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati vol = _volsDao.persist(vol); // Save usage event and update resource count for user vm volumes - if (vm instanceof UserVm) { - - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), - null, size, Volume.class.getName(), vol.getUuid()); + if (vm.getType() == VirtualMachine.Type.User) { + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, + vol.getAccountId(), + vol.getDataCenterId(), + vol.getId(), + vol.getName(), + offering.getId(), + null, + size, + Volume.class.getName(), + vol.getUuid()); _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume); _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, new Long(vol.getSize())); @@ -564,7 +571,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati vol = _volsDao.persist(vol); // Create event and update resource count for volumes if vm is a user vm - if (vm instanceof UserVm) { + if (vm.getType() == VirtualMachine.Type.User) { Long offeringId = null; From f1973340d30042ae39c7465adfbc5a9537b3e3fa Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Wed, 4 Dec 2013 11:36:33 -0800 Subject: [PATCH 106/170] CLOUDSTACK-5152: when deployVm with SG, verify that vm and sg belong to the same account. Do this verification even when the call is done by the ROOT admin Conflicts: server/src/com/cloud/user/AccountManagerImpl.java --- .../com/cloud/user/AccountManagerImpl.java | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index 43dd622dc8c..fa441ae65dd 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -39,7 +39,6 @@ import javax.naming.ConfigurationException; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; - import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.acl.SecurityChecker; @@ -55,6 +54,8 @@ import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationSe import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.region.gslb.GlobalLoadBalancerRuleDao; +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; import com.cloud.api.ApiDBUtils; import com.cloud.api.query.vo.ControlledViewEntity; @@ -380,6 +381,22 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Override public void checkAccess(Account caller, AccessType accessType, boolean sameOwner, ControlledEntity... entities) { + + //check for the same owner + Long ownerId = null; + ControlledEntity prevEntity = null; + if (sameOwner) { + for (ControlledEntity entity : entities) { + if (sameOwner) { + if (ownerId == null) { + ownerId = entity.getAccountId(); + } else if (ownerId.longValue() != entity.getAccountId()) { + throw new PermissionDeniedException("Entity " + entity + " and entity " + prevEntity + " belong to different accounts"); + } + prevEntity = entity; + } + } + } if (caller.getId() == Account.ACCOUNT_ID_SYSTEM || isRootAdmin(caller.getType())) { // no need to make permission checks if the system/root admin makes the call @@ -390,13 +407,11 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } HashMap> domains = new HashMap>(); - Long ownerId = null; - ControlledEntity prevEntity = null; for (ControlledEntity entity : entities) { long domainId = entity.getDomainId(); if (entity.getAccountId() != -1 && domainId == -1) { // If account exists domainId should too so calculate -// it. This condition might be hit for templates or entities which miss domainId in their tables + // it. This condition might be hit for templates or entities which miss domainId in their tables Account account = ApiDBUtils.findAccountById(entity.getAccountId()); domainId = account != null ? account.getDomainId() : -1; } @@ -421,15 +436,6 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } } - if (sameOwner) { - if (ownerId == null) { - ownerId = entity.getAccountId(); - } else if (ownerId.longValue() != entity.getAccountId()) { - throw new PermissionDeniedException("Entity " + entity + " and entity " + prevEntity + " belong to different accounts"); - } - prevEntity = entity; - } - if (!granted) { assert false : "How can all of the security checkers pass on checking this check: " + entity; throw new PermissionDeniedException("There's no way to confirm " + caller + " has access to " + entity); From 4e7487366968578f5e9418c92208f12b5775580b Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Wed, 4 Dec 2013 14:10:24 -0800 Subject: [PATCH 107/170] CLOUDSTACK-5200: UI > Infrastructure > Sockets > listView > fix a bug that Hosts and Sockets displayed wrong number. --- ui/scripts/system.js | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 0d8784f5006..cdece2fdf68 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -392,19 +392,22 @@ var currentPage = 1; var returnedHostCount = 0; var returnedHostCpusocketsSum = 0; - var returnedHostHavingCpusockets = true; - + var callListHostsWithPage = function(setTotalHostCount) { $.ajax({ url: createURL('listHosts'), async: false, data: { type: 'routing', - hypervisortype: hypervisor.name, + hypervisor: hypervisor.name, page: currentPage, pagesize: pageSize //global variable }, - success: function(json) { + success: function(json) { + if (json.listhostsresponse.count == undefined) { + return; + } + if (setTotalHostCount) { totalHostCount = json.listhostsresponse.count; } @@ -414,9 +417,7 @@ for (var i = 0; i < items.length; i++) { if (items[i].cpusockets != undefined && isNaN(items[i].cpusockets) == false) { returnedHostCpusocketsSum += items[i].cpusockets; - } else { - returnedHostHavingCpusockets = false; - } + } } if (returnedHostCount < totalHostCount) { @@ -428,10 +429,8 @@ } callListHostsWithPage(true); - - if (returnedHostHavingCpusockets) { - socketCount += returnedHostCpusocketsSum; - } + + socketCount += returnedHostCpusocketsSum; }) }); } @@ -7496,19 +7495,22 @@ var currentPage = 1; var returnedHostCount = 0; var returnedHostCpusocketsSum = 0; - var returnedHostHavingCpusockets = true; - + var callListHostsWithPage = function(setTotalHostCount) { $.ajax({ url: createURL('listHosts'), async: false, data: { type: 'routing', - hypervisortype: hypervisor.name, + hypervisor: hypervisor.name, page: currentPage, pagesize: pageSize //global variable }, - success: function(json) { + success: function(json) { + if (json.listhostsresponse.count == undefined) { + return; + } + if (setTotalHostCount) { totalHostCount = json.listhostsresponse.count; } @@ -7518,9 +7520,7 @@ for (var i = 0; i < items.length; i++) { if (items[i].cpusockets != undefined && isNaN(items[i].cpusockets) == false) { returnedHostCpusocketsSum += items[i].cpusockets; - } else { - returnedHostHavingCpusockets = false; - } + } } if (returnedHostCount < totalHostCount) { @@ -7532,11 +7532,11 @@ } callListHostsWithPage(true); - + return { hypervisor: hypervisor.name, hosts: totalHostCount, - sockets: (returnedHostHavingCpusockets? returnedHostCpusocketsSum : 'unknown') + sockets: returnedHostCpusocketsSum }; }) }); From 71d547ba875c1a7d936710512464a4343c66f28b Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Wed, 4 Dec 2013 14:53:28 -0800 Subject: [PATCH 108/170] CLOUDSTACK-5352: CPU cap calculated incorrectly for VMs on XenServer hosts. It should not be limited by the overprovisioning and should set the cap as service offering --- .../com/cloud/hypervisor/xen/resource/CitrixResourceBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 2a5913ab34f..5d172902e62 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -1361,7 +1361,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (vmSpec.getLimitCpuUse()) { // CPU cap is per VM, so need to assign cap based on the number of vcpus - utilization = (int)((speed * 0.99 * vmSpec.getCpus()) / _host.speed * 100); + utilization = (int) ((vmSpec.getMaxSpeed() * 0.99 * vmSpec.getCpus()) / _host.speed * 100); } vcpuParams.put("weight", Integer.toString(cpuWeight)); From 15c30059435667162c71b3cd1e3514bd378df8c6 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Wed, 4 Dec 2013 14:54:22 -0800 Subject: [PATCH 109/170] CLOUDSTACK-5139: UI > Infrastructure > Secondary Storage > Add Secondary Storage > providers dropdown - hardcode options instead of get them from listStorageProviders&type=image since not all of returned values are handled by UI (e.g. "NetApp" is not handled by UI). --- ui/scripts/system.js | 300 +++++++++++++++++++++---------------------- 1 file changed, 147 insertions(+), 153 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index cdece2fdf68..641ca9654d8 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -15660,171 +15660,165 @@ provider: { label: 'Provider', select: function(args) { - $.ajax({ - url: createURL('listStorageProviders'), - data: { - type: 'image' - }, - success: function(json) { - var objs = json.liststorageprovidersresponse.dataStoreProvider; - //var items = []; - var items = [{id: 'SMB', description: 'SMB/cifs'}]; //temporary, before Rajesh adds 'SMB' to listStorageProviders API response. - if (objs != null) { - for (var i = 0; i < objs.length; i++) { - if (objs[i].name == 'NFS') - items.unshift({ - id: objs[i].name, - description: objs[i].name - }); - else - items.push({ - id: objs[i].name, - description: objs[i].name - }); - } - } - args.response.success({ - data: items - }); + /* + UI no longer gets providers from "listStorageProviders&type=image" because: + (1) Not all of returned values are handled by UI (e.g. Provider "NetApp" is not handled by UI). + (2) Provider "SMB" which is handled by UI is not returned from "listStorageProviders&type=image" + */ + var items = [{ + id: 'NFS', + description: 'NFS' + }, { + id: 'SMB', + description: 'SMB/cifs' + }, { + id: 'S3', + description: 'S3' + }, { + id: 'Swift', + description: 'Swift' + }]; + + args.response.success({ + data: items + }); - args.$select.change(function() { - var $form = $(this).closest('form'); - if ($(this).val() == "NFS") { - //NFS, SMB - $form.find('.form-item[rel=zoneid]').css('display', 'inline-block'); - $form.find('.form-item[rel=nfsServer]').css('display', 'inline-block'); - $form.find('.form-item[rel=path]').css('display', 'inline-block'); - - //SMB - $form.find('.form-item[rel=smbUsername]').hide(); - $form.find('.form-item[rel=smbPassword]').hide(); - $form.find('.form-item[rel=smbDomain]').hide(); - - //S3 - $form.find('.form-item[rel=accesskey]').hide(); - $form.find('.form-item[rel=secretkey]').hide(); - $form.find('.form-item[rel=bucket]').hide(); - $form.find('.form-item[rel=endpoint]').hide(); - $form.find('.form-item[rel=usehttps]').hide(); - $form.find('.form-item[rel=connectiontimeout]').hide(); - $form.find('.form-item[rel=maxerrorretry]').hide(); - $form.find('.form-item[rel=sockettimeout]').hide(); + args.$select.change(function() { + var $form = $(this).closest('form'); + if ($(this).val() == "NFS") { + //NFS, SMB + $form.find('.form-item[rel=zoneid]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsServer]').css('display', 'inline-block'); + $form.find('.form-item[rel=path]').css('display', 'inline-block'); + + //SMB + $form.find('.form-item[rel=smbUsername]').hide(); + $form.find('.form-item[rel=smbPassword]').hide(); + $form.find('.form-item[rel=smbDomain]').hide(); + + //S3 + $form.find('.form-item[rel=accesskey]').hide(); + $form.find('.form-item[rel=secretkey]').hide(); + $form.find('.form-item[rel=bucket]').hide(); + $form.find('.form-item[rel=endpoint]').hide(); + $form.find('.form-item[rel=usehttps]').hide(); + $form.find('.form-item[rel=connectiontimeout]').hide(); + $form.find('.form-item[rel=maxerrorretry]').hide(); + $form.find('.form-item[rel=sockettimeout]').hide(); - $form.find('.form-item[rel=createNfsCache]').find('input').removeAttr('checked'); - $form.find('.form-item[rel=createNfsCache]').hide(); - $form.find('.form-item[rel=nfsCacheZoneid]').hide(); - $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); - $form.find('.form-item[rel=nfsCachePath]').hide(); + $form.find('.form-item[rel=createNfsCache]').find('input').removeAttr('checked'); + $form.find('.form-item[rel=createNfsCache]').hide(); + $form.find('.form-item[rel=nfsCacheZoneid]').hide(); + $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); + $form.find('.form-item[rel=nfsCachePath]').hide(); - //Swift - $form.find('.form-item[rel=url]').hide(); - $form.find('.form-item[rel=account]').hide(); - $form.find('.form-item[rel=username]').hide(); - $form.find('.form-item[rel=key]').hide(); - } else if ($(this).val() == "SMB") { - //NFS, SMB - $form.find('.form-item[rel=zoneid]').css('display', 'inline-block'); - $form.find('.form-item[rel=nfsServer]').css('display', 'inline-block'); - $form.find('.form-item[rel=path]').css('display', 'inline-block'); - - //SMB - $form.find('.form-item[rel=smbUsername]').css('display', 'inline-block'); - $form.find('.form-item[rel=smbPassword]').css('display', 'inline-block'); - $form.find('.form-item[rel=smbDomain]').css('display', 'inline-block'); - - //S3 - $form.find('.form-item[rel=accesskey]').hide(); - $form.find('.form-item[rel=secretkey]').hide(); - $form.find('.form-item[rel=bucket]').hide(); - $form.find('.form-item[rel=endpoint]').hide(); - $form.find('.form-item[rel=usehttps]').hide(); - $form.find('.form-item[rel=connectiontimeout]').hide(); - $form.find('.form-item[rel=maxerrorretry]').hide(); - $form.find('.form-item[rel=sockettimeout]').hide(); + //Swift + $form.find('.form-item[rel=url]').hide(); + $form.find('.form-item[rel=account]').hide(); + $form.find('.form-item[rel=username]').hide(); + $form.find('.form-item[rel=key]').hide(); + } else if ($(this).val() == "SMB") { + //NFS, SMB + $form.find('.form-item[rel=zoneid]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsServer]').css('display', 'inline-block'); + $form.find('.form-item[rel=path]').css('display', 'inline-block'); + + //SMB + $form.find('.form-item[rel=smbUsername]').css('display', 'inline-block'); + $form.find('.form-item[rel=smbPassword]').css('display', 'inline-block'); + $form.find('.form-item[rel=smbDomain]').css('display', 'inline-block'); + + //S3 + $form.find('.form-item[rel=accesskey]').hide(); + $form.find('.form-item[rel=secretkey]').hide(); + $form.find('.form-item[rel=bucket]').hide(); + $form.find('.form-item[rel=endpoint]').hide(); + $form.find('.form-item[rel=usehttps]').hide(); + $form.find('.form-item[rel=connectiontimeout]').hide(); + $form.find('.form-item[rel=maxerrorretry]').hide(); + $form.find('.form-item[rel=sockettimeout]').hide(); - $form.find('.form-item[rel=createNfsCache]').find('input').removeAttr('checked'); - $form.find('.form-item[rel=createNfsCache]').hide(); - $form.find('.form-item[rel=nfsCacheZoneid]').hide(); - $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); - $form.find('.form-item[rel=nfsCachePath]').hide(); + $form.find('.form-item[rel=createNfsCache]').find('input').removeAttr('checked'); + $form.find('.form-item[rel=createNfsCache]').hide(); + $form.find('.form-item[rel=nfsCacheZoneid]').hide(); + $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); + $form.find('.form-item[rel=nfsCachePath]').hide(); - //Swift - $form.find('.form-item[rel=url]').hide(); - $form.find('.form-item[rel=account]').hide(); - $form.find('.form-item[rel=username]').hide(); - $form.find('.form-item[rel=key]').hide(); - } else if ($(this).val() == "S3") { - //NFS, SMB - $form.find('.form-item[rel=zoneid]').hide(); - $form.find('.form-item[rel=nfsServer]').hide(); - $form.find('.form-item[rel=path]').hide(); - - //SMB - $form.find('.form-item[rel=smbUsername]').hide(); - $form.find('.form-item[rel=smbPassword]').hide(); - $form.find('.form-item[rel=smbDomain]').hide(); - - //S3 - $form.find('.form-item[rel=accesskey]').css('display', 'inline-block'); - $form.find('.form-item[rel=secretkey]').css('display', 'inline-block'); - $form.find('.form-item[rel=bucket]').css('display', 'inline-block'); - $form.find('.form-item[rel=endpoint]').css('display', 'inline-block'); - $form.find('.form-item[rel=usehttps]').css('display', 'inline-block'); - $form.find('.form-item[rel=connectiontimeout]').css('display', 'inline-block'); - $form.find('.form-item[rel=maxerrorretry]').css('display', 'inline-block'); - $form.find('.form-item[rel=sockettimeout]').css('display', 'inline-block'); + //Swift + $form.find('.form-item[rel=url]').hide(); + $form.find('.form-item[rel=account]').hide(); + $form.find('.form-item[rel=username]').hide(); + $form.find('.form-item[rel=key]').hide(); + } else if ($(this).val() == "S3") { + //NFS, SMB + $form.find('.form-item[rel=zoneid]').hide(); + $form.find('.form-item[rel=nfsServer]').hide(); + $form.find('.form-item[rel=path]').hide(); + + //SMB + $form.find('.form-item[rel=smbUsername]').hide(); + $form.find('.form-item[rel=smbPassword]').hide(); + $form.find('.form-item[rel=smbDomain]').hide(); + + //S3 + $form.find('.form-item[rel=accesskey]').css('display', 'inline-block'); + $form.find('.form-item[rel=secretkey]').css('display', 'inline-block'); + $form.find('.form-item[rel=bucket]').css('display', 'inline-block'); + $form.find('.form-item[rel=endpoint]').css('display', 'inline-block'); + $form.find('.form-item[rel=usehttps]').css('display', 'inline-block'); + $form.find('.form-item[rel=connectiontimeout]').css('display', 'inline-block'); + $form.find('.form-item[rel=maxerrorretry]').css('display', 'inline-block'); + $form.find('.form-item[rel=sockettimeout]').css('display', 'inline-block'); - $form.find('.form-item[rel=createNfsCache]').find('input').attr('checked', 'checked'); - $form.find('.form-item[rel=createNfsCache]').find('input').attr('disabled', 'disabled'); //Create NFS staging is required for S3 at this moment. So, disallow user to uncheck "Create NFS Secondary Staging" checkbox - $form.find('.form-item[rel=createNfsCache]').css('display', 'inline-block'); - $form.find('.form-item[rel=nfsCacheZoneid]').css('display', 'inline-block'); - $form.find('.form-item[rel=nfsCacheNfsServer]').css('display', 'inline-block'); - $form.find('.form-item[rel=nfsCachePath]').css('display', 'inline-block'); + $form.find('.form-item[rel=createNfsCache]').find('input').attr('checked', 'checked'); + $form.find('.form-item[rel=createNfsCache]').find('input').attr('disabled', 'disabled'); //Create NFS staging is required for S3 at this moment. So, disallow user to uncheck "Create NFS Secondary Staging" checkbox + $form.find('.form-item[rel=createNfsCache]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsCacheZoneid]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsCacheNfsServer]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsCachePath]').css('display', 'inline-block'); - //Swift - $form.find('.form-item[rel=url]').hide(); - $form.find('.form-item[rel=account]').hide(); - $form.find('.form-item[rel=username]').hide(); - $form.find('.form-item[rel=key]').hide(); - } else if ($(this).val() == "Swift") { - //NFS, SMB - $form.find('.form-item[rel=zoneid]').hide(); - $form.find('.form-item[rel=nfsServer]').hide(); - $form.find('.form-item[rel=path]').hide(); - - //SMB - $form.find('.form-item[rel=smbUsername]').hide(); - $form.find('.form-item[rel=smbPassword]').hide(); - $form.find('.form-item[rel=smbDomain]').hide(); - - //S3 - $form.find('.form-item[rel=accesskey]').hide(); - $form.find('.form-item[rel=secretkey]').hide(); - $form.find('.form-item[rel=bucket]').hide(); - $form.find('.form-item[rel=endpoint]').hide(); - $form.find('.form-item[rel=usehttps]').hide(); - $form.find('.form-item[rel=connectiontimeout]').hide(); - $form.find('.form-item[rel=maxerrorretry]').hide(); - $form.find('.form-item[rel=sockettimeout]').hide(); + //Swift + $form.find('.form-item[rel=url]').hide(); + $form.find('.form-item[rel=account]').hide(); + $form.find('.form-item[rel=username]').hide(); + $form.find('.form-item[rel=key]').hide(); + } else if ($(this).val() == "Swift") { + //NFS, SMB + $form.find('.form-item[rel=zoneid]').hide(); + $form.find('.form-item[rel=nfsServer]').hide(); + $form.find('.form-item[rel=path]').hide(); + + //SMB + $form.find('.form-item[rel=smbUsername]').hide(); + $form.find('.form-item[rel=smbPassword]').hide(); + $form.find('.form-item[rel=smbDomain]').hide(); + + //S3 + $form.find('.form-item[rel=accesskey]').hide(); + $form.find('.form-item[rel=secretkey]').hide(); + $form.find('.form-item[rel=bucket]').hide(); + $form.find('.form-item[rel=endpoint]').hide(); + $form.find('.form-item[rel=usehttps]').hide(); + $form.find('.form-item[rel=connectiontimeout]').hide(); + $form.find('.form-item[rel=maxerrorretry]').hide(); + $form.find('.form-item[rel=sockettimeout]').hide(); - $form.find('.form-item[rel=createNfsCache]').find('input').removeAttr('checked'); - $form.find('.form-item[rel=createNfsCache]').hide(); - $form.find('.form-item[rel=nfsCacheZoneid]').hide(); - $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); - $form.find('.form-item[rel=nfsCachePath]').hide(); + $form.find('.form-item[rel=createNfsCache]').find('input').removeAttr('checked'); + $form.find('.form-item[rel=createNfsCache]').hide(); + $form.find('.form-item[rel=nfsCacheZoneid]').hide(); + $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); + $form.find('.form-item[rel=nfsCachePath]').hide(); - //Swift - $form.find('.form-item[rel=url]').css('display', 'inline-block'); - $form.find('.form-item[rel=account]').css('display', 'inline-block'); - $form.find('.form-item[rel=username]').css('display', 'inline-block'); - $form.find('.form-item[rel=key]').css('display', 'inline-block'); - } - }); - - args.$select.change(); + //Swift + $form.find('.form-item[rel=url]').css('display', 'inline-block'); + $form.find('.form-item[rel=account]').css('display', 'inline-block'); + $form.find('.form-item[rel=username]').css('display', 'inline-block'); + $form.find('.form-item[rel=key]').css('display', 'inline-block'); } }); + + args.$select.change(); } }, From 71323f15c66a71fa2276987dda690761149f6fc9 Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Wed, 4 Dec 2013 14:59:24 -0800 Subject: [PATCH 110/170] CLOUDSTACK-5352: CPU cap calculated incorrectly for VMs on XenServer hosts. It should not be limited by the overprovisioning and should set the cap as service offering --- .../com/cloud/hypervisor/xen/resource/CitrixResourceBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 5d172902e62..ec62c251279 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -689,7 +689,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (vmSpec.getLimitCpuUse()) { long utilization = 0; // max CPU cap, default is unlimited - utilization = (int)((speed * 0.99 * vmSpec.getCpus()) / _host.speed * 100); + utilization = (int) ((vmSpec.getMaxSpeed() * 0.99 * vmSpec.getCpus()) / _host.speed * 100); //vm.addToVCPUsParamsLive(conn, "cap", Long.toString(utilization)); currently xenserver doesnot support Xapi to add VCPUs params live. callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "cap", "value", Long.toString(utilization), "vmname", vmSpec.getName()); } From 9a0de4333424fd23cc3e5e7059bec0787bf57990 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Wed, 4 Dec 2013 15:01:38 -0800 Subject: [PATCH 111/170] CLOUDSTACK-5139: UI > zone wizard > secondary storage step > providers dropdown - hardcode options instead of get them from listStorageProviders&type=image since not all of returned values are handled by UI (e.g. "NetApp" is not handled by UI). --- ui/scripts/zoneWizard.js | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/ui/scripts/zoneWizard.js b/ui/scripts/zoneWizard.js index 42fa799d422..5437fe42d04 100755 --- a/ui/scripts/zoneWizard.js +++ b/ui/scripts/zoneWizard.js @@ -1838,25 +1838,15 @@ if(s3stores != null && s3stores.length > 0) { storageproviders.push({ id: 'S3', description: 'S3'}); //if (region-wide) S3 store exists already, only "S3" option should be included here. Any other type of store is not allowed to be created since cloudstack doesn't support multiple types of store at this point. } else { - $.ajax({ - url: createURL('listStorageProviders'), - data: { - type: 'image' - }, - async: false, - success: function(json) { - var objs = json.liststorageprovidersresponse.dataStoreProvider; - if (objs != null) { - for (var i = 0; i < objs.length; i++) { - storageproviders.push({ - id: objs[i].name, - description: objs[i].name - }); - } - } - } - }); - storageproviders.push({ id: 'SMB', description: 'SMB/cifs'}); //temporary, before Rajesh adds 'SMB' to listStorageProviders API response. + /* + UI no longer gets providers from "listStorageProviders&type=image" because: + (1) Not all of returned values are handled by UI (e.g. Provider "NetApp" is not handled by UI). + (2) Provider "SMB" which is handled by UI is not returned from "listStorageProviders&type=image" + */ + storageproviders.push({ id: 'NFS', description: 'NFS'}); + storageproviders.push({ id: 'SMB', description: 'SMB/cifs'}); + storageproviders.push({ id: 'S3', description: 'S3'}); + storageproviders.push({ id: 'Swift', description: 'Swift'}); } args.response.success({ data: storageproviders From fd195433ae4779dd05079b063532ba71850f20bb Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Wed, 4 Dec 2013 16:12:42 -0800 Subject: [PATCH 112/170] fixing the test --- .../cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/hypervisors/xen/test/com/cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java b/plugins/hypervisors/xen/test/com/cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java index 788ad5a0cee..c56cc6d9e25 100644 --- a/plugins/hypervisors/xen/test/com/cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java +++ b/plugins/hypervisors/xen/test/com/cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java @@ -158,6 +158,7 @@ public class CitrixResourceBaseTest { doReturn(1).when(vmSpec).getCpus(); doNothing().when(vm).setVCPUsNumberLive(conn, 1L); doReturn(500).when(vmSpec).getMinSpeed(); + doReturn(500).when(vmSpec).getMaxSpeed(); doReturn(true).when(vmSpec).getLimitCpuUse(); doReturn(null).when(_resource).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "cap", "value", "99", "vmname", "i-2-3-VM"); Map args = mock(HashMap.class); From 0b16a45ceb330233866f78129f16a39dc82c6397 Mon Sep 17 00:00:00 2001 From: Rajesh Battala Date: Thu, 5 Dec 2013 11:10:13 +0530 Subject: [PATCH 113/170] Modified savepassword.sh path in Hyperv Resource according to the new template --- .../hyperv/resource/HypervDirectConnectResource.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java index e6a5f62a33a..f61e5ff4401 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java @@ -930,15 +930,14 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S String args = " -v " + vmIpAddress; if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domain router " + controlIp + ", /root/savepassword.sh " + args + " -p " + - StringUtils.getMaskedPasswordForDisplay(cmd.getPassword())); + s_logger.debug("Run command on domain router " + controlIp + ", /opt/cloud/bin/savepassword.sh " + args + " -p " + StringUtils.getMaskedPasswordForDisplay(cmd.getPassword())); } args += " -p " + password; try { - Pair result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/savepassword.sh " + args); + Pair result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/savepassword.sh " + args); if (!result.first()) { s_logger.error("savepassword command on domain router " + controlIp + " failed, message: " + result.second()); From 50c93777741c2d6e006cbbee40597c12050a4847 Mon Sep 17 00:00:00 2001 From: Rajesh Battala Date: Thu, 5 Dec 2013 11:59:59 +0530 Subject: [PATCH 114/170] CLOUDSTACK-5312 added hyperv support in seeding the systemvm template script --- scripts/storage/secondary/cloud-install-sys-tmplt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/storage/secondary/cloud-install-sys-tmplt b/scripts/storage/secondary/cloud-install-sys-tmplt index 2e822f3504c..96b11de41d4 100755 --- a/scripts/storage/secondary/cloud-install-sys-tmplt +++ b/scripts/storage/secondary/cloud-install-sys-tmplt @@ -20,9 +20,9 @@ usage() { - printf "Usage: %s: -m -f [-h ] [ -s ][-u ] [-F ] [-e