cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From prachida...@apache.org
Subject [2/2] git commit: updated refs/heads/planner_reserve to 1959377
Date Wed, 24 Apr 2013 22:42:52 GMT
Adding new DeploymentClusterPlanner interface


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

Branch: refs/heads/planner_reserve
Commit: 1959377d302eefb31320b023d292be3ce2ca775b
Parents: 526c0cc
Author: Prachi Damle <prachi@cloud.com>
Authored: Wed Apr 24 15:40:39 2013 -0700
Committer: Prachi Damle <prachi@cloud.com>
Committed: Wed Apr 24 15:40:39 2013 -0700

----------------------------------------------------------------------
 .../com/cloud/deploy/DeploymentClusterPlanner.java |   45 ++++
 api/src/com/cloud/deploy/DeploymentPlanner.java    |    6 +
 .../deploy/DeploymentPlanningManagerImpl.java      |  192 ++++++++++++++-
 server/src/com/cloud/vm/UserVmManagerImpl.java     |    4 -
 4 files changed, 233 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1959377d/api/src/com/cloud/deploy/DeploymentClusterPlanner.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/deploy/DeploymentClusterPlanner.java b/api/src/com/cloud/deploy/DeploymentClusterPlanner.java
new file mode 100644
index 0000000..4d8ee74
--- /dev/null
+++ b/api/src/com/cloud/deploy/DeploymentClusterPlanner.java
@@ -0,0 +1,45 @@
+// 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.deploy;
+
+import java.util.List;
+import com.cloud.exception.InsufficientServerCapacityException;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+
+/**
+ */
+public interface DeploymentClusterPlanner extends DeploymentPlanner {
+    /**
+     * This is called to determine list of possible clusters where a virtual
+     * machine can be deployed.
+     *
+     * @param vm
+     *            virtual machine.
+     * @param plan
+     *            deployment plan that tells you where it's being deployed to.
+     * @param avoid
+     *            avoid these data centers, pods, clusters, or hosts.
+     * @return DeployDestination for that virtual machine.
+     */
+    List<Long> orderClusters(VirtualMachineProfile<? extends VirtualMachine>
vm, DeploymentPlan plan,
+            ExcludeList avoid) throws InsufficientServerCapacityException;
+
+
+    PlannerResourceUsage getResourceType();
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1959377d/api/src/com/cloud/deploy/DeploymentPlanner.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/deploy/DeploymentPlanner.java b/api/src/com/cloud/deploy/DeploymentPlanner.java
index 537dd31..a17fabe 100644
--- a/api/src/com/cloud/deploy/DeploymentPlanner.java
+++ b/api/src/com/cloud/deploy/DeploymentPlanner.java
@@ -35,6 +35,7 @@ import com.cloud.vm.VirtualMachineProfile;
 /**
  */
 public interface DeploymentPlanner extends Adapter {
+
     /**
      * plan is called to determine where a virtual machine should be running.
      *
@@ -46,6 +47,7 @@ public interface DeploymentPlanner extends Adapter {
      *            avoid these data centers, pods, clusters, or hosts.
      * @return DeployDestination for that virtual machine.
      */
+    @Deprecated
     DeployDestination plan(VirtualMachineProfile<? extends VirtualMachine> vm, DeploymentPlan
plan, ExcludeList avoid) throws InsufficientServerCapacityException;
 
     /**
@@ -88,6 +90,10 @@ public interface DeploymentPlanner extends Adapter {
         userconcentratedpod_firstfit;
     }
 
+    public enum PlannerResourceUsage {
+        Shared, Dedicated;
+    }
+
     public static class ExcludeList {
         private Set<Long> _dcIds;
         private Set<Long> _podIds;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1959377d/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
index c7162a2..e03ffb1 100644
--- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
+++ b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
@@ -17,9 +17,11 @@
 package com.cloud.deploy;
 
 import java.util.List;
+import java.util.Map;
 
 import javax.ejb.Local;
 import javax.inject.Inject;
+import javax.naming.ConfigurationException;
 
 import org.apache.cloudstack.affinity.AffinityGroupProcessor;
 import org.apache.cloudstack.affinity.AffinityGroupVMMapVO;
@@ -27,21 +29,44 @@ import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
 import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
 import org.apache.log4j.Logger;
 
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
 import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.deploy.DeploymentPlanner.PlannerResourceUsage;
+import com.cloud.deploy.dao.PlannerHostReservationDao;
 import com.cloud.exception.AffinityConflictException;
+import com.cloud.exception.ConnectionException;
 import com.cloud.exception.InsufficientServerCapacityException;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.security.SecurityGroupVO;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.utils.component.ComponentContext;
 import com.cloud.utils.component.Manager;
 import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
 import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.dao.UserVmDao;
 import com.cloud.vm.dao.VMInstanceDao;
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.Listener;
+import com.cloud.agent.api.AgentControlAnswer;
+import com.cloud.agent.api.AgentControlCommand;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
 
 @Local(value = { DeploymentPlanningManager.class })
-public class DeploymentPlanningManagerImpl extends ManagerBase implements DeploymentPlanningManager,
Manager {
+public class DeploymentPlanningManagerImpl extends ManagerBase implements DeploymentPlanningManager,
Manager, Listener {
 
     private static final Logger s_logger = Logger.getLogger(DeploymentPlanningManagerImpl.class);
     @Inject
+    AgentManager _agentMgr;
+    @Inject
     protected UserVmDao _vmDao;
     @Inject
     protected VMInstanceDao _vmInstanceDao;
@@ -49,6 +74,10 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements
Deploy
     protected AffinityGroupDao _affinityGroupDao;
     @Inject
     protected AffinityGroupVMMapDao _affinityGroupVMMapDao;
+    @Inject
+    DataCenterDao _dcDao;
+    @Inject
+    PlannerHostReservationDao _plannerHostReserveDao;
 
     protected List<DeploymentPlanner> _planners;
     public List<DeploymentPlanner> getPlanners() {
@@ -88,19 +117,162 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements
Deploy
 
         // call planners
         DeployDestination dest = null;
-        for (DeploymentPlanner planner : _planners) {
-            if (planner.canHandle(vmProfile, plan, avoids)) {
-                dest = planner.plan(vmProfile, plan, avoids);
-            } else {
-                continue;
+        List<Long> clusterIds = null;
+
+        ServiceOffering offering = vmProfile.getServiceOffering();
+        if (offering != null && offering.getDeploymentPlanner() != null) {
+            DeploymentPlanner planner = ComponentContext.getComponent(offering.getDeploymentPlanner());
+            if (planner != null && planner.canHandle(vmProfile, plan, avoids)) {
+                while (true) {
+                    if (planner instanceof DeploymentClusterPlanner) {
+                        clusterIds = ((DeploymentClusterPlanner) planner).orderClusters(vmProfile,
plan, avoids);
+                    } else {
+                        dest = planner.plan(vmProfile, plan, avoids);
+                    }
+
+                    if (dest != null) {
+                        long hostId = dest.getHost().getId();
+                        avoids.addHost(dest.getHost().getId());
+
+                        if (checkIfHostCanBeUsed(hostId, DeploymentPlanner.PlannerResourceUsage.Shared))
{
+                            // found destination
+                            return dest;
+                        } else {
+                            // find another host - seems some concurrent deployment picked
it up for dedicated access
+                            continue;
+                        }
+                    } else if (clusterIds != null && !clusterIds.isEmpty()) {
+                        // planner refactoring. call allocators to list hosts
+
+                    } else {
+                        return null;
+                    }
+                }
             }
-            if (dest != null) {
-                avoids.addHost(dest.getHost().getId());
-                break;
+        }
+
+
+        return dest;
+    }
+
+    @DB
+    private boolean checkIfHostCanBeUsed(long hostId, PlannerResourceUsage resourceTypeRequired)
{
+        // TODO Auto-generated method stub
+        // check if this host has been picked up by some other planner
+        // exclusively
+        // if planner can work with shared host, check if this host has
+        // been marked as 'shared'
+        // else if planner needs dedicated host,
+
+        PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
+        if (reservationEntry != null) {
+            long id = reservationEntry.getId();
+            PlannerResourceUsage hostResourceType = reservationEntry.getResourceUsage();
+
+            if (hostResourceType != null) {
+                if (hostResourceType == resourceTypeRequired) {
+                    return true;
+                } else {
+                    return false;
+                }
+            } else {
+                // reserve the host for required resourceType
+                // let us lock the reservation entry before updating.
+                final Transaction txn = Transaction.currentTxn();
+
+                try {
+                    txn.start();
+
+                    final PlannerHostReservationVO lockedEntry = _plannerHostReserveDao.lockRow(id,
true);
+                    if (lockedEntry == null) {
+                        s_logger.error("Unable to lock the host entry for reservation, host:
" + hostId);
+                        return false;
+                    }
+                    // check before updating
+                    if (lockedEntry.getResourceUsage() == null) {
+                        lockedEntry.setResourceUsage(resourceTypeRequired);
+                        _plannerHostReserveDao.persist(lockedEntry);
+                        return true;
+                    } else {
+                        // someone updated it earlier. check if we can still use it
+                        if (lockedEntry.getResourceUsage() == resourceTypeRequired) {
+                            return true;
+                        } else {
+                            return false;
+                        }
+                    }
+                } finally {
+                    txn.commit();
+                }
             }
 
         }
-        return dest;
+
+        return false;
+    }
+
+    @Override
+    public boolean processAnswers(long agentId, long seq, Answer[] answers) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean processCommands(long agentId, long seq, Command[] commands) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd)
{
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws
ConnectionException {
+        if (!(cmd instanceof StartupRoutingCommand)) {
+            return;
+        }
+
+        PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(host.getId());
+        if (reservationEntry == null) {
+            // record the host in this table
+            PlannerHostReservationVO newHost = new PlannerHostReservationVO(host.getId(),
host.getDataCenterId(),
+                    host.getPodId(), host.getClusterId());
+            _plannerHostReserveDao.persist(newHost);
+        }
+
+    }
+
+    @Override
+    public boolean processDisconnect(long agentId, Status state) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isRecurring() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public int getTimeout() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public boolean processTimeout(long agentId, long seq) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws
ConfigurationException {
+        _agentMgr.registerForHostEvents(this, true, false, true);
+        return super.configure(name, params);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1959377d/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 75568b4..bee5eee 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -83,7 +83,6 @@ import com.cloud.dc.dao.DataCenterDao;
 import com.cloud.dc.dao.HostPodDao;
 import com.cloud.deploy.DataCenterDeployment;
 import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeployPlannerSelector;
 import com.cloud.deploy.DeploymentPlanner.ExcludeList;
 import com.cloud.domain.DomainVO;
 import com.cloud.domain.dao.DomainDao;
@@ -386,9 +385,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager,
Use
     @Inject
     AffinityGroupDao _affinityGroupDao;
 
-    @Inject
-    List<DeployPlannerSelector> plannerSelectors;
-
     protected ScheduledExecutorService _executor = null;
     protected int _expungeInterval;
     protected int _expungeDelay;


Mime
View raw message