on master help sign in
Merge branch 'pr48'
commit051e5f5a9ecf738421805f5b51ee9b5df3eb9944 authorDeni Bertovic <deni@denibertovic.com> dateTue 9 Jan 2018, 00:51 (9 years ago) parentd8c208410bad6a
4 files changed+39−23
Makefile+1−1 src/Docker/Client/Internal.hs+3−2 src/Docker/Client/Types.hs+23−20 tests/tests.hs+12
Makefile+1−1
@@ -18,7 +18,7 @@ repl:
1818
1919## Run tests. Example RUN_INTEGRATION_TESTS=1 make test
2020test:
21− @stack test
21+ @RUN_INTEGRATION_TESTS=1 stack test
2222
2323## Cut new release
2424release:
src/Docker/Client/Internal.hs+3−2
@@ -5,12 +5,13 @@ import qualified Data.Aeson as JSON
55import Data.ByteString (ByteString)
66import qualified Data.ByteString.Char8 as BSC
77import qualified Data.Conduit.Binary as CB
8−import Data.Text as T
8+import qualified Data.Text as T
99import Data.Text.Encoding (decodeUtf8, encodeUtf8)
1010import qualified Network.HTTP.Client as HTTP
1111import Network.HTTP.Conduit (requestBodySourceChunked)
1212import Network.HTTP.Types (Query, encodePath,
1313 encodePathSegments)
14+import Prelude hiding (all)
1415
1516import Docker.Client.Types
1617
@@ -26,7 +27,7 @@ encodeQ = encodeUtf8 . T.pack
2627
2728getEndpoint :: ApiVersion -> Endpoint -> T.Text
2829getEndpoint v VersionEndpoint = encodeURL [v, "version"]
29−getEndpoint v (ListContainersEndpoint _) = encodeURL [v, "containers", "json"] -- Make use of lsOpts here
30+getEndpoint v (ListContainersEndpoint (ListOpts all)) = encodeURLWithQuery [v, "containers", "json"] [("all", Just (encodeQ $ show all))]
3031getEndpoint v (ListImagesEndpoint _) = encodeURL [v, "images", "json"] -- Make use of lsOpts here
3132getEndpoint v (CreateContainerEndpoint _ cn) = case cn of
3233 Just cn -> encodeURLWithQuery [v, "containers", "create"] [("name", Just (encodeQ $ T.unpack cn))]
src/Docker/Client/Types.hs+23−20
@@ -246,11 +246,11 @@ data ContainerDetails = ContainerDetails {
246246-- | Data type used for parsing the mount information from a container
247247-- list.
248248data Mount = Mount {
249− mountName :: Text
249+ mountName :: Maybe Text -- this is optional
250250 , mountSource :: FilePath
251251 , mountDestination :: FilePath
252− , mountDriver :: Text
253− , mountMode :: Maybe VolumePermission -- apparently this can be null
252+ , mountDriver :: Maybe Text
253+ -- , mountMode :: Maybe VolumePermission -- apparently this can be null
254254 , mountRW :: Bool
255255 , mountPropogation :: Text
256256 }
@@ -258,14 +258,14 @@ data Mount = Mount {
258258
259259instance FromJSON Mount where
260260 parseJSON (JSON.Object o) = do
261− name <- o .: "Name"
261+ name <- o .:? "Name"
262262 src <- o .: "Source"
263263 dest <- o .: "Destination"
264− driver <- o .: "Driver"
265− mode <- o .: "Mode"
264+ driver <- o .:? "Driver"
265+ -- mode <- o .: "Mode"
266266 rw <- o .: "RW"
267267 prop <- o .: "Propagation"
268− return $ Mount name src dest driver mode rw prop
268+ return $ Mount name src dest driver rw prop
269269 parseJSON _ = fail "Mount is not an object"
270270
271271-- | Data type used for parsing the container state from a list of
@@ -520,13 +520,13 @@ data Container = Container
520520
521521instance FromJSON Container where
522522 parseJSON o@(JSON.Object v) =
523− Container <$> (parseJSON o)
523+ Container <$> parseJSON o
524524 <*> (v .: "Names")
525525 <*> (v .: "Image")
526− <*> (v .: "ImageID")
527− <*> (v .: "Command")
526+ <*> (v .: "ImageID") -- Doesn't exist anymore
527+ <*> (v .: "Command") -- Doesn't exist anymore
528528 <*> (v .: "Created")
529− <*> (v .: "Status")
529+ <*> (v .: "State")
530530 <*> (v .: "Ports")
531531 <*> (v .: "Labels")
532532 <*> (v .: "NetworkSettings" >>= parseNetworks)
@@ -535,7 +535,6 @@ instance FromJSON Container where
535535 parseNetworks (JSON.Object v) =
536536 (v .: "Networks") >>= parseJSON
537537 parseNetworks _ = fail "Container NetworkSettings: Not a JSON object."
538−
539538 parseJSON _ = fail "Container: Not a JSON object."
540539
541540-- | Represents the status of the container life cycle.
@@ -549,7 +548,7 @@ instance FromJSON Status where
549548 parseJSON (JSON.String "paused") = return Paused
550549 parseJSON (JSON.String "exited") = return Exited
551550 parseJSON (JSON.String "dead") = return Dead
552− parseJSON _ = fail "Unknown Status"
551+ parseJSON s = fail $ "Unknown Status: " ++ show s
553552
554553-- | Alias for representing a RepoDigest. We could newtype this and add
555554-- some validation.
@@ -658,7 +657,7 @@ defaultHostConfig = HostConfig {
658657 binds=[]
659658 , containerIDFile=Nothing
660659 , logConfig=LogDriverConfig JsonFile []
661− , networkMode=Bridge
660+ , networkMode=NetworkBridge
662661 , portBindings=[]
663662 , restartPolicy=RestartOff
664663 , volumeDriver=Nothing
@@ -789,6 +788,8 @@ instance ToJSON VolumePermission where
789788instance FromJSON VolumePermission where
790789 parseJSON "rw" = return ReadWrite
791790 parseJSON "ro" = return ReadOnly
791+ parseJSON "RW" = return ReadWrite
792+ parseJSON "RO" = return ReadOnly
792793 parseJSON _ = fail "Failed to parse VolumePermission"
793794
794795-- | Used for marking a directory in the container as "exposed" hence
@@ -935,19 +936,21 @@ instance FromJSON LogDriverConfig where
935936 parseJSON _ = fail "LogDriverConfig is not an object"
936937
937938-- TODO: Add container:<name|id> mode
938−data NetworkMode = Bridge | Host | NetworkDisabled
939+data NetworkMode = NetworkBridge | NetworkHost | NetworkDisabled | NetworkNamed Text
939940 deriving (Eq, Show, Ord)
940941
941942instance FromJSON NetworkMode where
942− parseJSON (JSON.String "bridge") = return Bridge
943− parseJSON (JSON.String "host") = return Host -- Note: Guessing on these.
943+ parseJSON (JSON.String "bridge") = return NetworkBridge
944+ parseJSON (JSON.String "host") = return NetworkHost -- Note: Guessing on these.
944945 parseJSON (JSON.String "none") = return NetworkDisabled
946+ parseJSON (JSON.String n) = return $ NetworkNamed n
945947 parseJSON _ = fail "Unknown NetworkMode"
946948
947949instance ToJSON NetworkMode where
948− toJSON Bridge = JSON.String "bridge"
949− toJSON Host = JSON.String "host"
950− toJSON NetworkDisabled = JSON.String "none"
950+ toJSON NetworkBridge = JSON.String "bridge"
951+ toJSON NetworkHost = JSON.String "host"
952+ toJSON NetworkDisabled = JSON.String "none"
953+ toJSON (NetworkNamed n) = JSON.String n
951954
952955data PortType = TCP | UDP deriving (Eq, Generic, Read, Ord)
953956
tests/tests.hs+12
@@ -2,6 +2,7 @@
22
33module Main where
44
5+import Prelude hiding (all)
56import qualified Test.QuickCheck.Monadic as QCM
67import Test.Tasty
78import Test.Tasty.HUnit
@@ -9,6 +10,7 @@ import Test.Tasty.QuickCheck (testProperty)
910
1011import Control.Concurrent (threadDelay)
1112import Control.Lens ((^.), (^?))
13+import Control.Monad (forM_)
1214import Control.Monad.IO.Class
1315import Control.Monad.Trans.Class (lift)
1416import qualified Data.Aeson as JSON
@@ -69,6 +71,15 @@ testFindImage =
6971 where
7072 imageFullName = testImageName <> ":latest"
7173
74+testListContainers :: IO ()
75+testListContainers =
76+ runDocker $
77+ do containerId <- createContainer (defaultCreateOpts (testImageName <> ":latest")) Nothing
78+ c <- fromRight containerId
79+ res <- listContainers $ ListOpts { all=True }
80+ deleteContainer (DeleteOpts True True) c
81+ lift $ assert $ isRight res
82+
7283testBuildFromDockerfile :: IO ()
7384testBuildFromDockerfile = do
7485 cur <- getCurrentDirectory
@@ -180,6 +191,7 @@ integrationTests =
180191 [ testCase "Get docker version" testDockerVersion
181192 , testCase "Build image from Dockerfile" testBuildFromDockerfile
182193 , testCase "Find image by name" testFindImage
194+ , testCase "List containers" testListContainers
183195 , testCase "Run a dummy container and read its log" testRunAndReadLog
184196 , testCase "Try to stop a container that doesn't exist" testStopNonexisting
185197 ]