module BB8.Queue where
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BSL
import qualified System.Directory as Sys
import System.FilePath (FilePath, (</>))
import qualified BB8.Common as BB8
import BB8.Jobs
import BB8.Types
-- * Running Jobs
-- | The working directory for a job
workingDirectory :: Config -> JobID -> FilePath
workingDirectory conf ident =
configWorkDirectory conf </> show ident ++ ".work"
-- | The build trace file for a job
buildLogFile :: Config -> JobID -> FilePath
buildLogFile conf ident =
configWorkDirectory conf </> show ident ++ ".work" </> "build-log"
-- | The execution trace file for a job
executionLogFile :: Config -> JobID -> FilePath
executionLogFile conf ident =
configWorkDirectory conf </> show ident ++ ".work" </> "run-log"
-- | The docker image name for a job
dockerImageName :: JobID -> String
dockerImageName ident =
"img-" ++ show ident
getTraceData :: Config -> Integer -> IO JobTrace
getTraceData conf ident = do
buildExists <- Sys.doesFileExist (buildLogFile conf ident)
buildTrc <- if buildExists
then Just `fmap` BS.readFile (buildLogFile conf ident)
else return Nothing
runExists <- Sys.doesFileExist (buildLogFile conf ident)
runTrc <- if runExists
then Just `fmap` BS.readFile (buildLogFile conf ident)
else return Nothing
return (JobTrace buildTrc runTrc)
-- | Run a single step of a job, returning a representation of the
-- next step of the job
runState :: Config -> Trace -> Job -> IO Job
runState conf trace job = case jobState job of
FetchingState -> do
-- this might not make sense any more, but we should still use it
-- to validate that the provided job information is correct
BB8.debug "fetching"
return job { jobState = BuildingState }
BuildingState -> do
BB8.debug "building"
let ident = jobID job
-- let's go to the job's working directory, making sure it exists
let dir = workingDirectory conf ident
let image = dockerImageName ident
let buildLog = buildLogFile conf ident
Sys.createDirectoryIfMissing True dir
-- and then run a docker build process
result <- traceCommand
"docker" ["build", "-t", image, "."] (Just dir) trace
BB8.debug ("got result: " ++ show result)
-- and write the build log in the appropriate place
BSL.writeFile buildLog (buildTraceOutput (resultTrace result))
case resultCode result of
0 -> return job { jobState = RunningState }
_ -> return job { jobState = FailedState }
RunningState -> do
BB8.debug "running"
-- let's go to the job's working directory, making sure it exists
let ident = jobID job
let dir = workingDirectory conf ident
let image = dockerImageName ident
let runLog = executionLogFile conf ident
Sys.createDirectoryIfMissing True dir
-- and then run a docker build process
result <- traceCommand
"docker" ["run", image] (Just dir) trace
BB8.debug ("got result: " ++ show result)
-- and write the build log in the appropriate place
BSL.writeFile runLog (buildTraceOutput (resultTrace result))
case resultCode result of
0 -> return job { jobState = FinishingState }
_ -> return job { jobState = FailedState }
FinishingState -> do
BB8.debug "finishing"
return job { jobState = DoneState }
_ -> return job