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