on master help sign in
Always test the container

Run the docker container test after checking it exists Ensures we print the nice setup instructions if something has changed since last time

commitada7bfc87ee92721a17597754bbd77e83d4197e2 authorTom Smalley <tfsmalley@gmail.com> dateFri 19 Oct 2018, 14:14 (8 years ago) parentd9cc47d
1 file changed+23−22
lib/command/src/Obelisk/Command/VmBuilder.hs+23−22
lib/command/src/Obelisk/Command/VmBuilder.hs+23−22
@@ -5,10 +5,9 @@
55module Obelisk.Command.VmBuilder where
66
77import Control.Applicative (liftA2)
8−import Control.Monad (unless)
9−import Control.Monad.Catch (try, handle)
8+import Control.Monad (when, unless)
9+import Control.Monad.Catch (handle)
1010import Control.Monad.IO.Class (liftIO)
11−import Data.Either (isRight)
1211import Data.Monoid ((<>))
1312import Data.String (IsString)
1413import Data.String.Here.Uninterpolated (hereLit)
@@ -16,7 +15,7 @@ import Data.Text (Text)
1615import qualified Data.Text as T
1716import qualified Data.Text.IO as T
1817import System.Directory (createDirectoryIfMissing)
19−import System.Exit (ExitCode)
18+import System.Exit (ExitCode(..))
2019import System.FilePath ((<.>), (</>))
2120import qualified System.Info
2221import System.Process (proc)
@@ -29,7 +28,7 @@ import Obelisk.Command.Nix (withNixRemoteCheck)
2928getNixBuildersArg :: MonadObelisk m => m String
3029getNixBuildersArg = do
3130 stateDir <- liftIO getDockerBuilderStateDir
32− exists <- containerExists
31+ exists <- containerExists stateDir
3332 if exists then startContainer else setupNixDocker stateDir
3433 pure $ nixBuildersArgString stateDir
3534
@@ -42,12 +41,14 @@ containerName :: IsString str => str
4241containerName = "obelisk-docker-nix-builder"
4342
4443-- | Check to see if the Docker container exists. This will exit with a helpful message if Docker is not installed.
45−containerExists :: MonadObelisk m => m Bool
46−containerExists = handle (\(_ :: IOError) -> failWith needDockerMsg) $ do
44+containerExists :: MonadObelisk m => FilePath -> m Bool
45+containerExists stateDir = handle (\(_ :: IOError) -> failWith needDockerMsg) $ do
4746 containerNames <- fmap (map T.strip . T.lines) $
4847 readProcessAndLogStderr Error $
4948 proc "docker" ["container", "list", "--all", "--format", "{{.Names}}"]
50− pure $ containerName `elem` containerNames
49+ let exists = containerName `elem` containerNames
50+ when exists $ testLinuxBuild stateDir
51+ pure exists
5152 where
5253 needDockerMsg = T.intercalate "\n"
5354 [ "This feature requires that you have Docker installed and the `docker` command available on your PATH."
@@ -87,16 +88,11 @@ setupNixDocker stateDir = withSpinner ("Creating Docker container named " <> con
8788 , "--publish", show containerSshPort <> ":22"
8889 , "--name", T.unpack containerName, T.unpack containerId
8990 ]
90− exists <- containerExists
91+ exists <- containerExists stateDir
9192 unless exists $
9293 failWith $ "Expected to see docker container named " <> containerName <> " but it does not exist."
9394
94− linuxBuildWorked <- if System.Info.os == "linux"
95− then pure False -- The Linux test is useless on Linux so just assume the setup is incomplete.
96− else testLinuxBuild stateDir
97− unless linuxBuildWorked $ do
98− let sshIdFile = stateDir </> sshKeyFileName
99− failWith $ setupInstructions sshIdFile
95+ testLinuxBuild stateDir
10096
10197-- | The instructions for setting up SSH access to the container for the Nix daemon.
10298setupInstructions :: FilePath -> Text
@@ -133,13 +129,18 @@ getDockerBuilderStateDir :: IO FilePath
133129getDockerBuilderStateDir = liftA2 (</>) getObeliskUserStateDir (pure "nix-docker-builder")
134130
135131-- | Run a test build to see if a Linux build can finish successfully.
136−testLinuxBuild :: MonadObelisk m => FilePath -> m Bool
137−testLinuxBuild stateDir =
138− fmap (isRight :: Either ExitCode () -> Bool) $ try $ withNixRemoteCheck $
139− callProcessAndLogOutput (Debug, Debug) $ proc "nix-build"
140− [ "-E", "(import <nixpkgs> { system = \"x86_64-linux\"; }).writeText \"test\" builtins.currentTime"
141− , "--builders", nixBuildersArgString stateDir
142− ]
132+testLinuxBuild :: MonadObelisk m => FilePath -> m ()
133+testLinuxBuild stateDir
134+ | System.Info.os == "linux" = failWith "Using the docker builder is not necessary on linux."
135+ | otherwise = withNixRemoteCheck $ do
136+ (exitCode, _stdout, stderr) <- readCreateProcessWithExitCode $ proc "nix-build"
137+ [ "-E", "(import <nixpkgs> { system = \"x86_64-linux\"; }).writeText \"test\" builtins.currentTime"
138+ , "--builders", nixBuildersArgString stateDir
139+ ]
140+ unless (exitCode == ExitSuccess) $ do
141+ let sshIdFile = stateDir </> sshKeyFileName
142+ putLog Error $ T.pack stderr
143+ failWith $ setupInstructions sshIdFile
143144
144145-- Copied from https://raw.githubusercontent.com/LnL7/nix-docker/bf28b99aebd8e403d2fc2171f4fa8878f857171c/ssh/Dockerfile
145146-- Renamed "insecure_rsa" to 'sshKeyFileName'