{-# LANGUAGE RecordWildCards     #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Docker.Client.Types (
      Endpoint(..)
    , URL
    , ApiVersion
    , ContainerID
    , fromContainerID
    , toContainerID
    , ImageID
    , fromImageID
    , toImageID
    , NetworkID
    , fromNetworkID
    , toNetworkID
    , Timeout(..)
    , StatusCode(..)
    , Signal(..)
    , ContainerDetails(..)
    , DockerClientOpts(..)
    , defaultClientOpts
    , ListOpts(..)
    , defaultListOpts
    , DockerVersion(..)
    , ContainerPortInfo(..)
    , Container(..)
    , ContainerState(..)
    , State(..)
    , Digest
    , Label(..)
    , Tag
    , Image(..)
    , Entrypoint(..)
    , dropImagePrefix
    , CreateOpts(..)
    , BuildOpts(..)
    , defaultBuildOpts
    , defaultCreateOpts
    , DetachKeys(..)
    , StartOpts(..)
    , defaultStartOpts
    , ContainerDeleteOpts(..)
    , defaultContainerDeleteOpts
    , ImageDeleteOpts(..)
    , defaultImageDeleteOpts
    , Timestamp
    , TailLogOpt(..)
    , LogOpts(..)
    , defaultLogOpts
    , CreateNetworkOpts(..)
    , defaultCreateNetworkOpts
    , VolumePermission(..)
    , Bind(..)
    , Volume(..)
    , Device(..)
    , ContainerName
    , VolumeFrom(..)
    , Link(..)
    , LogDriverType(..)
    , LogDriverOption(..)
    , LogDriverConfig(..)
    , NetworkMode(..)
    , PortType(..)
--    , NetworkInterface(..)
    , Network(..)
    , NetworkSettings(..)
    , NetworkOptions(..)
    , Mount(..)
    , PortBinding(..)
    , HostPort(..)
    , RetryCount
    , RestartPolicy(..)
    , Isolation(..)
    , UTSMode(..)
    , HostConfig(..)
    , defaultHostConfig
    , NetworkingConfig(..)
    , EndpointConfig(..)
    , Ulimit(..)
    , ContainerResources(..)
    , defaultContainerResources
    , Port
    , Name
    , Value
    , EnvVar(..)
    , ContainerConfig(..)
    , defaultContainerConfig
    , ExposedPort(..)
    , DeviceWeight(..)
    , DeviceRate(..)
    , addPortBinding
    , addExposedPort
    , addBind
    , setCmd
    , addLink
    , addVolume
    , addVolumeFrom
    , MemoryConstraint(..)
    , MemoryConstraintSize(..)
    ) where

import           Data.Aeson          (FromJSON, ToJSON, genericParseJSON,
                                      genericToJSON, object, parseJSON, toJSON,
                                      (.!=), (.:), (.:?), (.=))
import qualified Data.Aeson          as JSON
#if MIN_VERSION_aeson(2,0,0)
import qualified Data.Aeson.Key      as K
import qualified Data.Aeson.KeyMap   as KM
#endif
import           Data.Aeson.Types    (emptyObject, defaultOptions, fieldLabelModifier)
import           Data.Char           (isAlphaNum, toUpper)
import qualified Data.HashMap.Strict as HM
import           Data.Maybe          (fromMaybe)
import           Data.Monoid         ((<>))
import           Data.Scientific     (floatingOrInteger)
import           Data.Text           (Text)
import qualified Data.Text           as T
import           Data.Time.Clock     (UTCTime)
import qualified Data.Vector         as V
import           GHC.Generics        (Generic)
import           Prelude             hiding (all, tail)
import           Text.Read           (readMaybe)

-- | List of Docker Engine API endpoints
data Endpoint =
        VersionEndpoint
      | ListContainersEndpoint ListOpts
      | ListImagesEndpoint ListOpts
      | CreateContainerEndpoint CreateOpts (Maybe ContainerName)
      | StartContainerEndpoint StartOpts ContainerID
      | StopContainerEndpoint Timeout ContainerID
      | WaitContainerEndpoint ContainerID
      | KillContainerEndpoint Signal ContainerID
      | RestartContainerEndpoint Timeout ContainerID
      | PauseContainerEndpoint ContainerID
      | UnpauseContainerEndpoint ContainerID
      | ContainerLogsEndpoint LogOpts Bool ContainerID -- ^ Second argument (Bool) is whether to follow which is currently hardcoded to False.
      -- See note in 'Docker.Client.Api.getContainerLogs' for explanation why.
      | DeleteContainerEndpoint ContainerDeleteOpts ContainerID
      | InspectContainerEndpoint ContainerID
      | BuildImageEndpoint BuildOpts FilePath
      | CreateImageEndpoint T.Text Tag (Maybe T.Text) -- ^ Either pull an image from docker hub or imports an image from a tarball (or URL)
      | DeleteImageEndpoint ImageDeleteOpts ImageID
      | CreateNetworkEndpoint CreateNetworkOpts
      | RemoveNetworkEndpoint NetworkID
    deriving (Endpoint -> Endpoint -> Bool
(Endpoint -> Endpoint -> Bool)
-> (Endpoint -> Endpoint -> Bool) -> Eq Endpoint
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Endpoint -> Endpoint -> Bool
$c/= :: Endpoint -> Endpoint -> Bool
== :: Endpoint -> Endpoint -> Bool
$c== :: Endpoint -> Endpoint -> Bool
Eq, Int -> Endpoint -> ShowS
[Endpoint] -> ShowS
Endpoint -> String
(Int -> Endpoint -> ShowS)
-> (Endpoint -> String) -> ([Endpoint] -> ShowS) -> Show Endpoint
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Endpoint] -> ShowS
$cshowList :: [Endpoint] -> ShowS
show :: Endpoint -> String
$cshow :: Endpoint -> String
showsPrec :: Int -> Endpoint -> ShowS
$cshowsPrec :: Int -> Endpoint -> ShowS
Show)

-- | We should newtype this
type URL = Text

-- | We should newtype this
type ApiVersion = Text


-- | ID of a contianer
newtype ContainerID = ContainerID Text
    deriving (ContainerID -> ContainerID -> Bool
(ContainerID -> ContainerID -> Bool)
-> (ContainerID -> ContainerID -> Bool) -> Eq ContainerID
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ContainerID -> ContainerID -> Bool
$c/= :: ContainerID -> ContainerID -> Bool
== :: ContainerID -> ContainerID -> Bool
$c== :: ContainerID -> ContainerID -> Bool
Eq, Int -> ContainerID -> ShowS
[ContainerID] -> ShowS
ContainerID -> String
(Int -> ContainerID -> ShowS)
-> (ContainerID -> String)
-> ([ContainerID] -> ShowS)
-> Show ContainerID
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ContainerID] -> ShowS
$cshowList :: [ContainerID] -> ShowS
show :: ContainerID -> String
$cshow :: ContainerID -> String
showsPrec :: Int -> ContainerID -> ShowS
$cshowsPrec :: Int -> ContainerID -> ShowS
Show)

-- | Used for extracting the id of the container from the newtype
fromContainerID :: ContainerID -> Text
fromContainerID :: ContainerID -> Text
fromContainerID (ContainerID Text
t) = Text
t

-- | Used for parsing a Text value into a ContainerID. We apply some basic
-- validation here.
toContainerID :: Text -> Maybe ContainerID
toContainerID :: Text -> Maybe ContainerID
toContainerID Text
t =
    if (Char -> Bool) -> Text -> Bool
T.all (\Char
c -> Char -> Bool
isAlphaNum Char
c Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
':') Text
t then -- Note: Can we improve this whitelist?
        ContainerID -> Maybe ContainerID
forall a. a -> Maybe a
Just (ContainerID -> Maybe ContainerID)
-> ContainerID -> Maybe ContainerID
forall a b. (a -> b) -> a -> b
$ Text -> ContainerID
ContainerID Text
t
    else
        Maybe ContainerID
forall a. Maybe a
Nothing

-- ID of an image.
newtype ImageID = ImageID Text
    deriving (ImageID -> ImageID -> Bool
(ImageID -> ImageID -> Bool)
-> (ImageID -> ImageID -> Bool) -> Eq ImageID
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ImageID -> ImageID -> Bool
$c/= :: ImageID -> ImageID -> Bool
== :: ImageID -> ImageID -> Bool
$c== :: ImageID -> ImageID -> Bool
Eq, Int -> ImageID -> ShowS
[ImageID] -> ShowS
ImageID -> String
(Int -> ImageID -> ShowS)
-> (ImageID -> String) -> ([ImageID] -> ShowS) -> Show ImageID
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ImageID] -> ShowS
$cshowList :: [ImageID] -> ShowS
show :: ImageID -> String
$cshow :: ImageID -> String
showsPrec :: Int -> ImageID -> ShowS
$cshowsPrec :: Int -> ImageID -> ShowS
Show)

-- | Used for extracting the id of the image from the newtype.
fromImageID :: ImageID -> Text
fromImageID :: ImageID -> Text
fromImageID (ImageID Text
t) = Text
t

-- | Helper function used for parsing a Text value into an ImageID. For now
-- just basic validation is used.
toImageID :: Text -> Maybe ImageID
toImageID :: Text -> Maybe ImageID
toImageID Text
t =
    if (Char -> Bool) -> Text -> Bool
T.all (\Char
c -> Char -> Bool
isAlphaNum Char
c Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
':') Text
t then -- Note: Can we improve this whitelist?
        ImageID -> Maybe ImageID
forall a. a -> Maybe a
Just (ImageID -> Maybe ImageID) -> ImageID -> Maybe ImageID
forall a b. (a -> b) -> a -> b
$ Text -> ImageID
ImageID Text
t
    else
        Maybe ImageID
forall a. Maybe a
Nothing

-- | Timeout used for stopping a container. DefaultTimeout is 10 seconds.
data Timeout = Timeout Integer | DefaultTimeout deriving (Timeout -> Timeout -> Bool
(Timeout -> Timeout -> Bool)
-> (Timeout -> Timeout -> Bool) -> Eq Timeout
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Timeout -> Timeout -> Bool
$c/= :: Timeout -> Timeout -> Bool
== :: Timeout -> Timeout -> Bool
$c== :: Timeout -> Timeout -> Bool
Eq, Int -> Timeout -> ShowS
[Timeout] -> ShowS
Timeout -> String
(Int -> Timeout -> ShowS)
-> (Timeout -> String) -> ([Timeout] -> ShowS) -> Show Timeout
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Timeout] -> ShowS
$cshowList :: [Timeout] -> ShowS
show :: Timeout -> String
$cshow :: Timeout -> String
showsPrec :: Int -> Timeout -> ShowS
$cshowsPrec :: Int -> Timeout -> ShowS
Show)

data StatusCode = StatusCode Int

instance ToJSON StatusCode where
    toJSON :: StatusCode -> Value
toJSON (StatusCode Int
c) = [Pair] -> Value
object [Key
"StatusCode" Key -> Int -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Int
c]

instance FromJSON StatusCode where
    parseJSON :: Value -> Parser StatusCode
parseJSON (JSON.Object Object
o) = do
        Int
c <- Object
o Object -> Key -> Parser Int
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"StatusCode"
        if Int
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
255 then
          StatusCode -> Parser StatusCode
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> StatusCode
StatusCode Int
c)
        else
          String -> Parser StatusCode
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Unknown exit code"
    parseJSON Value
_ = String -> Parser StatusCode
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Unknown exit code"

-- TODO: Add more Signals or use an existing lib
-- | Signal used for sending to the process running in the container.
-- The default signal is SIGTERM.
data Signal = SIGHUP
            | SIGINT
            | SIGQUIT
            | SIGSTOP
            | SIGTERM
            | SIGUSR1
            | SIG Integer
            | SIGKILL deriving (Signal -> Signal -> Bool
(Signal -> Signal -> Bool)
-> (Signal -> Signal -> Bool) -> Eq Signal
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Signal -> Signal -> Bool
$c/= :: Signal -> Signal -> Bool
== :: Signal -> Signal -> Bool
$c== :: Signal -> Signal -> Bool
Eq, Int -> Signal -> ShowS
[Signal] -> ShowS
Signal -> String
(Int -> Signal -> ShowS)
-> (Signal -> String) -> ([Signal] -> ShowS) -> Show Signal
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Signal] -> ShowS
$cshowList :: [Signal] -> ShowS
show :: Signal -> String
$cshow :: Signal -> String
showsPrec :: Int -> Signal -> ShowS
$cshowsPrec :: Int -> Signal -> ShowS
Show)

instance FromJSON Signal where
    parseJSON :: Value -> Parser Signal
parseJSON (JSON.String Text
"SIGTERM") = Signal -> Parser Signal
forall (m :: * -> *) a. Monad m => a -> m a
return Signal
SIGTERM
    parseJSON (JSON.String Text
"SIGHUP")  = Signal -> Parser Signal
forall (m :: * -> *) a. Monad m => a -> m a
return Signal
SIGHUP -- Note: Guessing on the string values for these.
    parseJSON (JSON.String Text
"SIGINT")  = Signal -> Parser Signal
forall (m :: * -> *) a. Monad m => a -> m a
return Signal
SIGINT
    parseJSON (JSON.String Text
"SIGQUIT") = Signal -> Parser Signal
forall (m :: * -> *) a. Monad m => a -> m a
return Signal
SIGQUIT
    parseJSON (JSON.String Text
"SIGSTOP") = Signal -> Parser Signal
forall (m :: * -> *) a. Monad m => a -> m a
return Signal
SIGSTOP
    parseJSON (JSON.String Text
"SIGUSR1") = Signal -> Parser Signal
forall (m :: * -> *) a. Monad m => a -> m a
return Signal
SIGUSR1
    parseJSON Value
_                       = String -> Parser Signal
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Unknown Signal"

instance ToJSON Signal where
    toJSON :: Signal -> Value
toJSON Signal
SIGHUP  = Value
"SIGHUP"
    toJSON Signal
SIGINT  = Value
"SIGINT"
    toJSON Signal
SIGQUIT = Value
"SIGQUIT"
    toJSON Signal
SIGSTOP = Value
"SIGSTOP"
    toJSON Signal
SIGTERM = Value
"SIGTERM"
    toJSON Signal
SIGUSR1 = Value
"SIGUSR1"
    toJSON (SIG Integer
i) = Integer -> Value
forall a. ToJSON a => a -> Value
toJSON Integer
i
    toJSON Signal
SIGKILL = Value
"SIGKILL"

data ContainerDetails = ContainerDetails {
      ContainerDetails -> Text
appArmorProfile            :: Text
    , ContainerDetails -> [Text]
args                       :: [Text]
    , ContainerDetails -> ContainerConfig
containerDetailsConfig     :: ContainerConfig
    , ContainerDetails -> UTCTime
created                    :: UTCTime
    , ContainerDetails -> Text
driver                     :: Text
    -- , execIDs -- Not sure what this is in 1.24 spec.
    , ContainerDetails -> HostConfig
containerDetailsHostConfig :: HostConfig
    , ContainerDetails -> String
hostnamePath               :: FilePath
    , ContainerDetails -> String
hostsPath                  :: FilePath
    , ContainerDetails -> String
logPath                    :: FilePath
    , ContainerDetails -> ContainerID
containerDetailsId         :: ContainerID
    , ContainerDetails -> ImageID
containerDetailsImage      :: ImageID
    , ContainerDetails -> Text
mountLabel                 :: Text
    , ContainerDetails -> Text
name                       :: Text
    , ContainerDetails -> NetworkSettings
networkSettings            :: NetworkSettings
    , ContainerDetails -> String
path                       :: FilePath
    , ContainerDetails -> Text
processLabel               :: Text
    , ContainerDetails -> String
resolveConfPath            :: FilePath
    , ContainerDetails -> Int
restartCount               :: Int
    , ContainerDetails -> ContainerState
containerDetailsState      :: ContainerState
    , ContainerDetails -> [Mount]
mounts                     :: [Mount]
    }
    deriving (ContainerDetails -> ContainerDetails -> Bool
(ContainerDetails -> ContainerDetails -> Bool)
-> (ContainerDetails -> ContainerDetails -> Bool)
-> Eq ContainerDetails
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ContainerDetails -> ContainerDetails -> Bool
$c/= :: ContainerDetails -> ContainerDetails -> Bool
== :: ContainerDetails -> ContainerDetails -> Bool
$c== :: ContainerDetails -> ContainerDetails -> Bool
Eq, Int -> ContainerDetails -> ShowS
[ContainerDetails] -> ShowS
ContainerDetails -> String
(Int -> ContainerDetails -> ShowS)
-> (ContainerDetails -> String)
-> ([ContainerDetails] -> ShowS)
-> Show ContainerDetails
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ContainerDetails] -> ShowS
$cshowList :: [ContainerDetails] -> ShowS
show :: ContainerDetails -> String
$cshow :: ContainerDetails -> String
showsPrec :: Int -> ContainerDetails -> ShowS
$cshowsPrec :: Int -> ContainerDetails -> ShowS
Show, (forall x. ContainerDetails -> Rep ContainerDetails x)
-> (forall x. Rep ContainerDetails x -> ContainerDetails)
-> Generic ContainerDetails
forall x. Rep ContainerDetails x -> ContainerDetails
forall x. ContainerDetails -> Rep ContainerDetails x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ContainerDetails x -> ContainerDetails
$cfrom :: forall x. ContainerDetails -> Rep ContainerDetails x
Generic)

-- | Data type used for parsing the mount information from a container
-- list.
data Mount = Mount {
      Mount -> Maybe Text
mountName        :: Maybe Text -- this is optional
    , Mount -> String
mountSource      :: FilePath
    , Mount -> String
mountDestination :: FilePath
    , Mount -> Maybe Text
mountDriver      :: Maybe Text
    -- , mountMode        :: Maybe VolumePermission -- apparently this can be null
    , Mount -> Bool
mountRW          :: Bool
    , Mount -> Text
mountPropogation :: Text
    }
    deriving (Mount -> Mount -> Bool
(Mount -> Mount -> Bool) -> (Mount -> Mount -> Bool) -> Eq Mount
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Mount -> Mount -> Bool
$c/= :: Mount -> Mount -> Bool
== :: Mount -> Mount -> Bool
$c== :: Mount -> Mount -> Bool
Eq, Int -> Mount -> ShowS
[Mount] -> ShowS
Mount -> String
(Int -> Mount -> ShowS)
-> (Mount -> String) -> ([Mount] -> ShowS) -> Show Mount
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Mount] -> ShowS
$cshowList :: [Mount] -> ShowS
show :: Mount -> String
$cshow :: Mount -> String
showsPrec :: Int -> Mount -> ShowS
$cshowsPrec :: Int -> Mount -> ShowS
Show, (forall x. Mount -> Rep Mount x)
-> (forall x. Rep Mount x -> Mount) -> Generic Mount
forall x. Rep Mount x -> Mount
forall x. Mount -> Rep Mount x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Mount x -> Mount
$cfrom :: forall x. Mount -> Rep Mount x
Generic)

instance FromJSON Mount where
    parseJSON :: Value -> Parser Mount
parseJSON (JSON.Object Object
o) = do
        Maybe Text
name <- Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"Name"
        String
src <- Object
o Object -> Key -> Parser String
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Source"
        String
dest <- Object
o Object -> Key -> Parser String
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Destination"
        Maybe Text
driver <- Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"Driver"
        -- mode <- o .: "Mode"
        Bool
rw <- Object
o Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"RW"
        Text
prop <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Propagation"
        Mount -> Parser Mount
forall (m :: * -> *) a. Monad m => a -> m a
return (Mount -> Parser Mount) -> Mount -> Parser Mount
forall a b. (a -> b) -> a -> b
$ Maybe Text
-> String -> String -> Maybe Text -> Bool -> Text -> Mount
Mount Maybe Text
name String
src String
dest Maybe Text
driver Bool
rw Text
prop
    parseJSON Value
_ = String -> Parser Mount
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Mount is not an object"

-- | Data type used for parsing the container state from a list of
-- containers.
data ContainerState = ContainerState {
      ContainerState -> Text
containerError :: Text
    , ContainerState -> Int
exitCode       :: Int
    , ContainerState -> Maybe UTCTime
finishedAt     :: Maybe UTCTime -- Note: Is this a maybe?
    , ContainerState -> Bool
oomKilled      :: Bool
    , ContainerState -> Bool
dead           :: Bool
    , ContainerState -> Bool
paused         :: Bool
    , ContainerState -> Int
pid            :: Int
    , ContainerState -> Bool
restarting     :: Bool
    , ContainerState -> Bool
running        :: Bool
    , ContainerState -> UTCTime
startedAt      :: UTCTime
    , ContainerState -> State
state          :: State
    }
    deriving (ContainerState -> ContainerState -> Bool
(ContainerState -> ContainerState -> Bool)
-> (ContainerState -> ContainerState -> Bool) -> Eq ContainerState
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ContainerState -> ContainerState -> Bool
$c/= :: ContainerState -> ContainerState -> Bool
== :: ContainerState -> ContainerState -> Bool
$c== :: ContainerState -> ContainerState -> Bool
Eq, Int -> ContainerState -> ShowS
[ContainerState] -> ShowS
ContainerState -> String
(Int -> ContainerState -> ShowS)
-> (ContainerState -> String)
-> ([ContainerState] -> ShowS)
-> Show ContainerState
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ContainerState] -> ShowS
$cshowList :: [ContainerState] -> ShowS
show :: ContainerState -> String
$cshow :: ContainerState -> String
showsPrec :: Int -> ContainerState -> ShowS
$cshowsPrec :: Int -> ContainerState -> ShowS
Show, (forall x. ContainerState -> Rep ContainerState x)
-> (forall x. Rep ContainerState x -> ContainerState)
-> Generic ContainerState
forall x. Rep ContainerState x -> ContainerState
forall x. ContainerState -> Rep ContainerState x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ContainerState x -> ContainerState
$cfrom :: forall x. ContainerState -> Rep ContainerState x
Generic)

instance FromJSON ContainerState where
    parseJSON :: Value -> Parser ContainerState
parseJSON (JSON.Object Object
o) = do
        Text
err <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Error"
        Int
exit <- Object
o Object -> Key -> Parser Int
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"ExitCode"
        Maybe UTCTime
finished <- Object
o Object -> Key -> Parser (Maybe UTCTime)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"FinishedAt"
        Bool
oomKilled <- Object
o Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"OOMKilled"
        Bool
dead <- Object
o Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Dead"
        Bool
paused <- Object
o Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Paused"
        Int
pid <- Object
o Object -> Key -> Parser Int
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Pid"
        Bool
restarting <- Object
o Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Restarting"
        Bool
running <- Object
o Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Running"
        UTCTime
started <- Object
o Object -> Key -> Parser UTCTime
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"StartedAt"
        State
st <- Object
o Object -> Key -> Parser State
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Status"
        ContainerState -> Parser ContainerState
forall (m :: * -> *) a. Monad m => a -> m a
return (ContainerState -> Parser ContainerState)
-> ContainerState -> Parser ContainerState
forall a b. (a -> b) -> a -> b
$ Text
-> Int
-> Maybe UTCTime
-> Bool
-> Bool
-> Bool
-> Int
-> Bool
-> Bool
-> UTCTime
-> State
-> ContainerState
ContainerState Text
err Int
exit Maybe UTCTime
finished Bool
oomKilled Bool
dead Bool
paused Int
pid Bool
restarting Bool
running UTCTime
started State
st
    parseJSON Value
_ = String -> Parser ContainerState
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"ContainerState is not an object"


-- | Client options used to configure the remote engine we're talking to
data DockerClientOpts = DockerClientOpts {
      DockerClientOpts -> Text
apiVer  :: ApiVersion
    , DockerClientOpts -> Text
baseUrl :: URL
    }
    deriving (DockerClientOpts -> DockerClientOpts -> Bool
(DockerClientOpts -> DockerClientOpts -> Bool)
-> (DockerClientOpts -> DockerClientOpts -> Bool)
-> Eq DockerClientOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DockerClientOpts -> DockerClientOpts -> Bool
$c/= :: DockerClientOpts -> DockerClientOpts -> Bool
== :: DockerClientOpts -> DockerClientOpts -> Bool
$c== :: DockerClientOpts -> DockerClientOpts -> Bool
Eq, Int -> DockerClientOpts -> ShowS
[DockerClientOpts] -> ShowS
DockerClientOpts -> String
(Int -> DockerClientOpts -> ShowS)
-> (DockerClientOpts -> String)
-> ([DockerClientOpts] -> ShowS)
-> Show DockerClientOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DockerClientOpts] -> ShowS
$cshowList :: [DockerClientOpts] -> ShowS
show :: DockerClientOpts -> String
$cshow :: DockerClientOpts -> String
showsPrec :: Int -> DockerClientOpts -> ShowS
$cshowsPrec :: Int -> DockerClientOpts -> ShowS
Show)

-- | Default "DockerClientOpts" used for talking to the docker engine.
defaultClientOpts :: DockerClientOpts
defaultClientOpts :: DockerClientOpts
defaultClientOpts = DockerClientOpts :: Text -> Text -> DockerClientOpts
DockerClientOpts {
                  apiVer :: Text
apiVer = Text
"v1.24"
                , baseUrl :: Text
baseUrl = Text
"http://127.0.0.1:2375"
                }

-- | List options used for filtering the list of container or images.
data ListOpts = ListOpts { ListOpts -> Bool
all :: Bool } deriving (ListOpts -> ListOpts -> Bool
(ListOpts -> ListOpts -> Bool)
-> (ListOpts -> ListOpts -> Bool) -> Eq ListOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ListOpts -> ListOpts -> Bool
$c/= :: ListOpts -> ListOpts -> Bool
== :: ListOpts -> ListOpts -> Bool
$c== :: ListOpts -> ListOpts -> Bool
Eq, Int -> ListOpts -> ShowS
[ListOpts] -> ShowS
ListOpts -> String
(Int -> ListOpts -> ShowS)
-> (ListOpts -> String) -> ([ListOpts] -> ShowS) -> Show ListOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ListOpts] -> ShowS
$cshowList :: [ListOpts] -> ShowS
show :: ListOpts -> String
$cshow :: ListOpts -> String
showsPrec :: Int -> ListOpts -> ShowS
$cshowsPrec :: Int -> ListOpts -> ShowS
Show)

