packages feed

docker 0.1.0.1 → 0.2.0.1

raw patch · 5 files changed

+139/−12 lines, 5 filesdep +QuickCheckdep +dockerdep +http-typesdep ~aesondep ~bytestringdep ~containersPVP ok

version bump matches the API change (PVP)

Dependencies added: QuickCheck, docker, http-types, lens-aeson, process, tasty, tasty-hunit, tasty-quickcheck

Dependency ranges changed: aeson, bytestring, containers, lens, text, wreq

API changes (from Hackage documentation)

+ Network.Docker: _dockerEmptyDeleteQuery :: Endpoint -> DockerClientOpts -> IO (Response ByteString)
+ Network.Docker: deleteContainer :: DockerClientOpts -> String -> IO (Status)
+ Network.Docker: deleteContainerWithOpts :: DeleteOpts -> DockerClientOpts -> String -> IO (Status)
+ Network.Docker.Types: DeleteOpts :: Bool -> Bool -> DeleteOpts
+ Network.Docker.Types: RestartAlways :: RestartPolicy
+ Network.Docker.Types: RestartNever :: RestartPolicy
+ Network.Docker.Types: RestartOnFailure :: Int -> RestartPolicy
+ Network.Docker.Types: _RestartPolicy :: StartContainerOpts -> RestartPolicy
+ Network.Docker.Types: data DeleteOpts
+ Network.Docker.Types: data RestartPolicy
+ Network.Docker.Types: defaultDeleteOpts :: DeleteOpts
+ Network.Docker.Types: force :: DeleteOpts -> Bool
+ Network.Docker.Types: instance Show RestartPolicy
+ Network.Docker.Types: instance ToJSON RestartPolicy
+ Network.Docker.Types: removeVolumes :: DeleteOpts -> Bool
- Network.Docker.Types: StartContainerOpts :: [Text] -> [Text] -> [(Text, Text)] -> [(Text, [(Text, Text)])] -> Bool -> Bool -> [Text] -> [Text] -> StartContainerOpts
+ Network.Docker.Types: StartContainerOpts :: [Text] -> [Text] -> [(Text, Text)] -> [((Int, Text), Int)] -> Bool -> Bool -> [Text] -> [Text] -> RestartPolicy -> StartContainerOpts
- Network.Docker.Types: _PortBindings :: StartContainerOpts -> [(Text, [(Text, Text)])]
+ Network.Docker.Types: _PortBindings :: StartContainerOpts -> [((Int, Text), Int)]
- Network.Docker.Types: class HasResourceId t_aaOh where id = (resourceId . go_aaOj) where go_aaOj _f_aaOk (ResourceId __id'_aaOl) = ((\ __id_aaOm -> ResourceId __id_aaOm) <$> (_f_aaOk __id'_aaOl))
+ Network.Docker.Types: class HasResourceId c_acmu where id = (.) resourceId id
- Network.Docker.Types: id :: HasResourceId t_aaOh => Lens' t_aaOh String
+ Network.Docker.Types: id :: HasResourceId c_acmu => Lens' c_acmu String
- Network.Docker.Types: resourceId :: HasResourceId t_aaOh => Lens' t_aaOh ResourceId
+ Network.Docker.Types: resourceId :: HasResourceId c_acmu => Lens' c_acmu ResourceId

Files

