+-- in the derived order to be more intrusive actions.
+$(declareLADT ''String "RepairAction"
+ [ ("RANoop", "Ok")
+ , ("RALiveRepair", "live-repair")
+ , ("RAEvacuate", "evacuate")
+ , ("RAEvacuateFailover", "evacute-failover")
+ ])
+$(makeJSONInstance ''RepairAction)
+
+-- | Progress made on the particular repair event. Again we rely
+-- on the order in that everything larger than `RSPending` is finalized
+-- in the sense that no further jobs will be submitted.
+$(declareLADT ''String "RepairStatus"
+ [ ("RSNoted", "noted")
+ , ("RSPending", "pending")
+ , ("RSCanceled", "canceled")
+ , ("RSFailed", "failed")
+ , ("RSCompleted", "completed")
+ ])
+$(makeJSONInstance ''RepairStatus)
+
+$(buildObject "Incident" "incident" $
+ [ simpleField "original" [t| J.JSValue |]
+ , simpleField "action" [t| RepairAction |]
+ , defaultField [| [] |] $ simpleField "jobs" [t| [ JobId ] |]
+ , simpleField "node" [t| String |]
+ , simpleField "repair-status" [t| RepairStatus |]
+ , simpleField "tag" [t| String |]
+ ]
+ ++ uuidFields
+ ++ timeStampFields
+ ++ serialFields)
+
+instance SerialNoObject Incident where
+ serialOf = incidentSerial
+
+instance TimeStampObject Incident where
+ cTimeOf = incidentCtime
+ mTimeOf = incidentMtime
+
+instance UuidObject Incident where
+ uuidOf = incidentUuid
+
$(buildObject "MaintenanceData" "maint" $
[ defaultField [| C.maintdDefaultRoundDelay |]
$ simpleField "roundDelay" [t| Int |]
@@ -51,6 +101,7 @@ $(buildObject "MaintenanceData" "maint" $
, defaultField [| 0.1 :: Double |]
$ simpleField "balanceThreshold" [t| Double |]
, defaultField [| [] |] $ simpleField "evacuated" [t| [ String ] |]
+ , defaultField [| [] |] $ simpleField "incidents" [t| [ Incident ] |]
]
++ timeStampFields
++ serialFields)
diff --git a/src/Ganeti/WConfd/ConfigModifications.hs
b/src/Ganeti/WConfd/ConfigModifications.hs
index 25448c6..fe09a9d 100644
--- a/src/Ganeti/WConfd/ConfigModifications.hs
+++ b/src/Ganeti/WConfd/ConfigModifications.hs
@@ -711,6 +711,19 @@ rmMaintdEvacuated :: String -> WConfdMonad Bool
rmMaintdEvacuated name = changeAndBumpMaint . over maintEvacuatedL
$ filter (/= name)
+-- | Update an incident to the list of known incidents; if the incident,
+-- as identified by the UUID, is not present, it is added.
+updateMaintdIncident :: Incident -> WConfdMonad Bool
+updateMaintdIncident incident =
+ changeAndBumpMaint . over maintIncidentsL
+ $ (incident :) . filter ((/= uuidOf incident) . uuidOf)
+
+-- | Remove an incident from the list of known incidents.
+rmMaintdIncident :: String -> WConfdMonad Bool
+rmMaintdIncident uuid =
+ changeAndBumpMaint . over maintIncidentsL
+ $ filter ((/= uuid) . uuidOf)
+
-- * The list of functions exported to RPC.
exportedFunctions :: [Name]
@@ -737,4 +750,6 @@ exportedFunctions = [ 'addInstance
, 'setMaintdBalanceThreshold
, 'addMaintdEvacuated
, 'rmMaintdEvacuated
+ , 'updateMaintdIncident
+ , 'rmMaintdIncident
]
diff --git a/src/Ganeti/WConfd/Core.hs b/src/Ganeti/WConfd/Core.hs
index 3edccb6..fcbf235 100644
--- a/src/Ganeti/WConfd/Core.hs
+++ b/src/Ganeti/WConfd/Core.hs
@@ -64,6 +64,7 @@ import qualified Ganeti.Locking.Waiting as LW
import Ganeti.Objects ( ConfigData, DRBDSecret, LogicalVolume, Ip4Address
, configMaintenance, maintRoundDelay, maintJobs
, maintBalance, maintBalanceThreshold, maintEvacuated
+ , Incident, maintIncidents
)
import Ganeti.Objects.Lens (configClusterL, clusterMasterNodeL)
import Ganeti.Types (JobId)
@@ -178,6 +179,10 @@ maintenanceBalancing = liftM ((maintBalance &&&
maintBalanceThreshold)
maintenanceEvacuated :: WConfdMonad [String]
maintenanceEvacuated = liftM (maintEvacuated . configMaintenance) CW.readConfig
+-- | Get the list of current incidents.
+maintenanceIncidents :: WConfdMonad [Incident]
+maintenanceIncidents = liftM (maintIncidents . configMaintenance) CW.readConfig
+
-- ** Temporary reservations related functions
dropAllReservations :: ClientId -> WConfdMonad ()
@@ -412,6 +417,7 @@ exportedFunctions = [ 'echo
, 'maintenanceJobs
, 'maintenanceBalancing
, 'maintenanceEvacuated
+ , 'maintenanceIncidents
-- temporary reservations (common)
, 'dropAllReservations
-- DRBD
diff --git a/test/hs/Test/Ganeti/Objects.hs b/test/hs/Test/Ganeti/Objects.hs
index 525c96a..857f822 100644
--- a/test/hs/Test/Ganeti/Objects.hs
+++ b/test/hs/Test/Ganeti/Objects.hs
@@ -375,6 +375,24 @@ instance Arbitrary FilterRule where
<*> arbitrary
<*> genUUID
+instance Arbitrary RepairStatus where
+ arbitrary = elements [ RSNoted, RSPending, RSCanceled, RSFailed, RSCompleted
]
+
+instance Arbitrary RepairAction where
+ arbitrary = elements [ RANoop, RALiveRepair, RAEvacuate, RAEvacuateFailover ]
+
+instance Arbitrary Incident where
+ arbitrary = Incident <$> pure (J.JSObject $ J.toJSObject [])
+ <*> arbitrary
+ <*> arbitrary
+ <*> arbitrary
+ <*> arbitrary
+ <*> arbitrary
+ <*> arbitrary
+ <*> arbitrary
+ <*> arbitrary
+ <*> arbitrary
+
instance Arbitrary MaintenanceData where
arbitrary = MaintenanceData <$> (fromPositive <$> arbitrary)
<*> arbitrary
@@ -384,6 +402,7 @@ instance Arbitrary MaintenanceData where
<*> arbitrary
<*> arbitrary
<*> arbitrary
+ <*> arbitrary
-- | Generates a network instance with minimum netmasks of /24. Generating
-- bigger networks slows down the tests, because long bit strings are generated
--
2.5.0.rc2.392.g76e840b