Revision 5440c877

b/htools/Ganeti/HTools/Cluster.hs
110 110
-- type consists of actual opcodes (a restricted subset) that are
111 111
-- transmitted back to Ganeti.
112 112
data EvacSolution = EvacSolution
113
    { esMoved   :: [String]             -- ^ Instance moved successfully
114
    , esFailed  :: [String]             -- ^ Instance which were not
113
    { esMoved   :: [(Idx, Gdx, [Ndx])]  -- ^ Instances moved successfully
114
    , esFailed  :: [(Idx, String)]      -- ^ Instances which were not
115 115
                                        -- relocated
116 116
    , esOpCodes :: [[[OpCodes.OpCode]]] -- ^ List of lists of jobs
117 117
    }
......
1063 1063
-- | Updates the evac solution with the results of an instance
1064 1064
-- evacuation.
1065 1065
updateEvacSolution :: (Node.List, Instance.List, EvacSolution)
1066
                   -> Instance.Instance
1066
                   -> Idx
1067 1067
                   -> Result (Node.List, Instance.List, [OpCodes.OpCode])
1068 1068
                   -> (Node.List, Instance.List, EvacSolution)
1069
updateEvacSolution (nl, il, es) inst (Bad msg) =
1070
    (nl, il, es { esFailed = (Instance.name inst ++ ": " ++ msg):esFailed es})
1071
updateEvacSolution (_, _, es) inst (Ok (nl, il, opcodes)) =
1072
    (nl, il, es { esMoved = Instance.name inst:esMoved es
1069
updateEvacSolution (nl, il, es) idx (Bad msg) =
1070
    (nl, il, es { esFailed = (idx, msg):esFailed es})
1071
updateEvacSolution (_, _, es) idx (Ok (nl, il, opcodes)) =
1072
    (nl, il, es { esMoved = new_elem:esMoved es
1073 1073
                , esOpCodes = [opcodes]:esOpCodes es })
1074
     where inst = Container.find idx il
1075
           new_elem = (idx,
1076
                       instancePriGroup nl inst,
1077
                       Instance.allNodes inst)
1074 1078

  
1075 1079
-- | Node-evacuation IAllocator mode main function.
1076 1080
tryNodeEvac :: Group.List    -- ^ The cluster groups
......
1088 1092
                      splitCluster ini_nl ini_il
1089 1093
        (_, _, esol) =
1090 1094
            foldl' (\state@(nl, il, _) inst ->
1091
                        updateEvacSolution state inst $
1095
                        updateEvacSolution state (Instance.idx inst) $
1092 1096
                        availableGroupNodes group_ndx
1093 1097
                          excl_ndx (instancePriGroup nl inst) >>=
1094 1098
                        nodeEvacInstance nl il mode inst
......
1144 1148
                              av_nodes <- availableGroupNodes group_ndx
1145 1149
                                          excl_ndx gdx
1146 1150
                              nodeEvacInstance nl il ChangeAll inst av_nodes
1147
                        in updateEvacSolution state inst solution
1151
                        in updateEvacSolution state
1152
                               (Instance.idx inst) solution
1148 1153
                   )
1149 1154
            (ini_nl, ini_il, emptyEvacSolution)
1150 1155
            (map (`Container.find` ini_il) idxs)
1151 1156
    in return $ reverseEvacSolution esol
1152 1157

  
1153

  
1154 1158
-- | Recursively place instances on the cluster until we're out of space.
1155 1159
iterateAlloc :: Node.List
1156 1160
             -> Instance.List
b/htools/Ganeti/HTools/IAlloc.hs
241 241
    _ -> fail "Internal error: multiple allocation solutions"
242 242

  
243 243
-- | Convert a node-evacuation/change group result.
244
formatNodeEvac :: Cluster.EvacSolution -> Result IAllocResult
245
formatNodeEvac es =
246
    let fes = Cluster.esFailed es
247
        mes = Cluster.esMoved es
244
formatNodeEvac :: Group.List
245
               -> Node.List
246
               -> Instance.List
247
               -> Cluster.EvacSolution
248
               -> Result IAllocResult
249
formatNodeEvac gl nl il es =
250
    let iname = Instance.name . flip Container.find il
251
        nname = Node.name . flip Container.find nl
252
        gname = Group.name . flip Container.find gl
253
        fes = map (\(idx, msg) -> (iname idx, msg)) $ Cluster.esFailed es
254
        mes = map (\(idx, gdx, ndxs) -> (iname idx, gname gdx, map nname ndxs))
255
              $ Cluster.esMoved es
248 256
        failed = length fes
249 257
        moved  = length mes
250 258
        info = show failed ++ " instances failed to move and " ++ show moved ++
......
263 271
       Evacuate exnodes ->
264 272
           Cluster.tryMGEvac gl nl il exnodes >>= formatEvacuate
265 273
       ChangeGroup gdxs idxs ->
266
           Cluster.tryChangeGroup gl nl il idxs gdxs >>= formatNodeEvac
274
           Cluster.tryChangeGroup gl nl il idxs gdxs >>=
275
                  formatNodeEvac gl nl il
267 276
       NodeEvacuate xi mode ->
268
           Cluster.tryNodeEvac gl nl il mode xi >>= formatNodeEvac
277
           Cluster.tryNodeEvac gl nl il mode xi >>=
278
                  formatNodeEvac gl nl il
269 279

  
270 280
-- | Reads the request from the data file(s)
271 281
readRequest :: Options -> [String] -> IO Request

Also available in: Unified diff