-- | Default "ListOpts". Doesn't list stopped containers.
defaultListOpts :: ListOpts
defaultListOpts :: ListOpts
defaultListOpts = ListOpts :: Bool -> ListOpts
ListOpts { all :: Bool
all=Bool
False }

-- | Data type used for represneting the version of the docker engine
-- remote API.
data DockerVersion = DockerVersion {
                    DockerVersion -> Text
version       :: Text
                  , DockerVersion -> Text
apiVersion    :: ApiVersion
                  , DockerVersion -> Text
gitCommit     :: Text
                  , DockerVersion -> Text
goVersion     :: Text
                  , DockerVersion -> Text
os            :: Text
                  , DockerVersion -> Text
arch          :: Text
                  , DockerVersion -> Text
kernelVersion :: Text
                  , DockerVersion -> Text
buildTime     :: Text
                  } deriving (Int -> DockerVersion -> ShowS
[DockerVersion] -> ShowS
DockerVersion -> String
(Int -> DockerVersion -> ShowS)
-> (DockerVersion -> String)
-> ([DockerVersion] -> ShowS)
-> Show DockerVersion
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DockerVersion] -> ShowS
$cshowList :: [DockerVersion] -> ShowS
show :: DockerVersion -> String
$cshow :: DockerVersion -> String
showsPrec :: Int -> DockerVersion -> ShowS
$cshowsPrec :: Int -> DockerVersion -> ShowS
Show, DockerVersion -> DockerVersion -> Bool
(DockerVersion -> DockerVersion -> Bool)
-> (DockerVersion -> DockerVersion -> Bool) -> Eq DockerVersion
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DockerVersion -> DockerVersion -> Bool
$c/= :: DockerVersion -> DockerVersion -> Bool
== :: DockerVersion -> DockerVersion -> Bool
$c== :: DockerVersion -> DockerVersion -> Bool
Eq, (forall x. DockerVersion -> Rep DockerVersion x)
-> (forall x. Rep DockerVersion x -> DockerVersion)
-> Generic DockerVersion
forall x. Rep DockerVersion x -> DockerVersion
forall x. DockerVersion -> Rep DockerVersion x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DockerVersion x -> DockerVersion
$cfrom :: forall x. DockerVersion -> Rep DockerVersion x
Generic)


instance ToJSON DockerVersion where
    toJSON :: DockerVersion -> Value
toJSON = Options -> DockerVersion -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
defaultOptions {
         fieldLabelModifier :: ShowS
fieldLabelModifier = (\(Char
x:String
xs) -> Char -> Char
toUpper Char
x Char -> ShowS
forall a. a -> [a] -> [a]
: String
xs)}

instance FromJSON DockerVersion where
    parseJSON :: Value -> Parser DockerVersion
parseJSON = Options -> Value -> Parser DockerVersion
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
defaultOptions {
            fieldLabelModifier :: ShowS
fieldLabelModifier = (\(Char
x:String
xs) -> Char -> Char
toUpper Char
x Char -> ShowS
forall a. a -> [a] -> [a]
: String
xs)}

instance FromJSON ContainerDetails where
    parseJSON :: Value -> Parser ContainerDetails
parseJSON v :: Value
v@(JSON.Object Object
o) = do
        Text
appArmor <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"AppArmorProfile"
        [Text]
args <- Object
o Object -> Key -> Parser [Text]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Args"
        ContainerConfig
config <- Object
o Object -> Key -> Parser ContainerConfig
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Config"
        UTCTime
created <- Object
o Object -> Key -> Parser UTCTime
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Created"
        Text
driver <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Driver"
        HostConfig
hostConfig <- Object
o Object -> Key -> Parser HostConfig
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"HostConfig"
        String
hostnamePath <- Object
o Object -> Key -> Parser String
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"HostnamePath"
        String
hostsPath <- Object
o Object -> Key -> Parser String
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"HostsPath"
        String
logPath <- Object
o Object -> Key -> Parser String
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"LogPath"
        ContainerID
id <- Value -> Parser ContainerID
forall a. FromJSON a => Value -> Parser a
parseJSON Value
v
        ImageID
image <- Object
o Object -> Key -> Parser ImageID
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Image"
        Text
mountLabel <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"MountLabel"
        Text
name <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Name"
        NetworkSettings
networkSettings <- Object
o Object -> Key -> Parser NetworkSettings
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"NetworkSettings"
        String
path <- Object
o Object -> Key -> Parser String
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Path"
        Text
processLabel <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"ProcessLabel"
        String
resolveConfPath <- Object
o Object -> Key -> Parser String
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"ResolvConfPath"
        Int
restartCount <- Object
o Object -> Key -> Parser Int
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"RestartCount"
        ContainerState
state <- Object
o Object -> Key -> Parser ContainerState
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"State"
        [Mount]
mounts <- Object
o Object -> Key -> Parser [Mount]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Mounts"
        ContainerDetails -> Parser ContainerDetails
forall (m :: * -> *) a. Monad m => a -> m a
return (ContainerDetails -> Parser ContainerDetails)
-> ContainerDetails -> Parser ContainerDetails
forall a b. (a -> b) -> a -> b
$ Text
-> [Text]
-> ContainerConfig
-> UTCTime
-> Text
-> HostConfig
-> String
-> String
-> String
-> ContainerID
-> ImageID
-> Text
-> Text
-> NetworkSettings
-> String
-> Text
-> String
-> Int
-> ContainerState
-> [Mount]
-> ContainerDetails
ContainerDetails Text
appArmor [Text]
args ContainerConfig
config UTCTime
created Text
driver HostConfig
hostConfig String
hostnamePath String
hostsPath String
logPath ContainerID
id ImageID
image Text
mountLabel Text
name NetworkSettings
networkSettings String
path Text
processLabel String
resolveConfPath Int
restartCount ContainerState
state [Mount]
mounts
    parseJSON Value
_ = String -> Parser ContainerDetails
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"ContainerDetails is not an object"

instance ToJSON ContainerID where
    toJSON :: ContainerID -> Value
toJSON (ContainerID Text
cid) = [Pair] -> Value
object [Key
"Id" Key -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Text
cid]

instance FromJSON ContainerID where
    parseJSON :: Value -> Parser ContainerID
parseJSON (JSON.Object Object
o) = do
        Text
cid <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Id"
        case Text -> Maybe ContainerID
toContainerID Text
cid of
            Maybe ContainerID
Nothing ->
                String -> Parser ContainerID
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Invalid ContainerID"
            Just ContainerID
cid ->
                ContainerID -> Parser ContainerID
forall (m :: * -> *) a. Monad m => a -> m a
return ContainerID
cid
    parseJSON Value
_ = String -> Parser ContainerID
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"ContainerID is not an object."

instance ToJSON ImageID where
    toJSON :: ImageID -> Value
toJSON (ImageID Text
iid) = Text -> Value
JSON.String Text
iid

instance FromJSON ImageID where
    parseJSON :: Value -> Parser ImageID
parseJSON (JSON.String Text
t) = case Text -> Maybe ImageID
toImageID Text
t of
        Maybe ImageID
Nothing ->
            String -> Parser ImageID
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Invalid ImageID"
        Just ImageID
iid ->
            ImageID -> Parser ImageID
forall (m :: * -> *) a. Monad m => a -> m a
return ImageID
iid
    parseJSON Value
_ = String -> Parser ImageID
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"ImageID is not an object."

-- | Data type used for representing the information of various ports that
-- a contianer may expose.
data ContainerPortInfo = ContainerPortInfo {
                     ContainerPortInfo -> Maybe Text
ipAddressInfo   :: Maybe Text
                   , ContainerPortInfo -> Integer
privatePortInfo :: Port
                   , ContainerPortInfo -> Maybe Integer
publicPortInfo  :: Maybe Port
                   , ContainerPortInfo -> Maybe PortType
portTypeInfo    :: Maybe PortType
                   } deriving (ContainerPortInfo -> ContainerPortInfo -> Bool
(ContainerPortInfo -> ContainerPortInfo -> Bool)
-> (ContainerPortInfo -> ContainerPortInfo -> Bool)
-> Eq ContainerPortInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ContainerPortInfo -> ContainerPortInfo -> Bool
$c/= :: ContainerPortInfo -> ContainerPortInfo -> Bool
== :: ContainerPortInfo -> ContainerPortInfo -> Bool
$c== :: ContainerPortInfo -> ContainerPortInfo -> Bool
Eq, Int -> ContainerPortInfo -> ShowS
[ContainerPortInfo] -> ShowS
ContainerPortInfo -> String
(Int -> ContainerPortInfo -> ShowS)
-> (ContainerPortInfo -> String)
-> ([ContainerPortInfo] -> ShowS)
-> Show ContainerPortInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ContainerPortInfo] -> ShowS
$cshowList :: [ContainerPortInfo] -> ShowS
show :: ContainerPortInfo -> String
$cshow :: ContainerPortInfo -> String
showsPrec :: Int -> ContainerPortInfo -> ShowS
$cshowsPrec :: Int -> ContainerPortInfo -> ShowS
Show)

instance FromJSON ContainerPortInfo where
        parseJSON :: Value -> Parser ContainerPortInfo
parseJSON (JSON.Object Object
v) =
            Maybe Text
-> Integer -> Maybe Integer -> Maybe PortType -> ContainerPortInfo
ContainerPortInfo (Maybe Text
 -> Integer -> Maybe Integer -> Maybe PortType -> ContainerPortInfo)
-> Parser (Maybe Text)
-> Parser
     (Integer -> Maybe Integer -> Maybe PortType -> ContainerPortInfo)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Object
v Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"IP")
                Parser
  (Integer -> Maybe Integer -> Maybe PortType -> ContainerPortInfo)
-> Parser Integer
-> Parser (Maybe Integer -> Maybe PortType -> ContainerPortInfo)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
v Object -> Key -> Parser Integer
forall a. FromJSON a => Object -> Key -> Parser a
.:  Key
"PrivatePort")
                Parser (Maybe Integer -> Maybe PortType -> ContainerPortInfo)
-> Parser (Maybe Integer)
-> Parser (Maybe PortType -> ContainerPortInfo)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
v Object -> Key -> Parser (Maybe Integer)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"PublicPort")
                Parser (Maybe PortType -> ContainerPortInfo)
-> Parser (Maybe PortType) -> Parser ContainerPortInfo
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
v Object -> Key -> Parser (Maybe PortType)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"Type")
        parseJSON Value
_ = String -> Parser ContainerPortInfo
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"ContainerPortInfo: Not a JSON object."

-- For inspecting container details.
-- | Data type used for parsing the network information of each container
-- when listing them.
data NetworkOptions = NetworkOptions {
--                       ipamConfig          :: Maybe Text -- Don't see in 1.24
--                     , links               :: Maybe Text -- Don't see in 1.24
--                     , aliases             :: Maybe Text -- Don't see in 1.24
                      NetworkOptions -> Text
networkOptionsId                  :: Text
                    , NetworkOptions -> Text
networkOptionsEndpointId          :: Text
                    , NetworkOptions -> Text
networkOptionsGateway             :: Text
                    , NetworkOptions -> Text
networkOptionsIpAddress           :: Text -- Note: Parse this?
                    , NetworkOptions -> Int
networkOptionsIpPrefixLen         :: Int
                    , NetworkOptions -> Maybe Text
networkOptionsIpV6Gateway         :: Maybe Text
                    , NetworkOptions -> Maybe Text
networkOptionsGlobalIPv6Address   :: Maybe Text
                    , NetworkOptions -> Maybe Int
networkOptionsGlobalIPv6PrefixLen :: Maybe Int
                    , NetworkOptions -> Text
networkOptionsMacAddress          :: Text
                    } deriving (NetworkOptions -> NetworkOptions -> Bool
(NetworkOptions -> NetworkOptions -> Bool)
-> (NetworkOptions -> NetworkOptions -> Bool) -> Eq NetworkOptions
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NetworkOptions -> NetworkOptions -> Bool
$c/= :: NetworkOptions -> NetworkOptions -> Bool
== :: NetworkOptions -> NetworkOptions -> Bool
$c== :: NetworkOptions -> NetworkOptions -> Bool
Eq, Int -> NetworkOptions -> ShowS
[NetworkOptions] -> ShowS
NetworkOptions -> String
(Int -> NetworkOptions -> ShowS)
-> (NetworkOptions -> String)
-> ([NetworkOptions] -> ShowS)
-> Show NetworkOptions
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NetworkOptions] -> ShowS
$cshowList :: [NetworkOptions] -> ShowS
show :: NetworkOptions -> String
$cshow :: NetworkOptions -> String
showsPrec :: Int -> NetworkOptions -> ShowS
$cshowsPrec :: Int -> NetworkOptions -> ShowS
Show)

instance FromJSON NetworkOptions where
    parseJSON :: Value -> Parser NetworkOptions
parseJSON (JSON.Object Object
o) = do
        Text
networkId <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"NetworkID"
        Text
endpointId <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"EndpointID"
        Text
gateway <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Gateway"
        Text
ip <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"IPAddress"
        Int
ipLen <- Object
o Object -> Key -> Parser Int
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"IPPrefixLen"
        Maybe Text
ip6Gateway <- Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"IPv6Gateway"
        Maybe Text
globalIP6 <- Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"GlobalIPv6Address"
        Maybe Int
globalIP6Len <- Object
o Object -> Key -> Parser (Maybe Int)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"GlobalIPv6PrefixLen"
        Text
mac <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"MacAddress"
        NetworkOptions -> Parser NetworkOptions
forall (m :: * -> *) a. Monad m => a -> m a
return (NetworkOptions -> Parser NetworkOptions)
-> NetworkOptions -> Parser NetworkOptions
forall a b. (a -> b) -> a -> b
$ Text
-> Text
-> Text
-> Text
-> Int
-> Maybe Text
-> Maybe Text
-> Maybe Int
-> Text
-> NetworkOptions
NetworkOptions Text
networkId Text
endpointId Text
gateway Text
ip Int
ipLen Maybe Text
ip6Gateway Maybe Text
globalIP6 Maybe Int
globalIP6Len Text
mac
    parseJSON Value
_ = String -> Parser NetworkOptions
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"NetworkOptions is not an object"

-- TODO: Not sure what this is used for anymore.
data Network = Network NetworkMode NetworkOptions
    deriving (Network -> Network -> Bool
(Network -> Network -> Bool)
-> (Network -> Network -> Bool) -> Eq Network
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Network -> Network -> Bool
$c/= :: Network -> Network -> Bool
== :: Network -> Network -> Bool
$c== :: Network -> Network -> Bool
Eq, Int -> Network -> ShowS
[Network] -> ShowS
Network -> String
(Int -> Network -> ShowS)
-> (Network -> String) -> ([Network] -> ShowS) -> Show Network
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Network] -> ShowS
$cshowList :: [Network] -> ShowS
show :: Network -> String
$cshow :: Network -> String
showsPrec :: Int -> Network -> ShowS
$cshowsPrec :: Int -> Network -> ShowS
Show)

instance {-# OVERLAPPING #-} FromJSON [Network] where
    parseJSON :: Value -> Parser [Network]
parseJSON (JSON.Object Object
o) = (Parser [Network] -> Text -> Value -> Parser [Network])
-> Parser [Network] -> HashMap Text Value -> Parser [Network]
forall a k v. (a -> k -> v -> a) -> a -> HashMap k v -> a
HM.foldlWithKey' Parser [Network] -> Text -> Value -> Parser [Network]
f ([Network] -> Parser [Network]
forall (m :: * -> *) a. Monad m => a -> m a
return []) (Object -> HashMap Text Value
forall v. KeyMap v -> HashMap Text v
toHashMap Object
o)
        where
            f :: Parser [Network] -> Text -> Value -> Parser [Network]
f Parser [Network]
accM Text
k' Value
v' = do
                [Network]
acc <- Parser [Network]
accM
                NetworkMode
k <- Value -> Parser NetworkMode
forall a. FromJSON a => Value -> Parser a
parseJSON (Value -> Parser NetworkMode) -> Value -> Parser NetworkMode
forall a b. (a -> b) -> a -> b
$ Text -> Value
JSON.String Text
k'
                NetworkOptions
v <- Value -> Parser NetworkOptions
forall a. FromJSON a => Value -> Parser a
parseJSON Value
v'
                [Network] -> Parser [Network]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Network] -> Parser [Network]) -> [Network] -> Parser [Network]
forall a b. (a -> b) -> a -> b
$ (NetworkMode -> NetworkOptions -> Network
Network NetworkMode
k NetworkOptions
v)Network -> [Network] -> [Network]
forall a. a -> [a] -> [a]
:[Network]
acc
    parseJSON Value
_ = String -> Parser [Network]
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Networks is not an object"

-- | Data type reprsenting the various network settings a container can have.
data NetworkSettings = NetworkSettings {
                       NetworkSettings -> Text
networkSettingsBridge                 :: Text
                     , NetworkSettings -> Text
networkSettingsSandboxId              :: Text
                     , NetworkSettings -> Bool
networkSettingsHairpinMode            :: Bool
                     , NetworkSettings -> Text
networkSettingsLinkLocalIPv6Address   :: Text
                     , NetworkSettings -> Int
networkSettingsLinkLocalIPv6PrefixLen :: Int
                     , NetworkSettings -> [PortBinding]
networkSettingsPorts                  :: [PortBinding]
                     , NetworkSettings -> Text
networkSettingsSandboxKey             :: Text
                     , NetworkSettings -> Maybe [Text]
networkSettingsSecondaryIPAddresses   :: Maybe [Text] -- TODO: 1.24 spec is unclear
                     , NetworkSettings -> Maybe [Text]
networkSettingsSecondaryIPv6Addresses :: Maybe [Text] -- TODO: 1.24 spec is unclear
                     , NetworkSettings -> Text
networkSettingsEndpointID             :: Text
                     , NetworkSettings -> Text
networkSettingsGateway                :: Text
                     , NetworkSettings -> Text
networkSettingsGlobalIPv6Address      :: Text
                     , NetworkSettings -> Int
networkSettingsGlobalIPv6PrefixLen    :: Int
                     , NetworkSettings -> Text
networkSettingsIpAddress              :: Text
                     , NetworkSettings -> Int
networkSettingsIpPrefixLen            :: Int
                     , NetworkSettings -> Text
networkSettingsIpv6Gateway            :: Text
                     , NetworkSettings -> Text
networkSettingsMacAddress             :: Text
                     , NetworkSettings -> [Network]
networkSettingsNetworks               :: [Network]
                     }
                     deriving (NetworkSettings -> NetworkSettings -> Bool
(NetworkSettings -> NetworkSettings -> Bool)
-> (NetworkSettings -> NetworkSettings -> Bool)
-> Eq NetworkSettings
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NetworkSettings -> NetworkSettings -> Bool
$c/= :: NetworkSettings -> NetworkSettings -> Bool
== :: NetworkSettings -> NetworkSettings -> Bool
$c== :: NetworkSettings -> NetworkSettings -> Bool
Eq, Int -> NetworkSettings -> ShowS
[NetworkSettings] -> ShowS
NetworkSettings -> String
(Int -> NetworkSettings -> ShowS)
-> (NetworkSettings -> String)
-> ([NetworkSettings] -> ShowS)
-> Show NetworkSettings
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NetworkSettings] -> ShowS
$cshowList :: [NetworkSettings] -> ShowS
show :: NetworkSettings -> String
$cshow :: NetworkSettings -> String
showsPrec :: Int -> NetworkSettings -> ShowS
$cshowsPrec :: Int -> NetworkSettings -> ShowS
Show)

instance FromJSON NetworkSettings where
    parseJSON :: Value -> Parser NetworkSettings
parseJSON (JSON.Object Object
o) = do
        Text
bridge <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Bridge"
        Text
sandbox <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"SandboxID"
        Bool
hairpin <- Object
o Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"HairpinMode"
        Text
localIP6 <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"LinkLocalIPv6Address"
        Int
localIP6Len <- Object
o Object -> Key -> Parser Int
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"LinkLocalIPv6PrefixLen"
        [PortBinding]
ports <- Object
o Object -> Key -> Parser [PortBinding]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Ports" -- .!= []
        Text
sandboxKey <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"SandboxKey"
        Maybe [Text]
secondaryIP <- Object
o Object -> Key -> Parser (Maybe [Text])
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"SecondaryIPAddresses"
        Maybe [Text]
secondayIP6 <- Object
o Object -> Key -> Parser (Maybe [Text])
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"SecondaryIPv6Addresses"
        Text
endpointID <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"EndpointID"
        Text
gateway <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Gateway"
        Text
globalIP6 <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"GlobalIPv6Address"
        Int
globalIP6Len <- Object
o Object -> Key -> Parser Int
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"GlobalIPv6PrefixLen"
        Text
ip <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"IPAddress"
        Int
ipLen <- Object
o Object -> Key -> Parser Int
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"IPPrefixLen"
        Text
ip6Gateway <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"IPv6Gateway"
        Text
mac <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"MacAddress"
        [Network]
networks <- Object
o Object -> Key -> Parser [Network]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Networks"
        NetworkSettings -> Parser NetworkSettings
forall (m :: * -> *) a. Monad m => a -> m a
return (NetworkSettings -> Parser NetworkSettings)
-> NetworkSettings -> Parser NetworkSettings
forall a b. (a -> b) -> a -> b
$ Text
-> Text
-> Bool
-> Text
-> Int
-> [PortBinding]
-> Text
-> Maybe [Text]
-> Maybe [Text]
-> Text
-> Text
-> Text
-> Int
-> Text
-> Int
-> Text
-> Text
-> [Network]
-> NetworkSettings
NetworkSettings Text
bridge Text
sandbox Bool
hairpin Text
localIP6 Int
localIP6Len [PortBinding]
ports Text
sandboxKey Maybe [Text]
secondaryIP Maybe [Text]
secondayIP6 Text
endpointID Text
gateway Text
globalIP6 Int
globalIP6Len Text
ip Int
ipLen Text
ip6Gateway Text
mac [Network]
networks
    parseJSON Value
_ = String -> Parser NetworkSettings
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"NetworkSettings is not an object."

-- | Data type used for parsing a list of containers.
data Container = Container
               { Container -> ContainerID
containerId        :: ContainerID
               , Container -> [Text]
containerNames     :: [Text]
               , Container -> Text
containerImageName :: Text
               , Container -> ImageID
containerImageId   :: ImageID
               , Container -> Text
containerCommand   :: Text
               , Container -> Int
containerCreatedAt :: Int
               , Container -> State
containerState     :: State
               , Container -> Maybe Text
containerStatus    :: Maybe Text
               , Container -> [ContainerPortInfo]
containerPorts     :: [ContainerPortInfo]
               , Container -> [Label]
containerLabels    :: [Label]
               , Container -> [Network]
containerNetworks  :: [Network]
               , Container -> [Mount]
containerMounts    :: [Mount]
               } deriving (Int -> Container -> ShowS
[Container] -> ShowS
Container -> String
(Int -> Container -> ShowS)
-> (Container -> String)
-> ([Container] -> ShowS)
-> Show Container
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Container] -> ShowS
$cshowList :: [Container] -> ShowS
show :: Container -> String
$cshow :: Container -> String
showsPrec :: Int -> Container -> ShowS
$cshowsPrec :: Int -> Container -> ShowS
Show, Container -> Container -> Bool
(Container -> Container -> Bool)
-> (Container -> Container -> Bool) -> Eq Container
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Container -> Container -> Bool
$c/= :: Container -> Container -> Bool
== :: Container -> Container -> Bool
$c== :: Container -> Container -> Bool
Eq)

instance FromJSON Container where
        parseJSON :: Value -> Parser Container
parseJSON o :: Value
o@(JSON.Object Object
v) =
            ContainerID
-> [Text]
-> Text
-> ImageID
-> Text
-> Int
-> State
-> Maybe Text
-> [ContainerPortInfo]
-> [Label]
-> [Network]
-> [Mount]
-> Container
Container (ContainerID
 -> [Text]
 -> Text
 -> ImageID
 -> Text
 -> Int
 -> State
 -> Maybe Text
 -> [ContainerPortInfo]
 -> [Label]
 -> [Network]
 -> [Mount]
 -> Container)
-> Parser ContainerID
-> Parser
     ([Text]
      -> Text
      -> ImageID
      -> Text
      -> Int
      -> State
      -> Maybe Text
      -> [ContainerPortInfo]
      -> [Label]
      -> [Network]
      -> [Mount]
      -> Container)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser ContainerID
forall a. FromJSON a => Value -> Parser a
parseJSON Value
o
                Parser
  ([Text]
   -> Text
   -> ImageID
   -> Text
   -> Int
   -> State
   -> Maybe Text
   -> [ContainerPortInfo]
   -> [Label]
   -> [Network]
   -> [Mount]
   -> Container)
-> Parser [Text]
-> Parser
     (Text
      -> ImageID
      -> Text
      -> Int
      -> State
      -> Maybe Text
      -> [ContainerPortInfo]
      -> [Label]
      -> [Network]
      -> [Mount]
      -> Container)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
v Object -> Key -> Parser [Text]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Names")
                Parser
  (Text
   -> ImageID
   -> Text
   -> Int
   -> State
   -> Maybe Text
   -> [ContainerPortInfo]
   -> [Label]
   -> [Network]
   -> [Mount]
   -> Container)
-> Parser Text
-> Parser
     (ImageID
      -> Text
      -> Int
      -> State
      -> Maybe Text
      -> [ContainerPortInfo]
      -> [Label]
      -> [Network]
      -> [Mount]
      -> Container)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
v Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Image")
                Parser
  (ImageID
   -> Text
   -> Int
   -> State
   -> Maybe Text
   -> [ContainerPortInfo]
   -> [Label]
   -> [Network]
   -> [Mount]
   -> Container)
-> Parser ImageID
-> Parser
     (Text
      -> Int
      -> State
      -> Maybe Text
      -> [ContainerPortInfo]
      -> [Label]
      -> [Network]
      -> [Mount]
      -> Container)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
