On disk convertion to DRBD, a new secondary node has to be found.
Add a function doing this search in a way similar to what instance
allocation does: all possible placements are considered and the
one resulting in the best cluster metrics is taken.

To have a uniform interface, use the same signature as all allocation
functions, even though the group list is not needed (we have to take
the group of the primary node anyway).

Signed-off-by: Klaus Aehlig <[email protected]>
---
 Makefile.am                                    |  1 +
 src/Ganeti/HTools/Cluster/AllocateSecondary.hs | 70 ++++++++++++++++++++++++++
 2 files changed, 71 insertions(+)
 create mode 100644 src/Ganeti/HTools/Cluster/AllocateSecondary.hs

diff --git a/Makefile.am b/Makefile.am
index b1e3064..fc66e93 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -909,6 +909,7 @@ HS_LIB_SRCS = \
        src/Ganeti/HTools/Backend/Text.hs \
        src/Ganeti/HTools/CLI.hs \
        src/Ganeti/HTools/Cluster.hs \
+       src/Ganeti/HTools/Cluster/AllocateSecondary.hs \
        src/Ganeti/HTools/Cluster/AllocationSolution.hs \
        src/Ganeti/HTools/Cluster/Evacuate.hs \
        src/Ganeti/HTools/Cluster/Metrics.hs \
diff --git a/src/Ganeti/HTools/Cluster/AllocateSecondary.hs 
b/src/Ganeti/HTools/Cluster/AllocateSecondary.hs
new file mode 100644
index 0000000..a00d0e8
--- /dev/null
+++ b/src/Ganeti/HTools/Cluster/AllocateSecondary.hs
@@ -0,0 +1,70 @@
+{-| Implementation of finding a secondary for disk template conversion
+
+-}
+
+{-
+
+Copyright (C) 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.AllocateSecondary
+  ( tryAllocateSecondary
+  ) where
+
+import Control.Monad (unless)
+
+import Ganeti.BasicTypes
+import Ganeti.HTools.AlgorithmParams (AlgorithmOptions(..))
+import qualified Ganeti.HTools.Cluster as Cluster
+import Ganeti.HTools.Cluster.AllocationSolution (AllocSolution)
+import qualified Ganeti.HTools.Container as Container
+import qualified Ganeti.HTools.Group as Group
+import qualified Ganeti.HTools.Instance as Instance
+import qualified Ganeti.HTools.Node as Node
+import Ganeti.HTools.Types
+
+tryAllocateSecondary :: AlgorithmOptions
+                     -> Group.List    -- ^ The cluster groups
+                     -> Node.List     -- ^ The node list (cluster-wide,
+                                      -- not per group)
+                     -> Instance.List -- ^ Instance list (cluster-wide)
+                     -> Idx
+                     -> Result AllocSolution
+tryAllocateSecondary opts _ nl il idx = do
+  let inst = Container.find idx il
+  unless (Instance.sNode inst < 0)
+    $ fail "Instance already has a secondary"
+  let pidx = Instance.pNode inst
+      pnode = Container.find pidx nl
+      pnode' = Node.removePri pnode inst
+      nl' = Container.add pidx pnode' nl
+      inst' = inst { Instance.diskTemplate = DTDrbd8 }
+      gidx = Node.group pnode'
+      sidxs = filter (/= pidx) . Container.keys
+              $ Container.filter ((==) gidx . Node.group) nl'
+  Cluster.tryAlloc opts nl' il inst' $ Right [(pidx, sidxs)]
-- 
2.2.0.rc0.207.ga3a616c

Reply via email to