Repository: cloudstack
Updated Branches:
  refs/heads/master 8c671c49b -> 0a4ab3251


CLOUDSTACK-7513: listServiceOfferings API when called with VM's id also returns 
offerings to which it cant be upgraded. Adding the logic that when vmid is 
passed it looks for compatible offerngs using the storage type (local/shares), 
storage tags and also compute (cpu,speed, memory) in case the vm is running.
Also changed the scaleVm API to upgrade only when the destination offering has 
storage tags as a subset of current offering tags.


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/0a4ab325
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/0a4ab325
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/0a4ab325

Branch: refs/heads/master
Commit: 0a4ab3251a4974317e6a4597cbd9cb3ee2be3666
Parents: 8c671c4
Author: Nitin Mehta <[email protected]>
Authored: Mon Sep 15 11:02:34 2014 -0700
Committer: Nitin Mehta <[email protected]>
Committed: Mon Sep 15 11:02:34 2014 -0700

----------------------------------------------------------------------
 .../com/cloud/vm/VirtualMachineManagerImpl.java |  8 ++--
 .../com/cloud/api/query/QueryManagerImpl.java   | 48 +++++++++++++++-----
 2 files changed, 41 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0a4ab325/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git 
a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java 
b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
index 0e12bcb..f7adcf8 100755
--- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -2764,12 +2764,12 @@ public class VirtualMachineManagerImpl extends 
ManagerBase implements VirtualMac
                     newServiceOffering.getCpu() + " cpu(s) at " + 
newServiceOffering.getSpeed() + " Mhz, and " + newServiceOffering.getRamSize() 
+ " MB of memory");
         }
 
-        // Check that the service offering being upgraded to has all the tags 
of the current service offering
+        // Check that the service offering being upgraded to has storage tags 
subset of the current service offering storage tags, since volume is not 
migrated.
         List<String> currentTags = 
StringUtils.csvTagsToList(currentServiceOffering.getTags());
         List<String> newTags = 