v Object -> Key -> Parser ImageID
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"ImageID") -- Doesn't exist anymore
                Parser
  (Text
   -> Int
   -> State
   -> Maybe Text
   -> [ContainerPortInfo]
   -> [Label]
   -> [Network]
   -> [Mount]
   -> Container)
-> Parser Text
-> Parser
     (Int
      -> State
      -> Maybe Text
      -> [ContainerPortInfo]
      -> [Label]
      -> [Network]
      -> [Mount]
      -> Container)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
v Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Command") -- Doesn't exist anymore
                Parser
  (Int
   -> State
   -> Maybe Text
   -> [ContainerPortInfo]
   -> [Label]
   -> [Network]
   -> [Mount]
   -> Container)
-> Parser Int
-> Parser
     (State
      -> Maybe Text
      -> [ContainerPortInfo]
      -> [Label]
      -> [Network]
      -> [Mount]
      -> Container)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
v Object -> Key -> Parser Int
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Created")
                Parser
  (State
   -> Maybe Text
   -> [ContainerPortInfo]
   -> [Label]
   -> [Network]
   -> [Mount]
   -> Container)
-> Parser State
-> Parser
     (Maybe Text
      -> [ContainerPortInfo]
      -> [Label]
      -> [Network]
      -> [Mount]
      -> Container)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
v Object -> Key -> Parser State
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"State")
                Parser
  (Maybe Text
   -> [ContainerPortInfo]
   -> [Label]
   -> [Network]
   -> [Mount]
   -> Container)
-> Parser (Maybe Text)
-> Parser
     ([ContainerPortInfo]
      -> [Label] -> [Network] -> [Mount] -> Container)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
v Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Status")
                Parser
  ([ContainerPortInfo]
   -> [Label] -> [Network] -> [Mount] -> Container)
-> Parser [ContainerPortInfo]
-> Parser ([Label] -> [Network] -> [Mount] -> Container)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
v Object -> Key -> Parser [ContainerPortInfo]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Ports")
                Parser ([Label] -> [Network] -> [Mount] -> Container)
-> Parser [Label] -> Parser ([Network] -> [Mount] -> Container)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
v Object -> Key -> Parser [Label]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Labels")
                Parser ([Network] -> [Mount] -> Container)
-> Parser [Network] -> Parser ([Mount] -> Container)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
v Object -> Key -> Parser Value
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"NetworkSettings" Parser Value -> (Value -> Parser [Network]) -> Parser [Network]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Value -> Parser [Network]
forall a. FromJSON a => Value -> Parser a
parseNetworks)
                Parser ([Mount] -> Container) -> Parser [Mount] -> Parser Container
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
v Object -> Key -> Parser [Mount]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Mounts")
            where
                parseNetworks :: Value -> Parser b
parseNetworks (JSON.Object Object
v) =
                    (Object
v Object -> Key -> Parser Value
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Networks") Parser Value -> (Value -> Parser b) -> Parser b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Value -> Parser b
forall a. FromJSON a => Value -> Parser a
parseJSON
                parseNetworks Value
_ = String -> Parser b
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Container NetworkSettings: Not a JSON object."
        parseJSON Value
_ = String -> Parser Container
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Container: Not a JSON object."

-- | Represents the state of the container life cycle.
data State = Created | Restarting | Running | Paused | Exited | Dead
    deriving (State -> State -> Bool
(State -> State -> Bool) -> (State -> State -> Bool) -> Eq State
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: State -> State -> Bool
$c/= :: State -> State -> Bool
== :: State -> State -> Bool
$c== :: State -> State -> Bool
Eq, Int -> State -> ShowS
[State] -> ShowS
State -> String
(Int -> State -> ShowS)
-> (State -> String) -> ([State] -> ShowS) -> Show State
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [State] -> ShowS
$cshowList :: [State] -> ShowS
show :: State -> String
$cshow :: State -> String
showsPrec :: Int -> State -> ShowS
$cshowsPrec :: Int -> State -> ShowS
Show, (forall x. State -> Rep State x)
-> (forall x. Rep State x -> State) -> Generic State
forall x. Rep State x -> State
forall x. State -> Rep State x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep State x -> State
$cfrom :: forall x. State -> Rep State x
Generic)

instance FromJSON State where
    parseJSON :: Value -> Parser State
parseJSON (JSON.String Text
"running")    = State -> Parser State
forall (m :: * -> *) a. Monad m => a -> m a
return State
Running
    parseJSON (JSON.String Text
"created")    = State -> Parser State
forall (m :: * -> *) a. Monad m => a -> m a
return State
Created -- Note: Guessing on the string values of these.
    parseJSON (JSON.String Text
"restarting") = State -> Parser State
forall (m :: * -> *) a. Monad m => a -> m a
return State
Restarting
    parseJSON (JSON.String Text
"paused")     = State -> Parser State
forall (m :: * -> *) a. Monad m => a -> m a
return State
Paused
    parseJSON (JSON.String Text
"exited")     = State -> Parser State
forall (m :: * -> *) a. Monad m => a -> m a
return State
Exited
    parseJSON (JSON.String Text
"dead")       = State -> Parser State
forall (m :: * -> *) a. Monad m => a -> m a
return State
Dead
    parseJSON Value
s                          = String -> Parser State
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser State) -> String -> Parser State
forall a b. (a -> b) -> a -> b
$ String
"Unknown Status: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Value -> String
forall a. Show a => a -> String
show Value
s

-- | Alias for representing a RepoDigest. We could newtype this and add
-- some validation.
type Digest = Text

-- | Container and Image Labels.
data Label = Label Name Value deriving (Label -> Label -> Bool
(Label -> Label -> Bool) -> (Label -> Label -> Bool) -> Eq Label
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Label -> Label -> Bool
$c/= :: Label -> Label -> Bool
== :: Label -> Label -> Bool
$c== :: Label -> Label -> Bool
Eq, Int -> Label -> ShowS
[Label] -> ShowS
Label -> String
(Int -> Label -> ShowS)
-> (Label -> String) -> ([Label] -> ShowS) -> Show Label
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Label] -> ShowS
$cshowList :: [Label] -> ShowS
show :: Label -> String
$cshow :: Label -> String
showsPrec :: Int -> Label -> ShowS
$cshowsPrec :: Int -> Label -> ShowS
Show)


-- If there are multiple lables with the same Name in the list
-- then the last one wins.
instance {-# OVERLAPPING #-} ToJSON [Label] where
    toJSON :: [Label] -> Value
toJSON [] = Value
emptyObject
    toJSON (Label
l:[Label]
ls) = [Label] -> (Label -> String) -> (Label -> Text) -> Value
forall (t :: * -> *) r a.
(Foldable t, ToJSON r) =>
t a -> (a -> String) -> (a -> r) -> Value
toJsonKeyVal (Label
lLabel -> [Label] -> [Label]
forall a. a -> [a] -> [a]
:[Label]
ls) Label -> String
key Label -> Text
val
        where key :: Label -> String
key (Label Text
k Text
_) = Text -> String
T.unpack Text
k
              val :: Label -> Text
val (Label Text
_ Text
v) = Text
v

instance {-# OVERLAPPING #-} FromJSON [Label] where
    parseJSON :: Value -> Parser [Label]
parseJSON (JSON.Object Object
o) = (Parser [Label] -> Text -> Value -> Parser [Label])
-> Parser [Label] -> HashMap Text Value -> Parser [Label]
forall a k v. (a -> k -> v -> a) -> a -> HashMap k v -> a
HM.foldlWithKey' Parser [Label] -> Text -> Value -> Parser [Label]
f ([Label] -> Parser [Label]
forall (m :: * -> *) a. Monad m => a -> m a
return []) (Object -> HashMap Text Value
forall v. KeyMap v -> HashMap Text v
toHashMap Object
o)
        where f :: Parser [Label] -> Text -> Value -> Parser [Label]
f Parser [Label]
accM Text
k Value
v = do
                [Label]
acc <- Parser [Label]
accM
                Text
value <- Value -> Parser Text
forall a. FromJSON a => Value -> Parser a
parseJSON Value
v
                [Label] -> Parser [Label]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Label] -> Parser [Label]) -> [Label] -> Parser [Label]
forall a b. (a -> b) -> a -> b
$ (Text -> Text -> Label
Label Text
k Text
value)Label -> [Label] -> [Label]
forall a. a -> [a] -> [a]
:[Label]
acc
    parseJSON Value
JSON.Null = [Label] -> Parser [Label]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    parseJSON Value
_ = String -> Parser [Label]
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Failed to parse Labels. Not an object."

-- | Alias for Tags.
type Tag = Text

-- | Data type used for parsing information from a list of images.
data Image = DockerImage {
      Image -> ImageID
imageId          :: ImageID
    , Image -> Integer
imageCreated     :: Integer
    , Image -> Maybe ImageID
imageParentId    :: Maybe ImageID
    , Image -> [Text]
imageRepoTags    :: [Tag]
    , Image -> [Text]
imageRepoDigests :: [Digest]
    , Image -> Integer
imageSize        :: Integer
    , Image -> Integer
imageVirtualSize :: Integer
    , Image -> [Label]
imageLabels      :: [Label]
    } deriving (Int -> Image -> ShowS
[Image] -> ShowS
Image -> String
(Int -> Image -> ShowS)
-> (Image -> String) -> ([Image] -> ShowS) -> Show Image
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Image] -> ShowS
$cshowList :: [Image] -> ShowS
show :: Image -> String
$cshow :: Image -> String
showsPrec :: Int -> Image -> ShowS
$cshowsPrec :: Int -> Image -> ShowS
Show, Image -> Image -> Bool
(Image -> Image -> Bool) -> (Image -> Image -> Bool) -> Eq Image
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Image -> Image -> Bool
$c/= :: Image -> Image -> Bool
== :: Image -> Image -> Bool
$c== :: Image -> Image -> Bool
Eq, (forall x. Image -> Rep Image x)
-> (forall x. Rep Image x -> Image) -> Generic Image
forall x. Rep Image x -> Image
forall x. Image -> Rep Image x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Image x -> Image
$cfrom :: forall x. Image -> Rep Image x
Generic)

-- | Helper function used for dropping the "image" prefix when serializing
-- the Image data type to and from json.
dropImagePrefix :: [a] -> [a]
dropImagePrefix :: [a] -> [a]
dropImagePrefix = Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop Int
5


instance FromJSON Image where
    parseJSON :: Value -> Parser Image
parseJSON (JSON.Object Object
o) = do
        ImageID
imageId <- Object
o Object -> Key -> Parser ImageID
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Id"
        Integer
imageCreated <- Object
o Object -> Key -> Parser Integer
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Created"
        Maybe ImageID
imageParentId <- Object
o Object -> Key -> Parser (Maybe ImageID)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"ParentId"
        [Text]
imageRepoTags <- Object
o Object -> Key -> Parser (Maybe [Text])
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"RepoTags" Parser (Maybe [Text]) -> [Text] -> Parser [Text]
forall a. Parser (Maybe a) -> a -> Parser a
.!= []
        [Text]
imageRepoDigests <- Object
o Object -> Key -> Parser (Maybe [Text])
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"RepoDigests" Parser (Maybe [Text]) -> [Text] -> Parser [Text]
forall a. Parser (Maybe a) -> a -> Parser a
.!= []
        Integer
imageSize <- Object
o Object -> Key -> Parser Integer
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Size"
        Integer
imageVirtualSize <- Object
o Object -> Key -> Parser Integer
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"VirtualSize"
        [Label]
imageLabels <- Object
o Object -> Key -> Parser (Maybe [Label])
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"Labels" Parser (Maybe [Label]) -> [Label] -> Parser [Label]
forall a. Parser (Maybe a) -> a -> Parser a
.!= []
        Image -> Parser Image
forall (m :: * -> *) a. Monad m => a -> m a
return (Image -> Parser Image) -> Image -> Parser Image
forall a b. (a -> b) -> a -> b
$ ImageID
-> Integer
-> Maybe ImageID
-> [Text]
-> [Text]
-> Integer
-> Integer
-> [Label]
-> Image
DockerImage ImageID
imageId Integer
imageCreated Maybe ImageID
imageParentId [Text]
imageRepoTags [Text]
imageRepoDigests Integer
imageSize Integer
imageVirtualSize [Label]
imageLabels
    parseJSON Value
_ = String -> Parser Image
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Failed to parse DockerImage."

-- | Alias for Aliases.
type Alias = Text

-- | EndpointsConfig is container configuration for a specific network
newtype EndpointConfig = EndpointConfig [Alias] deriving (EndpointConfig -> EndpointConfig -> Bool
(EndpointConfig -> EndpointConfig -> Bool)
-> (EndpointConfig -> EndpointConfig -> Bool) -> Eq EndpointConfig
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EndpointConfig -> EndpointConfig -> Bool
$c/= :: EndpointConfig -> EndpointConfig -> Bool
== :: EndpointConfig -> EndpointConfig -> Bool
$c== :: EndpointConfig -> EndpointConfig -> Bool
Eq, Int -> EndpointConfig -> ShowS
[EndpointConfig] -> ShowS
EndpointConfig -> String
(Int -> EndpointConfig -> ShowS)
-> (EndpointConfig -> String)
-> ([EndpointConfig] -> ShowS)
-> Show EndpointConfig
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [EndpointConfig] -> ShowS
$cshowList :: [EndpointConfig] -> ShowS
show :: EndpointConfig -> String
$cshow :: EndpointConfig -> String
showsPrec :: Int -> EndpointConfig -> ShowS
$cshowsPrec :: Int -> EndpointConfig -> ShowS
Show)

instance ToJSON EndpointConfig where
  toJSON :: EndpointConfig -> Value
toJSON (EndpointConfig [Text]
aliases) = [Pair] -> Value
JSON.object
    [ Key
"Aliases" Key -> [Text] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [Text]
aliases
    ]

-- | Alias for endpoint name
type EndpointName = Text

-- | Data type for the NetworkingConfig section of the container settings
newtype NetworkingConfig = NetworkingConfig
  { NetworkingConfig -> HashMap Text EndpointConfig
endpointsConfig :: HM.HashMap EndpointName EndpointConfig
  } deriving (NetworkingConfig -> NetworkingConfig -> Bool
(NetworkingConfig -> NetworkingConfig -> Bool)
-> (NetworkingConfig -> NetworkingConfig -> Bool)
-> Eq NetworkingConfig
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NetworkingConfig -> NetworkingConfig -> Bool
$c/= :: NetworkingConfig -> NetworkingConfig -> Bool
== :: NetworkingConfig -> NetworkingConfig -> Bool
$c== :: NetworkingConfig -> NetworkingConfig -> Bool
Eq, Int -> NetworkingConfig -> ShowS
[NetworkingConfig] -> ShowS
NetworkingConfig -> String
(Int -> NetworkingConfig -> ShowS)
-> (NetworkingConfig -> String)
-> ([NetworkingConfig] -> ShowS)
-> Show NetworkingConfig
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NetworkingConfig] -> ShowS
$cshowList :: [NetworkingConfig] -> ShowS
show :: NetworkingConfig -> String
$cshow :: NetworkingConfig -> String
showsPrec :: Int -> NetworkingConfig -> ShowS
$cshowsPrec :: Int -> NetworkingConfig -> ShowS
Show)

instance ToJSON NetworkingConfig where
  toJSON :: NetworkingConfig -> Value
toJSON (NetworkingConfig HashMap Text EndpointConfig
endpointsConfig) = [Pair] -> Value
JSON.object
    [ Key
"EndpointsConfig" Key -> HashMap Text EndpointConfig -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= HashMap Text EndpointConfig
endpointsConfig
    ]

-- | Options used for creating a Container.
data CreateOpts = CreateOpts {
                  CreateOpts -> ContainerConfig
containerConfig  :: ContainerConfig
                , CreateOpts -> HostConfig
hostConfig       :: HostConfig
                , CreateOpts -> NetworkingConfig
networkingConfig :: NetworkingConfig
                } deriving (CreateOpts -> CreateOpts -> Bool
(CreateOpts -> CreateOpts -> Bool)
-> (CreateOpts -> CreateOpts -> Bool) -> Eq CreateOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CreateOpts -> CreateOpts -> Bool
$c/= :: CreateOpts -> CreateOpts -> Bool
== :: CreateOpts -> CreateOpts -> Bool
$c== :: CreateOpts -> CreateOpts -> Bool
Eq, Int -> CreateOpts -> ShowS
[CreateOpts] -> ShowS
CreateOpts -> String
(Int -> CreateOpts -> ShowS)
-> (CreateOpts -> String)
-> ([CreateOpts] -> ShowS)
-> Show CreateOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CreateOpts] -> ShowS
$cshowList :: [CreateOpts] -> ShowS
show :: CreateOpts -> String
$cshow :: CreateOpts -> String
showsPrec :: Int -> CreateOpts -> ShowS
$cshowsPrec :: Int -> CreateOpts -> ShowS
Show)

instance ToJSON CreateOpts where
    toJSON :: CreateOpts -> Value
toJSON (CreateOpts ContainerConfig
cc HostConfig
hc NetworkingConfig
nc) = do
        let ccJSON :: Value
ccJSON = ContainerConfig -> Value
forall a. ToJSON a => a -> Value
toJSON ContainerConfig
cc
        let hcJSON :: Value
hcJSON = HostConfig -> Value
forall a. ToJSON a => a -> Value
toJSON HostConfig
hc
        case Value
ccJSON of
            JSON.Object Object
o -> do
#if MIN_VERSION_aeson(2,0,0)
                let o1 :: Object
o1 = Key -> Value -> Object -> Object
forall v. Key -> v -> KeyMap v -> KeyMap v
KM.insert Key
"HostConfig" Value
hcJSON Object
o
                let o2 :: Object
o2 = Key -> Value -> Object -> Object
forall v. Key -> v -> KeyMap v -> KeyMap v
KM.insert Key
"NetworkingConfig" (NetworkingConfig -> Value
forall a. ToJSON a => a -> Value
toJSON NetworkingConfig
nc) Object
o1
#else
                let o1 = HM.insert "HostConfig" hcJSON o
                let o2 = HM.insert "NetworkingConfig" (toJSON nc) o1
#endif
                Object -> Value
JSON.Object Object
o2
            Value
_ -> String -> Value
forall a. HasCallStack => String -> a
error String
"ContainerConfig is not an object." -- This should never happen.

-- | Container configuration used for creating a container with sensible
-- defaults.
defaultContainerConfig :: Text -> ContainerConfig
defaultContainerConfig :: Text -> ContainerConfig
defaultContainerConfig Text
imageName = ContainerConfig :: Maybe Text
-> Maybe Text
-> Maybe Text
-> Bool
-> Bool
-> Bool
-> [ExposedPort]
-> Bool
-> Bool
-> Bool
-> [EnvVar]
-> [Text]
-> Text
-> [Volume]
-> Maybe String
-> Entrypoint
-> Maybe Bool
-> Maybe Text
-> [Label]
-> Signal
-> ContainerConfig
ContainerConfig {
                       hostname :: Maybe Text
hostname=Maybe Text
forall a. Maybe a
Nothing
                     , domainname :: Maybe Text
domainname=Maybe Text
forall a. Maybe a
Nothing
                     , user :: Maybe Text
user=Maybe Text
forall a. Maybe a
Nothing
                     , attachStdin :: Bool
attachStdin=Bool
False
                     , attachStdout :: Bool
attachStdout=Bool
False
                     , image :: Text
image=Text
imageName
                     , attachStderr :: Bool
attachStderr=Bool
False
                     , exposedPorts :: [ExposedPort]
exposedPorts=[]
                     , tty :: Bool
tty=Bool
False
                     , openStdin :: Bool
openStdin=Bool
False
                     , stdinOnce :: Bool
stdinOnce=Bool
False
                     , env :: [EnvVar]
env=[]
                     , cmd :: [Text]
cmd=[]
                     , volumes :: [Volume]
volumes=[]
                     , workingDir :: Maybe String
workingDir=Maybe String
forall a. Maybe a
Nothing
                     , entrypoint :: Entrypoint
entrypoint=[Text] -> Entrypoint
Entrypoint []
                     , networkDisabled :: Maybe Bool
networkDisabled=Maybe Bool
forall a. Maybe a
Nothing
                     , macAddress :: Maybe Text
macAddress=Maybe Text
forall a. Maybe a
Nothing
                     , labels :: [Label]
labels=[]
                     , stopSignal :: Signal
stopSignal=Signal
SIGTERM
                     }

-- | Default host confiratuon used for creating a container.
defaultHostConfig :: HostConfig
defaultHostConfig :: HostConfig
defaultHostConfig = HostConfig :: [Bind]
-> Maybe String
-> LogDriverConfig
-> NetworkMode
-> [PortBinding]
-> RestartPolicy
-> Maybe Text
-> [VolumeFrom]
-> [Text]
-> [Text]
-> [Text]
-> [Text]
-> [Text]
-> [Text]
-> Maybe Text
-> [Link]
-> Maybe Integer
-> Bool
-> Bool
-> Bool
-> [Text]
-> Maybe Integer
-> ContainerResources
-> HostConfig
HostConfig {
                       binds :: [Bind]
binds=[]
                     , containerIDFile :: Maybe String
containerIDFile=Maybe String
forall a. Maybe a
Nothing
                     , logConfig :: LogDriverConfig
logConfig=LogDriverType -> [LogDriverOption] -> LogDriverConfig
LogDriverConfig LogDriverType
JsonFile []
                     , networkMode :: NetworkMode
networkMode=NetworkMode
NetworkBridge
                     , portBindings :: [PortBinding]
portBindings=[]
                     , restartPolicy :: RestartPolicy
restartPolicy=RestartPolicy
RestartOff
                     , volumeDriver :: Maybe Text
volumeDriver=Maybe Text
forall a. Maybe a
Nothing
                     , volumesFrom :: [VolumeFrom]
volumesFrom=[]
                     , capAdd :: [Text]
capAdd=[]
                     , capDrop :: [Text]
capDrop=[]
                     , dns :: [Text]
dns=[]
                     , dnsOptions :: [Text]
dnsOptions=[]
                     , dnsSearch :: [Text]
dnsSearch=[]
                     , extraHosts :: [Text]
extraHosts=[]
                     , ipcMode :: Maybe Text
ipcMode=Maybe Text
forall a. Maybe a
Nothing
                     , links :: [Link]
links=[]
                     , oomScoreAdj :: Maybe Integer
oomScoreAdj=Maybe Integer
forall a. Maybe a
Nothing
                     , privileged :: Bool
privileged=Bool
False
                     , publishAllPorts :: Bool
publishAllPorts=Bool
False
                     , readonlyRootfs :: Bool
readonlyRootfs=Bool
False
                     , securityOpt :: [Text]
securityOpt=[]
                     , shmSize :: Maybe Integer
shmSize=Maybe Integer
forall a. Maybe a
Nothing
                     , resources :: ContainerResources
resources=ContainerResources
defaultContainerResources
                     }

-- Default container resource contstraints (None).
defaultContainerResources :: ContainerResources
defaultContainerResources :: ContainerResources
defaultContainerResources = ContainerResources :: Maybe Integer
-> Maybe Integer
-> Maybe [DeviceWeight]
-> Maybe [DeviceRate]
-> Maybe [DeviceRate]
-> Maybe [DeviceRate]
-> Maybe [DeviceRate]
-> Maybe Integer
-> Maybe Text
-> Maybe Text
-> [Device]
-> Maybe MemoryConstraint
-> Maybe MemoryConstraint
-> Maybe MemoryConstraint
-> Maybe MemoryConstraint
-> Maybe Bool
-> [Ulimit]
-> ContainerResources
ContainerResources {
                          cpuShares :: Maybe Integer
cpuShares=Maybe Integer
forall a. Maybe a
Nothing
                        , blkioWeight :: Maybe Integer
blkioWeight=Maybe Integer
forall a. Maybe a
Nothing
                        , blkioWeightDevice :: Maybe [DeviceWeight]
blkioWeightDevice=Maybe [DeviceWeight]
forall a. Maybe a
Nothing
                        , blkioDeviceReadBps :: Maybe [DeviceRate]
blkioDeviceReadBps=Maybe [DeviceRate]
forall a. Maybe a
Nothing
                        , blkioDeviceWriteBps :: Maybe [DeviceRate]
blkioDeviceWriteBps=Maybe [DeviceRate]
forall a. Maybe a
Nothing
                        , blkioDeviceReadIOps :: Maybe [DeviceRate]
blkioDeviceReadIOps=Maybe [DeviceRate]
forall a. Maybe a
Nothing
                        , blkioDeviceWriteIOps :: Maybe [DeviceRate]
blkioDeviceWriteIOps=Maybe [DeviceRate]
forall a. Maybe a
Nothing
                        , cpuPeriod :: Maybe Integer
cpuPeriod=Maybe Integer
forall a. Maybe a
Nothing
                        , cpusetCpus :: Maybe Text
cpusetCpus=Maybe Text
forall a. Maybe a
Nothing
                        , cpusetMems :: Maybe Text
cpusetMems=Maybe Text
forall a. Maybe a
Nothing
                        , devices :: [Device]
devices=[]
                        , kernelMemory :: Maybe MemoryConstraint
kernelMemory=Maybe MemoryConstraint
forall a. Maybe a
Nothing
                        , memory :: Maybe MemoryConstraint
memory=Maybe MemoryConstraint
forall a. Maybe a
Nothing
                        , memoryReservation :: Maybe MemoryConstraint
memoryReservation=Maybe MemoryConstraint
forall a. Maybe a
Nothing
                        , memorySwap :: Maybe MemoryConstraint
memorySwap=Maybe MemoryConstraint
forall a. Maybe a
Nothing
                        , oomKillDisable :: Maybe Bool
oomKillDisable=Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False
                        , ulimits :: [Ulimit]
ulimits=[]
                        }

-- | Default create options when creating a container. You only need to
-- specify an image name and the rest is all sensible defaults.
defaultCreateOpts :: T.Text -> CreateOpts
defaultCreateOpts :: Text -> CreateOpts
defaultCreateOpts Text
imageName = CreateOpts :: ContainerConfig -> HostConfig -> NetworkingConfig -> CreateOpts
CreateOpts
  { containerConfig :: ContainerConfig
containerConfig  = Text -> ContainerConfig
defaultContainerConfig Text
imageName
  , hostConfig :: HostConfig
hostConfig       = HostConfig
defaultHostConfig
  , networkingConfig :: NetworkingConfig
networkingConfig = HashMap Text EndpointConfig -> NetworkingConfig
NetworkingConfig HashMap Text EndpointConfig
forall k v. HashMap k v
HM.empty
  }

