On Wed, Jun 24, 2015 at 11:28:58AM +0200, 'Klaus Aehlig' via ganeti-devel wrote:
In this way we avoid a circular dependency: tryAlloc depends on
the notion of global N+1 redundancy and global N+1 redundancy for
plain instances depends on knowing how to allocate an instance on
a single node.

Signed-off-by: Klaus Aehlig <[email protected]>
---
Makefile.am                                     |  1 +
src/Ganeti/HTools/Cluster.hs                    | 47 ++------------
src/Ganeti/HTools/Cluster/AllocatePrimitives.hs | 85 +++++++++++++++++++++++++
3 files changed, 91 insertions(+), 42 deletions(-)
create mode 100644 src/Ganeti/HTools/Cluster/AllocatePrimitives.hs

diff --git a/Makefile.am b/Makefile.am
index c4bcf04..546f18a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -910,6 +910,7 @@ HS_LIB_SRCS = \
        src/Ganeti/HTools/Backend/Text.hs \
        src/Ganeti/HTools/CLI.hs \
        src/Ganeti/HTools/Cluster.hs \
+       src/Ganeti/HTools/Cluster/AllocatePrimitives.hs \
        src/Ganeti/HTools/Cluster/AllocateSecondary.hs \
        src/Ganeti/HTools/Cluster/AllocationSolution.hs \
        src/Ganeti/HTools/Cluster/Evacuate.hs \
