Revision 4ba5f148 src/Ganeti/HTools/Program/Harep.hs
b/src/Ganeti/HTools/Program/Harep.hs | ||
---|---|---|
41 | 41 |
import Ganeti.Errors |
42 | 42 |
import Ganeti.Jobs |
43 | 43 |
import Ganeti.OpCodes |
44 |
import Ganeti.OpParams |
|
44 | 45 |
import Ganeti.Types |
45 | 46 |
import Ganeti.Utils |
46 | 47 |
import qualified Ganeti.Constants as C |
... | ... | |
53 | 54 |
import Ganeti.HTools.Types |
54 | 55 |
import qualified Ganeti.HTools.Container as Container |
55 | 56 |
import qualified Ganeti.HTools.Instance as Instance |
57 |
import qualified Ganeti.HTools.Node as Node |
|
56 | 58 |
|
57 | 59 |
-- | Options list and functions. |
58 | 60 |
options :: IO [OptType] |
... | ... | |
271 | 273 |
|
272 | 274 |
return instData { tagsToRemove = [] } |
273 | 275 |
|
276 |
-- | Detect brokeness with an instance and suggest repair type and jobs to run. |
|
277 |
detectBroken :: Node.List -> Instance.Instance |
|
278 |
-> Maybe (AutoRepairType, [OpCode]) |
|
279 |
detectBroken nl inst = |
|
280 |
let disk = Instance.diskTemplate inst |
|
281 |
iname = Instance.name inst |
|
282 |
offPri = Node.offline $ Container.find (Instance.pNode inst) nl |
|
283 |
offSec = Node.offline $ Container.find (Instance.sNode inst) nl |
|
284 |
in |
|
285 |
case disk of |
|
286 |
DTDrbd8 |
|
287 |
| offPri && offSec -> |
|
288 |
Just ( |
|
289 |
ArReinstall, |
|
290 |
[ OpInstanceRecreateDisks { opInstanceName = iname |
|
291 |
, opRecreateDisksInfo = RecreateDisksAll |
|
292 |
, opNodes = [] |
|
293 |
-- FIXME: there should be a better way to |
|
294 |
-- specify opcode paramteres than abusing |
|
295 |
-- mkNonEmpty in this way (using the fact |
|
296 |
-- that Maybe is used both for optional |
|
297 |
-- fields, and to express failure). |
|
298 |
, opIallocator = mkNonEmpty "hail" |
|
299 |
} |
|
300 |
, OpInstanceReinstall { opInstanceName = iname |
|
301 |
, opOsType = Nothing |
|
302 |
, opTempOsParams = Nothing |
|
303 |
, opForceVariant = False |
|
304 |
} |
|
305 |
]) |
|
306 |
| offPri -> |
|
307 |
Just ( |
|
308 |
ArFailover, |
|
309 |
[ OpInstanceFailover { opInstanceName = iname |
|
310 |
-- FIXME: ditto, see above. |
|
311 |
, opShutdownTimeout = fromJust $ mkNonNegative |
|
312 |
C.defaultShutdownTimeout |
|
313 |
, opIgnoreConsistency = False |
|
314 |
, opTargetNode = Nothing |
|
315 |
, opIgnoreIpolicy = False |
|
316 |
, opIallocator = Nothing |
|
317 |
} |
|
318 |
]) |
|
319 |
| offSec -> |
|
320 |
Just ( |
|
321 |
ArFixStorage, |
|
322 |
[ OpInstanceReplaceDisks { opInstanceName = iname |
|
323 |
, opReplaceDisksMode = ReplaceNewSecondary |
|
324 |
, opReplaceDisksList = [] |
|
325 |
, opRemoteNode = Nothing |
|
326 |
-- FIXME: ditto, see above. |
|
327 |
, opIallocator = mkNonEmpty "hail" |
|
328 |
, opEarlyRelease = False |
|
329 |
, opIgnoreIpolicy = False |
|
330 |
} |
|
331 |
]) |
|
332 |
| otherwise -> Nothing |
|
333 |
|
|
334 |
DTPlain |
|
335 |
| offPri -> |
|
336 |
Just ( |
|
337 |
ArReinstall, |
|
338 |
[ OpInstanceRecreateDisks { opInstanceName = iname |
|
339 |
, opRecreateDisksInfo = RecreateDisksAll |
|
340 |
, opNodes = [] |
|
341 |
-- FIXME: ditto, see above. |
|
342 |
, opIallocator = mkNonEmpty "hail" |
|
343 |
} |
|
344 |
, OpInstanceReinstall { opInstanceName = iname |
|
345 |
, opOsType = Nothing |
|
346 |
, opTempOsParams = Nothing |
|
347 |
, opForceVariant = False |
|
348 |
} |
|
349 |
]) |
|
350 |
| otherwise -> Nothing |
|
351 |
|
|
352 |
_ -> Nothing -- Other cases are unimplemented for now: DTDiskless, |
|
353 |
-- DTFile, DTSharedFile, DTBlock, DTRbd, DTExt. |
|
354 |
|
|
274 | 355 |
-- | Main function. |
275 | 356 |
main :: Options -> [String] -> IO () |
276 | 357 |
main opts args = do |
... | ... | |
281 | 362 |
let master = fromMaybe luxiDef $ optLuxi opts |
282 | 363 |
opts' = opts { optLuxi = Just master } |
283 | 364 |
|
284 |
(ClusterData _ _ il _ _) <- loadExternalData opts'
|
|
365 |
(ClusterData _ nl il _ _) <- loadExternalData opts'
|
|
285 | 366 |
|
286 | 367 |
let iniDataRes = mapM setInitialState $ Container.elems il |
287 | 368 |
iniData <- exitIfBad "when parsing auto-repair tags" iniDataRes |
288 | 369 |
|
289 | 370 |
-- First step: check all pending repairs, see if they are completed. |
290 |
_unused_iniData' <- bracket (L.getClient master) L.closeClient $ |
|
291 |
forM iniData . processPending |
|
371 |
iniData' <- bracket (L.getClient master) L.closeClient $ |
|
372 |
forM iniData . processPending |
|
373 |
|
|
374 |
-- Second step: detect any problems. |
|
375 |
let _unused_repairs = map (detectBroken nl . arInstance) iniData' |
|
292 | 376 |
|
293 | 377 |
return () |
Also available in: Unified diff