-- | Override the key sequence for detaching a container.
-- Format is a single character [a-Z] or ctrl-<value> where <value> is one of: a-z, @, ^, [, , or _.
data DetachKeys = WithCtrl Char | WithoutCtrl Char | DefaultDetachKey deriving (DetachKeys -> DetachKeys -> Bool
(DetachKeys -> DetachKeys -> Bool)
-> (DetachKeys -> DetachKeys -> Bool) -> Eq DetachKeys
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DetachKeys -> DetachKeys -> Bool
$c/= :: DetachKeys -> DetachKeys -> Bool
== :: DetachKeys -> DetachKeys -> Bool
$c== :: DetachKeys -> DetachKeys -> Bool
Eq, Int -> DetachKeys -> ShowS
[DetachKeys] -> ShowS
DetachKeys -> String
(Int -> DetachKeys -> ShowS)
-> (DetachKeys -> String)
-> ([DetachKeys] -> ShowS)
-> Show DetachKeys
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DetachKeys] -> ShowS
$cshowList :: [DetachKeys] -> ShowS
show :: DetachKeys -> String
$cshow :: DetachKeys -> String
showsPrec :: Int -> DetachKeys -> ShowS
$cshowsPrec :: Int -> DetachKeys -> ShowS
Show)

-- | Options for starting a container.
data StartOpts = StartOpts { StartOpts -> DetachKeys
detachKeys :: DetachKeys } deriving (StartOpts -> StartOpts -> Bool
(StartOpts -> StartOpts -> Bool)
-> (StartOpts -> StartOpts -> Bool) -> Eq StartOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StartOpts -> StartOpts -> Bool
$c/= :: StartOpts -> StartOpts -> Bool
== :: StartOpts -> StartOpts -> Bool
$c== :: StartOpts -> StartOpts -> Bool
Eq, Int -> StartOpts -> ShowS
[StartOpts] -> ShowS
StartOpts -> String
(Int -> StartOpts -> ShowS)
-> (StartOpts -> String)
-> ([StartOpts] -> ShowS)
-> Show StartOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StartOpts] -> ShowS
$cshowList :: [StartOpts] -> ShowS
show :: StartOpts -> String
$cshow :: StartOpts -> String
showsPrec :: Int -> StartOpts -> ShowS
$cshowsPrec :: Int -> StartOpts -> ShowS
Show)

-- | Default options for staring a container.
defaultStartOpts :: StartOpts
defaultStartOpts :: StartOpts
defaultStartOpts = StartOpts :: DetachKeys -> StartOpts
StartOpts { detachKeys :: DetachKeys
detachKeys = DetachKeys
DefaultDetachKey }

-- | Options for deleting a container.
data ContainerDeleteOpts = ContainerDeleteOpts {
                  ContainerDeleteOpts -> Bool
deleteVolumes :: Bool -- ^ Automatically cleanup volumes that the container created as well.
                , ContainerDeleteOpts -> Bool
force         :: Bool -- ^ If the container is still running force deletion anyway.
                } deriving (ContainerDeleteOpts -> ContainerDeleteOpts -> Bool
(ContainerDeleteOpts -> ContainerDeleteOpts -> Bool)
-> (ContainerDeleteOpts -> ContainerDeleteOpts -> Bool)
-> Eq ContainerDeleteOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ContainerDeleteOpts -> ContainerDeleteOpts -> Bool
$c/= :: ContainerDeleteOpts -> ContainerDeleteOpts -> Bool
== :: ContainerDeleteOpts -> ContainerDeleteOpts -> Bool
$c== :: ContainerDeleteOpts -> ContainerDeleteOpts -> Bool
Eq, Int -> ContainerDeleteOpts -> ShowS
[ContainerDeleteOpts] -> ShowS
ContainerDeleteOpts -> String
(Int -> ContainerDeleteOpts -> ShowS)
-> (ContainerDeleteOpts -> String)
-> ([ContainerDeleteOpts] -> ShowS)
-> Show ContainerDeleteOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ContainerDeleteOpts] -> ShowS
$cshowList :: [ContainerDeleteOpts] -> ShowS
show :: ContainerDeleteOpts -> String
$cshow :: ContainerDeleteOpts -> String
showsPrec :: Int -> ContainerDeleteOpts -> ShowS
$cshowsPrec :: Int -> ContainerDeleteOpts -> ShowS
Show)

-- TODO: Add support for container build constraints
-- | Options for when building images from a Dockerfile
data BuildOpts = BuildOpts {
                 BuildOpts -> Text
buildImageName               :: Text -- ^ Image name in the form of name:tag; ie. myimage:latest.:w
               , BuildOpts -> Text
buildDockerfileName          :: Text -- ^ Name of dockerfile (default: Dockerfile)
               , BuildOpts -> Bool
buildQuiet                   :: Bool
               , BuildOpts -> Bool
buildNoCache                 :: Bool -- ^ Do not use cache when building the image.
               , BuildOpts -> Bool
buildRemoveItermediate       :: Bool -- ^ Remove intermediate containers after a successful build (default true).
               , BuildOpts -> Bool
buildForceRemoveIntermediate :: Bool -- ^ Always remove intermediate containers.
               , BuildOpts -> Bool
buildPullParent              :: Bool -- ^ Always attempt to pull a newer version of the *parent* image (ie. FROM debian:jessie).
               } deriving (BuildOpts -> BuildOpts -> Bool
(BuildOpts -> BuildOpts -> Bool)
-> (BuildOpts -> BuildOpts -> Bool) -> Eq BuildOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BuildOpts -> BuildOpts -> Bool
$c/= :: BuildOpts -> BuildOpts -> Bool
== :: BuildOpts -> BuildOpts -> Bool
$c== :: BuildOpts -> BuildOpts -> Bool
Eq, Int -> BuildOpts -> ShowS
[BuildOpts] -> ShowS
BuildOpts -> String
(Int -> BuildOpts -> ShowS)
-> (BuildOpts -> String)
-> ([BuildOpts] -> ShowS)
-> Show BuildOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BuildOpts] -> ShowS
$cshowList :: [BuildOpts] -> ShowS
show :: BuildOpts -> String
$cshow :: BuildOpts -> String
showsPrec :: Int -> BuildOpts -> ShowS
$cshowsPrec :: Int -> BuildOpts -> ShowS
Show)

defaultBuildOpts :: Text -> BuildOpts
defaultBuildOpts :: Text -> BuildOpts
defaultBuildOpts Text
nameTag = BuildOpts :: Text -> Text -> Bool -> Bool -> Bool -> Bool -> Bool -> BuildOpts
BuildOpts { buildImageName :: Text
buildImageName = Text
nameTag
                                     , buildDockerfileName :: Text
buildDockerfileName = Text
"Dockerfile"
                                     , buildQuiet :: Bool
buildQuiet = Bool
False
                                     , buildNoCache :: Bool
buildNoCache = Bool
False
                                     , buildRemoveItermediate :: Bool
buildRemoveItermediate = Bool
True
                                     , buildForceRemoveIntermediate :: Bool
buildForceRemoveIntermediate = Bool
False
                                     , buildPullParent :: Bool
buildPullParent = Bool
False
                                     }

-- | Default options for deleting a container. Most of the time we DON'T
-- want to delete the container's volumes or force delete it if it's
-- running.
defaultContainerDeleteOpts :: ContainerDeleteOpts
defaultContainerDeleteOpts :: ContainerDeleteOpts
defaultContainerDeleteOpts = ContainerDeleteOpts :: Bool -> Bool -> ContainerDeleteOpts
ContainerDeleteOpts { deleteVolumes :: Bool
deleteVolumes = Bool
False, force :: Bool
force = Bool
False }

-- | Image delete opts
data ImageDeleteOpts = ImageDeleteOpts deriving (ImageDeleteOpts -> ImageDeleteOpts -> Bool
(ImageDeleteOpts -> ImageDeleteOpts -> Bool)
-> (ImageDeleteOpts -> ImageDeleteOpts -> Bool)
-> Eq ImageDeleteOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ImageDeleteOpts -> ImageDeleteOpts -> Bool
$c/= :: ImageDeleteOpts -> ImageDeleteOpts -> Bool
== :: ImageDeleteOpts -> ImageDeleteOpts -> Bool
$c== :: ImageDeleteOpts -> ImageDeleteOpts -> Bool
Eq, Int -> ImageDeleteOpts -> ShowS
[ImageDeleteOpts] -> ShowS
ImageDeleteOpts -> String
(Int -> ImageDeleteOpts -> ShowS)
-> (ImageDeleteOpts -> String)
-> ([ImageDeleteOpts] -> ShowS)
-> Show ImageDeleteOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ImageDeleteOpts] -> ShowS
$cshowList :: [ImageDeleteOpts] -> ShowS
show :: ImageDeleteOpts -> String
$cshow :: ImageDeleteOpts -> String
showsPrec :: Int -> ImageDeleteOpts -> ShowS
$cshowsPrec :: Int -> ImageDeleteOpts -> ShowS
Show)

-- | Sane image deletion defaults
defaultImageDeleteOpts :: ImageDeleteOpts
defaultImageDeleteOpts :: ImageDeleteOpts
defaultImageDeleteOpts = ImageDeleteOpts
ImageDeleteOpts

-- | Timestamp alias.
type Timestamp = Integer

-- | Used for requesting N number of lines when tailing a containers log
-- output.
data TailLogOpt = Tail Integer | All deriving (TailLogOpt -> TailLogOpt -> Bool
(TailLogOpt -> TailLogOpt -> Bool)
-> (TailLogOpt -> TailLogOpt -> Bool) -> Eq TailLogOpt
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TailLogOpt -> TailLogOpt -> Bool
$c/= :: TailLogOpt -> TailLogOpt -> Bool
== :: TailLogOpt -> TailLogOpt -> Bool
$c== :: TailLogOpt -> TailLogOpt -> Bool
Eq, Int -> TailLogOpt -> ShowS
[TailLogOpt] -> ShowS
TailLogOpt -> String
(Int -> TailLogOpt -> ShowS)
-> (TailLogOpt -> String)
-> ([TailLogOpt] -> ShowS)
-> Show TailLogOpt
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TailLogOpt] -> ShowS
$cshowList :: [TailLogOpt] -> ShowS
show :: TailLogOpt -> String
$cshow :: TailLogOpt -> String
showsPrec :: Int -> TailLogOpt -> ShowS
$cshowsPrec :: Int -> TailLogOpt -> ShowS
Show)


-- | Log options used when requesting the log output from a container.
data LogOpts = LogOpts {
               LogOpts -> Bool
stdout     :: Bool
             , LogOpts -> Bool
stderr     :: Bool
             , LogOpts -> Maybe Integer
since      :: Maybe Timestamp
             , LogOpts -> Bool
timestamps :: Bool
             , LogOpts -> TailLogOpt
tail       :: TailLogOpt
             } deriving (LogOpts -> LogOpts -> Bool
(LogOpts -> LogOpts -> Bool)
-> (LogOpts -> LogOpts -> Bool) -> Eq LogOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LogOpts -> LogOpts -> Bool
$c/= :: LogOpts -> LogOpts -> Bool
== :: LogOpts -> LogOpts -> Bool
$c== :: LogOpts -> LogOpts -> Bool
Eq, Int -> LogOpts -> ShowS
[LogOpts] -> ShowS
LogOpts -> String
(Int -> LogOpts -> ShowS)
-> (LogOpts -> String) -> ([LogOpts] -> ShowS) -> Show LogOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LogOpts] -> ShowS
$cshowList :: [LogOpts] -> ShowS
show :: LogOpts -> String
$cshow :: LogOpts -> String
showsPrec :: Int -> LogOpts -> ShowS
$cshowsPrec :: Int -> LogOpts -> ShowS
Show)

-- | Sensible default for log options.
defaultLogOpts :: LogOpts
defaultLogOpts :: LogOpts
defaultLogOpts = LogOpts :: Bool -> Bool -> Maybe Integer -> Bool -> TailLogOpt -> LogOpts
LogOpts { stdout :: Bool
stdout = Bool
True
                         , stderr :: Bool
stderr = Bool
True
                         , since :: Maybe Integer
since = Maybe Integer
forall a. Maybe a
Nothing
                         , timestamps :: Bool
timestamps = Bool
True
                         , tail :: TailLogOpt
tail = TailLogOpt
All
                         }

-- | Options for creating a network
data CreateNetworkOpts = CreateNetworkOpts
  { CreateNetworkOpts -> Text
createNetworkName           :: Text -- ^ The network's name
  , CreateNetworkOpts -> Bool
createNetworkCheckDuplicate :: Bool -- ^ Check for networks with duplicate names.
  , CreateNetworkOpts -> Text
createNetworkDriver         :: Text -- ^ Name of the network driver plugin to use.
  , CreateNetworkOpts -> Bool
createNetworkInternal       :: Bool -- ^ Restrict external access to the network.
  , CreateNetworkOpts -> Bool
createNetworkEnableIPv6     :: Bool -- ^ Enable IPv6 on the network.
  } deriving (CreateNetworkOpts -> CreateNetworkOpts -> Bool
(CreateNetworkOpts -> CreateNetworkOpts -> Bool)
-> (CreateNetworkOpts -> CreateNetworkOpts -> Bool)
-> Eq CreateNetworkOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CreateNetworkOpts -> CreateNetworkOpts -> Bool
$c/= :: CreateNetworkOpts -> CreateNetworkOpts -> Bool
== :: CreateNetworkOpts -> CreateNetworkOpts -> Bool
$c== :: CreateNetworkOpts -> CreateNetworkOpts -> Bool
Eq, Int -> CreateNetworkOpts -> ShowS
[CreateNetworkOpts] -> ShowS
CreateNetworkOpts -> String
(Int -> CreateNetworkOpts -> ShowS)
-> (CreateNetworkOpts -> String)
-> ([CreateNetworkOpts] -> ShowS)
-> Show CreateNetworkOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CreateNetworkOpts] -> ShowS
$cshowList :: [CreateNetworkOpts] -> ShowS
show :: CreateNetworkOpts -> String
$cshow :: CreateNetworkOpts -> String
showsPrec :: Int -> CreateNetworkOpts -> ShowS
$cshowsPrec :: Int -> CreateNetworkOpts -> ShowS
Show)

-- | Sensible defalut for create network options
defaultCreateNetworkOpts :: Text -> CreateNetworkOpts
defaultCreateNetworkOpts :: Text -> CreateNetworkOpts
defaultCreateNetworkOpts Text
name =
  CreateNetworkOpts :: Text -> Bool -> Text -> Bool -> Bool -> CreateNetworkOpts
CreateNetworkOpts
  { createNetworkName :: Text
createNetworkName = Text
name
  , createNetworkCheckDuplicate :: Bool
createNetworkCheckDuplicate = Bool
False
  , createNetworkDriver :: Text
createNetworkDriver = Text
"bridge"
  , createNetworkInternal :: Bool
createNetworkInternal = Bool
True
  , createNetworkEnableIPv6 :: Bool
createNetworkEnableIPv6 = Bool
False
  }

instance ToJSON CreateNetworkOpts where
  toJSON :: CreateNetworkOpts -> Value
toJSON CreateNetworkOpts
opts =
    [Pair] -> Value
object
      [ Key
"Name" Key -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= CreateNetworkOpts -> Text
createNetworkName CreateNetworkOpts
opts
      , Key
"CheckDuplicate" Key -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= CreateNetworkOpts -> Bool
createNetworkCheckDuplicate CreateNetworkOpts
opts
      , Key
"Driver" Key -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= CreateNetworkOpts -> Text
createNetworkDriver CreateNetworkOpts
opts
      , Key
"Internal" Key -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= CreateNetworkOpts -> Bool
createNetworkInternal CreateNetworkOpts
opts
      , Key
"EnableIPv6" Key -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= CreateNetworkOpts -> Bool
createNetworkEnableIPv6 CreateNetworkOpts
opts
      ]

-- TOOD: Add support for SELinux Volume labels (eg. "ro,z" or "ro/Z")
-- | Set permissions on volumes that you mount in the container.
data VolumePermission = ReadWrite | ReadOnly deriving (VolumePermission -> VolumePermission -> Bool
(VolumePermission -> VolumePermission -> Bool)
-> (VolumePermission -> VolumePermission -> Bool)
-> Eq VolumePermission
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VolumePermission -> VolumePermission -> Bool
$c/= :: VolumePermission -> VolumePermission -> Bool
== :: VolumePermission -> VolumePermission -> Bool
$c== :: VolumePermission -> VolumePermission -> Bool
Eq, Int -> VolumePermission -> ShowS
[VolumePermission] -> ShowS
VolumePermission -> String
(Int -> VolumePermission -> ShowS)
-> (VolumePermission -> String)
-> ([VolumePermission] -> ShowS)
-> Show VolumePermission
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VolumePermission] -> ShowS
$cshowList :: [VolumePermission] -> ShowS
show :: VolumePermission -> String
$cshow :: VolumePermission -> String
showsPrec :: Int -> VolumePermission -> ShowS
$cshowsPrec :: Int -> VolumePermission -> ShowS
Show, (forall x. VolumePermission -> Rep VolumePermission x)
-> (forall x. Rep VolumePermission x -> VolumePermission)
-> Generic VolumePermission
forall x. Rep VolumePermission x -> VolumePermission
forall x. VolumePermission -> Rep VolumePermission x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep VolumePermission x -> VolumePermission
$cfrom :: forall x. VolumePermission -> Rep VolumePermission x
Generic)

instance ToJSON VolumePermission where
    toJSON :: VolumePermission -> Value
toJSON VolumePermission
ReadWrite = Value
"rw"
    toJSON VolumePermission
ReadOnly  = Value
"ro"

instance FromJSON VolumePermission where
    parseJSON :: Value -> Parser VolumePermission
parseJSON Value
"rw" = VolumePermission -> Parser VolumePermission
forall (m :: * -> *) a. Monad m => a -> m a
return VolumePermission
ReadWrite
    parseJSON Value
"ro" = VolumePermission -> Parser VolumePermission
forall (m :: * -> *) a. Monad m => a -> m a
return VolumePermission
ReadOnly
    parseJSON Value
"RW" = VolumePermission -> Parser VolumePermission
forall (m :: * -> *) a. Monad m => a -> m a
return VolumePermission
ReadWrite
    parseJSON Value
"RO" = VolumePermission -> Parser VolumePermission
forall (m :: * -> *) a. Monad m => a -> m a
return VolumePermission
ReadOnly
    parseJSON Value
_    = String -> Parser VolumePermission
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Failed to parse VolumePermission"

-- | Used for marking a directory in the container as "exposed" hence
-- taking it outside of the COW filesystem and making it mountable
-- in other containers using "VolumesFrom". The volume usually get's
-- created somewhere in @/var/lib/docker/volumes@ (depending on the volume
-- driver used).
-- The CLI example is:
--
-- @
-- docker run --name app -v \/opt\/data -it myapp:latest
-- docker run --name app2 --volumes-from app \/bin\/bash -c "ls -l \/opt\/data"
-- @
newtype Volume = Volume FilePath deriving (Volume -> Volume -> Bool
(Volume -> Volume -> Bool)
-> (Volume -> Volume -> Bool) -> Eq Volume
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Volume -> Volume -> Bool
$c/= :: Volume -> Volume -> Bool
== :: Volume -> Volume -> Bool
$c== :: Volume -> Volume -> Bool
Eq, Int -> Volume -> ShowS
[Volume] -> ShowS
Volume -> String
(Int -> Volume -> ShowS)
-> (Volume -> String) -> ([Volume] -> ShowS) -> Show Volume
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Volume] -> ShowS
$cshowList :: [Volume] -> ShowS
show :: Volume -> String
$cshow :: Volume -> String
showsPrec :: Int -> Volume -> ShowS
$cshowsPrec :: Int -> Volume -> ShowS
Show)

instance {-# OVERLAPPING #-} ToJSON [Volume] where
    toJSON :: [Volume] -> Value
toJSON [] = Value
emptyObject
    toJSON (Volume
v:[Volume]
vs) = [Volume] -> (Volume -> String) -> Value
forall (t :: * -> *) a. Foldable t => t a -> (a -> String) -> Value
toJsonKey (Volume
vVolume -> [Volume] -> [Volume]
forall a. a -> [a] -> [a]
:[Volume]
vs) Volume -> String
getKey
        where getKey :: Volume -> String
getKey (Volume String
v) = String
v

instance {-# OVERLAPPING #-} FromJSON [Volume] where
#if MIN_VERSION_aeson(2,0,0)
    parseJSON :: Value -> Parser [Volume]
parseJSON (JSON.Object Object
o) = [Volume] -> Parser [Volume]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Volume] -> Parser [Volume]) -> [Volume] -> Parser [Volume]
forall a b. (a -> b) -> a -> b
$ (Key -> Volume) -> [Key] -> [Volume]
forall a b. (a -> b) -> [a] -> [b]
map (String -> Volume
Volume (String -> Volume) -> (Key -> String) -> Key -> Volume
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> String
K.toString) ([Key] -> [Volume]) -> [Key] -> [Volume]
forall a b. (a -> b) -> a -> b
$ Object -> [Key]
forall v. KeyMap v -> [Key]
KM.keys Object
o
#else
    parseJSON (JSON.Object o) = return $ map (Volume . T.unpack) $ HM.keys o
#endif
    parseJSON (Value
JSON.Null)     = [Volume] -> Parser [Volume]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    parseJSON Value
_               = String -> Parser [Volume]
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Volume is not an object"


data Bind = Bind { Bind -> Text
hostSrc          :: Text
                 , Bind -> Text
containerDest    :: Text
                 , Bind -> Maybe VolumePermission
volumePermission :: Maybe VolumePermission
                 } deriving (Bind -> Bind -> Bool
(Bind -> Bind -> Bool) -> (Bind -> Bind -> Bool) -> Eq Bind
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Bind -> Bind -> Bool
$c/= :: Bind -> Bind -> Bool
== :: Bind -> Bind -> Bool
$c== :: Bind -> Bind -> Bool
Eq, Int -> Bind -> ShowS
[Bind] -> ShowS
Bind -> String
(Int -> Bind -> ShowS)
-> (Bind -> String) -> ([Bind] -> ShowS) -> Show Bind
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Bind] -> ShowS
$cshowList :: [Bind] -> ShowS
show :: Bind -> String
$cshow :: Bind -> String
showsPrec :: Int -> Bind -> ShowS
$cshowsPrec :: Int -> Bind -> ShowS
Show)

instance FromJSON Bind where
    parseJSON :: Value -> Parser Bind
parseJSON (JSON.String Text
t) = case (Char -> Bool) -> Text -> [Text]
T.split (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
':') Text
t of
        [Text
src, Text
dest]       -> Bind -> Parser Bind
forall (m :: * -> *) a. Monad m => a -> m a
return (Bind -> Parser Bind) -> Bind -> Parser Bind
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Maybe VolumePermission -> Bind
Bind Text
src Text
dest Maybe VolumePermission
forall a. Maybe a
Nothing
        [Text
src, Text
dest, Text
"rw"] -> Bind -> Parser Bind
forall (m :: * -> *) a. Monad m => a -> m a
return (Bind -> Parser Bind) -> Bind -> Parser Bind
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Maybe VolumePermission -> Bind
Bind Text
src Text
dest (Maybe VolumePermission -> Bind) -> Maybe VolumePermission -> Bind
forall a b. (a -> b) -> a -> b
$ VolumePermission -> Maybe VolumePermission
forall a. a -> Maybe a
Just VolumePermission
ReadWrite
        [Text
src, Text
dest, Text
"ro"] -> Bind -> Parser Bind
forall (m :: * -> *) a. Monad m => a -> m a
return (Bind -> Parser Bind) -> Bind -> Parser Bind
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Maybe VolumePermission -> Bind
Bind Text
src Text
dest (Maybe VolumePermission -> Bind) -> Maybe VolumePermission -> Bind
forall a b. (a -> b) -> a -> b
$ VolumePermission -> Maybe VolumePermission
forall a. a -> Maybe a
Just VolumePermission
ReadOnly
        [Text]
_                 -> String -> Parser Bind
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Could not parse Bind"
    parseJSON Value
_ = String -> Parser Bind
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Bind is not a string"

data Device = Device {
              Device -> String
pathOnHost        :: FilePath
            , Device -> String
pathInContainer   :: FilePath
            , Device -> Text
cgroupPermissions :: Text
            } deriving (Device -> Device -> Bool
(Device -> Device -> Bool)
-> (Device -> Device -> Bool) -> Eq Device
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Device -> Device -> Bool
$c/= :: Device -> Device -> Bool
== :: Device -> Device -> Bool
$c== :: Device -> Device -> Bool
Eq, Int -> Device -> ShowS
[Device] -> ShowS
Device -> String
(Int -> Device -> ShowS)
-> (Device -> String) -> ([Device] -> ShowS) -> Show Device
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Device] -> ShowS
$cshowList :: [Device] -> ShowS
show :: Device -> String
$cshow :: Device -> String
showsPrec :: Int -> Device -> ShowS
$cshowsPrec :: Int -> Device -> ShowS
Show, (forall x. Device -> Rep Device x)
-> (forall x. Rep Device x -> Device) -> Generic Device
forall x. Rep Device x -> Device
forall x. Device -> Rep Device x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Device x -> Device
$cfrom :: forall x. Device -> Rep Device x
Generic)

instance ToJSON Device where
    toJSON :: Device -> Value
toJSON = Options -> Device -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
defaultOptions {
         fieldLabelModifier :: ShowS
fieldLabelModifier = (\(Char
x:String
xs) -> Char -> Char
toUpper Char
x Char -> ShowS
forall a. a -> [a] -> [a]
: String
xs)}

instance FromJSON Device where
    parseJSON :: Value -> Parser Device
