pullImage :: (MonadLogger m,MonadIO m,MonadThrow m)
          => EnvOverride -> DockerOpts -> String -> m ()
pullImage envOverride docker image =
  do $logInfo (concatT ["Pulling image from registry: '",image,"'"])
     when (dockerRegistryLogin docker)
          (do $logInfo "You may need to log in."
              callProcess $ Cmd
                Nothing
                "docker"
                envOverride
                (concat
                   [["login"]
                   ,maybe [] (\n -> ["--username=" ++ n]) (dockerRegistryUsername docker)
                   ,maybe [] (\p -> ["--password=" ++ p]) (dockerRegistryPassword docker)
                   ,[takeWhile (/= '/') image]]))
     -- We redirect the stdout of the process to stderr so that the output
     -- of @docker pull@ will not interfere with the output of other
     -- commands when using --auto-docker-pull. See issue #2733.
     let stdoutToStderr cp = cp
           { std_out = UseHandle stderr
           , std_err = UseHandle stderr
           , std_in = CreatePipe
           }
     (Just hin, _, _, ph) <- createProcess' "pullImage" stdoutToStderr $
       Cmd Nothing "docker" envOverride ["pull",image]
     liftIO (hClose hin)
     ec <- liftIO (waitForProcess ph)
     case ec of
       ExitSuccess -> return ()
       ExitFailure _ -> throwM (PullFailedException image)

-- | Check docker version (throws exception if incorrect)
pullImage :: (MonadLogger m,MonadIO m,MonadThrow m)
          => EnvOverride -> DockerOpts -> String -> m ()
pullImage envOverride docker image =
  do $logInfo (concatT ["Pulling image from registry: '",image,"'"])
     when (dockerRegistryLogin docker)
          (do $logInfo "You may need to log in."
              callProcess $ Cmd
                Nothing
                "docker"
                envOverride
                (concat
                   [["login"]
                   ,maybe [] (\n -> ["--username=" ++ n]) (dockerRegistryUsername docker)
                   ,maybe [] (\p -> ["--password=" ++ p]) (dockerRegistryPassword docker)
                   ,[takeWhile (/= '/') image]]))
     -- We redirect the stdout of the process to stderr so that the output
     -- of @docker pull@ will not interfere with the output of other
     -- commands when using --auto-docker-pull. See issue #2733.
     let stdoutToStderr cp = cp
           { std_out = UseHandle stderr
           , std_err = UseHandle stderr
           , std_in = CreatePipe
           }
     (Just hin, _, _, ph) <- createProcess' "pullImage" stdoutToStderr $
       Cmd Nothing "docker" envOverride ["pull",image]
     liftIO (hClose hin)
     ec <- liftIO (waitForProcess ph)
     case ec of
       ExitSuccess -> return ()
       ExitFailure _ -> throwM (PullFailedException image)

-- | Check docker version (throws exception if incorrect)
pullImage envOverride docker image =
  do $logInfo (concatT ["Pulling image from registry: '",image,"'"])
     when (dockerRegistryLogin docker)
          (do $logInfo "You may need to log in."
              callProcess $ Cmd
                Nothing
                "docker"
                envOverride
                (concat
                   [["login"]
                   ,maybe [] (\n -> ["--username=" ++ n]) (dockerRegistryUsername docker)
                   ,maybe [] (\p -> ["--password=" ++ p]) (dockerRegistryPassword docker)
                   ,[takeWhile (/= '/') image]]))
     -- We redirect the stdout of the process to stderr so that the output
     -- of @docker pull@ will not interfere with the output of other
     -- commands when using --auto-docker-pull. See issue #2733.
     let stdoutToStderr cp = cp
           { std_out = UseHandle stderr
           , std_err = UseHandle stderr
           , std_in = CreatePipe
           }
     (Just hin, _, _, ph) <- createProcess' "pullImage" stdoutToStderr $
       Cmd Nothing "docker" envOverride ["pull",image]
     liftIO (hClose hin)
     ec <- liftIO (waitForProcess ph)
     case ec of
       ExitSuccess -> return ()
       ExitFailure _ -> throwM (PullFailedException image)

-- | Check docker version (throws exception if incorrect)