diff --git a/src/Ganeti/HTools/Cluster.hs b/src/Ganeti/HTools/Cluster.hs
index 0ad96ab..adfe87d 100644
--- a/src/Ganeti/HTools/Cluster.hs
+++ b/src/Ganeti/HTools/Cluster.hs
@@ -94,18 +94,18 @@ import Text.Printf (printf)
import Ganeti.BasicTypes
import Ganeti.HTools.AlgorithmParams (AlgorithmOptions(..), defaultOptions)
import qualified Ganeti.HTools.Container as Container
+import Ganeti.HTools.Cluster.AllocatePrimitives ( allocateOnSingle
+                                                , allocateOnPair)
import Ganeti.HTools.Cluster.AllocationSolution
-    ( AllocElement, GenericAllocSolution(..) , AllocSolution, 
emptyAllocSolution
+    ( GenericAllocSolution(..) , AllocSolution, emptyAllocSolution
    , sumAllocs, extractNl, updateIl
    , annotateSolution, solutionDescription, collapseFailures
    , emptyAllocCollection, concatAllocCollections, collectionToSolution )
import Ganeti.HTools.Cluster.Evacuate ( EvacSolution(..), emptyEvacSolution
                                      , updateEvacSolution, reverseEvacSolution
                                      , nodeEvacInstance)
-import Ganeti.HTools.Cluster.Metrics ( compCV, compCVfromStats
-                                     , compClusterStatistics
-                                     , updateClusterStatisticsTwice)
-import Ganeti.HTools.Cluster.Moves (setInstanceLocationScore, applyMoveEx)
+import Ganeti.HTools.Cluster.Metrics (compCV, compClusterStatistics)
+import Ganeti.HTools.Cluster.Moves (applyMoveEx)
import Ganeti.HTools.Cluster.Utils (splitCluster, instancePriGroup
                                   , availableGroupNodes, iMoveToJob)
import Ganeti.HTools.GlobalN1 (allocGlobalN1, redundant)
@@ -116,7 +116,6 @@ import qualified Ganeti.HTools.Group as Group
import Ganeti.HTools.Types
import Ganeti.Compat
import Ganeti.Utils
-import Ganeti.Utils.Statistics
import Ganeti.Types (EvacMode(..))

-- * Types
@@ -314,42 +313,6 @@ compareTables :: Table -> Table -> Table
compareTables a@(Table _ _ a_cv _) b@(Table _ _ b_cv _ ) =
  if a_cv > b_cv then b else a

--- | Tries to allocate an instance on one given node.
-allocateOnSingle :: AlgorithmOptions
-                 -> Node.List -> Instance.Instance -> Ndx
-                 -> OpResult AllocElement
-allocateOnSingle opts nl inst new_pdx =
-  let p = Container.find new_pdx nl
-      new_inst = Instance.setBoth inst new_pdx Node.noSecondary
-      force = algIgnoreSoftErrors opts
-  in do
-    Instance.instMatchesPolicy inst (Node.iPolicy p) (Node.exclStorage p)
-    new_p <- Node.addPriEx force p inst
-    let new_nl = Container.add new_pdx new_p nl
-        new_score = compCV new_nl
-    return (new_nl, new_inst, [new_p], new_score)
-
--- | Tries to allocate an instance on a given pair of nodes.
-allocateOnPair :: AlgorithmOptions
-               -> [Statistics]
-               -> Node.List -> Instance.Instance -> Ndx -> Ndx
-               -> OpResult AllocElement
-allocateOnPair opts stats nl inst new_pdx new_sdx =
-  let tgt_p = Container.find new_pdx nl
-      tgt_s = Container.find new_sdx nl
-      force = algIgnoreSoftErrors opts
-  in do
-    Instance.instMatchesPolicy inst (Node.iPolicy tgt_p)
-      (Node.exclStorage tgt_p)
-    let new_inst = Instance.setBoth (setInstanceLocationScore inst tgt_p tgt_s)
-                   new_pdx new_sdx
-    new_p <- Node.addPriEx force tgt_p new_inst
-    new_s <- Node.addSec tgt_s new_inst new_pdx
-    let new_nl = Container.addTwo new_pdx new_p new_sdx new_s nl
-        new_stats = updateClusterStatisticsTwice stats
-                      (tgt_p, new_p) (tgt_s, new_s)
-    return (new_nl, new_inst, [new_p, new_s], compCVfromStats new_stats)
-
-- | Tries to perform an instance move and returns the best table
-- between the original one and the new one.
checkSingleStep :: Bool -- ^ Whether to unconditionally ignore soft errors
diff --git a/src/Ganeti/HTools/Cluster/AllocatePrimitives.hs 
b/src/Ganeti/HTools/Cluster/AllocatePrimitives.hs
new file mode 100644
index 0000000..3e90e02
--- /dev/null
+++ b/src/Ganeti/HTools/Cluster/AllocatePrimitives.hs
@@ -0,0 +1,85 @@
+{-| Implementation of the primitives of instance allocation
+
+-}
+
+{-
+
+Copyright (C) 2009, 2010, 2011, 2012, 2013, 2015 Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+-}
+
+module Ganeti.HTools.Cluster.AllocatePrimitives
+  ( allocateOnSingle
+  , allocateOnPair
+  ) where
+
+import Ganeti.HTools.AlgorithmParams (AlgorithmOptions(..))
+import Ganeti.HTools.Cluster.AllocationSolution (AllocElement)
+import Ganeti.HTools.Cluster.Metrics ( compCV, compCVfromStats
+                                     , updateClusterStatisticsTwice)
+import Ganeti.HTools.Cluster.Moves (setInstanceLocationScore)
+import qualified Ganeti.HTools.Container as Container
+import qualified Ganeti.HTools.Instance as Instance
+import qualified Ganeti.HTools.Node as Node
+import Ganeti.HTools.Types
+import Ganeti.Utils.Statistics
+
+-- | Tries to allocate an instance on one given node.
+allocateOnSingle :: AlgorithmOptions
+                 -> Node.List -> Instance.Instance -> Ndx
+                 -> OpResult AllocElement
+allocateOnSingle opts nl inst new_pdx =
+  let p = Container.find new_pdx nl
+      new_inst = Instance.setBoth inst new_pdx Node.noSecondary
+      force = algIgnoreSoftErrors opts
+  in do
+    Instance.instMatchesPolicy inst (Node.iPolicy p) (Node.exclStorage p)
+    new_p <- Node.addPriEx force p inst
+    let new_nl = Container.add new_pdx new_p nl
+        new_score = compCV new_nl
+    return (new_nl, new_inst, [new_p], new_score)
+
+-- | Tries to allocate an instance on a given pair of nodes.
+allocateOnPair :: AlgorithmOptions
+               -> [Statistics]
+               -> Node.List -> Instance.Instance -> Ndx -> Ndx
+               -> OpResult AllocElement
+allocateOnPair opts stats nl inst new_pdx new_sdx =
+  let tgt_p = Container.find new_pdx nl
+      tgt_s = Container.find new_sdx nl
+      force = algIgnoreSoftErrors opts
+  in do
+    Instance.instMatchesPolicy inst (Node.iPolicy tgt_p)
+      (Node.exclStorage tgt_p)
+    let new_inst = Instance.setBoth (setInstanceLocationScore inst tgt_p tgt_s)
+                   new_pdx new_sdx
+    new_p <- Node.addPriEx force tgt_p new_inst
+    new_s <- Node.addSec tgt_s new_inst new_pdx
+    let new_nl = Container.addTwo new_pdx new_p new_sdx new_s nl
+        new_stats = updateClusterStatisticsTwice stats
+                      (tgt_p, new_p) (tgt_s, new_s)
+    return (new_nl, new_inst, [new_p, new_s], compCVfromStats new_stats)
--
2.4.3.573.g4eafbef


LGTM

Reply via email to