parseJSON = Options -> Value -> Parser Device
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
defaultOptions {
            fieldLabelModifier :: ShowS
fieldLabelModifier = (\(Char
x:String
xs) -> Char -> Char
toUpper Char
x Char -> ShowS
forall a. a -> [a] -> [a]
: String
xs)}

type ContainerName = Text

data VolumeFrom = VolumeFrom ContainerName (Maybe VolumePermission) deriving (VolumeFrom -> VolumeFrom -> Bool
(VolumeFrom -> VolumeFrom -> Bool)
-> (VolumeFrom -> VolumeFrom -> Bool) -> Eq VolumeFrom
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VolumeFrom -> VolumeFrom -> Bool
$c/= :: VolumeFrom -> VolumeFrom -> Bool
== :: VolumeFrom -> VolumeFrom -> Bool
$c== :: VolumeFrom -> VolumeFrom -> Bool
Eq, Int -> VolumeFrom -> ShowS
[VolumeFrom] -> ShowS
VolumeFrom -> String
(Int -> VolumeFrom -> ShowS)
-> (VolumeFrom -> String)
-> ([VolumeFrom] -> ShowS)
-> Show VolumeFrom
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VolumeFrom] -> ShowS
$cshowList :: [VolumeFrom] -> ShowS
show :: VolumeFrom -> String
$cshow :: VolumeFrom -> String
showsPrec :: Int -> VolumeFrom -> ShowS
$cshowsPrec :: Int -> VolumeFrom -> ShowS
Show)

instance FromJSON VolumeFrom where
    parseJSON :: Value -> Parser VolumeFrom
parseJSON (JSON.String Text
t) = case (Char -> Bool) -> Text -> [Text]
T.split (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
':') Text
t of
        [Text
vol]       -> VolumeFrom -> Parser VolumeFrom
forall (m :: * -> *) a. Monad m => a -> m a
return (VolumeFrom -> Parser VolumeFrom)
-> VolumeFrom -> Parser VolumeFrom
forall a b. (a -> b) -> a -> b
$ Text -> Maybe VolumePermission -> VolumeFrom
VolumeFrom Text
vol Maybe VolumePermission
forall a. Maybe a
Nothing
        [Text
vol, Text
"rw"] -> VolumeFrom -> Parser VolumeFrom
forall (m :: * -> *) a. Monad m => a -> m a
return (VolumeFrom -> Parser VolumeFrom)
-> VolumeFrom -> Parser VolumeFrom
forall a b. (a -> b) -> a -> b
$ Text -> Maybe VolumePermission -> VolumeFrom
VolumeFrom Text
vol (Maybe VolumePermission -> VolumeFrom)
-> Maybe VolumePermission -> VolumeFrom
forall a b. (a -> b) -> a -> b
$ VolumePermission -> Maybe VolumePermission
forall a. a -> Maybe a
Just VolumePermission
ReadWrite
        [Text
vol, Text
"ro"] -> VolumeFrom -> Parser VolumeFrom
forall (m :: * -> *) a. Monad m => a -> m a
return (VolumeFrom -> Parser VolumeFrom)
-> VolumeFrom -> Parser VolumeFrom
forall a b. (a -> b) -> a -> b
$ Text -> Maybe VolumePermission -> VolumeFrom
VolumeFrom Text
vol (Maybe VolumePermission -> VolumeFrom)
-> Maybe VolumePermission -> VolumeFrom
forall a b. (a -> b) -> a -> b
$ VolumePermission -> Maybe VolumePermission
forall a. a -> Maybe a
Just VolumePermission
ReadOnly
        [Text]
_           -> String -> Parser VolumeFrom
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Could not parse VolumeFrom"
    parseJSON Value
_ = String -> Parser VolumeFrom
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"VolumeFrom is not a string"

instance ToJSON VolumeFrom where
    toJSON :: VolumeFrom -> Value
toJSON (VolumeFrom Text
n Maybe VolumePermission
p) = case Maybe VolumePermission
p of
        Maybe VolumePermission
Nothing  -> Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Value) -> Text -> Value
forall a b. (a -> b) -> a -> b
$ Text
n Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
":" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"rw"
        Just VolumePermission
per -> Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Value) -> Text -> Value
forall a b. (a -> b) -> a -> b
$ Text
n Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
":" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ VolumePermission -> String
forall a. Show a => a -> String
show VolumePermission
per)

instance ToJSON Bind where
    toJSON :: Bind -> Value
toJSON (Bind Text
src Text
dest Maybe VolumePermission
mode) = Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Value) -> Text -> Value
forall a b. (a -> b) -> a -> b
$ case Maybe VolumePermission
mode of
                        Maybe VolumePermission
Nothing -> [Text] -> Text
T.concat[Text
src, Text
":", Text
dest]
                        Just VolumePermission
m ->  [Text] -> Text
T.concat[Text
src, Text
":", Text
dest, Text
":", Text
str]
                            where str :: Text
str = case VolumePermission
m of
                                    VolumePermission
ReadOnly -> Text
"ro"
                                    VolumePermission
ReadWrite -> Text
"rw"

data Link = Link Text (Maybe Text) deriving (Link -> Link -> Bool
(Link -> Link -> Bool) -> (Link -> Link -> Bool) -> Eq Link
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Link -> Link -> Bool
$c/= :: Link -> Link -> Bool
== :: Link -> Link -> Bool
$c== :: Link -> Link -> Bool
Eq, Int -> Link -> ShowS
[Link] -> ShowS
Link -> String
(Int -> Link -> ShowS)
-> (Link -> String) -> ([Link] -> ShowS) -> Show Link
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Link] -> ShowS
$cshowList :: [Link] -> ShowS
show :: Link -> String
$cshow :: Link -> String
showsPrec :: Int -> Link -> ShowS
$cshowsPrec :: Int -> Link -> ShowS
Show)

instance FromJSON Link where
    parseJSON :: Value -> Parser Link
parseJSON (JSON.String Text
t) = case (Char -> Bool) -> Text -> [Text]
T.split (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
':') Text
t of
        [Text
f]   -> Link -> Parser Link
forall (m :: * -> *) a. Monad m => a -> m a
return (Link -> Parser Link) -> Link -> Parser Link
forall a b. (a -> b) -> a -> b
$ Text -> Maybe Text -> Link
Link Text
f Maybe Text
forall a. Maybe a
Nothing
        [Text
f,Text
s] -> Link -> Parser Link
forall (m :: * -> *) a. Monad m => a -> m a
return (Link -> Parser Link) -> Link -> Parser Link
forall a b. (a -> b) -> a -> b
$ Text -> Maybe Text -> Link
Link Text
f (Maybe Text -> Link) -> Maybe Text -> Link
forall a b. (a -> b) -> a -> b
$ Text -> Maybe Text
forall a. a -> Maybe a
Just Text
s
        [Text]
_     -> String -> Parser Link
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Could not parse Link"
    parseJSON Value
_ = String -> Parser Link
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Link is not a string"

instance ToJSON Link where
    toJSON :: Link -> Value
toJSON (Link Text
n1 Maybe Text
n2) = Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Value) -> Text -> Value
forall a b. (a -> b) -> a -> b
$ case Maybe Text
n2 of
                        Maybe Text
Nothing -> [Text] -> Text
T.concat[Text
n1, Text
":", Text
n1] -- use same name in container
                        Just Text
n  ->  [Text] -> Text
T.concat[Text
n1, Text
":", Text
n] -- used specified name in container

-- { "Type": "<driver_name>", "Config": {"key1": "val1"} }
data LogDriverType = JsonFile | Syslog | Journald | Gelf | Fluentd | AwsLogs | Splunk | Etwlogs | LoggingDisabled deriving (LogDriverType -> LogDriverType -> Bool
(LogDriverType -> LogDriverType -> Bool)
-> (LogDriverType -> LogDriverType -> Bool) -> Eq LogDriverType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LogDriverType -> LogDriverType -> Bool
$c/= :: LogDriverType -> LogDriverType -> Bool
== :: LogDriverType -> LogDriverType -> Bool
$c== :: LogDriverType -> LogDriverType -> Bool
Eq, Int -> LogDriverType -> ShowS
[LogDriverType] -> ShowS
LogDriverType -> String
(Int -> LogDriverType -> ShowS)
-> (LogDriverType -> String)
-> ([LogDriverType] -> ShowS)
-> Show LogDriverType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LogDriverType] -> ShowS
$cshowList :: [LogDriverType] -> ShowS
show :: LogDriverType -> String
$cshow :: LogDriverType -> String
showsPrec :: Int -> LogDriverType -> ShowS
$cshowsPrec :: Int -> LogDriverType -> ShowS
Show)

instance FromJSON LogDriverType where
    parseJSON :: Value -> Parser LogDriverType
parseJSON (JSON.String Text
"json-file") = LogDriverType -> Parser LogDriverType
forall (m :: * -> *) a. Monad m => a -> m a
return LogDriverType
JsonFile
    parseJSON (JSON.String Text
"syslog")    = LogDriverType -> Parser LogDriverType
forall (m :: * -> *) a. Monad m => a -> m a
return LogDriverType
Syslog
    parseJSON (JSON.String Text
"journald")  = LogDriverType -> Parser LogDriverType
forall (m :: * -> *) a. Monad m => a -> m a
return LogDriverType
Journald
    parseJSON (JSON.String Text
"gelf")      = LogDriverType -> Parser LogDriverType
forall (m :: * -> *) a. Monad m => a -> m a
return LogDriverType
Gelf
    parseJSON (JSON.String Text
"fluentd")   = LogDriverType -> Parser LogDriverType
forall (m :: * -> *) a. Monad m => a -> m a
return LogDriverType
Fluentd
    parseJSON (JSON.String Text
"awslogs")   = LogDriverType -> Parser LogDriverType
forall (m :: * -> *) a. Monad m => a -> m a
return LogDriverType
AwsLogs
    parseJSON (JSON.String Text
"splunk")    = LogDriverType -> Parser LogDriverType
forall (m :: * -> *) a. Monad m => a -> m a
return LogDriverType
Splunk
    parseJSON (JSON.String Text
"etwlogs")   = LogDriverType -> Parser LogDriverType
forall (m :: * -> *) a. Monad m => a -> m a
return LogDriverType
Etwlogs
    parseJSON (JSON.String Text
"none")      = LogDriverType -> Parser LogDriverType
forall (m :: * -> *) a. Monad m => a -> m a
return LogDriverType
LoggingDisabled
    parseJSON Value
_                         = String -> Parser LogDriverType
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Unknown LogDriverType"

instance ToJSON LogDriverType where
    toJSON :: LogDriverType -> Value
toJSON LogDriverType
JsonFile        = Text -> Value
JSON.String Text
"json-file"
    toJSON LogDriverType
Syslog          = Text -> Value
JSON.String Text
"syslog"
    toJSON LogDriverType
Journald        = Text -> Value
JSON.String Text
"journald"
    toJSON LogDriverType
Gelf            = Text -> Value
JSON.String Text
"gelf"
    toJSON LogDriverType
Fluentd         = Text -> Value
JSON.String Text
"fluentd"
    toJSON LogDriverType
AwsLogs         = Text -> Value
JSON.String Text
"awslogs"
    toJSON LogDriverType
Splunk          = Text -> Value
JSON.String Text
"splunk"
    toJSON LogDriverType
Etwlogs         = Text -> Value
JSON.String Text
"etwlogs"
    toJSON LogDriverType
LoggingDisabled = Text -> Value
JSON.String Text
"none"

data LogDriverOption = LogDriverOption Name Value deriving (LogDriverOption -> LogDriverOption -> Bool
(LogDriverOption -> LogDriverOption -> Bool)
-> (LogDriverOption -> LogDriverOption -> Bool)
-> Eq LogDriverOption
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LogDriverOption -> LogDriverOption -> Bool
$c/= :: LogDriverOption -> LogDriverOption -> Bool
== :: LogDriverOption -> LogDriverOption -> Bool
$c== :: LogDriverOption -> LogDriverOption -> Bool
Eq, Int -> LogDriverOption -> ShowS
[LogDriverOption] -> ShowS
LogDriverOption -> String
(Int -> LogDriverOption -> ShowS)
-> (LogDriverOption -> String)
-> ([LogDriverOption] -> ShowS)
-> Show LogDriverOption
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LogDriverOption] -> ShowS
$cshowList :: [LogDriverOption] -> ShowS
show :: LogDriverOption -> String
$cshow :: LogDriverOption -> String
showsPrec :: Int -> LogDriverOption -> ShowS
$cshowsPrec :: Int -> LogDriverOption -> ShowS
Show)

instance {-# OVERLAPPING #-} ToJSON [LogDriverOption] where
    toJSON :: [LogDriverOption] -> Value
toJSON [] = Value
emptyObject
    toJSON (LogDriverOption
o:[LogDriverOption]
os) = [LogDriverOption]
-> (LogDriverOption -> String)
-> (LogDriverOption -> Text)
-> Value
forall (t :: * -> *) r a.
(Foldable t, ToJSON r) =>
t a -> (a -> String) -> (a -> r) -> Value
toJsonKeyVal (LogDriverOption
oLogDriverOption -> [LogDriverOption] -> [LogDriverOption]
forall a. a -> [a] -> [a]
:[LogDriverOption]
os) LogDriverOption -> String
key LogDriverOption -> Text
val
        where key :: LogDriverOption -> String
key (LogDriverOption Text
n Text
_) = Text -> String
T.unpack Text
n
              val :: LogDriverOption -> Text
val (LogDriverOption Text
_ Text
v) = Text
v

instance {-# OVERLAPPING #-} FromJSON [LogDriverOption] where
    parseJSON :: Value -> Parser [LogDriverOption]
parseJSON (JSON.Object Object
o) = (Parser [LogDriverOption]
 -> Text -> Value -> Parser [LogDriverOption])
-> Parser [LogDriverOption]
-> HashMap Text Value
-> Parser [LogDriverOption]
forall a k v. (a -> k -> v -> a) -> a -> HashMap k v -> a
HM.foldlWithKey' Parser [LogDriverOption]
-> Text -> Value -> Parser [LogDriverOption]
f ([LogDriverOption] -> Parser [LogDriverOption]
forall (m :: * -> *) a. Monad m => a -> m a
return []) (Object -> HashMap Text Value
forall v. KeyMap v -> HashMap Text v
toHashMap Object
o)
        where f :: Parser [LogDriverOption]
-> Text -> Value -> Parser [LogDriverOption]
f Parser [LogDriverOption]
accM Text
k Value
v = do
                [LogDriverOption]
acc <- Parser [LogDriverOption]
accM
                Text
value <- Value -> Parser Text
forall a. FromJSON a => Value -> Parser a
parseJSON Value
v
                [LogDriverOption] -> Parser [LogDriverOption]
forall (m :: * -> *) a. Monad m => a -> m a
return ([LogDriverOption] -> Parser [LogDriverOption])
-> [LogDriverOption] -> Parser [LogDriverOption]
forall a b. (a -> b) -> a -> b
$ (Text -> Text -> LogDriverOption
LogDriverOption Text
k Text
value)LogDriverOption -> [LogDriverOption] -> [LogDriverOption]
forall a. a -> [a] -> [a]
:[LogDriverOption]
acc
    parseJSON Value
JSON.Null = [LogDriverOption] -> Parser [LogDriverOption]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    parseJSON Value
_ = String -> Parser [LogDriverOption]
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Failed to parse LogDriverOptions"

data LogDriverConfig = LogDriverConfig LogDriverType [LogDriverOption] deriving (LogDriverConfig -> LogDriverConfig -> Bool
(LogDriverConfig -> LogDriverConfig -> Bool)
-> (LogDriverConfig -> LogDriverConfig -> Bool)
-> Eq LogDriverConfig
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LogDriverConfig -> LogDriverConfig -> Bool
$c/= :: LogDriverConfig -> LogDriverConfig -> Bool
== :: LogDriverConfig -> LogDriverConfig -> Bool
$c== :: LogDriverConfig -> LogDriverConfig -> Bool
Eq, Int -> LogDriverConfig -> ShowS
[LogDriverConfig] -> ShowS
LogDriverConfig -> String
(Int -> LogDriverConfig -> ShowS)
-> (LogDriverConfig -> String)
-> ([LogDriverConfig] -> ShowS)
-> Show LogDriverConfig
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LogDriverConfig] -> ShowS
$cshowList :: [LogDriverConfig] -> ShowS
show :: LogDriverConfig -> String
$cshow :: LogDriverConfig -> String
showsPrec :: Int -> LogDriverConfig -> ShowS
$cshowsPrec :: Int -> LogDriverConfig -> ShowS
Show)

instance ToJSON LogDriverConfig where
    toJSON :: LogDriverConfig -> Value
toJSON (LogDriverConfig LogDriverType
driverType []) = [Pair] -> Value
object [Key
"Type" Key -> LogDriverType -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= LogDriverType
driverType]
    toJSON (LogDriverConfig LogDriverType
driverType [LogDriverOption]
driverOptions) = [Pair] -> Value
object [Key
"Type" Key -> LogDriverType -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= LogDriverType
driverType, Key
"Config" Key -> [LogDriverOption] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [LogDriverOption]
driverOptions]

instance FromJSON LogDriverConfig where
    parseJSON :: Value -> Parser LogDriverConfig
parseJSON (JSON.Object Object
o) = do
        LogDriverType
typ <- Object
o Object -> Key -> Parser LogDriverType
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Type"
        [LogDriverOption]
opts <- Object
o Object -> Key -> Parser [LogDriverOption]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Config"
        LogDriverConfig -> Parser LogDriverConfig
forall (m :: * -> *) a. Monad m => a -> m a
return (LogDriverConfig -> Parser LogDriverConfig)
-> LogDriverConfig -> Parser LogDriverConfig
forall a b. (a -> b) -> a -> b
$ LogDriverType -> [LogDriverOption] -> LogDriverConfig
LogDriverConfig LogDriverType
typ [LogDriverOption]
opts
    parseJSON Value
_ = String -> Parser LogDriverConfig
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"LogDriverConfig is not an object"

-- TODO: Add container:<name|id> mode
data NetworkMode = NetworkBridge | NetworkHost | NetworkDisabled | NetworkNamed Text
    deriving (NetworkMode -> NetworkMode -> Bool
(NetworkMode -> NetworkMode -> Bool)
-> (NetworkMode -> NetworkMode -> Bool) -> Eq NetworkMode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NetworkMode -> NetworkMode -> Bool
$c/= :: NetworkMode -> NetworkMode -> Bool
== :: NetworkMode -> NetworkMode -> Bool
$c== :: NetworkMode -> NetworkMode -> Bool
Eq, Int -> NetworkMode -> ShowS
[NetworkMode] -> ShowS
NetworkMode -> String
(Int -> NetworkMode -> ShowS)
-> (NetworkMode -> String)
-> ([NetworkMode] -> ShowS)
-> Show NetworkMode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NetworkMode] -> ShowS
$cshowList :: [NetworkMode] -> ShowS
show :: NetworkMode -> String
$cshow :: NetworkMode -> String
showsPrec :: Int -> NetworkMode -> ShowS
$cshowsPrec :: Int -> NetworkMode -> ShowS
Show, Eq NetworkMode
Eq NetworkMode
-> (NetworkMode -> NetworkMode -> Ordering)
-> (NetworkMode -> NetworkMode -> Bool)
-> (NetworkMode -> NetworkMode -> Bool)
-> (NetworkMode -> NetworkMode -> Bool)
-> (NetworkMode -> NetworkMode -> Bool)
-> (NetworkMode -> NetworkMode -> NetworkMode)
-> (NetworkMode -> NetworkMode -> NetworkMode)
-> Ord NetworkMode
NetworkMode -> NetworkMode -> Bool
NetworkMode -> NetworkMode -> Ordering
NetworkMode -> NetworkMode -> NetworkMode
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: NetworkMode -> NetworkMode -> NetworkMode
$cmin :: NetworkMode -> NetworkMode -> NetworkMode
max :: NetworkMode -> NetworkMode -> NetworkMode
$cmax :: NetworkMode -> NetworkMode -> NetworkMode
>= :: NetworkMode -> NetworkMode -> Bool
$c>= :: NetworkMode -> NetworkMode -> Bool
> :: NetworkMode -> NetworkMode -> Bool
$c> :: NetworkMode -> NetworkMode -> Bool
<= :: NetworkMode -> NetworkMode -> Bool
$c<= :: NetworkMode -> NetworkMode -> Bool
< :: NetworkMode -> NetworkMode -> Bool
$c< :: NetworkMode -> NetworkMode -> Bool
compare :: NetworkMode -> NetworkMode -> Ordering
$ccompare :: NetworkMode -> NetworkMode -> Ordering
$cp1Ord :: Eq NetworkMode
Ord)

instance FromJSON NetworkMode where
    parseJSON :: Value -> Parser NetworkMode
parseJSON (JSON.String Text
"bridge") = NetworkMode -> Parser NetworkMode
forall (m :: * -> *) a. Monad m => a -> m a
return NetworkMode
NetworkBridge
    parseJSON (JSON.String Text
"host")   = NetworkMode -> Parser NetworkMode
forall (m :: * -> *) a. Monad m => a -> m a
return NetworkMode
NetworkHost -- Note: Guessing on these.
    parseJSON (JSON.String Text
"none")   = NetworkMode -> Parser NetworkMode
forall (m :: * -> *) a. Monad m => a -> m a
return NetworkMode
NetworkDisabled
    parseJSON (JSON.String Text
n)        = NetworkMode -> Parser NetworkMode
forall (m :: * -> *) a. Monad m => a -> m a
return (NetworkMode -> Parser NetworkMode)
-> NetworkMode -> Parser NetworkMode
forall a b. (a -> b) -> a -> b
$ Text -> NetworkMode
NetworkNamed Text
n
    parseJSON Value
_                      = String -> Parser NetworkMode
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Unknown NetworkMode"

instance ToJSON NetworkMode where
    toJSON :: NetworkMode -> Value
toJSON NetworkMode
NetworkBridge    = Text -> Value
JSON.String Text
"bridge"
    toJSON NetworkMode
NetworkHost      = Text -> Value
JSON.String Text
"host"
    toJSON NetworkMode
NetworkDisabled  = Text -> Value
JSON.String Text
"none"
    toJSON (NetworkNamed Text
n) = Text -> Value
JSON.String Text
n

newtype NetworkID = NetworkID Text
    deriving (NetworkID -> NetworkID -> Bool
(NetworkID -> NetworkID -> Bool)
-> (NetworkID -> NetworkID -> Bool) -> Eq NetworkID
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NetworkID -> NetworkID -> Bool
$c/= :: NetworkID -> NetworkID -> Bool
== :: NetworkID -> NetworkID -> Bool
$c== :: NetworkID -> NetworkID -> Bool
Eq, Int -> NetworkID -> ShowS
[NetworkID] -> ShowS
NetworkID -> String
(Int -> NetworkID -> ShowS)
-> (NetworkID -> String)
-> ([NetworkID] -> ShowS)
-> Show NetworkID
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NetworkID] -> ShowS
$cshowList :: [NetworkID] -> ShowS
show :: NetworkID -> String
$cshow :: NetworkID -> String
showsPrec :: Int -> NetworkID -> ShowS
$cshowsPrec :: Int -> NetworkID -> ShowS
Show)

-- | Used for extracting the id of the container from the newtype
fromNetworkID :: NetworkID -> Text
fromNetworkID :: NetworkID -> Text
fromNetworkID (NetworkID Text
t) = Text
t

-- | Used for parsing a Text value into a NetworkID.
toNetworkID :: Text -> Maybe NetworkID
toNetworkID :: Text -> Maybe NetworkID
toNetworkID Text
t = NetworkID -> Maybe NetworkID
forall a. a -> Maybe a
Just (NetworkID -> Maybe NetworkID) -> NetworkID -> Maybe NetworkID
forall a b. (a -> b) -> a -> b
$ Text -> NetworkID
NetworkID Text
t

instance FromJSON NetworkID where
  parseJSON :: Value -> Parser NetworkID
parseJSON (JSON.Object Object
o) = do
    Text
nid <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Id"
    NetworkID -> Parser NetworkID
forall (m :: * -> *) a. Monad m => a -> m a
return (NetworkID -> Parser NetworkID) -> NetworkID -> Parser NetworkID
forall a b. (a -> b) -> a -> b
$ Text -> NetworkID
NetworkID Text
nid
  parseJSON Value
_ = String -> Parser NetworkID
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"NetworkID is not an object."

instance ToJSON NetworkID where
  toJSON :: NetworkID -> Value
toJSON (NetworkID Text
nid) = [Pair] -> Value
object [Key
"Id" Key -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Text
nid]

data PortType = TCP | UDP deriving (PortType -> PortType -> Bool
(PortType -> PortType -> Bool)
-> (PortType -> PortType -> Bool) -> Eq PortType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PortType -> PortType -> Bool
$c/= :: PortType -> PortType -> Bool
== :: PortType -> PortType -> Bool
$c== :: PortType -> PortType -> Bool
Eq, (forall x. PortType -> Rep PortType x)
-> (forall x. Rep PortType x -> PortType) -> Generic PortType
forall x. Rep PortType x -> PortType
forall x. PortType -> Rep PortType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PortType x -> PortType
$cfrom :: forall x. PortType -> Rep PortType x
Generic, ReadPrec [PortType]
ReadPrec PortType
Int -> ReadS PortType
ReadS [PortType]
(Int -> ReadS PortType)
-> ReadS [PortType]
-> ReadPrec PortType
-> ReadPrec [PortType]
-> Read PortType
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PortType]
$creadListPrec :: ReadPrec [PortType]
readPrec :: ReadPrec PortType
$creadPrec :: ReadPrec PortType
readList :: ReadS [PortType]
$creadList :: ReadS [PortType]
readsPrec :: Int -> ReadS PortType
$creadsPrec :: Int -> ReadS PortType
Read, Eq PortType
Eq PortType
-> (PortType -> PortType -> Ordering)
-> (PortType -> PortType -> Bool)
-> (PortType -> PortType -> Bool)
-> (PortType -> PortType -> Bool)
-> (PortType -> PortType -> Bool)
-> (PortType -> PortType -> PortType)
-> (PortType -> PortType -> PortType)
-> Ord PortType
PortType -> PortType -> Bool
PortType -> PortType -> Ordering
PortType -> PortType -> PortType
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PortType -> PortType -> PortType
$cmin :: PortType -> PortType -> PortType
max :: PortType -> PortType -> PortType
$cmax :: PortType -> PortType -> PortType
>= :: PortType -> PortType -> Bool
$c>= :: PortType -> PortType -> Bool
> :: PortType -> PortType -> Bool
$c> :: PortType -> PortType -> Bool
<= :: PortType -> PortType -> Bool
$c<= :: PortType -> PortType -> Bool
< :: PortType -> PortType -> Bool
$c< :: PortType -> PortType -> Bool
compare :: PortType -> PortType -> Ordering
$ccompare :: PortType -> PortType -> Ordering
$cp1Ord :: Eq PortType
Ord)

