batchd-docker-0.1.0.0: src/Batchd/Ext/Docker.hs
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE StandaloneDeriving #-}
-- | This module contains an implementation of batchd host controllers,
-- which controls docker containers.
module Batchd.Ext.Docker
(DockerSettings (..),
dockerDriver,
defaultDockerUrl
) where
import Control.Monad (when)
import Control.Monad.Trans
import Control.Monad.Catch
import Control.Monad.IO.Unlift
import Control.Exception
import Data.Maybe
import Data.Typeable
import qualified Data.Text as T
import Data.Aeson
import Batchd.Core
import Docker.Client
deriving instance Typeable DockerError
instance Exception DockerError
-- | Settings of Docker host controller
data DockerSettings = DockerSettings {
dEnableStartStop :: Bool -- ^ Automatic start\/stop of containers can be disabled in config file
, dUnixSocket :: Maybe FilePath -- ^ This should be usually specified for default docker installation on local host
, dBaseUrl :: URL -- ^ Docker API URL
}
deriving (Show)
instance FromJSON DockerSettings where
parseJSON (Object v) = do
driver <- v .: "driver"
when (driver /= ("docker" :: T.Text)) $
fail $ "incorrect driver specification"
enable <- v .:? "enable_start_stop" .!= True
socket <- v .:? "unix_socket"
url <- v .:? "base_url" .!= defaultDockerUrl
return $ DockerSettings enable socket url
-- | Default Docker API URL.
defaultDockerUrl :: URL
defaultDockerUrl = baseUrl defaultClientOpts
getHttpHandler :: (MonadIO m, MonadMask m, MonadUnliftIO m) => DockerSettings -> m (HttpHandler m)
getHttpHandler d = do
case dUnixSocket d of
Nothing -> defaultHttpHandler
Just path -> unixHttpHandler path
-- | Initialize Docker host controller
dockerDriver :: HostDriver
dockerDriver =
controllerFromConfig "docker" $ \d lts -> HostController {
controllerDriverName = driverName dockerDriver,
getActualHostName = \_ -> return Nothing,
doesSupportStartStop = dEnableStartStop d,
startHost = \host -> do
handler <- getHttpHandler d
let opts = defaultClientOpts {baseUrl = dBaseUrl d}
r <- runDockerT (opts, handler) $ do
startContainer defaultStartOpts $ fromJust $ toContainerID $ hControllerId host
case r of
Right _ -> return $ Right ()
Left err -> return $ Left $ UnknownError $ show err,
stopHost = \name -> do
handler <- getHttpHandler d
let opts = defaultClientOpts {baseUrl = dBaseUrl d}
r <- runDockerT (opts, handler) $ do
stopContainer DefaultTimeout $ fromJust $ toContainerID name
case r of
Right _ -> return $ Right ()
Left err -> return $ Left $ UnknownError $ show err
}