StringUtils.csvTagsToList(newServiceOffering.getTags());
-        if (!newTags.containsAll(currentTags)) {
-            throw new InvalidParameterValueException("Unable to upgrade 
virtual machine; the new service offering " + "does not have all the tags of 
the " +
-                    "current service offering. Current service offering tags: 
" + currentTags + "; " + "new service " + "offering tags: " + newTags);
+        if (!currentTags.containsAll(newTags)) {
+            throw new InvalidParameterValueException("Unable to upgrade 
virtual machine; the new service offering " + " should have tags as subset of " 
+
+                    "current service offering tags. Current service offering 
tags: " + currentTags + "; " + "new service " + "offering tags: " + newTags);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0a4ab325/server/src/com/cloud/api/query/QueryManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java 
b/server/src/com/cloud/api/query/QueryManagerImpl.java
index 2156b0f..4f775fc 100644
--- a/server/src/com/cloud/api/query/QueryManagerImpl.java
+++ b/server/src/com/cloud/api/query/QueryManagerImpl.java
@@ -26,6 +26,7 @@ import java.util.Set;
 import javax.ejb.Local;
 import javax.inject.Inject;
 
+import com.cloud.utils.StringUtils;
 import org.apache.cloudstack.acl.ControlledEntity.ACLType;
 import org.apache.cloudstack.affinity.AffinityGroupDomainMapVO;
 import org.apache.cloudstack.affinity.AffinityGroupResponse;
@@ -2507,9 +2508,25 @@ public class QueryManagerImpl extends ManagerBase 
implements QueryService {
         return _diskOfferingJoinDao.searchAndCount(sc, searchFilter);
     }
 
+    private List<ServiceOfferingJoinVO> 
filterOfferingsOnCurrentTags(List<ServiceOfferingJoinVO> offerings, 
ServiceOfferingVO currentVmOffering){
+        if(currentVmOffering == null) return offerings;
+        List<String> currentTagsList = 
StringUtils.csvTagsToList(currentVmOffering.getTags());
+
+        // New offerings should be a subset of existing storage tags. Discard 
offerings who are not.
+        List<ServiceOfferingJoinVO> filteredOfferings = new ArrayList<>();
+        for (ServiceOfferingJoinVO offering : offerings){
+            List<String> tags = StringUtils.csvTagsToList(offering.getTags());
+            if(currentTagsList.containsAll(tags)){
+                filteredOfferings.add(offering);
+            }
+        }
+        return filteredOfferings;
+    }
+
     @Override
     public ListResponse<ServiceOfferingResponse> 
searchForServiceOfferings(ListServiceOfferingsCmd cmd) {
         Pair<List<ServiceOfferingJoinVO>, Integer> result = 
searchForServiceOfferingsInternal(cmd);
+         result.first();
         ListResponse<ServiceOfferingResponse> response = new 
ListResponse<ServiceOfferingResponse>();
         List<ServiceOfferingResponse> offeringResponses =
             
ViewResponseHelper.createServiceOfferingResponse(result.first().toArray(new 
ServiceOfferingJoinVO[result.first().size()]));
@@ -2519,11 +2536,11 @@ public class QueryManagerImpl extends ManagerBase 
implements QueryService {
 
     private Pair<List<ServiceOfferingJoinVO>, Integer> 
searchForServiceOfferingsInternal(ListServiceOfferingsCmd cmd) {
         // Note
-        // The list method for offerings is being modified in accordance with
+        // The filteredOfferings method for offerings is being modified in 
accordance with
         // discussion with Will/Kevin
         // For now, we will be listing the following based on the usertype
-        // 1. For root, we will list all offerings
-        // 2. For domainAdmin and regular users, we will list everything in
+        // 1. For root, we will filteredOfferings all offerings
+        // 2. For domainAdmin and regular users, we will filteredOfferings 
everything in
         // their domains+parent domains ... all the way
         // till
         // root
@@ -2539,6 +2556,7 @@ public class QueryManagerImpl extends ManagerBase 
implements QueryService {
         Long domainId = cmd.getDomainId();
         Boolean isSystem = cmd.getIsSystem();
         String vmTypeStr = cmd.getSystemVmType();
+        ServiceOfferingVO currentVmOffering = null;
 
         SearchCriteria<ServiceOfferingJoinVO> sc = 
_srvOfferingJoinDao.createSearchCriteria();
         if (!_accountMgr.isRootAdmin(caller.getId()) && isSystem) {
@@ -2566,14 +2584,18 @@ public class QueryManagerImpl extends ManagerBase 
implements QueryService {
 
             _accountMgr.checkAccess(caller, null, true, vmInstance);
 
-            ServiceOfferingVO offering = 
_srvOfferingDao.findByIdIncludingRemoved(vmInstance.getId(), 
vmInstance.getServiceOfferingId());
-            sc.addAnd("id", SearchCriteria.Op.NEQ, offering.getId());
+            currentVmOffering = 
_srvOfferingDao.findByIdIncludingRemoved(vmInstance.getId(), 
vmInstance.getServiceOfferingId());
+            sc.addAnd("id", SearchCriteria.Op.NEQ, currentVmOffering.getId());
+
+            // 1. Only return offerings with the same storage type
+            sc.addAnd("useLocalStorage", SearchCriteria.Op.EQ, 
currentVmOffering.getUseLocalStorage());
 
-            // Only return offerings with the same Guest IP type and storage
-            // pool preference
-            // sc.addAnd("guestIpType", SearchCriteria.Op.EQ,
-            // offering.getGuestIpType());
-            sc.addAnd("useLocalStorage", SearchCriteria.Op.EQ, 
offering.getUseLocalStorage());
+            // 2.In case vm is running return only offerings greater than 
equal to current offering compute.
+            if(vmInstance.getState() == VirtualMachine.State.Running){
+                sc.addAnd("cpu", Op.GTEQ, currentVmOffering.getCpu());
+                sc.addAnd("speed", Op.GTEQ, currentVmOffering.getSpeed());
+                sc.addAnd("ramSize", Op.GTEQ, currentVmOffering.getRamSize());
+            }
         }
 
         // boolean includePublicOfferings = false;
@@ -2648,7 +2670,11 @@ public class QueryManagerImpl extends ManagerBase 
implements QueryService {
             sc.addAnd("vmType", SearchCriteria.Op.EQ, vmTypeStr);
         }
 
-        return _srvOfferingJoinDao.searchAndCount(sc, searchFilter);
+        Pair<List<ServiceOfferingJoinVO>, Integer> result = 
_srvOfferingJoinDao.searchAndCount(sc, searchFilter);
+
+        //Couldn't figure out a smart way to filter offerings based on tags in 
sql so doing it in Java.
+        List<ServiceOfferingJoinVO> filteredOfferings = 
filterOfferingsOnCurrentTags(result.first(), currentVmOffering);
+        return new Pair<>(filteredOfferings, result.second());
     }
 
     @Override

Reply via email to