@@ -11,9 +11,6 @@ module Docker.Client.Types (
12 , fromImageID
12 , fromImageID
13 , toImageID
13 , toImageID
17 , Timeout(..)
14 , Timeout(..)
18 , StatusCode(..)
15 , StatusCode(..)
19 , Signal(..)
16 , Signal(..)
@@ -26,12 +23,11 @@ module Docker.Client.Types (
26 , ContainerPortInfo(..)
23 , ContainerPortInfo(..)
27 , Container(..)
24 , Container(..)
28 , ContainerState(..)
25 , ContainerState(..)
29− , State(..)
26+ , Status(..)
31 , Label(..)
28 , Label(..)
33 , Image(..)
30 , Image(..)
35 , dropImagePrefix
31 , dropImagePrefix
36 , CreateOpts(..)
32 , CreateOpts(..)
37 , BuildOpts(..)
33 , BuildOpts(..)
@@ -40,16 +36,12 @@ module Docker.Client.Types (
40 , DetachKeys(..)
36 , DetachKeys(..)
41 , StartOpts(..)
37 , StartOpts(..)
42 , defaultStartOpts
38 , defaultStartOpts
43− , ContainerDeleteOpts(..)
39+ , DeleteOpts(..)
44− , defaultContainerDeleteOpts
40+ , defaultDeleteOpts
45− , ImageDeleteOpts(..)
46− , defaultImageDeleteOpts
47 , Timestamp
41 , Timestamp
48 , TailLogOpt(..)
42 , TailLogOpt(..)
49 , LogOpts(..)
43 , LogOpts(..)
50 , defaultLogOpts
44 , defaultLogOpts
51− , CreateNetworkOpts(..)
52− , defaultCreateNetworkOpts
53 , VolumePermission(..)
45 , VolumePermission(..)
54 , Bind(..)
46 , Bind(..)
55 , Volume(..)
47 , Volume(..)
@@ -75,8 +67,6 @@ module Docker.Client.Types (
75 , UTSMode(..)
67 , UTSMode(..)
76 , HostConfig(..)
68 , HostConfig(..)
77 , defaultHostConfig
69 , defaultHostConfig
78− , NetworkingConfig(..)
80 , Ulimit(..)
70 , Ulimit(..)
81 , ContainerResources(..)
71 , ContainerResources(..)
82 , defaultContainerResources
72 , defaultContainerResources
@@ -106,13 +96,13 @@ import Data.Aeson (FromJSON, ToJSON, genericParseJSON,
106import qualified Data.Aeson as JSON
96import qualified Data.Aeson as JSON
107import Data.Aeson.Types (defaultOptions, fieldLabelModifier)
97import Data.Aeson.Types (defaultOptions, fieldLabelModifier)
108import Data.Char (isAlphaNum, toUpper)
98import Data.Char (isAlphaNum, toUpper)
99+import Data.Foldable (asum)
109import qualified Data.HashMap.Strict as HM
100import qualified Data.HashMap.Strict as HM
110import Data.Monoid ((<>))
101import Data.Monoid ((<>))
111import Data.Scientific (floatingOrInteger)
102import Data.Scientific (floatingOrInteger)
112import Data.Text (Text)
103import Data.Text (Text)
113import qualified Data.Text as T
104import qualified Data.Text as T
114import Data.Time.Clock (UTCTime)
105import Data.Time.Clock (UTCTime)
115−import qualified Data.Vector as V
116import GHC.Generics (Generic)
106import GHC.Generics (Generic)
117import Prelude hiding (all, tail)
107import Prelude hiding (all, tail)
118import Text.Read (readMaybe)
108import Text.Read (readMaybe)
@@ -132,13 +122,10 @@ data Endpoint =
132 | UnpauseContainerEndpoint ContainerID
122 | UnpauseContainerEndpoint ContainerID
133 | ContainerLogsEndpoint LogOpts Bool ContainerID -- ^ Second argument (Bool) is whether to follow which is currently hardcoded to False.
123 | ContainerLogsEndpoint LogOpts Bool ContainerID -- ^ Second argument (Bool) is whether to follow which is currently hardcoded to False.
134 -- See note in 'Docker.Client.Api.getContainerLogs' for explanation why.
124 -- See note in 'Docker.Client.Api.getContainerLogs' for explanation why.
135− | DeleteContainerEndpoint ContainerDeleteOpts ContainerID
125+ | DeleteContainerEndpoint DeleteOpts ContainerID
136 | InspectContainerEndpoint ContainerID
126 | InspectContainerEndpoint ContainerID
137 | BuildImageEndpoint BuildOpts FilePath
127 | BuildImageEndpoint BuildOpts FilePath
138 | CreateImageEndpoint T.Text Tag (Maybe T.Text) -- ^ Either pull an image from docker hub or imports an image from a tarball (or URL)
128 | CreateImageEndpoint T.Text Tag (Maybe T.Text) -- ^ Either pull an image from docker hub or imports an image from a tarball (or URL)
139− | DeleteImageEndpoint ImageDeleteOpts ImageID
140− | CreateNetworkEndpoint CreateNetworkOpts
141− | RemoveNetworkEndpoint NetworkID
142 deriving (Eq, Show)
129 deriving (Eq, Show)
144-- | We should newtype this
131-- | We should newtype this
@@ -250,7 +237,7 @@ data ContainerDetails = ContainerDetails {
250 , processLabel :: Text
237 , processLabel :: Text
251 , resolveConfPath :: FilePath
238 , resolveConfPath :: FilePath
252 , restartCount :: Int
239 , restartCount :: Int
253− , containerDetailsState :: ContainerState
240+ , state :: ContainerState
254 , mounts :: [Mount]
241 , mounts :: [Mount]
256 deriving (Eq, Show, Generic)
243 deriving (Eq, Show, Generic)
@@ -258,11 +245,11 @@ data ContainerDetails = ContainerDetails {
258-- | Data type used for parsing the mount information from a container
245-- | Data type used for parsing the mount information from a container
260data Mount = Mount {
247data Mount = Mount {
261− mountName :: Maybe Text -- this is optional
248+ mountName :: Text
262 , mountSource :: FilePath
249 , mountSource :: FilePath
263 , mountDestination :: FilePath
250 , mountDestination :: FilePath
264− , mountDriver :: Maybe Text
251+ , mountDriver :: Text
265− -- , mountMode :: Maybe VolumePermission -- apparently this can be null
252+ , mountMode :: Maybe VolumePermission -- apparently this can be null
266 , mountRW :: Bool
253 , mountRW :: Bool
267 , mountPropogation :: Text
254 , mountPropogation :: Text
@@ -270,14 +257,14 @@ data Mount = Mount {
271instance FromJSON Mount where
258instance FromJSON Mount where
272 parseJSON (JSON.Object o) = do
259 parseJSON (JSON.Object o) = do
273− name <- o .:? "Name"
260+ name <- o .: "Name"
274 src <- o .: "Source"
261 src <- o .: "Source"
275 dest <- o .: "Destination"
262 dest <- o .: "Destination"
276− driver <- o .:? "Driver"
263+ driver <- o .: "Driver"
277− -- mode <- o .: "Mode"
264+ mode <- o .: "Mode"
278 rw <- o .: "RW"
265 rw <- o .: "RW"
279 prop <- o .: "Propagation"
266 prop <- o .: "Propagation"
280− return $ Mount name src dest driver rw prop
267+ return $ Mount name src dest driver mode rw prop
281 parseJSON _ = fail "Mount is not an object"
268 parseJSON _ = fail "Mount is not an object"
283-- | Data type used for parsing the container state from a list of
270-- | Data type used for parsing the container state from a list of
@@ -293,7 +280,7 @@ data ContainerState = ContainerState {
293 , restarting :: Bool
280 , restarting :: Bool
294 , running :: Bool
281 , running :: Bool
295 , startedAt :: UTCTime
282 , startedAt :: UTCTime
296− , state :: State
283+ , status :: Status
298 deriving (Eq, Show, Generic)
285 deriving (Eq, Show, Generic)
@@ -523,8 +510,7 @@ data Container = Container
523 , containerImageId :: ImageID
510 , containerImageId :: ImageID
524 , containerCommand :: Text
511 , containerCommand :: Text
525 , containerCreatedAt :: Int
512 , containerCreatedAt :: Int
526− , containerState :: State
527− , containerStatus :: Maybe Text
513+ , containerStatus :: Status
528 , containerPorts :: [ContainerPortInfo]
514 , containerPorts :: [ContainerPortInfo]
529 , containerLabels :: [Label]
515 , containerLabels :: [Label]
530 , containerNetworks :: [Network]
516 , containerNetworks :: [Network]
@@ -532,14 +518,13 @@ data Container = Container
532 } deriving (Show, Eq)
518 } deriving (Show, Eq)
534instance FromJSON Container where
520instance FromJSON Container where
535− parseJSON o@(JSON.Object v) =
521+ parseJSON (JSON.Object v) =
536− Container <$> parseJSON o
522+ Container <$> (v .: "Id")
537 <*> (v .: "Names")
523 <*> (v .: "Names")
538 <*> (v .: "Image")
524 <*> (v .: "Image")
539− <*> (v .: "ImageID") -- Doesn't exist anymore
525+ <*> (v .: "ImageID")
540− <*> (v .: "Command") -- Doesn't exist anymore
526+ <*> (v .: "Command")
541 <*> (v .: "Created")
527 <*> (v .: "Created")
543 <*> (v .: "Status")
528 <*> (v .: "Status")
544 <*> (v .: "Ports")
529 <*> (v .: "Ports")
545 <*> (v .: "Labels")
530 <*> (v .: "Labels")
@@ -549,20 +534,21 @@ instance FromJSON Container where
549 parseNetworks (JSON.Object v) =
534 parseNetworks (JSON.Object v) =
550 (v .: "Networks") >>= parseJSON
535 (v .: "Networks") >>= parseJSON
551 parseNetworks _ = fail "Container NetworkSettings: Not a JSON object."
536 parseNetworks _ = fail "Container NetworkSettings: Not a JSON object."
552 parseJSON _ = fail "Container: Not a JSON object."
538 parseJSON _ = fail "Container: Not a JSON object."
554−-- | Represents the state of the container life cycle.
540+-- | Represents the status of the container life cycle.
555−data State = Created | Restarting | Running | Paused | Exited | Dead
541+data Status = Created | Restarting | Running | Paused | Exited | Dead
556 deriving (Eq, Show, Generic)
542 deriving (Eq, Show, Generic)
558−instance FromJSON State where
544+instance FromJSON Status where
559 parseJSON (JSON.String "running") = return Running
545 parseJSON (JSON.String "running") = return Running
560 parseJSON (JSON.String "created") = return Created -- Note: Guessing on the string values of these.
546 parseJSON (JSON.String "created") = return Created -- Note: Guessing on the string values of these.
561 parseJSON (JSON.String "restarting") = return Restarting
547 parseJSON (JSON.String "restarting") = return Restarting
562 parseJSON (JSON.String "paused") = return Paused
548 parseJSON (JSON.String "paused") = return Paused
563 parseJSON (JSON.String "exited") = return Exited
549 parseJSON (JSON.String "exited") = return Exited
564 parseJSON (JSON.String "dead") = return Dead
550 parseJSON (JSON.String "dead") = return Dead
565− parseJSON s = fail $ "Unknown Status: " ++ show s
551+ parseJSON _ = fail "Unknown Status"
567-- | Alias for representing a RepoDigest. We could newtype this and add
553-- | Alias for representing a RepoDigest. We could newtype this and add
568-- some validation.
554-- some validation.
@@ -623,46 +609,20 @@ instance FromJSON Image where
623 return $ DockerImage imageId imageCreated imageParentId imageRepoTags imageRepoDigests imageSize imageVirtualSize imageLabels
609 return $ DockerImage imageId imageCreated imageParentId imageRepoTags imageRepoDigests imageSize imageVirtualSize imageLabels
624 parseJSON _ = fail "Failed to parse DockerImage."
610 parseJSON _ = fail "Failed to parse DockerImage."
626−-- | Alias for Aliases.
629−-- | EndpointsConfig is container configuration for a specific network
630−newtype EndpointConfig = EndpointConfig [Alias] deriving (Eq, Show)
632−instance ToJSON EndpointConfig where
633− toJSON (EndpointConfig aliases) = JSON.object
634− [ "Aliases" .= aliases
637−-- | Alias for endpoint name
638−type EndpointName = Text
640−-- | Data type for the NetworkingConfig section of the container settings
641−newtype NetworkingConfig = NetworkingConfig
642− { endpointsConfig :: HM.HashMap EndpointName EndpointConfig
643− } deriving (Eq, Show)
645−instance ToJSON NetworkingConfig where
646− toJSON (NetworkingConfig endpointsConfig) = JSON.object
647− [ "EndpointsConfig" .= endpointsConfig
650-- | Options used for creating a Container.
613-- | Options used for creating a Container.
651data CreateOpts = CreateOpts {
614data CreateOpts = CreateOpts {
652− containerConfig :: ContainerConfig
615+ containerConfig :: ContainerConfig
653− , hostConfig :: HostConfig
616+ , hostConfig :: HostConfig
654− , networkingConfig :: NetworkingConfig
655 } deriving (Eq, Show)
617 } deriving (Eq, Show)
657instance ToJSON CreateOpts where
619instance ToJSON CreateOpts where
658− toJSON (CreateOpts cc hc nc) = do
620+ toJSON (CreateOpts cc hc) = do
659 let ccJSON = toJSON cc
621 let ccJSON = toJSON cc
660 let hcJSON = toJSON hc
622 let hcJSON = toJSON hc
661 case ccJSON of
623 case ccJSON of
662 JSON.Object (o :: HM.HashMap T.Text JSON.Value) -> do
624 JSON.Object (o :: HM.HashMap T.Text JSON.Value) -> do
663− let o1 = HM.insert "HostConfig" hcJSON o
625+ JSON.Object $ HM.insert "HostConfig" hcJSON o
664− let o2 = HM.insert "NetworkingConfig" (toJSON nc) o1
666 _ -> error "ContainerConfig is not an object." -- This should never happen.
626 _ -> error "ContainerConfig is not an object." -- This should never happen.
668-- | Container configuration used for creating a container with sensible
628-- | Container configuration used for creating a container with sensible
@@ -684,7 +644,7 @@ defaultContainerConfig imageName = ContainerConfig {
685 , volumes=[]
645 , volumes=[]
686 , workingDir=Nothing
646 , workingDir=Nothing
687− , entrypoint=Entrypoint []
647+ , entrypoint=[]
688 , networkDisabled=Nothing
648 , networkDisabled=Nothing
689 , macAddress=Nothing
649 , macAddress=Nothing
690 , labels=[]
650 , labels=[]
@@ -697,7 +657,7 @@ defaultHostConfig = HostConfig {
698 , containerIDFile=Nothing
658 , containerIDFile=Nothing
699 , logConfig=LogDriverConfig JsonFile []
659 , logConfig=LogDriverConfig JsonFile []
700− , networkMode=NetworkBridge
660+ , networkMode=Bridge
701 , portBindings=[]
661 , portBindings=[]
702 , restartPolicy=RestartOff
662 , restartPolicy=RestartOff
703 , volumeDriver=Nothing
663 , volumeDriver=Nothing
@@ -737,18 +697,14 @@ defaultContainerResources = ContainerResources {
737 , memory=Nothing
697 , memory=Nothing
738 , memoryReservation=Nothing
698 , memoryReservation=Nothing
739 , memorySwap=Nothing
699 , memorySwap=Nothing
740− , oomKillDisable=Just False
700+ , oomKillDisable=False
741 , ulimits=[]
701 , ulimits=[]
744-- | Default create options when creating a container. You only need to
704-- | Default create options when creating a container. You only need to
745-- specify an image name and the rest is all sensible defaults.
705-- specify an image name and the rest is all sensible defaults.
746defaultCreateOpts :: T.Text -> CreateOpts
706defaultCreateOpts :: T.Text -> CreateOpts
747−defaultCreateOpts imageName = CreateOpts
748− { containerConfig = defaultContainerConfig imageName
707+defaultCreateOpts imageName = CreateOpts { containerConfig = defaultContainerConfig imageName, hostConfig = defaultHostConfig }
749− , hostConfig = defaultHostConfig
750− , networkingConfig = NetworkingConfig HM.empty
753-- | Override the key sequence for detaching a container.
709-- | Override the key sequence for detaching a container.
754-- Format is a single character [a-Z] or ctrl-<value> where <value> is one of: a-z, @, ^, [, , or _.
710-- Format is a single character [a-Z] or ctrl-<value> where <value> is one of: a-z, @, ^, [, , or _.
@@ -762,7 +718,7 @@ defaultStartOpts :: StartOpts
762defaultStartOpts = StartOpts { detachKeys = DefaultDetachKey }
718defaultStartOpts = StartOpts { detachKeys = DefaultDetachKey }
764-- | Options for deleting a container.
720-- | Options for deleting a container.
765−data ContainerDeleteOpts = ContainerDeleteOpts {
721+data DeleteOpts = DeleteOpts {
766 deleteVolumes :: Bool -- ^ Automatically cleanup volumes that the container created as well.
722 deleteVolumes :: Bool -- ^ Automatically cleanup volumes that the container created as well.
767 , force :: Bool -- ^ If the container is still running force deletion anyway.
723 , force :: Bool -- ^ If the container is still running force deletion anyway.
768 } deriving (Eq, Show)
724 } deriving (Eq, Show)
@@ -792,15 +748,8 @@ defaultBuildOpts nameTag = BuildOpts { buildImageName = nameTag
792-- | Default options for deleting a container. Most of the time we DON'T
748-- | Default options for deleting a container. Most of the time we DON'T
793-- want to delete the container's volumes or force delete it if it's
749-- want to delete the container's volumes or force delete it if it's
794-- running.
750-- running.
795−defaultContainerDeleteOpts :: ContainerDeleteOpts
751+defaultDeleteOpts :: DeleteOpts
796−defaultContainerDeleteOpts = ContainerDeleteOpts { deleteVolumes = False, force = False }
752+defaultDeleteOpts = DeleteOpts { deleteVolumes = False, force = False }
798−-- | Image delete opts
799−data ImageDeleteOpts = ImageDeleteOpts deriving (Eq, Show)
801−-- | Sane image deletion defaults
802−defaultImageDeleteOpts :: ImageDeleteOpts
803−defaultImageDeleteOpts = ImageDeleteOpts
805-- | Timestamp alias.
754-- | Timestamp alias.
806type Timestamp = Integer
755type Timestamp = Integer
@@ -828,36 +777,6 @@ defaultLogOpts = LogOpts { stdout = True
828 , tail = All
777 , tail = All
831−-- | Options for creating a network
832−data CreateNetworkOpts = CreateNetworkOpts
833− { createNetworkName :: Text -- ^ The network's name
834− , createNetworkCheckDuplicate :: Bool -- ^ Check for networks with duplicate names.
835− , createNetworkDriver :: Text -- ^ Name of the network driver plugin to use.
836− , createNetworkInternal :: Bool -- ^ Restrict external access to the network.
837− , createNetworkEnableIPv6 :: Bool -- ^ Enable IPv6 on the network.
838− } deriving (Eq, Show)
840−-- | Sensible defalut for create network options
841−defaultCreateNetworkOpts :: Text -> CreateNetworkOpts
842−defaultCreateNetworkOpts name =
844− { createNetworkName = name
845− , createNetworkCheckDuplicate = False
846− , createNetworkDriver = "bridge"
847− , createNetworkInternal = True
848− , createNetworkEnableIPv6 = False
851−instance ToJSON CreateNetworkOpts where
854− [ "Name" .= createNetworkName opts
855− , "CheckDuplicate" .= createNetworkCheckDuplicate opts
856− , "Driver" .= createNetworkDriver opts
857− , "Internal" .= createNetworkInternal opts
858− , "EnableIPv6" .= createNetworkEnableIPv6 opts
861-- TOOD: Add support for SELinux Volume labels (eg. "ro,z" or "ro/Z")
780-- TOOD: Add support for SELinux Volume labels (eg. "ro,z" or "ro/Z")
862-- | Set permissions on volumes that you mount in the container.
781-- | Set permissions on volumes that you mount in the container.
863data VolumePermission = ReadWrite | ReadOnly deriving (Eq, Show, Generic)
782data VolumePermission = ReadWrite | ReadOnly deriving (Eq, Show, Generic)
@@ -869,8 +788,6 @@ instance ToJSON VolumePermission where
869instance FromJSON VolumePermission where
788instance FromJSON VolumePermission where
870 parseJSON "rw" = return ReadWrite
789 parseJSON "rw" = return ReadWrite
871 parseJSON "ro" = return ReadOnly
790 parseJSON "ro" = return ReadOnly
872− parseJSON "RW" = return ReadWrite
873− parseJSON "RO" = return ReadOnly
874 parseJSON _ = fail "Failed to parse VolumePermission"
791 parseJSON _ = fail "Failed to parse VolumePermission"
876-- | Used for marking a directory in the container as "exposed" hence
793-- | Used for marking a directory in the container as "exposed" hence
@@ -1017,41 +934,19 @@ instance FromJSON LogDriverConfig where
1017 parseJSON _ = fail "LogDriverConfig is not an object"
934 parseJSON _ = fail "LogDriverConfig is not an object"
1019-- TODO: Add container:<name|id> mode
936-- TODO: Add container:<name|id> mode
1020−data NetworkMode = NetworkBridge | NetworkHost | NetworkDisabled | NetworkNamed Text
937+data NetworkMode = Bridge | Host | NetworkDisabled
1021 deriving (Eq, Show, Ord)
938 deriving (Eq, Show, Ord)
1023instance FromJSON NetworkMode where
940instance FromJSON NetworkMode where
1024− parseJSON (JSON.String "bridge") = return NetworkBridge
941+ parseJSON (JSON.String "bridge") = return Bridge
1025− parseJSON (JSON.String "host") = return NetworkHost -- Note: Guessing on these.
942+ parseJSON (JSON.String "host") = return Host -- Note: Guessing on these.
1026 parseJSON (JSON.String "none") = return NetworkDisabled
943 parseJSON (JSON.String "none") = return NetworkDisabled
1027− parseJSON (JSON.String n) = return $ NetworkNamed n
1028 parseJSON _ = fail "Unknown NetworkMode"
944 parseJSON _ = fail "Unknown NetworkMode"
1030instance ToJSON NetworkMode where
946instance ToJSON NetworkMode where
1031− toJSON NetworkBridge = JSON.String "bridge"
947+ toJSON Bridge = JSON.String "bridge"
1032− toJSON NetworkHost = JSON.String "host"
948+ toJSON Host = JSON.String "host"
1033− toJSON NetworkDisabled = JSON.String "none"
949+ toJSON NetworkDisabled = JSON.String "none"
1034− toJSON (NetworkNamed n) = JSON.String n
1036−newtype NetworkID = NetworkID Text
1037− deriving (Eq, Show)
1039−-- | Used for extracting the id of the container from the newtype
1040−fromNetworkID :: NetworkID -> Text
1041−fromNetworkID (NetworkID t) = t
1043−-- | Used for parsing a Text value into a NetworkID.
1044−toNetworkID :: Text -> Maybe NetworkID
1045−toNetworkID t = Just $ NetworkID t
1047−instance FromJSON NetworkID where
1048− parseJSON (JSON.Object o) = do
1050− return $ NetworkID nid
1051− parseJSON _ = fail "NetworkID is not an object."
1053−instance ToJSON NetworkID where
1054− toJSON (NetworkID nid) = object ["Id" .= nid]
1056data PortType = TCP | UDP deriving (Eq, Generic, Read, Ord)
951data PortType = TCP | UDP deriving (Eq, Generic, Read, Ord)
@@ -1414,7 +1309,7 @@ data ContainerResources = ContainerResources {
1414 , memoryReservation :: Maybe MemoryConstraint
1309 , memoryReservation :: Maybe MemoryConstraint
1415 , memorySwap :: Maybe MemoryConstraint
1310 , memorySwap :: Maybe MemoryConstraint
1416 -- , memorySwappiness :: Integer -- 1.24: Missing from inspecting container details... Going to omit for now.
1311 -- , memorySwappiness :: Integer -- 1.24: Missing from inspecting container details... Going to omit for now.
1417− , oomKillDisable :: Maybe Bool
1312+ , oomKillDisable :: Bool
1418 -- , pidsLimit :: Integer -- 1.24: Missing from inspecting container details... Going to omit for now.
1313 -- , pidsLimit :: Integer -- 1.24: Missing from inspecting container details... Going to omit for now.
1419 , ulimits :: [Ulimit]
1314 , ulimits :: [Ulimit]
1420 -- TODO: Missing from 1.24
1315 -- TODO: Missing from 1.24
@@ -1452,7 +1347,7 @@ instance FromJSON EnvVar where
1452 parseJSON _ = fail "EnvVar is not a string"
1347 parseJSON _ = fail "EnvVar is not a string"
1454instance ToJSON EnvVar where
1349instance ToJSON EnvVar where
1455− toJSON (EnvVar n v) = JSON.String $ n <> T.pack "=" <> v
1350+ toJSON (EnvVar n v) = object [n .= v]
1457-- | ExposedPort represents a port (and it's type)
1352-- | ExposedPort represents a port (and it's type)
1458-- that a container should expose to other containers or the host system.
1353-- that a container should expose to other containers or the host system.
@@ -1492,21 +1387,6 @@ instance {-# OVERLAPPING #-} ToJSON [ExposedPort] where
1492 where key (ExposedPort p t) = show p <> slash <> show t
1387 where key (ExposedPort p t) = show p <> slash <> show t
1493 slash = T.unpack "/"
1388 slash = T.unpack "/"
1495−data Entrypoint = Entrypoint [T.Text] deriving (Eq, Show, Generic)
1497−instance ToJSON Entrypoint where
1498− toJSON (Entrypoint (e:es)) = toJSON (e:es)
1499− toJSON (Entrypoint []) = JSON.Null
1501−instance FromJSON Entrypoint where
1502− parseJSON (JSON.String e) = return $ Entrypoint [e]
1503− parseJSON (JSON.Array ar) = do
1504− arr <- mapM parseJSON (V.toList ar)
1505− return $ Entrypoint arr
1506− parseJSON JSON.Null = return $ Entrypoint []
1507− parseJSON _ = fail "Failed to parse Entrypoint"
1510data ContainerConfig = ContainerConfig {
1390data ContainerConfig = ContainerConfig {
1511 hostname :: Maybe Text
1391 hostname :: Maybe Text
1512 , domainname :: Maybe Text
1392 , domainname :: Maybe Text
@@ -1525,7 +1405,7 @@ data ContainerConfig = ContainerConfig {
1525 , image :: Text
1405 , image :: Text
1526 , volumes :: [Volume]
1406 , volumes :: [Volume]
1527 , workingDir :: Maybe FilePath
1407 , workingDir :: Maybe FilePath
1528− , entrypoint :: Entrypoint
1408+ , entrypoint :: [Text]
1529 , networkDisabled :: Maybe Bool -- Note: Should we expand the JSON instance and take away the Maybe? Null is False?
1409 , networkDisabled :: Maybe Bool -- Note: Should we expand the JSON instance and take away the Maybe? Null is False?
1530 , macAddress :: Maybe Text
1410 , macAddress :: Maybe Text
1531 -- , onBuild :: Maybe Text -- For 1.24, only see this in the inspect response.
1411 -- , onBuild :: Maybe Text -- For 1.24, only see this in the inspect response.
@@ -1533,7 +1413,6 @@ data ContainerConfig = ContainerConfig {
1533 , stopSignal :: Signal
1413 , stopSignal :: Signal
1534 } deriving (Eq, Show, Generic)
1414 } deriving (Eq, Show, Generic)
1537instance ToJSON ContainerConfig where
1416instance ToJSON ContainerConfig where
1538 toJSON = genericToJSON defaultOptions {
1417 toJSON = genericToJSON defaultOptions {
1539 fieldLabelModifier = (\(x:xs) -> toUpper x : xs)}
1418 fieldLabelModifier = (\(x:xs) -> toUpper x : xs)}
@@ -1555,7 +1434,9 @@ instance FromJSON ContainerConfig where
1555 image <- o .: "Image"
1434 image <- o .: "Image"
1556 volumes <- o .: "Volumes"
1435 volumes <- o .: "Volumes"
1557 workingDir <- o .:? "WorkingDir"
1436 workingDir <- o .:? "WorkingDir"
1437+ entrypoint <- asum [ o .:? "Entrypoint" .!= []
1558− entrypoint <- o .: "Entrypoint"
1438+ , (:[]) <$> o .: "Entrypoint"
1559 networkDisabled <- o .:? "networkDisabled"
1440 networkDisabled <- o .:? "networkDisabled"
1560 macAddress <- o .:? "MacAddress"
1441 macAddress <- o .:? "MacAddress"
1561 labels <- o .:? "Labels" .!= []
1442 labels <- o .:? "Labels" .!= []
@@ -1564,11 +1445,7 @@ instance FromJSON ContainerConfig where
1564 macAddress labels stopSignal
1445 macAddress labels stopSignal
1565 parseJSON _ = fail "NetworkSettings is not an object."
1446 parseJSON _ = fail "NetworkSettings is not an object."
1567−#if MIN_VERSION_base(4,13,0)
1568−parseIntegerText :: (MonadFail m) => Text -> m Integer
1570parseIntegerText :: (Monad m) => Text -> m Integer
1448parseIntegerText :: (Monad m) => Text -> m Integer
1572parseIntegerText t = case readMaybe $ T.unpack t of
1449parseIntegerText t = case readMaybe $ T.unpack t of
1573 Nothing ->
1450 Nothing ->
1574 fail "Could not parse Integer"
1451 fail "Could not parse Integer"