instance Show PortType where
    show :: PortType -> String
show PortType
TCP = String
"tcp"
    show PortType
UDP = String
"udp"

instance ToJSON PortType where
    toJSON :: PortType -> Value
toJSON PortType
TCP = Value
"tcp"
    toJSON PortType
UDP = Value
"udp"

instance FromJSON PortType where
    parseJSON :: Value -> Parser PortType
parseJSON Value
val = case Value
val of
                    Value
"tcp" -> PortType -> Parser PortType
forall (m :: * -> *) a. Monad m => a -> m a
return PortType
TCP
                    Value
"udp" -> PortType -> Parser PortType
forall (m :: * -> *) a. Monad m => a -> m a
return PortType
UDP
                    Value
_     -> String -> Parser PortType
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"PortType: Invalid port type."

-- newtype NetworkInterface = NetworkInterface Text deriving (Eq, Show)
--
-- instance FromJSON NetworkInterface where
--     parseJSON (JSON.String v) = return $ NetworkInterface v
--     parseJSON _  = fail "Network interface is not a string."
--
-- instance ToJSON NetworkInterface where
--     toJSON (NetworkInterface i) = JSON.String i

-- | This datastructure models mapping a Port from the container onto the
-- host system s that the service running in the container can be accessed from
-- the outside world. We either map a port onto all interfaces (default) or onto a specific
-- interface like `127.0.0.1`.
-- __NOTE__: We should disallow duplicate port bindings as the ToJSON
-- instance will only send the last one.
-- { <port>/<protocol>: [{ "HostPort": "<port>"  }] }
data PortBinding = PortBinding {
                   PortBinding -> Integer
containerPort :: Port
                 , PortBinding -> PortType
portType      :: PortType
                 , PortBinding -> [HostPort]
hostPorts     :: [HostPort]
                 } deriving (PortBinding -> PortBinding -> Bool
(PortBinding -> PortBinding -> Bool)
-> (PortBinding -> PortBinding -> Bool) -> Eq PortBinding
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PortBinding -> PortBinding -> Bool
$c/= :: PortBinding -> PortBinding -> Bool
== :: PortBinding -> PortBinding -> Bool
$c== :: PortBinding -> PortBinding -> Bool
Eq, Int -> PortBinding -> ShowS
[PortBinding] -> ShowS
PortBinding -> String
(Int -> PortBinding -> ShowS)
-> (PortBinding -> String)
-> ([PortBinding] -> ShowS)
-> Show PortBinding
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PortBinding] -> ShowS
$cshowList :: [PortBinding] -> ShowS
show :: PortBinding -> String
$cshow :: PortBinding -> String
showsPrec :: Int -> PortBinding -> ShowS
$cshowsPrec :: Int -> PortBinding -> ShowS
Show)

portAndType2Text :: Port -> PortType -> Text
portAndType2Text :: Integer -> PortType -> Text
portAndType2Text Integer
p PortType
t = (String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Integer -> String
forall a. Show a => a -> String
show Integer
p) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ PortType -> String
forall a. Show a => a -> String
show PortType
t)


-- | A helper function to more easily add a bind mount to existing
-- "CreateOpts" records.
addBind :: Bind -> CreateOpts -> CreateOpts
addBind :: Bind -> CreateOpts -> CreateOpts
addBind Bind
b CreateOpts
c = CreateOpts
c{hostConfig :: HostConfig
hostConfig=HostConfig
hc{binds :: [Bind]
binds=[Bind]
obs [Bind] -> [Bind] -> [Bind]
forall a. Semigroup a => a -> a -> a
<> [Bind
b]}}
    where hc :: HostConfig
hc = CreateOpts -> HostConfig
hostConfig CreateOpts
c
          obs :: [Bind]
obs = HostConfig -> [Bind]
binds (HostConfig -> [Bind]) -> HostConfig -> [Bind]
forall a b. (a -> b) -> a -> b
$ CreateOpts -> HostConfig
hostConfig CreateOpts
c

-- | Helper function for adding a Command to and existing
-- CreateOpts record.
setCmd :: Text -> CreateOpts -> CreateOpts
setCmd :: Text -> CreateOpts -> CreateOpts
setCmd Text
ccmd CreateOpts
c = CreateOpts
c{containerConfig :: ContainerConfig
containerConfig=ContainerConfig
cc{cmd :: [Text]
cmd=[Text
ccmd]}}
    where cc :: ContainerConfig
cc = CreateOpts -> ContainerConfig
containerConfig CreateOpts
c

-- | Helper function for adding a "Link" to and existing
-- CreateOpts record.
addLink :: Link -> CreateOpts -> CreateOpts
addLink :: Link -> CreateOpts -> CreateOpts
addLink Link
l CreateOpts
c =  CreateOpts
c{hostConfig :: HostConfig
hostConfig=HostConfig
hc{links :: [Link]
links=[Link]
ols [Link] -> [Link] -> [Link]
forall a. Semigroup a => a -> a -> a
<> [Link
l]}}
    where hc :: HostConfig
hc = CreateOpts -> HostConfig
hostConfig CreateOpts
c
          ols :: [Link]
ols = HostConfig -> [Link]
links (HostConfig -> [Link]) -> HostConfig -> [Link]
forall a b. (a -> b) -> a -> b
$ CreateOpts -> HostConfig
hostConfig CreateOpts
c

-- | Helper function for adding a "Volume" to and existing
-- CreateOpts record.
addVolume :: Volume -> CreateOpts -> CreateOpts
addVolume :: Volume -> CreateOpts -> CreateOpts
addVolume Volume
v CreateOpts
c = CreateOpts
c{containerConfig :: ContainerConfig
containerConfig=ContainerConfig
cc{volumes :: [Volume]
volumes=[Volume]
oldvs [Volume] -> [Volume] -> [Volume]
forall a. Semigroup a => a -> a -> a
<> [Volume
v]}}
    where cc :: ContainerConfig
cc = CreateOpts -> ContainerConfig
containerConfig CreateOpts
c
          oldvs :: [Volume]
oldvs = ContainerConfig -> [Volume]
volumes ContainerConfig
cc

-- | Helper function for adding a "VolumeFrom" to and existing
-- CreateOpts record.
addVolumeFrom :: VolumeFrom -> CreateOpts -> CreateOpts
addVolumeFrom :: VolumeFrom -> CreateOpts -> CreateOpts
addVolumeFrom VolumeFrom
vf CreateOpts
c = CreateOpts
c{hostConfig :: HostConfig
hostConfig=HostConfig
hc{volumesFrom :: [VolumeFrom]
volumesFrom=[VolumeFrom]
oldvfs [VolumeFrom] -> [VolumeFrom] -> [VolumeFrom]
forall a. Semigroup a => a -> a -> a
<> [VolumeFrom
vf]}}
    where hc :: HostConfig
hc = CreateOpts -> HostConfig
hostConfig CreateOpts
c
          oldvfs :: [VolumeFrom]
oldvfs = HostConfig -> [VolumeFrom]
volumesFrom HostConfig
hc

-- | A convenience function that adds PortBindings to and exiting
-- "CreateOpts" record.  Useful with 'defaultCreateOpts'
-- Example:
--
-- >>> let pb = PortBinding 80 TCP [HostPort "0.0.0.0" 8000]
-- >>> addPortBinding pb $ defaultCreateOpts "nginx:latest"
addPortBinding :: PortBinding -> CreateOpts -> CreateOpts
addPortBinding :: PortBinding -> CreateOpts -> CreateOpts
addPortBinding PortBinding
pb CreateOpts
c = CreateOpts
c{hostConfig :: HostConfig
hostConfig=HostConfig
hc{portBindings :: [PortBinding]
portBindings=[PortBinding]
pbs [PortBinding] -> [PortBinding] -> [PortBinding]
forall a. Semigroup a => a -> a -> a
<> [PortBinding
pb]}}
    where hc :: HostConfig
hc = CreateOpts -> HostConfig
hostConfig CreateOpts
c
          pbs :: [PortBinding]
pbs = HostConfig -> [PortBinding]
portBindings (HostConfig -> [PortBinding]) -> HostConfig -> [PortBinding]
forall a b. (a -> b) -> a -> b
$ CreateOpts -> HostConfig
hostConfig CreateOpts
c

-- | Helper function for adding a "ExposedPort" to and existing
-- CreateOpts record.
addExposedPort :: ExposedPort -> CreateOpts -> CreateOpts
addExposedPort :: ExposedPort -> CreateOpts -> CreateOpts
addExposedPort ExposedPort
ep CreateOpts
c = CreateOpts
c{containerConfig :: ContainerConfig
containerConfig=ContainerConfig
cc{exposedPorts :: [ExposedPort]
exposedPorts=[ExposedPort]
oldeps [ExposedPort] -> [ExposedPort] -> [ExposedPort]
forall a. Semigroup a => a -> a -> a
<> [ExposedPort
ep]}}
    where cc :: ContainerConfig
cc = CreateOpts -> ContainerConfig
containerConfig CreateOpts
c
          oldeps :: [ExposedPort]
oldeps = ContainerConfig -> [ExposedPort]
exposedPorts ContainerConfig
cc


instance {-# OVERLAPPING #-} FromJSON [PortBinding] where
    parseJSON :: Value -> Parser [PortBinding]
parseJSON (JSON.Object Object
o) = (Parser [PortBinding] -> Text -> Value -> Parser [PortBinding])
-> Parser [PortBinding]
-> HashMap Text Value
-> Parser [PortBinding]
forall a k v. (a -> k -> v -> a) -> a -> HashMap k v -> a
HM.foldlWithKey' Parser [PortBinding] -> Text -> Value -> Parser [PortBinding]
f ([PortBinding] -> Parser [PortBinding]
forall (m :: * -> *) a. Monad m => a -> m a
return []) (Object -> HashMap Text Value
forall v. KeyMap v -> HashMap Text v
toHashMap Object
o)
        where
            f :: Parser [PortBinding] -> Text -> Value -> Parser [PortBinding]
f Parser [PortBinding]
accM Text
k Value
v = case (Char -> Bool) -> Text -> [Text]
T.split (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'/') Text
k of
                [Text
port', Text
portType'] -> do
                    Integer
port <- Text -> Parser Integer
forall (m :: * -> *). MonadFail m => Text -> m Integer
parseIntegerText Text
port'
                    PortType
portType <- Value -> Parser PortType
forall a. FromJSON a => Value -> Parser a
parseJSON (Value -> Parser PortType) -> Value -> Parser PortType
forall a b. (a -> b) -> a -> b
$ Text -> Value
JSON.String Text
portType'
                    [PortBinding]
acc <- Parser [PortBinding]
accM
                    [HostPort]
hps <- [HostPort] -> Maybe [HostPort] -> [HostPort]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [HostPort] -> [HostPort])
-> Parser (Maybe [HostPort]) -> Parser [HostPort]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser (Maybe [HostPort])
forall a. FromJSON a => Value -> Parser a
parseJSON Value
v
                    [PortBinding] -> Parser [PortBinding]
forall (m :: * -> *) a. Monad m => a -> m a
return ([PortBinding] -> Parser [PortBinding])
-> [PortBinding] -> Parser [PortBinding]
forall a b. (a -> b) -> a -> b
$ (Integer -> PortType -> [HostPort] -> PortBinding
PortBinding Integer
port PortType
portType [HostPort]
hps)PortBinding -> [PortBinding] -> [PortBinding]
forall a. a -> [a] -> [a]
:[PortBinding]
acc
                [Text]
_ -> String -> Parser [PortBinding]
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Could not parse PortBindings"
    parseJSON (Value
JSON.Null) = [PortBinding] -> Parser [PortBinding]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    parseJSON Value
_ = String -> Parser [PortBinding]
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"PortBindings is not an object"

instance {-# OVERLAPPING #-} ToJSON [PortBinding] where
    toJSON :: [PortBinding] -> Value
toJSON [] = Value
emptyObject
    toJSON (PortBinding
p:[PortBinding]
ps) = [PortBinding]
-> (PortBinding -> String) -> (PortBinding -> [HostPort]) -> Value
forall (t :: * -> *) r a.
(Foldable t, ToJSON r) =>
t a -> (a -> String) -> (a -> r) -> Value
toJsonKeyVal (PortBinding
pPortBinding -> [PortBinding] -> [PortBinding]
forall a. a -> [a] -> [a]
:[PortBinding]
ps) PortBinding -> String
key PortBinding -> [HostPort]
val
        where key :: PortBinding -> String
key PortBinding
p =  Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Integer -> PortType -> Text
portAndType2Text (PortBinding -> Integer
containerPort PortBinding
p) (PortBinding -> PortType
portType PortBinding
p)
              val :: PortBinding -> [HostPort]
val PortBinding
p =  PortBinding -> [HostPort]
hostPorts PortBinding
p

data HostPort = HostPort {
      HostPort -> Text
hostIp   :: Text
    , HostPort -> Integer
hostPost :: Port
    }
    deriving (HostPort -> HostPort -> Bool
(HostPort -> HostPort -> Bool)
-> (HostPort -> HostPort -> Bool) -> Eq HostPort
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HostPort -> HostPort -> Bool
$c/= :: HostPort -> HostPort -> Bool
== :: HostPort -> HostPort -> Bool
$c== :: HostPort -> HostPort -> Bool
Eq, Int -> HostPort -> ShowS
[HostPort] -> ShowS
HostPort -> String
(Int -> HostPort -> ShowS)
-> (HostPort -> String) -> ([HostPort] -> ShowS) -> Show HostPort
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HostPort] -> ShowS
$cshowList :: [HostPort] -> ShowS
show :: HostPort -> String
$cshow :: HostPort -> String
showsPrec :: Int -> HostPort -> ShowS
$cshowsPrec :: Int -> HostPort -> ShowS
Show)

instance ToJSON HostPort where
    toJSON :: HostPort -> Value
toJSON (HostPort Text
i Integer
p) = [Pair] -> Value
object [Key
"HostPort" Key -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Integer -> String
forall a. Show a => a -> String
show Integer
p, Key
"HostIp" Key -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Text
i]

instance FromJSON HostPort where
    parseJSON :: Value -> Parser HostPort
parseJSON (JSON.Object Object
o) = do
        Integer
p <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"HostPort" Parser Text -> (Text -> Parser Integer) -> Parser Integer
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> Parser Integer
forall (m :: * -> *). MonadFail m => Text -> m Integer
parseIntegerText
        Text
i <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"HostIp"
        HostPort -> Parser HostPort
forall (m :: * -> *) a. Monad m => a -> m a
return (HostPort -> Parser HostPort) -> HostPort -> Parser HostPort
forall a b. (a -> b) -> a -> b
$ Text -> Integer -> HostPort
HostPort Text
i Integer
p
    parseJSON Value
_ = String -> Parser HostPort
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"HostPort is not an object."

-- { "Name": "on-failure" , "MaximumRetryCount": 2}
type RetryCount = Integer
data RestartPolicy = RestartAlways | RestartUnlessStopped | RestartOnFailure RetryCount | RestartOff  deriving (RestartPolicy -> RestartPolicy -> Bool
(RestartPolicy -> RestartPolicy -> Bool)
-> (RestartPolicy -> RestartPolicy -> Bool) -> Eq RestartPolicy
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RestartPolicy -> RestartPolicy -> Bool
$c/= :: RestartPolicy -> RestartPolicy -> Bool
== :: RestartPolicy -> RestartPolicy -> Bool
$c== :: RestartPolicy -> RestartPolicy -> Bool
Eq, Int -> RestartPolicy -> ShowS
[RestartPolicy] -> ShowS
RestartPolicy -> String
(Int -> RestartPolicy -> ShowS)
-> (RestartPolicy -> String)
-> ([RestartPolicy] -> ShowS)
-> Show RestartPolicy
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RestartPolicy] -> ShowS
$cshowList :: [RestartPolicy] -> ShowS
show :: RestartPolicy -> String
$cshow :: RestartPolicy -> String
showsPrec :: Int -> RestartPolicy -> ShowS
$cshowsPrec :: Int -> RestartPolicy -> ShowS
Show)

instance FromJSON RestartPolicy where
    parseJSON :: Value -> Parser RestartPolicy
parseJSON (JSON.Object Object
o) = do
        (Text
name :: Text) <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Name"
        case Text
name of
            Text
"always" -> RestartPolicy -> Parser RestartPolicy
forall (m :: * -> *) a. Monad m => a -> m a
return RestartPolicy
RestartAlways
            Text
"unless-stopped" -> RestartPolicy -> Parser RestartPolicy
forall (m :: * -> *) a. Monad m => a -> m a
return RestartPolicy
RestartUnlessStopped
            Text
"on-failure" -> do
                Integer
retry <- Object
o Object -> Key -> Parser Integer
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"MaximumRetryCount"
                RestartPolicy -> Parser RestartPolicy
forall (m :: * -> *) a. Monad m => a -> m a
return (RestartPolicy -> Parser RestartPolicy)
-> RestartPolicy -> Parser RestartPolicy
forall a b. (a -> b) -> a -> b
$ Integer -> RestartPolicy
RestartOnFailure Integer
retry
            Text
"no" -> RestartPolicy -> Parser RestartPolicy
forall (m :: * -> *) a. Monad m => a -> m a
return RestartPolicy
RestartOff
            Text
_ -> String -> Parser RestartPolicy
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Could not parse RestartPolicy"
    parseJSON Value
_ = String -> Parser RestartPolicy
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"RestartPolicy is not an object"

instance ToJSON RestartPolicy where
    toJSON :: RestartPolicy -> Value
toJSON RestartPolicy
RestartAlways = [Pair] -> Value
object [Key
"Name" Key -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Text -> Value
JSON.String Text
"always"]
    toJSON RestartPolicy
RestartUnlessStopped = [Pair] -> Value
object [Key
"Name" Key -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Text -> Value
JSON.String Text
"unless-stopped"]
    toJSON (RestartOnFailure Integer
c) = [Pair] -> Value
object [Key
"Name" Key -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Text -> Value
JSON.String Text
"on-failure", Key
"MaximumRetryCount" Key -> Integer -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Integer
c]
    toJSON RestartPolicy
RestartOff = [Pair] -> Value
object [Key
"Name" Key -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Text -> Value
JSON.String Text
"no"]

data Isolation = Default | Process | Hyperv  deriving (Isolation -> Isolation -> Bool
(Isolation -> Isolation -> Bool)
-> (Isolation -> Isolation -> Bool) -> Eq Isolation
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Isolation -> Isolation -> Bool
$c/= :: Isolation -> Isolation -> Bool
== :: Isolation -> Isolation -> Bool
$c== :: Isolation -> Isolation -> Bool
Eq, Int -> Isolation -> ShowS
[Isolation] -> ShowS
Isolation -> String
(Int -> Isolation -> ShowS)
-> (Isolation -> String)
-> ([Isolation] -> ShowS)
-> Show Isolation
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Isolation] -> ShowS
$cshowList :: [Isolation] -> ShowS
show :: Isolation -> String
$cshow :: Isolation -> String
showsPrec :: Int -> Isolation -> ShowS
$cshowsPrec :: Int -> Isolation -> ShowS
Show)

newtype UTSMode = UTSMode Text deriving (UTSMode -> UTSMode -> Bool
(UTSMode -> UTSMode -> Bool)
-> (UTSMode -> UTSMode -> Bool) -> Eq UTSMode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UTSMode -> UTSMode -> Bool
$c/= :: UTSMode -> UTSMode -> Bool
== :: UTSMode -> UTSMode -> Bool
$c== :: UTSMode -> UTSMode -> Bool
Eq, Int -> UTSMode -> ShowS
[UTSMode] -> ShowS
UTSMode -> String
(Int -> UTSMode -> ShowS)
-> (UTSMode -> String) -> ([UTSMode] -> ShowS) -> Show UTSMode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UTSMode] -> ShowS
$cshowList :: [UTSMode] -> ShowS
show :: UTSMode -> String
$cshow :: UTSMode -> String
showsPrec :: Int -> UTSMode -> ShowS
$cshowsPrec :: Int -> UTSMode -> ShowS
Show)

-- TODO: Add Tmpfs : List of tmpfs (mounts) used for the container
-- TODO: Add UTSMode : UTS namespace to use for the container
-- TODO: Sysctls map[string]string `json:",omitempty"` // List of Namespaced sysctls used for the container
data HostConfig = HostConfig
                { HostConfig -> [Bind]
binds           :: [Bind]
                , HostConfig -> Maybe String
containerIDFile :: Maybe FilePath -- 1.24: Only in responses, not create
                , HostConfig -> LogDriverConfig
logConfig       :: LogDriverConfig
                , HostConfig -> NetworkMode
networkMode     :: NetworkMode
                , HostConfig -> [PortBinding]
portBindings    :: [PortBinding]
                , HostConfig -> RestartPolicy
restartPolicy   :: RestartPolicy
                , HostConfig -> Maybe Text
volumeDriver    :: Maybe Text
                , HostConfig -> [VolumeFrom]
volumesFrom     :: [VolumeFrom]
                , HostConfig -> [Text]
capAdd          :: [Text]
                , HostConfig -> [Text]
capDrop         :: [Text]
                , HostConfig -> [Text]
dns             :: [Text]
                , HostConfig -> [Text]
dnsOptions      :: [Text]
                , HostConfig -> [Text]
dnsSearch       :: [Text]
                , HostConfig -> [Text]
extraHosts      :: [Text]
                -- , groupAdd        :: [Integer] -- 1.24: Missing from inspecting container details... Going to omit for now.
                , HostConfig -> Maybe Text
ipcMode         :: Maybe Text -- 1.24: Only in inspect, not create
                , HostConfig -> [Link]
links           :: [Link]
                , HostConfig -> Maybe Integer
oomScoreAdj     :: Maybe Integer
                -- , pidMode         :: Text -- 1.24: Don't see pidMode, just pidsLimit
                , HostConfig -> Bool
privileged      :: Bool
                , HostConfig -> Bool
publishAllPorts :: Bool
                , HostConfig -> Bool
readonlyRootfs  :: Bool
                , HostConfig -> [Text]
securityOpt     :: [Text]
                -- , utsMode         :: UTSMode -- 1.24: Don't see this
                , HostConfig -> Maybe Integer
shmSize         :: Maybe Integer
                -- , consoleSize     :: Integer -- 1.24: Don't see this
                -- , isolation       :: Isolation -- 1.24: Don't see this
                , HostConfig -> ContainerResources
resources       :: ContainerResources
                } deriving (HostConfig -> HostConfig -> Bool
(HostConfig -> HostConfig -> Bool)
-> (HostConfig -> HostConfig -> Bool) -> Eq HostConfig
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HostConfig -> HostConfig -> Bool
$c/= :: HostConfig -> HostConfig -> Bool
== :: HostConfig -> HostConfig -> Bool
$c== :: HostConfig -> HostConfig -> Bool
Eq, Int -> HostConfig -> ShowS
[HostConfig] -> ShowS
HostConfig -> String
(Int -> HostConfig -> ShowS)
-> (HostConfig -> String)
-> ([HostConfig] -> ShowS)
-> Show HostConfig
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HostConfig] -> ShowS
$cshowList :: [HostConfig] -> ShowS
show :: HostConfig -> String
$cshow :: HostConfig -> String
showsPrec :: Int -> HostConfig -> ShowS
$cshowsPrec :: Int -> HostConfig -> ShowS
Show, (forall x. HostConfig -> Rep HostConfig x)
-> (forall x. Rep HostConfig x -> HostConfig) -> Generic HostConfig
forall x. Rep HostConfig x -> HostConfig
forall x. HostConfig -> Rep HostConfig x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep HostConfig x -> HostConfig
$cfrom :: forall x. HostConfig -> Rep HostConfig x
Generic)

instance FromJSON HostConfig where
    parseJSON :: Value -> Parser HostConfig
parseJSON v :: Value
v@(JSON.Object Object
o) = [Bind]
-> Maybe String
-> LogDriverConfig
-> NetworkMode
-> [PortBinding]
-> RestartPolicy
-> Maybe Text
-> [VolumeFrom]
-> [Text]
-> [Text]
-> [Text]
-> [Text]
-> [Text]
-> [Text]
-> Maybe Text
-> [Link]
-> Maybe Integer
-> Bool
-> Bool
-> Bool
-> [Text]
-> Maybe Integer
-> ContainerResources
-> HostConfig
HostConfig
        ([Bind]
 -> Maybe String
 -> LogDriverConfig
 -> NetworkMode
 -> [PortBinding]
 -> RestartPolicy
 -> Maybe Text
 -> [VolumeFrom]
 -> [Text]
 -> [Text]
 -> [Text]
 -> [Text]
 -> [Text]
 -> [Text]
 -> Maybe Text
 -> [Link]
 -> Maybe Integer
 -> Bool
 -> Bool
 -> Bool
 -> [Text]
 -> Maybe Integer
 -> ContainerResources
 -> HostConfig)
