Revision 8072af6c

b/src/Ganeti/HTools/Program/Harep.hs
352 352
     _ -> Nothing  -- Other cases are unimplemented for now: DTDiskless,
353 353
                   -- DTFile, DTSharedFile, DTBlock, DTRbd, DTExt.
354 354

  
355
-- | Perform the suggested repair on an instance if its policy allows it.
356
doRepair :: L.Client -> InstanceData -> (AutoRepairType, [OpCode])
357
         -> IO InstanceData
358
doRepair client instData (rtype, opcodes) =
359
  let inst = arInstance instData
360
      ipol = Instance.arPolicy inst
361
      iname = Instance.name inst
362
  in
363
  case ipol of
364
    ArEnabled maxtype ->
365
      if rtype > maxtype then do
366
        uuid <- newUUID
367
        time <- getClockTime
368

  
369
        let arState' = ArNeedsRepair (
370
              updateTag $ AutoRepairData rtype uuid time [] (Just ArEnoperm) "")
371
            instData' = instData { arState = arState'
372
                                 , tagsToRemove = delCurTag instData
373
                                 }
374

  
375
        putStrLn ("Not performing a repair of type " ++ show rtype ++ " on " ++
376
          iname ++ " because only repairs up to " ++ show maxtype ++
377
          " are allowed")
378
        commitChange client instData'  -- Adds "enoperm" result label.
379
      else do
380
        putStrLn ("Executing " ++ show rtype ++ " repair on " ++ iname)
381

  
382
        uuid <- newUUID
383
        time <- getClockTime
384
        jids <- submitJobs [map wrapOpCode opcodes] client
385

  
386
        case jids of
387
          Bad e    -> exitErr e
388
          Ok jids' ->
389
            let arState' = ArPendingRepair (
390
                  updateTag $ AutoRepairData rtype uuid time jids' Nothing "")
391
                instData' = instData { arState = arState'
392
                                     , tagsToRemove = delCurTag instData
393
                                     }
394
            in
395
             commitChange client instData'  -- Adds "pending" label.
396

  
397
    otherSt -> do
398
      putStrLn ("Not repairing " ++ iname ++ " because it's in state " ++
399
                show otherSt)
400
      return instData
401

  
355 402
-- | Main function.
356 403
main :: Options -> [String] -> IO ()
357 404
main opts args = do
......
372 419
              forM iniData . processPending
373 420

  
374 421
  -- Second step: detect any problems.
375
  let _unused_repairs = map (detectBroken nl . arInstance) iniData'
422
  let repairs = map (detectBroken nl . arInstance) iniData'
423

  
424
  -- Third step: create repair jobs for broken instances that are in ArHealthy.
425
  let maybeRepair c (i, r) = maybe (return i) (repairHealthy c i) r
426
      repairHealthy c i = case arState i of
427
                            ArHealthy _ -> doRepair c i
428
                            _           -> const (return i)
429

  
430
  _unused_repairDone <- bracket (L.getClient master) L.closeClient $
431
                        forM (zip iniData' repairs) . maybeRepair
376 432

  
377 433
  return ()

Also available in: Unified diff