Revision db56cfc4 htools/Ganeti/HTools/Cluster.hs

b/htools/Ganeti/HTools/Cluster.hs
79 79
import Data.Function (on)
80 80
import qualified Data.IntSet as IntSet
81 81
import Data.List
82
import Data.Maybe (fromJust)
82 83
import Data.Ord (comparing)
83 84
import Text.Printf (printf)
84 85
import Control.Monad
......
923 924
        ops = iMoveToJob nl' il' idx Failover
924 925
    return (nl', il', ops)
925 926

  
927
nodeEvacInstance nl il ChangeSecondary
928
                 inst@(Instance.Instance {Instance.diskTemplate = DTDrbd8})
929
                 avail_nodes =
930
  do
931
    let gdx = instancePriGroup nl inst
932
    (nl', inst', _, ndx) <- annotateResult "Can't find any good node" $
933
                            eitherToResult $
934
                            foldl' (evacDrbdSecondaryInner nl inst gdx)
935
                            (Left "no nodes available") avail_nodes
936
    let idx = Instance.idx inst
937
        il' = Container.add idx inst' il
938
        ops = iMoveToJob nl' il' idx (ReplaceSecondary ndx)
939
    return (nl', il', ops)
940

  
926 941
nodeEvacInstance _ _ _ (Instance.Instance
927 942
                        {Instance.diskTemplate = DTDrbd8}) _ =
928 943
                  fail "DRBD relocations not implemented yet"
929 944

  
945
-- | Inner fold function for changing secondary of a DRBD instance.
946
--
947
-- The "running" solution is either a @Left String@, which means we
948
-- don't have yet a working solution, or a @Right (...)@, which
949
-- represents a valid solution; it holds the modified node list, the
950
-- modified instance (after evacuation), the score of that solution,
951
-- and the new secondary node index.
952
evacDrbdSecondaryInner :: Node.List -- ^ Cluster node list
953
                       -> Instance.Instance -- ^ Instance being evacuated
954
                       -> Gdx -- ^ The group index of the instance
955
                       -> Either String ( Node.List
956
                                        , Instance.Instance
957
                                        , Score
958
                                        , Ndx)  -- ^ Current best solution
959
                       -> Ndx  -- ^ Node we're evaluating as new secondary
960
                       -> Either String ( Node.List
961
                                        , Instance.Instance
962
                                        , Score
963
                                        , Ndx) -- ^ New best solution
964
evacDrbdSecondaryInner nl inst gdx accu ndx =
965
    case applyMove nl inst (ReplaceSecondary ndx) of
966
      OpFail fm ->
967
          case accu of
968
            Right _ -> accu
969
            Left _ -> Left $ "Node " ++ Container.nameOf nl ndx ++
970
                      " failed: " ++ show fm
971
      OpGood (nl', inst', _, _) ->
972
          let nodes = Container.elems nl'
973
              -- The fromJust below is ugly (it can fail nastily), but
974
              -- at this point we should have any internal mismatches,
975
              -- and adding a monad here would be quite involved
976
              grpnodes = fromJust (gdx `lookup` (Node.computeGroups nodes))
977
              new_cv = compCVNodes grpnodes
978
              new_accu = Right (nl', inst', new_cv, ndx)
979
          in case accu of
980
               Left _ -> new_accu
981
               Right (_, _, old_cv, _) ->
982
                   if old_cv < new_cv
983
                   then accu
984
                   else new_accu
985

  
930 986
-- | Computes the local nodes of a given instance which are available
931 987
-- for allocation.
932 988
availableLocalNodes :: Node.List

Also available in: Unified diff