module Ganeti.Ssconf
( SSKey(..)
, sSKeyToRaw
, sSKeyFromRaw
, getPrimaryIPFamily
, keyToFilename
, sSFilePrefix
) where
import Ganeti.THH
import Control.Exception
import Control.Monad (liftM)
import Data.Char (isSpace)
import Data.Maybe (fromMaybe)
import qualified Network.Socket as Socket
import System.FilePath ((</>))
import System.IO.Error (isDoesNotExistError)
import qualified Ganeti.Constants as C
import Ganeti.BasicTypes
import Ganeti.HTools.Utils
maxFileSize :: Int
maxFileSize = 131072
sSFilePrefix :: FilePath
sSFilePrefix = C.ssconfFileprefix
$(declareSADT "SSKey"
[ ("SSClusterName", 'C.ssClusterName)
, ("SSClusterTags", 'C.ssClusterTags)
, ("SSFileStorageDir", 'C.ssFileStorageDir)
, ("SSSharedFileStorageDir", 'C.ssSharedFileStorageDir)
, ("SSMasterCandidates", 'C.ssMasterCandidates)
, ("SSMasterCandidatesIps", 'C.ssMasterCandidatesIps)
, ("SSMasterIp", 'C.ssMasterIp)
, ("SSMasterNetdev", 'C.ssMasterNetdev)
, ("SSMasterNetmask", 'C.ssMasterNetmask)
, ("SSMasterNode", 'C.ssMasterNode)
, ("SSNodeList", 'C.ssNodeList)
, ("SSNodePrimaryIps", 'C.ssNodePrimaryIps)
, ("SSNodeSecondaryIps", 'C.ssNodeSecondaryIps)
, ("SSOfflineNodes", 'C.ssOfflineNodes)
, ("SSOnlineNodes", 'C.ssOnlineNodes)
, ("SSPrimaryIpFamily", 'C.ssPrimaryIpFamily)
, ("SSInstanceList", 'C.ssInstanceList)
, ("SSReleaseVersion", 'C.ssReleaseVersion)
, ("SSHypervisorList", 'C.ssHypervisorList)
, ("SSMaintainNodeHealth", 'C.ssMaintainNodeHealth)
, ("SSUidPool", 'C.ssUidPool)
, ("SSNodegroups", 'C.ssNodegroups)
])
keyToFilename :: Maybe FilePath
-> SSKey
-> FilePath
keyToFilename optpath key = fromMaybe C.dataDir optpath </>
sSFilePrefix ++ sSKeyToRaw key
catchIOErrors :: Maybe a
-> IO a
-> IO (Result a)
catchIOErrors def action =
Control.Exception.catch
(do
result <- action
return (Ok result)
) (\err -> let bad_result = Bad (show err)
in return $ if isDoesNotExistError err
then maybe bad_result Ok def
else bad_result)
readSSConfFile :: Maybe FilePath
-> Maybe String
-> SSKey
-> IO (Result String)
readSSConfFile optpath def key = do
result <- catchIOErrors def . readFile . keyToFilename optpath $ key
return (liftM (take maxFileSize) result)
rstripSpace :: String -> String
rstripSpace = reverse . dropWhile isSpace . reverse
parseIPFamily :: Int -> Result Socket.Family
parseIPFamily fam | fam == C.ip4Family = Ok Socket.AF_INET
| fam == C.ip6Family = Ok Socket.AF_INET6
| otherwise = Bad $ "Unknown af_family value: " ++ show fam
getPrimaryIPFamily :: Maybe FilePath -> IO (Result Socket.Family)
getPrimaryIPFamily optpath = do
result <- readSSConfFile optpath (Just (show C.ip4Family)) SSPrimaryIpFamily
return (result >>= return . rstripSpace >>=
tryRead "Parsing af_family" >>= parseIPFamily)