From 0c8cef359ceb7ee89d418ad5d5407b52816c3875 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Mon, 5 Mar 2012 20:45:46 +0200
Subject: [PATCH] Extend the possible move types with FailoverToAny

This brings together all previous pieces and allows balancing to work
(with the known caveats related to disk space calculation) for shared
storage disk templates.

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Guido Trotter <ultrotter@google.com>
---
 htools/Ganeti/HTools/Cluster.hs | 20 +++++++++++++++++++-
 htools/Ganeti/HTools/Types.hs   |  2 ++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/htools/Ganeti/HTools/Cluster.hs b/htools/Ganeti/HTools/Cluster.hs
index 0b1617a80..385a57683 100644
--- a/htools/Ganeti/HTools/Cluster.hs
+++ b/htools/Ganeti/HTools/Cluster.hs
@@ -395,6 +395,17 @@ applyMove nl inst Failover =
                 new_inst, old_sdx, old_pdx)
   in new_nl
 
+-- Failover to any (fa)
+applyMove nl inst (FailoverToAny new_pdx) = do
+  let (old_pdx, old_sdx, old_pnode, _) = instanceNodes nl inst
+      new_pnode = Container.find new_pdx nl
+      force_failover = Node.offline old_pnode
+  new_pnode' <- Node.addPriEx force_failover new_pnode inst
+  let old_pnode' = Node.removePri old_pnode inst
+      inst' = Instance.setPri inst new_pdx
+      nl' = Container.addTwo old_pdx old_pnode' new_pdx new_pnode' nl
+  return (nl', inst', new_pdx, old_sdx)
+
 -- Replace the primary (f:, r:np, f)
 applyMove nl inst (ReplacePrimary new_pdx) =
   let (old_pdx, old_sdx, old_p, old_s) = instanceNodes nl inst
@@ -520,7 +531,10 @@ possibleMoves :: MirrorType -- ^ The mirroring type of the instance
 
 possibleMoves MirrorNone _ _ _ = []
 
-possibleMoves MirrorExternal _ _ _ = []
+possibleMoves MirrorExternal _ False _ = []
+
+possibleMoves MirrorExternal _ True tdx =
+  [ FailoverToAny tdx ]
 
 possibleMoves MirrorInternal _ False tdx =
   [ ReplaceSecondary tdx ]
@@ -1215,12 +1229,14 @@ computeMoves :: Instance.Instance -- ^ The instance to be moved
 computeMoves i inam mv c d =
   case mv of
     Failover -> ("f", [mig])
+    FailoverToAny _ -> (printf "fa:%s" c, [mig_any])
     FailoverAndReplace _ -> (printf "f r:%s" d, [mig, rep d])
     ReplaceSecondary _ -> (printf "r:%s" d, [rep d])
     ReplaceAndFailover _ -> (printf "r:%s f" c, [rep c, mig])
     ReplacePrimary _ -> (printf "f r:%s f" c, [mig, rep c, mig])
   where morf = if Instance.isRunning i then "migrate" else "failover"
         mig = printf "%s -f %s" morf inam::String
+        mig_any = printf "%s -f -n %s %s" morf c inam
         rep n = printf "replace-disks -n %s %s" n inam
 
 -- | Converts a placement to string format.
@@ -1374,10 +1390,12 @@ iMoveToJob nl il idx move =
       iname = Instance.name inst
       lookNode  = Just . Container.nameOf nl
       opF = OpCodes.OpInstanceMigrate iname True False True Nothing
+      opFA n = OpCodes.OpInstanceMigrate iname True False True (lookNode n)
       opR n = OpCodes.OpInstanceReplaceDisks iname (lookNode n)
               OpCodes.ReplaceNewSecondary [] Nothing
   in case move of
        Failover -> [ opF ]
+       FailoverToAny np -> [ opFA np ]
        ReplacePrimary np -> [ opF, opR np, opF ]
        ReplaceSecondary ns -> [ opR ns ]
        ReplaceAndFailover np -> [ opR np, opF ]
diff --git a/htools/Ganeti/HTools/Types.hs b/htools/Ganeti/HTools/Types.hs
index 3bc5794db..b6e92b739 100644
--- a/htools/Ganeti/HTools/Types.hs
+++ b/htools/Ganeti/HTools/Types.hs
@@ -300,6 +300,8 @@ type Placement = (Idx, Ndx, Ndx, IMove, Score)
 
 -- | An instance move definition.
 data IMove = Failover                -- ^ Failover the instance (f)
+           | FailoverToAny Ndx       -- ^ Failover to a random node
+                                     -- (fa:np), for shared storage
            | ReplacePrimary Ndx      -- ^ Replace primary (f, r:np, f)
            | ReplaceSecondary Ndx    -- ^ Replace secondary (r:ns)
            | ReplaceAndFailover Ndx  -- ^ Replace secondary, failover (r:np, f)
-- 
GitLab