Network/Docker.hs view
@@ -5,7 +5,7 @@ import           Control.Applicative    ((<$>), (<*>)) import           Control.Lens import           Data.Aeson             (FromJSON, ToJSON, decode, eitherDecode,-                                         encode)+                                         toJSON) import           Data.Aeson.Lens        (key, _String) import           Data.Aeson.TH import qualified Data.ByteString.Lazy   as L@@ -44,11 +44,13 @@ _dockerGetQuery endpoint clientOpts = get (fullUrl clientOpts endpoint)  _dockerPostQuery :: ToJSON a => Endpoint -> DockerClientOpts -> a -> IO (Response L.ByteString)-_dockerPostQuery endpoint clientOpts postObject = post (fullUrl clientOpts endpoint) (encode postObject)+_dockerPostQuery endpoint clientOpts postObject = post (fullUrl clientOpts endpoint) (toJSON postObject)  emptyPost = "" :: String-_dockerEmptyPostQuery endpoint clientOpts = post (fullUrl clientOpts endpoint) (encode emptyPost)+_dockerEmptyPostQuery endpoint clientOpts = post (fullUrl clientOpts endpoint) (toJSON emptyPost) +_dockerEmptyDeleteQuery endpoint clientOpts = delete (fullUrl clientOpts endpoint)+ getDockerVersion :: DockerClientOpts -> IO (Maybe DockerVersion) getDockerVersion = decodeResponse . _dockerGetQuery "/version" @@ -78,6 +80,13 @@  unpauseContainer :: DockerClientOpts -> String -> IO (Status) unpauseContainer  clientOpts containerId = (^. responseStatus) <$> _dockerEmptyPostQuery (printf "/containers/%s/unpause" containerId) clientOpts++deleteContainer :: DockerClientOpts -> String -> IO (Status)+deleteContainer = deleteContainerWithOpts defaultDeleteOpts++deleteContainerWithOpts :: DeleteOpts -> DockerClientOpts -> String -> IO (Status)+deleteContainerWithOpts (DeleteOpts removeVolumes force) clientOpts containerId = (^. responseStatus) <$> _dockerEmptyDeleteQuery req clientOpts+  where req = printf "/containers/%s?v=%s;force=%s" containerId (show removeVolumes) (show force)  getContainerLogsStream :: DockerClientOpts -> String -> IO () getContainerLogsStream  clientOpts containerId = do
Network/Docker/Options.hs view
@@ -4,12 +4,8 @@ import           Network.Docker.Utils  dopts :: Options-dopts = Options {+dopts = defaultOptions {       fieldLabelModifier = strip_underscore-    , constructorTagModifier = id-    , allNullaryToStringTag = True-    , omitNothingFields = True-    , sumEncoding = defaultTaggedObject     }  
Network/Docker/Types.hs view
@@ -6,6 +6,7 @@  module Network.Docker.Types where +import           Prelude                hiding(id) import           Control.Applicative import           Control.Lens.TH import           Control.Lens.TH@@ -68,7 +69,14 @@             , _type        :: PortType             } deriving (Show, Eq) +data DeleteOpts = DeleteOpts+            { removeVolumes :: Bool+            , force         :: Bool+            } +defaultDeleteOpts = DeleteOpts False False++ data DockerContainer = DockerContainer                     { _containerId        :: ResourceId                     , _containerImageId   :: ResourceId@@ -156,11 +164,12 @@                         { _Binds           :: [T.Text]                         , _Links           :: [T.Text]                         , _LxcConf         :: [(T.Text, T.Text)]-                        , _PortBindings    :: [(T.Text, [(T.Text, T.Text)])]+                        , _PortBindings    :: [((Int,T.Text),Int)]                         , _PublishAllPorts :: Bool                         , _Privileged      :: Bool                         , _Dns             :: [T.Text]                         , _VolumesFrom     :: [T.Text]+			, _RestartPolicy   :: RestartPolicy                         } deriving (Show)  defaultStartOpts = StartContainerOpts@@ -172,6 +181,7 @@                 , _Privileged = False                 , _Dns = []                 , _VolumesFrom = []+                , _RestartPolicy = RestartNever                 }  instance ToJSON StartContainerOpts where@@ -179,12 +189,23 @@             [ "Binds" .= _Binds             , "Links" .= _Links             , "LxcConf" .= _LxcConf-            , "PortBindings" .= _PortBindings+            , "PortBindings" .= object (map (\((h,p),c)->T.concat [T.pack (show h),"/",p] .= [object ["HostPort" .= show c]]) _PortBindings)             , "PublishAllPorts" .= _PublishAllPorts             , "Privileged" .= _Privileged             , "Dns" .= _Dns             , "VolumesFrom" .= _VolumesFrom+	    , "RestartPolicy" .= _RestartPolicy             ]++data RestartPolicy = RestartNever+                   | RestartAlways+                   | RestartOnFailure Int+                   deriving (Show)++instance ToJSON RestartPolicy where+  toJSON RestartNever = object ["Name" .= (""::String), "MaximumRetryCount" .= (0::Int) ]+  toJSON RestartAlways = object ["Name" .= ("always"::String), "MaximumRetryCount" .= (0::Int) ]+  toJSON (RestartOnFailure n) = object ["Name" .= ("on-failure"::String), "MaximumRetryCount" .= n ]  makeClassy ''ResourceId 
docker.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                docker-version:             0.1.0.1+version:             0.2.0.1 synopsis:            Haskell wrapper for Docker Remote API -- description: homepage:            https://github.com/denibertovic/docker-hs@@ -21,6 +21,45 @@   exposed-modules:     Network.Docker, Network.Docker.Options, Network.Docker.Types, Network.Docker.Utils   -- other-modules:   other-extensions:    OverloadedStrings, DeriveFunctor, FlexibleContexts, TemplateHaskell-  build-depends:       base >=4.7 && <4.8, lens >=4.2 && <4.3, aeson >=0.7 && <0.8, bytestring >=0.10 && <0.11, text >=1.1 && <1.2, wreq >=0.1 && <0.2, containers >=0.5 && <0.6, data-default >= 0.5.3, network-uri >= 2.6.0.1, pipes-http >= 1.0.0, pipes >= 4.1.2, pipes-text >= 0.0.0.12, pipes-bytestring >= 2.1.0+  build-depends:       base >= 4.7 && < 4.8+                     , lens >= 4.2+                     , aeson >= 0.7+                     , lens-aeson+                     , bytestring >= 0.10+                     , text >= 1.1+                     , wreq >= 0.3+                     , containers >= 0.5+                     , data-default >= 0.5.3+                     , network-uri >= 2.6.0.1+                     , pipes-http >= 1.0.0+                     , pipes >= 4.1.2+                     , pipes-text >= 0.0.0.12+                     , pipes-bytestring >= 2.1.0   -- hs-source-dirs:   default-language:    Haskell2010++test-suite tests+    build-depends:       base >= 4.7 && < 4.8+                       , docker+                       , lens >= 4.2+                       , aeson >= 0.7+                       , lens-aeson+                       , bytestring >= 0.10+                       , text >= 1.1+                       , wreq >= 0.3+                       , containers >= 0.5+                       , data-default >= 0.5.3+                       , pipes >= 4.1.2+                       , pipes-http >= 1.0.0+                       , pipes-text >= 0.0.0.12+                       , pipes-bytestring >= 2.1.0+                       , tasty >= 0.10.1+                       , tasty-quickcheck >= 0.8.2+                       , QuickCheck >= 2.7+                       , tasty-hunit >= 0.8+                       , process+                       , http-types+    type:                exitcode-stdio-1.0+    main-is:             tests.hs+    hs-source-dirs:      tests+    default-language:    Haskell2010
+ tests/tests.hs view
@@ -0,0 +1,62 @@+module Main where++import Network.Docker+import Network.Docker.Types++import Test.Tasty+import Test.Tasty.HUnit+import qualified Test.Tasty.QuickCheck as QC+import qualified Test.QuickCheck.Monadic as QCM++import Data.Maybe (isJust, fromJust)+import System.Process (system)+import Data.Text (unpack)+import Control.Concurrent (threadDelay)+import Network.HTTP.Types.Status+import qualified Data.ByteString.Char8 as C+import qualified Data.ByteString       as B+import qualified Data.ByteString.Lazy  as BL++opts = defaultClientOpts { baseUrl = "http://127.0.0.1:2375/" }++test_image_name = "docker-hs-test"++toStrict1 = B.concat . BL.toChunks++checkDockerVersion :: IO ()+checkDockerVersion =  do v <- getDockerVersion opts+                         assert $ isJust v++findTestImage :: IO ()+findTestImage = do images <- getDockerImages opts+                   let x = fmap (filter ((== [test_image_name++":latest"]) . _repoTags)) images+                   assert $ fmap length x == Just 1++runAndReadLog :: IO ()+runAndReadLog = do containerId <- createContainer opts (defaultCreateOpts {_image = test_image_name++":latest"})+                   assert $ isJust containerId+                   let c = unpack $ fromJust containerId+                   status1 <- startContainer opts c defaultStartOpts+                   threadDelay 300000 -- give 300ms for the application to finish+                   assert $ status1 == status204+                   status2 <- killContainer opts c+                   logs <- getContainerLogs opts c+                   assert $ status2 == status204+                   assert $ (C.pack "123") `C.isInfixOf` (toStrict1 logs)+                   status3 <- deleteContainer opts c+                   assert $ status3 == status204+++tests :: TestTree+tests = testGroup "Metrics tests" [+    testCase "Get docker version" checkDockerVersion,+    testCase "Find image by name" findTestImage,+    testCase "Run a dummy container and read its log" runAndReadLog]++setup :: IO()+setup =  system ("docker build -t "++test_image_name++" tests") >> return ()++main :: IO()+main = do+  setup+  defaultMain tests