module Ganeti.Metad.ConfigCore where
import Control.Applicative
import Control.Concurrent.MVar.Lifted
import Control.Monad.Base
import Control.Monad.IO.Class
import Control.Monad.Reader
import Control.Monad.Trans.Control
import Language.Haskell.TH (Name)
import qualified Text.JSON as J
import Ganeti.BasicTypes
import Ganeti.Errors
import qualified Ganeti.JSON as J
import Ganeti.Logging as L
import Ganeti.Metad.Config as Config
import Ganeti.Metad.Types (InstanceParams)
data MetadHandle = MetadHandle
{ mhInstParams :: MVar InstanceParams
}
type MetadMonadIntType = ReaderT MetadHandle IO
newtype MetadMonadInt a = MetadMonadInt
{ getMetadMonadInt :: MetadMonadIntType a }
deriving ( Functor, Applicative, Monad, MonadIO, MonadBase IO
, L.MonadLog )
instance MonadBaseControl IO MetadMonadInt where
#if MIN_VERSION_monad_control(1,0,0)
type StM MetadMonadInt b = StM MetadMonadIntType b
liftBaseWith f = MetadMonadInt . liftBaseWith
$ \r -> f (r . getMetadMonadInt)
restoreM = MetadMonadInt . restoreM
#else
newtype StM MetadMonadInt b = StMMetadMonadInt
{ runStMMetadMonadInt :: StM MetadMonadIntType b }
liftBaseWith f = MetadMonadInt . liftBaseWith
$ \r -> f (liftM StMMetadMonadInt . r . getMetadMonadInt)
restoreM = MetadMonadInt . restoreM . runStMMetadMonadInt
#endif
runMetadMonadInt :: MetadMonadInt a -> MetadHandle -> IO a
runMetadMonadInt (MetadMonadInt k) = runReaderT k
type MetadMonad = ResultT GanetiException MetadMonadInt
metadHandle :: MetadMonad MetadHandle
metadHandle = lift . MetadMonadInt $ ask
instParams :: MetadMonad InstanceParams
instParams = readMVar . mhInstParams =<< metadHandle
modifyInstParams :: (InstanceParams -> MetadMonad (InstanceParams, a))
-> MetadMonad a
modifyInstParams f = do
h <- metadHandle
modifyMVar (mhInstParams h) f
echo :: String -> MetadMonad String
echo = return
updateConfig :: J.JSValue -> MetadMonad ()
updateConfig input = do
(name, m'instanceParams) <- J.fromJResultE "Could not get instance parameters"
$ Config.getInstanceParams input
case m'instanceParams of
Nothing -> L.logInfo $ "No communication NIC for instance " ++ name
++ ", skipping"
Just instanceParams -> do
cfg' <- modifyInstParams $ \cfg ->
let cfg' = mergeConfig cfg instanceParams
in return (cfg', cfg')
L.logInfo $
"Updated instance " ++ name ++ " configuration"
L.logDebug $ "Instance configuration: " ++ show cfg'
exportedFunctions :: [Name]
exportedFunctions = [ 'echo
, 'updateConfig
]