-> Parser [Bind]
-> Parser
     (Maybe String
      -> LogDriverConfig
      -> NetworkMode
      -> [PortBinding]
      -> RestartPolicy
      -> Maybe Text
      -> [VolumeFrom]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> Maybe Text
      -> [Link]
      -> Maybe Integer
      -> Bool
      -> Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser [Bind]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Binds"
        Parser
  (Maybe String
   -> LogDriverConfig
   -> NetworkMode
   -> [PortBinding]
   -> RestartPolicy
   -> Maybe Text
   -> [VolumeFrom]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> Maybe Text
   -> [Link]
   -> Maybe Integer
   -> Bool
   -> Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser (Maybe String)
-> Parser
     (LogDriverConfig
      -> NetworkMode
      -> [PortBinding]
      -> RestartPolicy
      -> Maybe Text
      -> [VolumeFrom]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> Maybe Text
      -> [Link]
      -> Maybe Integer
      -> Bool
      -> Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser (Maybe String)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"ContainerIDFile"
        Parser
  (LogDriverConfig
   -> NetworkMode
   -> [PortBinding]
   -> RestartPolicy
   -> Maybe Text
   -> [VolumeFrom]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> Maybe Text
   -> [Link]
   -> Maybe Integer
   -> Bool
   -> Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser LogDriverConfig
-> Parser
     (NetworkMode
      -> [PortBinding]
      -> RestartPolicy
      -> Maybe Text
      -> [VolumeFrom]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> Maybe Text
      -> [Link]
      -> Maybe Integer
      -> Bool
      -> Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser LogDriverConfig
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"LogConfig"
        Parser
  (NetworkMode
   -> [PortBinding]
   -> RestartPolicy
   -> Maybe Text
   -> [VolumeFrom]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> Maybe Text
   -> [Link]
   -> Maybe Integer
   -> Bool
   -> Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser NetworkMode
-> Parser
     ([PortBinding]
      -> RestartPolicy
      -> Maybe Text
      -> [VolumeFrom]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> Maybe Text
      -> [Link]
      -> Maybe Integer
      -> Bool
      -> Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser NetworkMode
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"NetworkMode"
        Parser
  ([PortBinding]
   -> RestartPolicy
   -> Maybe Text
   -> [VolumeFrom]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> Maybe Text
   -> [Link]
   -> Maybe Integer
   -> Bool
   -> Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser [PortBinding]
-> Parser
     (RestartPolicy
      -> Maybe Text
      -> [VolumeFrom]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> Maybe Text
      -> [Link]
      -> Maybe Integer
      -> Bool
      -> Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser [PortBinding]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"PortBindings"
        Parser
  (RestartPolicy
   -> Maybe Text
   -> [VolumeFrom]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> Maybe Text
   -> [Link]
   -> Maybe Integer
   -> Bool
   -> Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser RestartPolicy
-> Parser
     (Maybe Text
      -> [VolumeFrom]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> Maybe Text
      -> [Link]
      -> Maybe Integer
      -> Bool
      -> Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser RestartPolicy
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"RestartPolicy"
        Parser
  (Maybe Text
   -> [VolumeFrom]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> Maybe Text
   -> [Link]
   -> Maybe Integer
   -> Bool
   -> Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser (Maybe Text)
-> Parser
     ([VolumeFrom]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> Maybe Text
      -> [Link]
      -> Maybe Integer
      -> Bool
      -> Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"VolumeDriver"
        Parser
  ([VolumeFrom]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> Maybe Text
   -> [Link]
   -> Maybe Integer
   -> Bool
   -> Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser [VolumeFrom]
-> Parser
     ([Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> Maybe Text
      -> [Link]
      -> Maybe Integer
      -> Bool
      -> Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser [VolumeFrom]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"VolumesFrom"
        Parser
  ([Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> Maybe Text
   -> [Link]
   -> Maybe Integer
   -> Bool
   -> Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser [Text]
-> Parser
     ([Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> Maybe Text
      -> [Link]
      -> Maybe Integer
      -> Bool
      -> Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser [Text]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"CapAdd"
        Parser
  ([Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> Maybe Text
   -> [Link]
   -> Maybe Integer
   -> Bool
   -> Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser [Text]
-> Parser
     ([Text]
      -> [Text]
      -> [Text]
      -> [Text]
      -> Maybe Text
      -> [Link]
      -> Maybe Integer
      -> Bool
      -> Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser [Text]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"CapDrop"
        Parser
  ([Text]
   -> [Text]
   -> [Text]
   -> [Text]
   -> Maybe Text
   -> [Link]
   -> Maybe Integer
   -> Bool
   -> Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser [Text]
-> Parser
     ([Text]
      -> [Text]
      -> [Text]
      -> Maybe Text
      -> [Link]
      -> Maybe Integer
      -> Bool
      -> Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser [Text]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Dns"
        Parser
  ([Text]
   -> [Text]
   -> [Text]
   -> Maybe Text
   -> [Link]
   -> Maybe Integer
   -> Bool
   -> Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser [Text]
-> Parser
     ([Text]
      -> [Text]
      -> Maybe Text
      -> [Link]
      -> Maybe Integer
      -> Bool
      -> Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser [Text]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"DnsOptions"
        Parser
  ([Text]
   -> [Text]
   -> Maybe Text
   -> [Link]
   -> Maybe Integer
   -> Bool
   -> Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser [Text]
-> Parser
     ([Text]
      -> Maybe Text
      -> [Link]
      -> Maybe Integer
      -> Bool
      -> Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser [Text]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"DnsSearch"
        Parser
  ([Text]
   -> Maybe Text
   -> [Link]
   -> Maybe Integer
   -> Bool
   -> Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser [Text]
-> Parser
     (Maybe Text
      -> [Link]
      -> Maybe Integer
      -> Bool
      -> Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser [Text]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"ExtraHosts"
        Parser
  (Maybe Text
   -> [Link]
   -> Maybe Integer
   -> Bool
   -> Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser (Maybe Text)
-> Parser
     ([Link]
      -> Maybe Integer
      -> Bool
      -> Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"IpcMode"
        Parser
  ([Link]
   -> Maybe Integer
   -> Bool
   -> Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser [Link]
-> Parser
     (Maybe Integer
      -> Bool
      -> Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser (Maybe [Link])
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"Links" Parser (Maybe [Link]) -> [Link] -> Parser [Link]
forall a. Parser (Maybe a) -> a -> Parser a
.!= []
        Parser
  (Maybe Integer
   -> Bool
   -> Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser (Maybe Integer)
-> Parser
     (Bool
      -> Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser (Maybe Integer)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"OomScoreAdj"
        Parser
  (Bool
   -> Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser Bool
-> Parser
     (Bool
      -> Bool
      -> [Text]
      -> Maybe Integer
      -> ContainerResources
      -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Privileged"
        Parser
  (Bool
   -> Bool
   -> [Text]
   -> Maybe Integer
   -> ContainerResources
   -> HostConfig)
-> Parser Bool
-> Parser
     (Bool
      -> [Text] -> Maybe Integer -> ContainerResources -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"PublishAllPorts"
        Parser
  (Bool
   -> [Text] -> Maybe Integer -> ContainerResources -> HostConfig)
-> Parser Bool
-> Parser
     ([Text] -> Maybe Integer -> ContainerResources -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"ReadonlyRootfs"
        Parser
  ([Text] -> Maybe Integer -> ContainerResources -> HostConfig)
-> Parser [Text]
-> Parser (Maybe Integer -> ContainerResources -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser [Text]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"SecurityOpt"
        Parser (Maybe Integer -> ContainerResources -> HostConfig)
-> Parser (Maybe Integer)
-> Parser (ContainerResources -> HostConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser (Maybe Integer)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"ShmSize"
        Parser (ContainerResources -> HostConfig)
-> Parser ContainerResources -> Parser HostConfig
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Value -> Parser ContainerResources
forall a. FromJSON a => Value -> Parser a
parseJSON Value
v
    parseJSON Value
_ = String -> Parser HostConfig
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"HostConfig is not an object."

instance ToJSON HostConfig where
    toJSON :: HostConfig -> Value
toJSON HostConfig{Bool
[Text]
[PortBinding]
[Link]
[VolumeFrom]
[Bind]
Maybe Integer
Maybe String
Maybe Text
ContainerResources
RestartPolicy
NetworkMode
LogDriverConfig
resources :: ContainerResources
shmSize :: Maybe Integer
securityOpt :: [Text]
readonlyRootfs :: Bool
publishAllPorts :: Bool
privileged :: Bool
oomScoreAdj :: Maybe Integer
links :: [Link]
ipcMode :: Maybe Text
extraHosts :: [Text]
dnsSearch :: [Text]
dnsOptions :: [Text]
dns :: [Text]
capDrop :: [Text]
capAdd :: [Text]
volumesFrom :: [VolumeFrom]
volumeDriver :: Maybe Text
restartPolicy :: RestartPolicy
portBindings :: [PortBinding]
networkMode :: NetworkMode
logConfig :: LogDriverConfig
containerIDFile :: Maybe String
binds :: [Bind]
resources :: HostConfig -> ContainerResources
shmSize :: HostConfig -> Maybe Integer
securityOpt :: HostConfig -> [Text]
readonlyRootfs :: HostConfig -> Bool
publishAllPorts :: HostConfig -> Bool
privileged :: HostConfig -> Bool
oomScoreAdj :: HostConfig -> Maybe Integer
links :: HostConfig -> [Link]
ipcMode :: HostConfig -> Maybe Text
extraHosts :: HostConfig -> [Text]
dnsSearch :: HostConfig -> [Text]
dnsOptions :: HostConfig -> [Text]
dns :: HostConfig -> [Text]
capDrop :: HostConfig -> [Text]
capAdd :: HostConfig -> [Text]
volumesFrom :: HostConfig -> [VolumeFrom]
volumeDriver :: HostConfig -> Maybe Text
restartPolicy :: HostConfig -> RestartPolicy
portBindings :: HostConfig -> [PortBinding]
networkMode :: HostConfig -> NetworkMode
logConfig :: HostConfig -> LogDriverConfig
containerIDFile :: HostConfig -> Maybe String
binds :: HostConfig -> [Bind]
..} =
        let arr :: [Pair]
arr = [
                Key
"Binds" Key -> [Bind] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [Bind]
binds
              , Key
"ContainerIDFile" Key -> Maybe String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe String
containerIDFile
              , Key
"LogConfig" Key -> LogDriverConfig -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= LogDriverConfig
logConfig
              , Key
"NetworkMode" Key -> NetworkMode -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= NetworkMode
networkMode
              , Key
"PortBindings" Key -> [PortBinding] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [PortBinding]
portBindings
              , Key
"RestartPolicy" Key -> RestartPolicy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= RestartPolicy
restartPolicy
              , Key
"VolumeDriver" Key -> Maybe Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe Text
volumeDriver
              , Key
"VolumesFrom" Key -> [VolumeFrom] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [VolumeFrom]
volumesFrom
              , Key
"CapAdd" Key -> [Text] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [Text]
capAdd
              , Key
"CapDrop" Key -> [Text] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [Text]
capDrop
              , Key
"Dns" Key -> [Text] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [Text]
dns
              , Key
"DnsOptions" Key -> [Text] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [Text]
dnsOptions
              , Key
"DnsSearch" Key -> [Text] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [Text]
dnsSearch
              , Key
"ExtraHosts" Key -> [Text] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [Text]
extraHosts
              , Key
"IpcMode" Key -> Maybe Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe Text
ipcMode
              , Key
"Links" Key -> [Link] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [Link]
links
              , Key
"OomScoreAdj" Key -> Maybe Integer -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe Integer
oomScoreAdj
              , Key
"Privileged" Key -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Bool
privileged
              , Key
"PublishAllPorts" Key -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Bool
publishAllPorts
              , Key
"ReadonlyRootfs" Key -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Bool
readonlyRootfs
              , Key
"SecurityOpt" Key -> [Text] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [Text]
securityOpt
              , Key
"ShmSize" Key -> Maybe Integer -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe Integer
shmSize
              ]
        in
        [Pair] -> Value
object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$ [Pair]
arr [Pair] -> [Pair] -> [Pair]
forall a. Semigroup a => a -> a -> a
<> ( ContainerResources -> [Pair]
forall a. KeyValue a => ContainerResources -> [a]
resourcesArr ContainerResources
resources)

        where
            -- JP: Not sure if this is better than a separate ToJSON instance with a bunch of `HM.insert`s.
            resourcesArr :: ContainerResources -> [a]
resourcesArr ContainerResources{[Ulimit]
[Device]
Maybe Bool
Maybe Integer
Maybe [DeviceRate]
Maybe [DeviceWeight]
Maybe Text
Maybe MemoryConstraint
ulimits :: [Ulimit]
oomKillDisable :: Maybe Bool
memorySwap :: Maybe MemoryConstraint
memoryReservation :: Maybe MemoryConstraint
memory :: Maybe MemoryConstraint
kernelMemory :: Maybe MemoryConstraint
devices :: [Device]
cpusetMems :: Maybe Text
cpusetCpus :: Maybe Text
cpuPeriod :: Maybe Integer
blkioDeviceWriteIOps :: Maybe [DeviceRate]
blkioDeviceReadIOps :: Maybe [DeviceRate]
blkioDeviceWriteBps :: Maybe [DeviceRate]
blkioDeviceReadBps :: Maybe [DeviceRate]
blkioWeightDevice :: Maybe [DeviceWeight]
blkioWeight :: Maybe Integer
cpuShares :: Maybe Integer
ulimits :: ContainerResources -> [Ulimit]
oomKillDisable :: ContainerResources -> Maybe Bool
memorySwap :: ContainerResources -> Maybe MemoryConstraint
memoryReservation :: ContainerResources -> Maybe MemoryConstraint
memory :: ContainerResources -> Maybe MemoryConstraint
kernelMemory :: ContainerResources -> Maybe MemoryConstraint
devices :: ContainerResources -> [Device]
cpusetMems :: ContainerResources -> Maybe Text
cpusetCpus :: ContainerResources -> Maybe Text
cpuPeriod :: ContainerResources -> Maybe Integer
blkioDeviceWriteIOps :: ContainerResources -> Maybe [DeviceRate]
blkioDeviceReadIOps :: ContainerResources -> Maybe [DeviceRate]
blkioDeviceWriteBps :: ContainerResources -> Maybe [DeviceRate]
blkioDeviceReadBps :: ContainerResources -> Maybe [DeviceRate]
blkioWeightDevice :: ContainerResources -> Maybe [DeviceWeight]
blkioWeight :: ContainerResources -> Maybe Integer
cpuShares :: ContainerResources -> Maybe Integer
..} = [
                Key
"CpuShares" Key -> Maybe Integer -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe Integer
cpuShares
              , Key
"BlkioWeight" Key -> Maybe Integer -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe Integer
blkioWeight
              , Key
"BlkioWeightDevice" Key -> Maybe [DeviceWeight] -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe [DeviceWeight]
blkioWeightDevice
              , Key
"BlkioDeviceReadBps" Key -> Maybe [DeviceRate] -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe [DeviceRate]
blkioDeviceReadBps
              , Key
"BlkioDeviceWriteBps" Key -> Maybe [DeviceRate] -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe [DeviceRate]
blkioDeviceWriteBps
              , Key
"BlkioDeviceReadIOps" Key -> Maybe [DeviceRate] -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe [DeviceRate]
blkioDeviceReadIOps
              , Key
"BlkioDeviceWriteIOps" Key -> Maybe [DeviceRate] -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe [DeviceRate]
blkioDeviceWriteIOps
              , Key
"CpuPeriod" Key -> Maybe Integer -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe Integer
cpuPeriod
              , Key
"CpusetCpus" Key -> Maybe Text -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe Text
cpusetCpus
              , Key
"CpusetMems" Key -> Maybe Text -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe Text
cpusetMems
              , Key
"Devices" Key -> [Device] -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [Device]
devices
              , Key
"KernelMemory" Key -> Maybe MemoryConstraint -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe MemoryConstraint
kernelMemory
              , Key
"Memory" Key -> Maybe MemoryConstraint -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe MemoryConstraint
memory
              , Key
"MemoryReservation" Key -> Maybe MemoryConstraint -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe MemoryConstraint
memoryReservation
              , Key
"MemorySwap" Key -> Maybe MemoryConstraint -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe MemoryConstraint
memorySwap
              , Key
"OomKillDisable" Key -> Maybe Bool -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe Bool
oomKillDisable
              , Key
"Ulimits" Key -> [Ulimit] -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [Ulimit]
ulimits
              ]




-- { "Name": <name>, "Soft": <soft limit>, "Hard": <hard limit>  }
-- { "Name": "nofile", "Soft": 1024, "Hard": 2048  }
data Ulimit = Ulimit {
              Ulimit -> Text
ulimitName :: Text
            , Ulimit -> Integer
ulimitSoft :: Integer
            , Ulimit -> Integer
ulimitHard :: Integer
            } deriving (Ulimit -> Ulimit -> Bool
(Ulimit -> Ulimit -> Bool)
-> (Ulimit -> Ulimit -> Bool) -> Eq Ulimit
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Ulimit -> Ulimit -> Bool
$c/= :: Ulimit -> Ulimit -> Bool
== :: Ulimit -> Ulimit -> Bool
$c== :: Ulimit -> Ulimit -> Bool
Eq, Int -> Ulimit -> ShowS
[Ulimit] -> ShowS
Ulimit -> String
(Int -> Ulimit -> ShowS)
-> (Ulimit -> String) -> ([Ulimit] -> ShowS) -> Show Ulimit
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Ulimit] -> ShowS
$cshowList :: [Ulimit] -> ShowS
show :: Ulimit -> String
$cshow :: Ulimit -> String
showsPrec :: Int -> Ulimit -> ShowS
$cshowsPrec :: Int -> Ulimit -> ShowS
Show, (forall x. Ulimit -> Rep Ulimit x)
-> (forall x. Rep Ulimit x -> Ulimit) -> Generic Ulimit
forall x. Rep Ulimit x -> Ulimit
forall x. Ulimit -> Rep Ulimit x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Ulimit x -> Ulimit
$cfrom :: forall x. Ulimit -> Rep Ulimit x
Generic)

instance FromJSON Ulimit where
    parseJSON :: Value -> Parser Ulimit
parseJSON = Options -> Value -> Parser Ulimit
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
defaultOptions {
        fieldLabelModifier :: ShowS
fieldLabelModifier = Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
5}

instance ToJSON Ulimit where
    toJSON :: Ulimit -> Value
toJSON = Options -> Ulimit -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
defaultOptions {
        fieldLabelModifier :: ShowS
fieldLabelModifier = Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
5}

data DeviceWeight = DeviceWeight {
      DeviceWeight -> String
deviceWeightPath   :: FilePath
    , DeviceWeight -> Text
deviceWeightWeight :: Text
    }
    deriving (Int -> DeviceWeight -> ShowS
[DeviceWeight] -> ShowS
DeviceWeight -> String
(Int -> DeviceWeight -> ShowS)
-> (DeviceWeight -> String)
-> ([DeviceWeight] -> ShowS)
-> Show DeviceWeight
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DeviceWeight] -> ShowS
$cshowList :: [DeviceWeight] -> ShowS
show :: DeviceWeight -> String
$cshow :: DeviceWeight -> String
showsPrec :: Int -> DeviceWeight -> ShowS
$cshowsPrec :: Int -> DeviceWeight -> ShowS
Show, DeviceWeight -> DeviceWeight -> Bool
(DeviceWeight -> DeviceWeight -> Bool)
-> (DeviceWeight -> DeviceWeight -> Bool) -> Eq DeviceWeight
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DeviceWeight -> DeviceWeight -> Bool
$c/= :: DeviceWeight -> DeviceWeight -> Bool
== :: DeviceWeight -> DeviceWeight -> Bool
$c== :: DeviceWeight -> DeviceWeight -> Bool
Eq)

instance FromJSON DeviceWeight where
    parseJSON :: Value -> Parser DeviceWeight
parseJSON (JSON.Object Object
o) = String -> Text -> DeviceWeight
DeviceWeight
        (String -> Text -> DeviceWeight)
-> Parser String -> Parser (Text -> DeviceWeight)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser String
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Path"
        Parser (Text -> DeviceWeight) -> Parser Text -> Parser DeviceWeight
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Weight"
    parseJSON Value
_ = String -> Parser DeviceWeight
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"DeviceWeight is not an object."

instance ToJSON DeviceWeight where
    toJSON :: DeviceWeight -> Value
toJSON (DeviceWeight String
p Text
w) = [Pair] -> Value
object [
          Key
"Path" Key -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= String
p
        , Key
"Weight" Key -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Text
w
        ]

data DeviceRate = DeviceRate {
      DeviceRate -> String
deviceRatePath :: FilePath
    , DeviceRate -> Text
deviceRateRate :: Text
    }
    deriving (Int -> DeviceRate -> ShowS
[DeviceRate] -> ShowS
DeviceRate -> String
(Int -> DeviceRate -> ShowS)
-> (DeviceRate -> String)
-> ([DeviceRate] -> ShowS)
-> Show DeviceRate
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DeviceRate] -> ShowS
$cshowList :: [DeviceRate] -> ShowS
show :: DeviceRate -> String
$cshow :: DeviceRate -> String
showsPrec :: Int -> DeviceRate -> ShowS
$cshowsPrec :: Int -> DeviceRate -> ShowS
Show, DeviceRate -> DeviceRate -> Bool
(DeviceRate -> DeviceRate -> Bool)
-> (DeviceRate -> DeviceRate -> Bool) -> Eq DeviceRate
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DeviceRate -> DeviceRate -> Bool
$c/= :: DeviceRate -> DeviceRate -> Bool
== :: DeviceRate -> DeviceRate -> Bool
$c== :: DeviceRate -> DeviceRate -> Bool
Eq)

instance FromJSON DeviceRate where
    parseJSON :: Value -> Parser DeviceRate
parseJSON (JSON.Object Object
o) = String -> Text -> DeviceRate
DeviceRate
        (String -> Text -> DeviceRate)
-> Parser String -> Parser (Text -> DeviceRate)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser String
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Path"
        Parser (Text -> DeviceRate) -> Parser Text -> Parser DeviceRate
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Rate"
    parseJSON Value
_ = String -> Parser DeviceRate
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"DeviceRate is not an object."

instance ToJSON DeviceRate where
    toJSON :: DeviceRate -> Value
toJSON (DeviceRate String
p Text
r) = [Pair] -> Value
object [
          Key
"Path" Key -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= String
p
        , Key
"Rate" Key -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Text
r
        ]

data MemoryConstraintSize = B | MB | GB deriving (MemoryConstraintSize -> MemoryConstraintSize -> Bool
(MemoryConstraintSize -> MemoryConstraintSize -> Bool)
-> (MemoryConstraintSize -> MemoryConstraintSize -> Bool)
-> Eq MemoryConstraintSize
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MemoryConstraintSize -> MemoryConstraintSize -> Bool
$c/= :: MemoryConstraintSize -> MemoryConstraintSize -> Bool
== :: MemoryConstraintSize -> MemoryConstraintSize -> Bool
$c== :: MemoryConstraintSize -> MemoryConstraintSize -> Bool
Eq, Int -> MemoryConstraintSize -> ShowS
[MemoryConstraintSize] -> ShowS
MemoryConstraintSize -> String
(Int -> MemoryConstraintSize -> ShowS)
-> (MemoryConstraintSize -> String)
-> ([MemoryConstraintSize] -> ShowS)
-> Show MemoryConstraintSize
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MemoryConstraintSize] -> ShowS
$cshowList :: [MemoryConstraintSize] -> ShowS
show :: MemoryConstraintSize -> String
$cshow :: MemoryConstraintSize -> String
showsPrec :: Int -> MemoryConstraintSize -> ShowS
$cshowsPrec :: Int -> MemoryConstraintSize -> ShowS
Show)

data MemoryConstraint = MemoryConstraint Integer MemoryConstraintSize deriving (MemoryConstraint -> MemoryConstraint -> Bool
(MemoryConstraint -> MemoryConstraint -> Bool)
-> (MemoryConstraint -> MemoryConstraint -> Bool)
-> Eq MemoryConstraint
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MemoryConstraint -> MemoryConstraint -> Bool
$c/= :: MemoryConstraint -> MemoryConstraint -> Bool
== :: MemoryConstraint -> MemoryConstraint -> Bool
$c== :: MemoryConstraint -> MemoryConstraint -> Bool
Eq, Int -> MemoryConstraint -> ShowS
[MemoryConstraint] -> ShowS
MemoryConstraint -> String
(Int -> MemoryConstraint -> ShowS)
-> (MemoryConstraint -> String)
-> ([MemoryConstraint] -> ShowS)
-> Show MemoryConstraint
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MemoryConstraint] -> ShowS
$cshowList :: [MemoryConstraint] -> ShowS
show :: MemoryConstraint -> String
$cshow :: MemoryConstraint -> String
showsPrec :: Int -> MemoryConstraint -> ShowS
$cshowsPrec :: Int -> MemoryConstraint -> ShowS
Show)

instance ToJSON MemoryConstraint where
    toJSON :: MemoryConstraint -> Value
toJSON (MemoryConstraint Integer
x MemoryConstraintSize
B)  = Integer -> Value
forall a. ToJSON a => a -> Value
toJSON Integer
x
    toJSON (MemoryConstraint Integer
x MemoryConstraintSize
MB) = Integer -> Value
forall a. ToJSON a => a -> Value
toJSON (Integer -> Value) -> Integer -> Value
forall a b. (a -> b) -> a -> b
$ Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1024 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1024
    toJSON (MemoryConstraint Integer
x MemoryConstraintSize
GB) = Integer -> Value
forall a. ToJSON a => a -> Value
toJSON (Integer -> Value) -> Integer -> Value
forall a b. (a -> b) -> a -> b
$ Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1024 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1024 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1024

instance FromJSON MemoryConstraint where
    parseJSON :: Value -> Parser MemoryConstraint
parseJSON (JSON.Number Scientific
x) = case (Scientific -> Either Double Integer
forall r i. (RealFloat r, Integral i) => Scientific -> Either r i
floatingOrInteger Scientific
x) of
                                    Left (Double
_ :: Double) -> String -> Parser MemoryConstraint
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Failed to parse MemoryConstraint"
                                    Right Integer
i -> MemoryConstraint -> Parser MemoryConstraint
forall (m :: * -> *) a. Monad m => a -> m a
return (MemoryConstraint -> Parser MemoryConstraint)
-> MemoryConstraint -> Parser MemoryConstraint
forall a b. (a -> b) -> a -> b
$ Integer -> MemoryConstraintSize -> MemoryConstraint
MemoryConstraint Integer
i MemoryConstraintSize
B
                                    -- The docker daemon will always return the number as bytes (integer), regardless of how we set them (using MB or GB)
    parseJSON Value
_ = String -> Parser MemoryConstraint
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Failed to parse MemoryConstraint"

data ContainerResources = ContainerResources {
                          ContainerResources -> Maybe Integer
cpuShares            :: Maybe Integer
                        -- , cgroupParent      :: Text -- 1.24: Missing from inspecting container details... Going to omit for now.
                        , ContainerResources -> Maybe Integer
blkioWeight          :: Maybe Integer
                        , ContainerResources -> Maybe [DeviceWeight]
blkioWeightDevice    :: Maybe [DeviceWeight]
                        , ContainerResources -> Maybe [DeviceRate]
blkioDeviceReadBps   :: Maybe [DeviceRate] -- TODO: Not Text
                        , ContainerResources -> Maybe [DeviceRate]
blkioDeviceWriteBps  :: Maybe [DeviceRate] -- TODO: Not Text
                        , ContainerResources -> Maybe [DeviceRate]
blkioDeviceReadIOps  :: Maybe [DeviceRate] -- TODO: Not Text
                        , ContainerResources -> Maybe [DeviceRate]
blkioDeviceWriteIOps :: Maybe [DeviceRate] -- TODO: Not Text
                        , ContainerResources -> Maybe Integer
cpuPeriod            :: Maybe Integer
                        -- , cpuQuota          :: Integer -- 1.24: Missing from inspecting container details... Going to omit for now.
                        , ContainerResources -> Maybe Text
cpusetCpus           :: Maybe Text
                        , ContainerResources -> Maybe Text
cpusetMems           :: Maybe Text
                        , ContainerResources -> [Device]
devices              :: [Device]
                        -- , diskQuota         :: Integer -- Don't see this ins 1.24.
                        , ContainerResources -> Maybe MemoryConstraint
kernelMemory         :: Maybe MemoryConstraint
                        , ContainerResources -> Maybe MemoryConstraint
memory               :: Maybe MemoryConstraint
                        , ContainerResources -> Maybe MemoryConstraint
memoryReservation    :: Maybe MemoryConstraint
                        , ContainerResources -> Maybe MemoryConstraint
memorySwap           :: Maybe MemoryConstraint
                        -- , memorySwappiness  :: Integer -- 1.24: Missing from inspecting container details... Going to omit for now.
                        , ContainerResources -> Maybe Bool
oomKillDisable       :: Maybe Bool
                        -- , pidsLimit         :: Integer -- 1.24: Missing from inspecting container details... Going to omit for now.
                        , ContainerResources -> [Ulimit]
ulimits              :: [Ulimit]
                        -- TODO: Missing from 1.24
                        -- StorageOpt :: [(Text, Text)]
                        -- VolumeDriver :: ??
                        -- EndpointsConfig :: ??
                        -- TODO: Only in inspect container in 1.24
                        -- CpuPercent :: Int +
                        -- MaximumIOps :: Int +
                        -- MaximumIOBps :: Int +
                        -- LxcConf :: [??] +
                        } deriving (ContainerResources -> ContainerResources -> Bool
(ContainerResources -> ContainerResources -> Bool)
-> (ContainerResources -> ContainerResources -> Bool)
-> Eq ContainerResources
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ContainerResources -> ContainerResources -> Bool
$c/= :: ContainerResources -> ContainerResources -> Bool
== :: ContainerResources -> ContainerResources -> Bool
$c== :: ContainerResources -> ContainerResources -> Bool
Eq, Int -> ContainerResources -> ShowS
[ContainerResources] -> ShowS
ContainerResources -> String
(Int -> ContainerResources -> ShowS)
-> (ContainerResources -> String)
-> ([ContainerResources] -> ShowS)
-> Show ContainerResources
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ContainerResources] -> ShowS
$cshowList :: [ContainerResources] -> ShowS
show :: ContainerResources -> String
$cshow :: ContainerResources -> String
showsPrec :: Int -> ContainerResources -> ShowS
$cshowsPrec :: Int -> ContainerResources -> ShowS
Show, (forall x. ContainerResources -> Rep ContainerResources x)
-> (forall x. Rep ContainerResources x -> ContainerResources)
-> Generic ContainerResources
forall x. Rep ContainerResources x -> ContainerResources
forall x. ContainerResources -> Rep ContainerResources x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ContainerResources x -> ContainerResources
$cfrom :: forall x. ContainerResources -> Rep ContainerResources x
Generic)

-- instance ToJSON ContainerResources where
--     toJSON = genericToJSON defaultOptions {
--          fieldLabelModifier = (\(x:xs) -> toUpper x : xs)}

instance FromJSON ContainerResources where
    parseJSON :: Value -> Parser ContainerResources
parseJSON = Options -> Value -> Parser ContainerResources
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
defaultOptions {
        fieldLabelModifier :: ShowS
fieldLabelModifier = (\(Char
x:String
xs) -> Char -> Char
toUpper Char
x Char -> ShowS
forall a. a -> [a] -> [a]
: String
xs)}

type Port = Integer

type Name = Text
type Value = Text

data EnvVar = EnvVar Name Value
    deriving (EnvVar -> EnvVar -> Bool
(EnvVar -> EnvVar -> Bool)
-> (EnvVar -> EnvVar -> Bool) -> Eq EnvVar
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EnvVar -> EnvVar -> Bool
$c/= :: EnvVar -> EnvVar -> Bool
== :: EnvVar -> EnvVar -> Bool
$c== :: EnvVar -> EnvVar -> Bool
Eq, Int -> EnvVar -> ShowS
[EnvVar] -> ShowS
EnvVar -> String
(Int -> EnvVar -> ShowS)
-> (EnvVar -> String) -> ([EnvVar] -> ShowS) -> Show EnvVar
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [EnvVar] -> ShowS
$cshowList :: [EnvVar] -> ShowS
show :: EnvVar -> String
$cshow :: EnvVar -> String
showsPrec :: Int -> EnvVar -> ShowS
$cshowsPrec :: Int -> EnvVar -> ShowS
Show)

instance FromJSON EnvVar where
    parseJSON :: Value -> Parser EnvVar
parseJSON (JSON.String Text
env) =
        let (Text
n, Text
v') = (Char -> Bool) -> Text -> (Text, Text)
T.break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'=') Text
env in
        let v :: Text
v = Int -> Text -> Text
T.drop Int
1 Text
v' in
        EnvVar -> Parser EnvVar
forall (m :: * -> *) a. Monad m => a -> m a
return (EnvVar -> Parser EnvVar) -> EnvVar -> Parser EnvVar
forall a b. (a -> b) -> a -> b
$ Text -> Text -> EnvVar
EnvVar Text
n Text
v
    parseJSON Value
_ = String -> Parser EnvVar
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"EnvVar is not a string"

instance ToJSON EnvVar where
    toJSON :: EnvVar -> Value
toJSON (EnvVar Text
n Text
v) = Text -> Value
JSON.String (Text -> Value) -> Text -> Value
forall a b. (a -> b) -> a -> b
$ Text
n Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack String
"=" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
v

-- | ExposedPort represents a port (and it's type)
-- that a container should expose to other containers or the host system.
-- `NOTE`: This does not automatically expose the port onto the host
-- system but rather it just tags it. It's best to be used with
-- the PublishAllPorts flag. It is also useful for
-- the daemon to know which Environment variables to
-- inject into a container linking to our container.
-- Example linking a Postgres container named db would inject the following
-- environment variables automatically if we set the corresponding
--
-- ExposedPort:
--
-- @
-- DB_PORT_5432_TCP_PORT="5432"
-- DB_PORT_5432_TCP_PROTO="tcp"
-- DB_PORT_5432_TCP="tcp://172.17.0.1:5432"
-- @
data ExposedPort = ExposedPort Port PortType deriving (ExposedPort -> ExposedPort -> Bool
(ExposedPort -> ExposedPort -> Bool)
-> (ExposedPort -> ExposedPort -> Bool) -> Eq ExposedPort
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExposedPort -> ExposedPort -> Bool
$c/= :: ExposedPort -> ExposedPort -> Bool
== :: ExposedPort -> ExposedPort -> Bool
$c== :: ExposedPort -> ExposedPort -> Bool
Eq, Int -> ExposedPort -> ShowS
[ExposedPort] -> ShowS
ExposedPort -> String
(Int -> ExposedPort -> ShowS)
-> (ExposedPort -> String)
-> ([ExposedPort] -> ShowS)
-> Show ExposedPort
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ExposedPort] -> ShowS
$cshowList :: [ExposedPort] -> ShowS
show :: ExposedPort -> String
$cshow :: ExposedPort -> String
showsPrec :: Int -> ExposedPort -> ShowS
$cshowsPrec :: Int -> ExposedPort -> ShowS
Show)

instance {-# OVERLAPPING #-} FromJSON [ExposedPort] where
    parseJSON :: Value -> Parser [ExposedPort]
parseJSON (JSON.Object Object
o) = (Parser [ExposedPort] -> Text -> Value -> Parser [ExposedPort])
-> Parser [ExposedPort]
-> HashMap Text Value
-> Parser [ExposedPort]
forall a k v. (a -> k -> v -> a) -> a -> HashMap k v -> a
HM.foldlWithKey' Parser [ExposedPort] -> Text -> Value -> Parser [ExposedPort]
forall p. Parser [ExposedPort] -> Text -> p -> Parser [ExposedPort]
f ([ExposedPort] -> Parser [ExposedPort]
forall (m :: * -> *) a. Monad m => a -> m a
return []) (Object -> HashMap Text Value
forall v. KeyMap v -> HashMap Text v
toHashMap Object
o)
        where
            f :: Parser [ExposedPort] -> Text -> p -> Parser [ExposedPort]
f Parser [ExposedPort]
accM Text
k p
_ = case (Char -> Bool) -> Text -> [Text]
T.split (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'/') Text
k of
                [Text
port', Text
portType'] -> do
                    Integer
port <- Text -> Parser Integer
forall (m :: * -> *). MonadFail m => Text -> m Integer
parseIntegerText Text
port'
                    PortType
portType <- Value -> Parser PortType
forall a. FromJSON a => Value -> Parser a
parseJSON (Value -> Parser PortType) -> Value -> Parser PortType
forall a b. (a -> b) -> a -> b
$ Text -> Value
JSON.String Text
portType'
                    [ExposedPort]
acc <- Parser [ExposedPort]
accM
                    [ExposedPort] -> Parser [ExposedPort]
forall (m :: * -> *) a. Monad m => a -> m a
return ([ExposedPort] -> Parser [ExposedPort])
-> [ExposedPort] -> Parser [ExposedPort]
forall a b. (a -> b) -> a -> b
$ (Integer -> PortType -> ExposedPort
ExposedPort Integer
port PortType
portType)ExposedPort -> [ExposedPort] -> [ExposedPort]
forall a. a -> [a] -> [a]
:[ExposedPort]
acc
                [Text]
_ -> String -> Parser [ExposedPort]
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Could not parse ExposedPorts"
    parseJSON (Value
JSON.Null) = [ExposedPort] -> Parser [ExposedPort]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    parseJSON Value
_ = String -> Parser [ExposedPort]
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"ExposedPorts is not an object"

instance {-# OVERLAPPING #-} ToJSON [ExposedPort] where
    toJSON :: [ExposedPort] -> Value
toJSON [] = Value
emptyObject
    toJSON (ExposedPort
p:[ExposedPort]
ps) = [ExposedPort] -> (ExposedPort -> String) -> Value
forall (t :: * -> *) a. Foldable t => t a -> (a -> String) -> Value
toJsonKey (ExposedPort
pExposedPort -> [ExposedPort] -> [ExposedPort]
forall a. a -> [a] -> [a]
:[ExposedPort]
ps) ExposedPort -> String
key
        where key :: ExposedPort -> String
key (ExposedPort Integer
p PortType
t) = Integer -> String
forall a. Show a => a -> String
show Integer
p String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
slash String -> ShowS
forall a. Semigroup a => a -> a -> a
<> PortType -> String
forall a. Show a => a -> String
show PortType
t
              slash :: String
slash = Text -> String
T.unpack Text
"/"

data Entrypoint = Entrypoint [T.Text] deriving (Entrypoint -> Entrypoint -> Bool
(Entrypoint -> Entrypoint -> Bool)
-> (Entrypoint -> Entrypoint -> Bool) -> Eq Entrypoint
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Entrypoint -> Entrypoint -> Bool
$c/= :: Entrypoint -> Entrypoint -> Bool
== :: Entrypoint -> Entrypoint -> Bool
$c== :: Entrypoint -> Entrypoint -> Bool
Eq, Int -> Entrypoint -> ShowS
[Entrypoint] -> ShowS
Entrypoint -> String
(Int -> Entrypoint -> ShowS)
-> (Entrypoint -> String)
-> ([Entrypoint] -> ShowS)
-> Show Entrypoint
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Entrypoint] -> ShowS
$cshowList :: [Entrypoint] -> ShowS
show :: Entrypoint -> String
$cshow :: Entrypoint -> String
showsPrec :: Int -> Entrypoint -> ShowS
$cshowsPrec :: Int -> Entrypoint -> ShowS
Show, (forall x. Entrypoint -> Rep Entrypoint x)
-> (forall x. Rep Entrypoint x -> Entrypoint) -> Generic Entrypoint
forall x. Rep Entrypoint x -> Entrypoint
forall x. Entrypoint -> Rep Entrypoint x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Entrypoint x -> Entrypoint
$cfrom :: forall x. Entrypoint -> Rep Entrypoint x
Generic)

instance ToJSON Entrypoint where
    toJSON :: Entrypoint -> Value
toJSON (Entrypoint (Text
e:[Text]
es)) = [Text] -> Value
forall a. ToJSON a => a -> Value
toJSON (Text
eText -> [Text] -> [Text]
forall a. a -> [a] -> [a]
:[Text]
es)
    toJSON (Entrypoint [])     = Value
JSON.Null

instance FromJSON Entrypoint where
    parseJSON :: Value -> Parser Entrypoint
parseJSON (JSON.String Text
e) = Entrypoint -> Parser Entrypoint
forall (m :: * -> *) a. Monad m => a -> m a
return (Entrypoint -> Parser Entrypoint)
-> Entrypoint -> Parser Entrypoint
forall a b. (a -> b) -> a -> b
$ [Text] -> Entrypoint
Entrypoint [Text
e]
    parseJSON (JSON.Array Array
ar) = do
      [Text]
arr <- (Value -> Parser Text) -> [Value] -> Parser [Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Value -> Parser Text
forall a. FromJSON a => Value -> Parser a
parseJSON (Array -> [Value]
forall a. Vector a -> [a]
V.toList Array
ar)
      Entrypoint -> Parser Entrypoint
forall (m :: * -> *) a. Monad m => a -> m a
return (Entrypoint -> Parser Entrypoint)
-> Entrypoint -> Parser Entrypoint
forall a b. (a -> b) -> a -> b
$ [Text] -> Entrypoint
Entrypoint [Text]
arr
    parseJSON Value
JSON.Null       = Entrypoint -> Parser Entrypoint
forall (m :: * -> *) a. Monad m => a -> m a
return (Entrypoint -> Parser Entrypoint)
-> Entrypoint -> Parser Entrypoint
forall a b. (a -> b) -> a -> b
$ [Text] -> Entrypoint
Entrypoint []
    parseJSON Value
_ = String -> Parser Entrypoint
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Failed to parse Entrypoint"


data ContainerConfig = ContainerConfig {
                       ContainerConfig -> Maybe Text
hostname        :: Maybe Text
                     , ContainerConfig -> Maybe Text
domainname      :: Maybe Text
                     , ContainerConfig -> Maybe Text
user            :: Maybe Text
                     , ContainerConfig -> Bool
attachStdin     :: Bool
                     , ContainerConfig -> Bool
attachStdout    :: Bool
                     , ContainerConfig -> Bool
attachStderr    :: Bool
                     , ContainerConfig -> [ExposedPort]
exposedPorts    :: [ExposedPort]
                     -- , publishService  :: Text -- Don't see this in 1.24
                     , ContainerConfig -> Bool
tty             :: Bool
                     , ContainerConfig -> Bool
openStdin       :: Bool
                     , ContainerConfig -> Bool
stdinOnce       :: Bool
                     , ContainerConfig -> [EnvVar]
env             :: [EnvVar]
                     , ContainerConfig -> [Text]
cmd             :: [Text]
                     -- , argsEscaped     :: Bool -- Don't see this in 1.24
                     , ContainerConfig -> Text
image           :: Text
                     , ContainerConfig -> [Volume]
volumes         :: [Volume]
                     , ContainerConfig -> Maybe String
workingDir      :: Maybe FilePath
                     , ContainerConfig -> Entrypoint
entrypoint      :: Entrypoint
                     , ContainerConfig -> Maybe Bool
networkDisabled :: Maybe Bool -- Note: Should we expand the JSON instance and take away the Maybe? Null is False?
                     , ContainerConfig -> Maybe Text
macAddress      :: Maybe Text
                     -- , onBuild         :: Maybe Text -- For 1.24, only see this in the inspect response.
                     , ContainerConfig -> [Label]
labels          :: [Label]
                     , ContainerConfig -> Signal
stopSignal      :: Signal
                     } deriving (ContainerConfig -> ContainerConfig -> Bool
(ContainerConfig -> ContainerConfig -> Bool)
-> (ContainerConfig -> ContainerConfig -> Bool)
-> Eq ContainerConfig
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ContainerConfig -> ContainerConfig -> Bool
$c/= :: ContainerConfig -> ContainerConfig -> Bool
== :: ContainerConfig -> ContainerConfig -> Bool
$c== :: ContainerConfig -> ContainerConfig -> Bool
Eq, Int -> ContainerConfig -> ShowS
[ContainerConfig] -> ShowS
ContainerConfig -> String
(Int -> ContainerConfig -> ShowS)
-> (ContainerConfig -> String)
-> ([ContainerConfig] -> ShowS)
-> Show ContainerConfig
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ContainerConfig] -> ShowS
$cshowList :: [ContainerConfig] -> ShowS
show :: ContainerConfig -> String
$cshow :: ContainerConfig -> String
showsPrec :: Int -> ContainerConfig -> ShowS
$cshowsPrec :: Int -> ContainerConfig -> ShowS
Show, (forall x. ContainerConfig -> Rep ContainerConfig x)
-> (forall x. Rep ContainerConfig x -> ContainerConfig)
-> Generic ContainerConfig
forall x. Rep ContainerConfig x -> ContainerConfig
forall x. ContainerConfig -> Rep ContainerConfig x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ContainerConfig x -> ContainerConfig
$cfrom :: forall x. ContainerConfig -> Rep ContainerConfig x
Generic)


instance ToJSON ContainerConfig where
    toJSON :: ContainerConfig -> Value
toJSON = Options -> ContainerConfig -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
defaultOptions {
         fieldLabelModifier :: ShowS
fieldLabelModifier = (\(Char
x:String
xs) -> Char -> Char
toUpper Char
x Char -> ShowS
forall a. a -> [a] -> [a]
: String
xs)}

instance FromJSON ContainerConfig where
    parseJSON :: Value -> Parser ContainerConfig
parseJSON (JSON.Object Object
o) = do
        Maybe Text
hostname <- Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"Hostname"
        Maybe Text
domainname <- Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"Domainname"
        Maybe Text
user <- Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"User"
        Bool
attachStdin <- Object
o Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"AttachStdin"
        Bool
attachStdout <- Object
o Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"AttachStdout"
        Bool
attachStderr <- Object
o Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"AttachStderr"
        [ExposedPort]
exposedPorts <- Object
o Object -> Key -> Parser (Maybe [ExposedPort])
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"ExposedPorts" Parser (Maybe [ExposedPort])
-> [ExposedPort] -> Parser [ExposedPort]
forall a. Parser (Maybe a) -> a -> Parser a
.!= []
        Bool
tty <- Object
o Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Tty"
        Bool
openStdin <- Object
o Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"OpenStdin"
        Bool
stdinOnce <- Object
o Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"StdinOnce"
        [EnvVar]
env <- Object
o Object -> Key -> Parser [EnvVar]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Env"
        [Text]
cmd <- Object
o Object -> Key -> Parser [Text]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Cmd"
        Text
image <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Image"
        [Volume]
volumes <- Object
o Object -> Key -> Parser [Volume]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Volumes"
        Maybe String
workingDir <- Object
o Object -> Key -> Parser (Maybe String)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"WorkingDir"
        Entrypoint
entrypoint <- Object
o Object -> Key -> Parser Entrypoint
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Entrypoint"
        Maybe Bool
networkDisabled <- Object
o Object -> Key -> Parser (Maybe Bool)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"networkDisabled"
        Maybe Text
macAddress <- Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"MacAddress"
        [Label]
labels <- Object
o Object -> Key -> Parser (Maybe [Label])
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"Labels" Parser (Maybe [Label]) -> [Label] -> Parser [Label]
forall a. Parser (Maybe a) -> a -> Parser a
.!= []
        Signal
stopSignal <- Object
o Object -> Key -> Parser Signal
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"StopSignal"
        ContainerConfig -> Parser ContainerConfig
forall (m :: * -> *) a. Monad m => a -> m a
return (ContainerConfig -> Parser ContainerConfig)
-> ContainerConfig -> Parser ContainerConfig
forall a b. (a -> b) -> a -> b
$ Maybe Text
-> Maybe Text
-> Maybe Text
-> Bool
-> Bool
-> Bool
-> [ExposedPort]
-> Bool
-> Bool
-> Bool
-> [EnvVar]
-> [Text]
-> Text
-> [Volume]
-> Maybe String
-> Entrypoint
-> Maybe Bool
-> Maybe Text
-> [Label]
-> Signal
-> ContainerConfig
ContainerConfig Maybe Text
hostname Maybe Text
domainname Maybe Text
user Bool
attachStdin Bool
attachStdout Bool
attachStderr [ExposedPort]
exposedPorts Bool
tty Bool
openStdin Bool
stdinOnce [EnvVar]
env [Text]
cmd Text
image [Volume]
volumes Maybe String
workingDir Entrypoint
entrypoint Maybe Bool
networkDisabled
            Maybe Text
macAddress [Label]
labels Signal
stopSignal
    parseJSON Value
_ = String -> Parser ContainerConfig
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"NetworkSettings is not an object."

#if MIN_VERSION_base(4,13,0)
parseIntegerText :: (MonadFail m) => Text -> m Integer
#else
parseIntegerText :: (Monad m) => Text -> m Integer
#endif
parseIntegerText :: Text -> m Integer
parseIntegerText Text
t = case String -> Maybe Integer
forall a. Read a => String -> Maybe a
readMaybe (String -> Maybe Integer) -> String -> Maybe Integer
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack Text
t of
    Maybe Integer
Nothing ->
        String -> m Integer
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Could not parse Integer"
    Just Integer
i ->
        Integer -> m Integer
forall (m :: * -> *) a. Monad m => a -> m a
return Integer
i

-- | Helper function for converting a data type [a] to a json dictionary
-- like so {"something": {}, "something2": {}}
toJsonKey :: Foldable t => t a -> (a -> String) -> JSON.Value
#if MIN_VERSION_aeson(2,0,0)
toJsonKey :: t a -> (a -> String) -> Value
toJsonKey t a
vs a -> String
getKey = Object -> Value
JSON.Object (Object -> Value) -> Object -> Value
forall a b. (a -> b) -> a -> b
$ (Object -> a -> Object) -> Object -> t a -> Object
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Object -> a -> Object
f Object
forall v. KeyMap v
KM.empty t a
vs
        where f :: Object -> a -> Object
f Object
acc a
x = Key -> Value -> Object -> Object
forall v. Key -> v -> KeyMap v -> KeyMap v
KM.insert (Text -> Key
K.fromText (Text -> Key) -> Text -> Key
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ a -> String
getKey a
x) Value
emptyObject Object
acc
#else
toJsonKey vs getKey = JSON.Object $ foldl f HM.empty vs
        where f acc x = HM.insert (T.pack $ getKey x) emptyObject acc
#endif

-- | Helper function for converting a data type [a] to a json dictionary
-- like so {"something": "val1", "something2": "val2"}
toJsonKeyVal :: (Foldable t, JSON.ToJSON r) => t a -> (a -> String) -> (a -> r) -> JSON.Value
#if MIN_VERSION_aeson(2,0,0)
toJsonKeyVal :: t a -> (a -> String) -> (a -> r) -> Value
toJsonKeyVal t a
vs a -> String
getKey a -> r
getVal = Object -> Value
JSON.Object (Object -> Value) -> Object -> Value
forall a b. (a -> b) -> a -> b
$ (Object -> a -> Object) -> Object -> t a -> Object
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Object -> a -> Object
f Object
forall v. KeyMap v
KM.empty t a
vs
        where f :: Object -> a -> Object
f Object
acc a
x = Key -> Value -> Object -> Object
forall v. Key -> v -> KeyMap v -> KeyMap v
KM.insert (String -> Key
K.fromString (String -> Key) -> String -> Key
forall a b. (a -> b) -> a -> b
$ a -> String
getKey a
x) (r -> Value
forall a. ToJSON a => a -> Value
toJSON (r -> Value) -> r -> Value
forall a b. (a -> b) -> a -> b
$ a -> r
getVal a
x) Object
acc
#else
toJsonKeyVal vs getKey getVal = JSON.Object $ foldl f HM.empty vs
        where f acc x = HM.insert (T.pack $ getKey x) (toJSON $ getVal x) acc
#endif

-- | Helper function to convert from aeson's new @KeyMap@ type to an ordinary
-- @HashMap@. A no-op for older versions of aeson. Used to avoid CPP everywhere
-- and @KeyMap@ has no equivalent of @foldlWithKey'@ so even more code changes
-- would be required.
#if MIN_VERSION_aeson(2,0,0)
toHashMap :: KM.KeyMap v -> HM.HashMap T.Text v
toHashMap :: KeyMap v -> HashMap Text v
toHashMap = KeyMap v -> HashMap Text v
forall v. KeyMap v -> HashMap Text v
KM.toHashMapText
#else
toHashMap :: HM.HashMap T.Text v -> HM.HashMap T.Text v
toHashMap = id
#endif