on master help sign in
docker seems to work
commit0b858297bff5e29de0cbe6635c2f2430da0c46cf authoriko <ilyakooo0@gmail.com> dateSun 12 Jan 2020, 17:12 (7 years ago) parent33713bd
7 files changed+86−20
package.yaml+3 sc-build.cabal+4−1 src/Data/Tasks/Build.hs+50−12 src/Server.hs+12−6 src/Server/Config.hs+5−1 stack.yaml+2 tasks.yaml+10
package.yaml+3
@@ -46,6 +46,9 @@ library:
4646 - blaze-markup
4747 - blaze-html
4848 - clay
49+ - docker
50+ - exceptions
51+ - transformers
4952
5053executables:
5154 sc-build-exe:
sc-build.cabal+4−1
@@ -4,7 +4,7 @@ cabal-version: 1.12
44--
55-- see: https://github.com/sol/hpack
66--
7−-- hash: bb953e6231fcc3939bfe085afcd3e792cbc40462461bbe4fb82ae69f1796be4c
7+-- hash: 56eccc7f4958f234614ddcff75d3b965ad9a29747591e1e71b73d56faaf48d1c
88
99name: sc-build
1010version: 0.1.0.0
@@ -52,6 +52,8 @@ library
5252 , containers
5353 , cryptonite
5454 , directory
55+ , docker
56+ , exceptions
5557 , generics-sop
5658 , github
5759 , github-app
@@ -66,6 +68,7 @@ library
6668 , squeal-postgresql
6769 , text
6870 , time
71+ , transformers
6972 , typed-process
7073 , unliftio
7174 , unliftio-core
src/Data/Tasks/Build.hs+50−12
@@ -3,12 +3,13 @@
33
44module Data.Tasks.Build
55 ( Build (..),
6+ HasDockerInfo (..),
67 )
78where
89
910import Colog
1011import Control.GithubCloner
11−import Control.Monad.IO.Class
12+import Control.Monad.Except
1213import Control.Monad.IO.Unlift
1314import Control.Task
1415import Control.Task.Scheduler
@@ -21,6 +22,7 @@ import Data.Submission.Query
2122import Data.Tasks.StatusUpdate
2223import qualified Data.Text as T
2324import Data.Time.Clock.POSIX
25+import qualified Docker.Client as D
2426import GHC.Generics
2527import GitHub
2628import Server.Schema
@@ -33,7 +35,7 @@ import UnliftIO.Exception
3335data Build
3436 = Build
3537 { preProcessShell :: String,
36− buildCommand :: String,
38+ dockerFile :: String,
3739 owner :: Name Owner,
3840 repoName :: Name Repo,
3941 sha :: Name Commit
@@ -42,7 +44,7 @@ data Build
4244
4345instance Task Build "build-repo" where
4446
45− type TaskMonad Build m = (MonadUnliftIO m, GithubCloner m, StaticPQ m)
47+ type TaskMonad Build m = (MonadUnliftIO m, GithubCloner m, StaticPQ m, HasDockerInfo m)
4648
4749 performTask Build {..} =
4850 bracket createDir (liftIO . removePathForcibly) $ \dir -> do
@@ -63,10 +65,38 @@ instance Task Build "build-repo" where
6365 scheduleTask erroredTask
6466 updateSubmissionStatus fullRepoName sha' (SubmissionFailed err)
6567 ExitSuccess -> do
66− (buildCode, buildOut, buildErr) <- readProcess . setWorkingDir dir . fromString $ buildCommand
67− case buildCode of
68− ExitFailure n -> do
69− let err = BS.unpack buildErr
68+ h <- liftIO D.defaultHttpHandler
69+ dUrl <- getDockerUrl
70+ let opts = D.defaultCreateOpts imageName
71+ runDocker :: forall a m. MonadIO m => D.DockerT IO a -> m a
72+ runDocker = liftIO . D.runDockerT (D.defaultClientOpts {D.baseUrl = dUrl}, h)
73+ imageName = T.pack dir
74+ liftIO $ writeFile (dir <> "/Dockerfile") dockerFile
75+ absDir <- liftIO $ makeAbsolute dir
76+ let waitDockerForever cid =
77+ D.waitContainer cid >>= \case
78+ Left D.GenericDockerError {} -> waitDockerForever cid
79+ a -> return a
80+ dockerRes <- runDocker . runExceptT $ do
81+ ExceptT $ D.buildImageFromDockerfile (D.defaultBuildOpts imageName) absDir
82+ cid <- ExceptT $ D.createContainer opts Nothing
83+ ExceptT $ D.startContainer D.defaultStartOpts cid
84+ buildCode <- ExceptT $ waitDockerForever cid
85+ buildOut <-
86+ ExceptT $
87+ D.getContainerLogs
88+ D.LogOpts
89+ { stdout = True,
90+ stderr = False,
91+ since = Nothing,
92+ timestamps = False,
93+ tail = D.All
94+ }
95+ cid
96+ return (buildCode, buildOut)
97+ case dockerRes of
98+ Right (ExitFailure n, buildOut) -> do
99+ let err = BS.unpack buildOut
70100 logError . T.pack $
71101 "test command for repo " <> show fullRepoName <> " at sha "
72102 <> show sha
@@ -76,10 +106,15 @@ instance Task Build "build-repo" where
76106 <> err
77107 scheduleTask erroredTask
78108 updateSubmissionStatus fullRepoName sha' (SubmissionFailed err)
79− ExitSuccess ->
80− case decode buildOut of
81− Nothing -> do
82− let err = BS.unpack buildOut
109+ Left err' -> do
110+ let err = show err'
111+ logError . T.pack $ err
112+ scheduleTask erroredTask
113+ updateSubmissionStatus fullRepoName sha' (SubmissionFailed err)
114+ Right (ExitSuccess, buildOut) ->
115+ case eitherDecode' (BS.dropWhile (/= '{') buildOut) of
116+ Left err' -> do
117+ let err = err' <> " " <> BS.unpack buildOut
83118 logError . T.pack $
84119 "could not decode test result from repo " <> show fullRepoName
85120 <> " at sha "
@@ -88,7 +123,7 @@ instance Task Build "build-repo" where
88123 <> err
89124 scheduleTask erroredTask
90125 updateSubmissionStatus fullRepoName sha' (SubmissionFailed err)
91− Just testResult@TestResult {..} -> do
126+ Right testResult@TestResult {..} -> do
92127 let total = M.size tests
93128 passed = M.size . M.filter id $ tests
94129 description = T.pack $ show passed <> "/" <> show total
@@ -131,3 +166,6 @@ getTmpDirName = liftIO $ do
131166 time :: Integer <- round <$> getPOSIXTime
132167 i <- randomIO @Int
133168 return $ show time <> "-" <> show i
169+
170+class HasDockerInfo m where
171+ getDockerUrl :: m T.Text
src/Server.hs+12−6
@@ -99,7 +99,7 @@ webhookPushEvent _ ((), ev) = do
9999 (T.unpack name)
100100 (T.unpack sha)
101101 (Jsonb BuildScheduled)
102− scheduleTask $ Build prebuild build (N owner) (N repoName) (N sha)
102+ scheduleTask $ Build prebuild dockerfile (N owner) (N repoName) (N sha)
103103 liftIO $ do
104104 print ev
105105 hFlush stdout
@@ -127,7 +127,7 @@ retestSubmission owner repoName sha = do
127127 Just (name, TaskConfig {..}) | T.take (T.length name) repoName' == name -> do
128128 scheduleTask $ StatusUpdate (N owner') (N repoName') (N sha') pendingStatus
129129 updateSubmissionStatus fullRepoName sha BuildScheduled
130− scheduleTask $ Build prebuild build (N owner') (N repoName') (N sha')
130+ scheduleTask $ Build prebuild dockerfile (N owner') (N repoName') (N sha')
131131 _ -> return ()
132132 redirectToSubmission owner repoName sha
133133
@@ -157,7 +157,7 @@ runServer = do
157157 pool <- createConnectionPool databseUrl 1 0.5 10
158158 _ <- forkIO $ do
159159 updateTasks ts tasksPath
160− threadDelay $ 10 * 60 * (10 ^ (6 :: Int))
160+ threadDelay $ 5 * 60 * (10 ^ (6 :: Int))
161161 let context =
162162 gitPolyHubKey (return webhookSecret)
163163 :. EmptyContext
@@ -167,7 +167,8 @@ runServer = do
167167 githubAccessToken = GithubAccessToken personalAccessToken,
168168 tasks = ts,
169169 logger = simpleMessageAction,
170− baseUrl = baseSiteUrl
170+ baseUrl = baseSiteUrl,
171+ dockerUrl = T.pack cfgDockerUrl
171172 }
172173 repeatIfNotEmpty n f = f >>= \m -> do
173174 when (m == 0) $ liftIO $ threadDelay n
@@ -204,7 +205,8 @@ data ServerData m
204205 githubAccessToken :: !GithubAccessToken,
205206 tasks :: IORef TasksConfig,
206207 logger :: LogAction m Message,
207− baseUrl :: String
208+ baseUrl :: String,
209+ dockerUrl :: T.Text
208210 }
209211
210212newtype PolyGitHubKey = PolyGitHubKey (forall result. GitHubKey result)
@@ -232,12 +234,16 @@ instance MonadReader (ServerData n) m => MonadHasBaseUrl m where
232234instance (MonadIO m, MonadReader (ServerData n) m) => HasTasks m where
233235 getTasks = asks tasks >>= liftIO . readIORef
234236
237+instance (MonadReader (ServerData n) m) => HasDockerInfo m where
238+ getDockerUrl = asks dockerUrl
239+
235240type TasksConfig = Map T.Text TaskConfig
236241
237242data TaskConfig
238243 = TaskConfig
239244 { prebuild :: String,
240− build :: String
245+ dockerfile :: String
246+ -- build :: T.Text
241247 }
242248 deriving stock (Show, Eq, Generic)
243249 deriving anyclass (FromJSON, ToJSON)
src/Server/Config.hs+5−1
@@ -27,7 +27,9 @@ data Config
2727 githubUsername :: !String,
2828 tasksPath :: !FilePath,
2929 databseUrl :: !ByteString,
30− baseSiteUrl :: !String
30+ baseSiteUrl :: !String,
31+ cfgDockerUrl :: !String,
32+ cfgDockerFile :: !FilePath
3133 }
3234 deriving (Show)
3335
@@ -44,6 +46,8 @@ getConfig =
4446 <*> (fromMaybe (error "no TASKS") <$> lookupEnv "TASKS")
4547 <*> (maybe (error "no DATABASE_URL") BS8.pack <$> lookupEnv "DATABASE_URL")
4648 <*> (fromMaybe "http://localhost:8080" <$> lookupEnv "PORT")
49+ <*> (fromMaybe "http://localhost:1234" <$> lookupEnv "DOCKER_URL")
50+ <*> (fromMaybe "TmpDockerfile" <$> lookupEnv "DOCKER_FILE")
4751 where
4852 readPem :: IO PrivateKey
4953 readPem = do
stack.yaml+2
@@ -46,6 +46,8 @@ extra-deps:
4646- git: https://github.com/ilyakooo0/github-app
4747 commit: 0bede85ab53eb8f953cf6f4e58a756a205e88e0b
4848- servant-github-webhook-0.4.2.0
49+- docker-0.6.0.2
50+- http-client-0.5.14
4951
5052# Override default flag values for local packages and extra-deps
5153# flags: {}
tasks.yamlnew file+10
@@ -0,0 +1,10 @@
1+test-task:
2+ prebuild: |
3+ cp -f ../../test-task/package.yaml .
4+ cp -f ../../test-task/stack.yaml .
5+ cp -f -R ../../test-task/test .
6+ dockerfile: |
7+ FROM fast-lts-14.20
8+ COPY . src
9+ WORKDIR /src
10+ ENTRYPOINT stack test --fast