commit 1c31b2630f51dd6598cba10ce38cf1c750f68e59
Author: Jose A. Lopes <jabolopes@google.com>
Date:   Mon Sep 16 12:30:18 2013 +0200

    Flip dependency between Haskell types and constants
    
    Before this patch, Haskell types, such as, 'GanetiDaemon' and
    'GanetiGroup', and related functions were taking their values from
    Haskell constants.  However, given that the role of Haskell to Python
    constants is to leverage Haskell and its typesystem, it makes sense to
    first define the Haskell types and then have the constants depend on
    these types.  In other words, this patch series inverts the dependency
    between (some) Haskell types and constants.
    
    Signed-off-by: Jose A. Lopes <jabolopes@google.com>
    Reviewed-by: Michele Tartara <mtartara@google.com>

diff --git a/lib/constants.py b/lib/constants.py
index f7e83f2..1540a4c 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -203,8 +203,8 @@ VALID_EXTRA_LOGREASONS = compat.UniqueFrozenset([
 # These are the extra logfiles, grouped by daemon
 DAEMONS_EXTRA_LOGBASE = {
   MOND: {
-    EXTRA_LOGREASON_ACCESS: "monitoring-daemon-access",
-    EXTRA_LOGREASON_ERROR: "monitoring-daemon-error",
+    EXTRA_LOGREASON_ACCESS: _constants.EXTRA_LOGREASON_ACCESS,
+    EXTRA_LOGREASON_ERROR: _constants.EXTRA_LOGREASON_ERROR,
     }
   }
 
diff --git a/src/Ganeti/ConstantUtils.hs b/src/Ganeti/ConstantUtils.hs
index 34b2a4d..c96a855 100644
--- a/src/Ganeti/ConstantUtils.hs
+++ b/src/Ganeti/ConstantUtils.hs
@@ -63,3 +63,11 @@ data Protocol = Tcp | Udp
 instance PyValue Protocol where
   showValue Tcp = "\"tcp\""
   showValue Udp = "\"udp\""
+
+-- | Failure exit code
+--
+-- This is defined here and not in 'Ganeti.HsConstants' together with
+-- the other exit codes in order to avoid a circular dependency
+-- between 'Ganeti.HsConstants' and 'Ganeti.Runtime'
+exitFailure :: Int
+exitFailure = 1
diff --git a/src/Ganeti/HsConstants.hs b/src/Ganeti/HsConstants.hs
index 31ed272..244f5f9 100644
--- a/src/Ganeti/HsConstants.hs
+++ b/src/Ganeti/HsConstants.hs
@@ -40,7 +40,11 @@ import Data.Map (Map)
 import qualified Data.Map as Map (fromList)
 
 import AutoConf
-import Ganeti.ConstantUtils
+import Ganeti.ConstantUtils (FrozenSet, Protocol(..))
+import qualified Ganeti.ConstantUtils as ConstantUtils (mkSet, exitFailure)
+import Ganeti.Runtime (GanetiDaemon(..), MiscGroup(..), GanetiGroup(..),
+                       ExtraLogReason(..))
+import qualified Ganeti.Runtime as Runtime
 
 -- * Admin states
 
@@ -59,46 +63,46 @@ adminstAll = mkSet [adminstDown, adminstOffline, adminstUp]
 -- * User separation
 
 daemonsGroup :: String
-daemonsGroup = AutoConf.daemonsGroup
+daemonsGroup = Runtime.daemonGroup (ExtraGroup DaemonsGroup)
 
 adminGroup :: String
-adminGroup = AutoConf.adminGroup
+adminGroup = Runtime.daemonGroup (ExtraGroup AdminGroup)
 
 masterdUser :: String
-masterdUser = AutoConf.masterdUser
+masterdUser = Runtime.daemonUser GanetiMasterd
 
 masterdGroup :: String
-masterdGroup = AutoConf.masterdGroup
+masterdGroup = Runtime.daemonGroup (DaemonGroup GanetiMasterd)
 
 rapiUser :: String
-rapiUser = AutoConf.rapiUser
+rapiUser = Runtime.daemonUser GanetiRapi
 
 rapiGroup :: String
-rapiGroup = AutoConf.rapiGroup
+rapiGroup = Runtime.daemonGroup (DaemonGroup GanetiRapi)
 
 confdUser :: String
-confdUser = AutoConf.confdUser
+confdUser = Runtime.daemonUser GanetiConfd
 
 confdGroup :: String
-confdGroup = AutoConf.confdGroup
+confdGroup = Runtime.daemonGroup (DaemonGroup GanetiConfd)
 
 luxidUser :: String
-luxidUser = AutoConf.luxidUser
+luxidUser = Runtime.daemonUser GanetiLuxid
 
 luxidGroup :: String
-luxidGroup = AutoConf.luxidGroup
+luxidGroup = Runtime.daemonGroup (DaemonGroup GanetiLuxid)
 
 nodedUser :: String
-nodedUser = AutoConf.nodedUser
+nodedUser = Runtime.daemonUser GanetiNoded
 
 nodedGroup :: String
-nodedGroup = AutoConf.nodedGroup
+nodedGroup = Runtime.daemonGroup (DaemonGroup GanetiNoded)
 
 mondUser :: String
-mondUser = AutoConf.mondUser
+mondUser = Runtime.daemonUser GanetiMond
 
 mondGroup :: String
-mondGroup = AutoConf.mondGroup
+mondGroup = Runtime.daemonGroup (DaemonGroup GanetiMond)
 
 sshLoginUser :: String
 sshLoginUser = AutoConf.sshLoginUser
@@ -117,22 +121,22 @@ scp = "scp"
 -- * Daemons
 
 confd :: String
-confd = "ganeti-confd"
+confd = Runtime.daemonName GanetiConfd
 
 masterd :: String
-masterd = "ganeti-masterd"
+masterd = Runtime.daemonName GanetiMasterd
 
 mond :: String
-mond = "ganeti-mond"
+mond = Runtime.daemonName GanetiMond
 
 noded :: String
-noded = "ganeti-noded"
+noded = Runtime.daemonName GanetiNoded
 
 luxid :: String
-luxid = "ganeti-luxid"
+luxid = Runtime.daemonName GanetiLuxid
 
 rapi :: String
-rapi = "ganeti-rapi"
+rapi = Runtime.daemonName GanetiRapi
 
 daemons :: FrozenSet String
 daemons =
@@ -163,6 +167,12 @@ daemonsPorts =
                 (rapi, (Tcp, defaultRapiPort)),
                 (ssh, (Tcp, 22))]
 
+extraLogreasonAccess :: String
+extraLogreasonAccess = Runtime.daemonsExtraLogbase GanetiMond AccessLog
+
+extraLogreasonError :: String
+extraLogreasonError = Runtime.daemonsExtraLogbase GanetiMond ErrorLog
+
 -- * Possible values for NodeGroup.alloc_policy
 
 allocPolicyLastResort :: String
diff --git a/src/Ganeti/Luxi.hs b/src/Ganeti/Luxi.hs
index ce2a279..ca602b4 100644
--- a/src/Ganeti/Luxi.hs
+++ b/src/Ganeti/Luxi.hs
@@ -76,8 +76,8 @@ import Ganeti.Errors
 import Ganeti.JSON
 import Ganeti.OpParams (pTagsObject)
 import Ganeti.OpCodes
-import Ganeti.Runtime
 import qualified Ganeti.Query.Language as Qlang
+import Ganeti.Runtime (GanetiDaemon(..), MiscGroup(..), GanetiGroup(..))
 import Ganeti.THH
 import Ganeti.Types
 import Ganeti.Utils
diff --git a/src/Ganeti/Monitoring/Server.hs b/src/Ganeti/Monitoring/Server.hs
index 2cedbac..d30c7d1 100644
--- a/src/Ganeti/Monitoring/Server.hs
+++ b/src/Ganeti/Monitoring/Server.hs
@@ -117,15 +117,12 @@ checkMain _ = return $ Right ()
 -- | Prepare function for monitoring agent.
 prepMain :: PrepFn CheckResult PrepResult
 prepMain opts _ = do
-  mAccessLog <- daemonsExtraLogFile GanetiMond AccessLog
-  mErrorLog <- daemonsExtraLogFile GanetiMond ErrorLog
-  case (mAccessLog, mErrorLog) of
-    (Just accessLog, Just errorLog) ->
-      return $
-        setPort
-          (maybe C.defaultMondPort fromIntegral (optPort opts))
-          (defaultHttpConf accessLog errorLog)
-    _ -> fail "Failed to retrieve extra log filepaths for the monitoring daemon"
+  accessLog <- daemonsExtraLogFile GanetiMond AccessLog
+  errorLog <- daemonsExtraLogFile GanetiMond ErrorLog
+  return $
+    setPort
+      (maybe C.defaultMondPort fromIntegral (optPort opts))
+      (defaultHttpConf accessLog errorLog)
 
 -- * Query answers
 
diff --git a/src/Ganeti/Runtime.hs b/src/Ganeti/Runtime.hs
index a831067..b5d4ba5 100644
--- a/src/Ganeti/Runtime.hs
+++ b/src/Ganeti/Runtime.hs
@@ -30,10 +30,12 @@ module Ganeti.Runtime
   , RuntimeEnts
   , daemonName
   , daemonOnlyOnMaster
+  , daemonLogBase
   , daemonUser
   , daemonGroup
   , ExtraLogReason(..)
   , daemonLogFile
+  , daemonsExtraLogbase
   , daemonsExtraLogFile
   , daemonPidFile
   , getEnts
@@ -51,10 +53,12 @@ import System.Posix.Types
 import System.Posix.User
 import Text.Printf
 
-import qualified Ganeti.Constants as C
+import qualified Ganeti.ConstantUtils as ConstantUtils
 import qualified Ganeti.Path as Path
 import Ganeti.BasicTypes
 
+import AutoConf
+
 data GanetiDaemon = GanetiMasterd
                   | GanetiNoded
                   | GanetiRapi
@@ -75,12 +79,12 @@ type RuntimeEnts = (M.Map GanetiDaemon UserID, M.Map GanetiGroup GroupID)
 
 -- | Returns the daemon name for a given daemon.
 daemonName :: GanetiDaemon -> String
-daemonName GanetiMasterd = C.masterd
-daemonName GanetiNoded   = C.noded
-daemonName GanetiRapi    = C.rapi
-daemonName GanetiConfd   = C.confd
-daemonName GanetiLuxid   = C.luxid
-daemonName GanetiMond    = C.mond
+daemonName GanetiMasterd = "ganeti-masterd"
+daemonName GanetiNoded   = "ganeti-noded"
+daemonName GanetiRapi    = "ganeti-rapi"
+daemonName GanetiConfd   = "ganeti-confd"
+daemonName GanetiLuxid   = "ganeti-luxid"
+daemonName GanetiMond    = "ganeti-mond"
 
 -- | Returns whether the daemon only runs on the master node.
 daemonOnlyOnMaster :: GanetiDaemon -> Bool
@@ -93,43 +97,38 @@ daemonOnlyOnMaster GanetiMond    = False
 
 -- | Returns the log file base for a daemon.
 daemonLogBase :: GanetiDaemon -> String
-daemonLogBase GanetiMasterd = C.daemonsLogbaseGanetiMasterd
-daemonLogBase GanetiNoded   = C.daemonsLogbaseGanetiNoded
-daemonLogBase GanetiRapi    = C.daemonsLogbaseGanetiRapi
-daemonLogBase GanetiConfd   = C.daemonsLogbaseGanetiConfd
-daemonLogBase GanetiLuxid   = C.daemonsLogbaseGanetiLuxid
-daemonLogBase GanetiMond    = C.daemonsLogbaseGanetiMond
+daemonLogBase GanetiMasterd = "master-daemon"
+daemonLogBase GanetiNoded   = "node-daemon"
+daemonLogBase GanetiRapi    = "rapi-daemon"
+daemonLogBase GanetiConfd   = "conf-daemon"
+daemonLogBase GanetiLuxid   = "luxi-daemon"
+daemonLogBase GanetiMond    = "monitoring-daemon"
 
 -- | Returns the configured user name for a daemon.
 daemonUser :: GanetiDaemon -> String
-daemonUser GanetiMasterd = C.masterdUser
-daemonUser GanetiNoded   = C.nodedUser
-daemonUser GanetiRapi    = C.rapiUser
-daemonUser GanetiConfd   = C.confdUser
-daemonUser GanetiLuxid   = C.luxidUser
-daemonUser GanetiMond    = C.mondUser
+daemonUser GanetiMasterd = AutoConf.masterdUser
+daemonUser GanetiNoded   = AutoConf.nodedUser
+daemonUser GanetiRapi    = AutoConf.rapiUser
+daemonUser GanetiConfd   = AutoConf.confdUser
+daemonUser GanetiLuxid   = AutoConf.luxidUser
+daemonUser GanetiMond    = AutoConf.mondUser
 
 -- | Returns the configured group for a daemon.
 daemonGroup :: GanetiGroup -> String
-daemonGroup (DaemonGroup GanetiMasterd) = C.masterdGroup
-daemonGroup (DaemonGroup GanetiNoded)   = C.nodedGroup
-daemonGroup (DaemonGroup GanetiRapi)    = C.rapiGroup
-daemonGroup (DaemonGroup GanetiConfd)   = C.confdGroup
-daemonGroup (DaemonGroup GanetiLuxid)   = C.luxidGroup
-daemonGroup (DaemonGroup GanetiMond)    = C.mondGroup
-daemonGroup (ExtraGroup  DaemonsGroup)  = C.daemonsGroup
-daemonGroup (ExtraGroup  AdminGroup)    = C.adminGroup
+daemonGroup (DaemonGroup GanetiMasterd) = AutoConf.masterdGroup
+daemonGroup (DaemonGroup GanetiNoded)   = AutoConf.nodedGroup
+daemonGroup (DaemonGroup GanetiRapi)    = AutoConf.rapiGroup
+daemonGroup (DaemonGroup GanetiConfd)   = AutoConf.confdGroup
+daemonGroup (DaemonGroup GanetiLuxid)   = AutoConf.luxidGroup
+daemonGroup (DaemonGroup GanetiMond)    = AutoConf.mondGroup
+daemonGroup (ExtraGroup  DaemonsGroup)  = AutoConf.daemonsGroup
+daemonGroup (ExtraGroup  AdminGroup)    = AutoConf.adminGroup
 
 data ExtraLogReason = AccessLog | ErrorLog
 
-daemonsExtraLogbase :: GanetiDaemon -> ExtraLogReason -> Maybe String
-daemonsExtraLogbase GanetiMond AccessLog =
-  Just C.daemonsExtraLogbaseGanetiMondAccess
-
-daemonsExtraLogbase GanetiMond ErrorLog =
-  Just C.daemonsExtraLogbaseGanetiMondError
-
-daemonsExtraLogbase _ _ = Nothing
+daemonsExtraLogbase :: GanetiDaemon -> ExtraLogReason -> String
+daemonsExtraLogbase daemon AccessLog = daemonLogBase daemon ++ "-access"
+daemonsExtraLogbase daemon ErrorLog = daemonLogBase daemon ++ "-error"
 
 -- | Returns the log file for a daemon.
 daemonLogFile :: GanetiDaemon -> IO FilePath
@@ -137,12 +136,11 @@ daemonLogFile daemon = do
   logDir <- Path.logDir
   return $ logDir </> daemonLogBase daemon <.> "log"
 
-daemonsExtraLogFile :: GanetiDaemon -> ExtraLogReason -> IO (Maybe FilePath)
+-- | Returns the extra log files for a daemon.
+daemonsExtraLogFile :: GanetiDaemon -> ExtraLogReason -> IO FilePath
 daemonsExtraLogFile daemon logreason = do
   logDir <- Path.logDir
-  case daemonsExtraLogbase daemon logreason of
-    Nothing -> return Nothing
-    Just logbase -> return . Just $ logDir </> logbase <.> "log"
+  return $ logDir </> daemonsExtraLogbase daemon logreason <.> "log"
 
 -- | Returns the pid file name for a daemon.
 daemonPidFile :: GanetiDaemon -> IO FilePath
@@ -202,4 +200,4 @@ checkUidMatch name expected actual =
                    \expected %d\n" name
               (fromIntegral actual::Int)
               (fromIntegral expected::Int) :: IO ()
-    exitWith $ ExitFailure C.exitFailure
+    exitWith $ ExitFailure ConstantUtils.exitFailure
