buffet-0.2.0: src/Buffet/Test/UsingDockerImage.hs
module Buffet.Test.UsingDockerImage
( Configuration(..)
, DockerBuild(..)
, get
) where
import qualified Buffet.Ir.Ir as Ir
import qualified Buffet.Toolbox.TextTools as TextTools
import qualified Control.Exception as Exception
import qualified Data.Map.Strict as Map
import qualified Data.Text as T
import qualified Data.Word as Word
import qualified Numeric
import Prelude (Eq, IO, Ord, Show, ($), (.), concatMap, mconcat, pure)
import qualified System.IO as IO
import qualified System.Process.Typed as Process
import qualified System.Random as Random
data Configuration =
Configuration
{ log :: IO.Handle
, dockerBuild :: DockerBuild
}
deriving (Eq, Show)
data DockerBuild =
DockerBuild
{ dockerfile :: T.Text
, arguments :: Map.Map Ir.Option T.Text
}
deriving (Eq, Ord, Show)
get :: (T.Text -> IO a) -> Configuration -> IO a
get useImage configuration =
Exception.bracket
(buildImage configuration)
(removeImage configuration)
useImage
buildImage :: Configuration -> IO T.Text
buildImage configuration = do
image <- randomImage
let processBase =
Process.proc "docker" $
mconcat [["build", "--tag", T.unpack image], buildArgs, ["-"]]
Process.runProcess_ .
Process.setStderr (Process.useHandleOpen log') .
Process.setStdout (Process.useHandleOpen log') $
Process.setStdin (textInput dockerfile') processBase
pure image
where
buildArgs =
concatMap
(\(key, value) ->
[ "--build-arg"
, mconcat [T.unpack $ Ir.option key, "=", T.unpack value]
]) $
Map.toAscList arguments'
arguments' = arguments $ dockerBuild configuration
log' = log configuration
textInput = Process.byteStringInput . TextTools.encodeUtf8
dockerfile' = dockerfile $ dockerBuild configuration
randomImage :: IO T.Text
randomImage = do
tagNumber <- Random.randomIO
let _ = tagNumber :: Word.Word64
tag = T.pack $ Numeric.showHex tagNumber ""
pure $ mconcat [name, T.pack ":", tag]
where
name = T.pack "buffet-tmp"
removeImage :: Configuration -> T.Text -> IO ()
removeImage configuration image =
Process.runProcess_ .
Process.setStderr (Process.useHandleOpen log') .
Process.setStdout (Process.useHandleOpen log') $
Process.proc "docker" ["rmi", T.unpack image]
where
log' = log configuration