On Fri, Aug 07, 2015 at 03:07:56PM +0200, 'Klaus Aehlig' via ganeti-devel wrote:
Add a data structure for the presentation of incidents
reported by the node-status data collector. It contains
all the information the maintenance daemons associates
with an incident, including jobs submitted. Again, the
information is stored in the configuration.

Signed-off-by: Klaus Aehlig <[email protected]>
---
lib/objects.py                           |  2 +-
src/Ganeti/Objects/Maintenance.hs        | 51 ++++++++++++++++++++++++++++++++
src/Ganeti/WConfd/ConfigModifications.hs | 15 ++++++++++
src/Ganeti/WConfd/Core.hs                |  6 ++++
test/hs/Test/Ganeti/Objects.hs           | 19 ++++++++++++
5 files changed, 92 insertions(+), 1 deletion(-)

diff --git a/lib/objects.py b/lib/objects.py
index 22ef009..02db0e3 100644
--- a/lib/objects.py
+++ b/lib/objects.py
@@ -558,7 +558,7 @@ class Filter(ConfigObject):
class Maintenance(ConfigObject):
  """Config object representing the state of the maintenance daemon"""
  __slots__ = ["roundDelay", "jobs", "evacuated", "balance", "balanceThreshold",
-               "serial_no"] + _TIMESTAMPS
+               "incidents", "serial_no"] + _TIMESTAMPS

  def UpgradeConfig(self):
    if self.serial_no is None:
diff --git a/src/Ganeti/Objects/Maintenance.hs 
b/src/Ganeti/Objects/Maintenance.hs
index 6011e3d..6bf091c 100644
--- a/src/Ganeti/Objects/Maintenance.hs
+++ b/src/Ganeti/Objects/Maintenance.hs
@@ -36,13 +36,63 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

module Ganeti.Objects.Maintenance
  ( MaintenanceData(..)
+  , RepairAction(..)
+  , RepairStatus(..)
+  , Incident(..)
  ) where

+import qualified Text.JSON as J
+
import qualified Ganeti.Constants as C
import Ganeti.THH
import Ganeti.THH.Field
import Ganeti.Types

+-- | Action to be taken for a certain repair event. Note
+-- that he order is important, as we rely on values higher
+-- 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


LGTM

Reply via email to