Fetch the reason trail from file, failing gracefully if it is not found, and
include it in the output of the instance status data collector.

Signed-off-by: Michele Tartara <[email protected]>
---
 src/Ganeti/DataCollectors/InstStatus.hs      | 25 +++++++++++++++++++++++++
 src/Ganeti/DataCollectors/InstStatusTypes.hs |  2 ++
 2 files changed, 27 insertions(+)

diff --git a/src/Ganeti/DataCollectors/InstStatus.hs 
b/src/Ganeti/DataCollectors/InstStatus.hs
index 9a7b300..ec8b3ef 100644
--- a/src/Ganeti/DataCollectors/InstStatus.hs
+++ b/src/Ganeti/DataCollectors/InstStatus.hs
@@ -30,6 +30,7 @@ module Ganeti.DataCollectors.InstStatus
   ) where
 
 
+import Control.Exception.Base
 import Data.Maybe
 import qualified Data.Map as Map
 import Network.BSD (getHostName)
@@ -44,7 +45,10 @@ import Ganeti.DataCollectors.InstStatusTypes
 import Ganeti.DataCollectors.Types
 import Ganeti.Hypervisor.Xen
 import Ganeti.Hypervisor.Xen.Types
+import Ganeti.Logging
 import Ganeti.Objects
+import Ganeti.Path
+import Ganeti.Types
 import Ganeti.Utils
 
 -- * Command line options
@@ -79,6 +83,25 @@ getInstances node srvAddr srvPort = do
       Just (J.Error msg) -> BT.Bad msg
       Nothing -> BT.Bad "No answer from the Confd server"
 
+-- | Try to get the reason trail for an instance. In case it is not possible,
+-- log the failure and return an empty list instead.
+getReasonTrail :: String -> IO ReasonTrail
+getReasonTrail instanceName = do
+  fileName <- getInstReasonFilename instanceName
+  content <- try $ readFile fileName
+  case content of
+    Left e -> do
+      logWarning $
+        "Unable to open the reason trail for instance " ++ instanceName ++
+        " expected at " ++ fileName ++ ": " ++ show (e :: IOException)
+      return []
+    Right trailString ->
+      case J.decode trailString of
+        J.Ok t -> return t
+        J.Error msg -> do
+          logWarning $ "Unable to parse the reason trail: " ++ msg
+          return []
+
 -- | Determine the value of the status field for the report of one instance
 computeStatusField :: AdminState -> ActualState -> DCStatus
 computeStatusField AdminDown actualState =
@@ -118,6 +141,7 @@ buildStatus domains uptimes inst = do
                 else domState dom
             _ -> ActualUnknown
       status = computeStatusField adminState actualState
+  trail <- getReasonTrail name
   return $
     InstStatus
       name
@@ -126,6 +150,7 @@ buildStatus domains uptimes inst = do
       actualState
       uptime
       (instMtime inst)
+      trail
       status
 
 -- | Main function.
diff --git a/src/Ganeti/DataCollectors/InstStatusTypes.hs 
b/src/Ganeti/DataCollectors/InstStatusTypes.hs
index 8e30db9..84c2ef1 100644
--- a/src/Ganeti/DataCollectors/InstStatusTypes.hs
+++ b/src/Ganeti/DataCollectors/InstStatusTypes.hs
@@ -33,6 +33,7 @@ import Ganeti.DataCollectors.Types
 import Ganeti.Hypervisor.Xen.Types
 import Ganeti.Objects
 import Ganeti.THH
+import Ganeti.Types
 
 -- | Data type representing the status of an instance to be returned.
 $(buildObject "InstStatus" "iStat"
@@ -43,5 +44,6 @@ $(buildObject "InstStatus" "iStat"
   , optionalNullSerField $
     simpleField "uptime"       [t| String |]
   , simpleField "mtime"        [t| Double |]
+  , simpleField "state_reason" [t| ReasonTrail |]
   , simpleField "status"       [t| DCStatus |]
   ])
-- 
1.8.2.1

Reply via email to