summaryrefslogtreecommitdiff
path: root/src/cuirass/http.scm
diff options
context:
space:
mode:
Diffstat (limited to 'src/cuirass/http.scm')
-rw-r--r--src/cuirass/http.scm158
1 files changed, 133 insertions, 25 deletions
diff --git a/src/cuirass/http.scm b/src/cuirass/http.scm
index a45e6b1..5a5eb52 100644
--- a/src/cuirass/http.scm
+++ b/src/cuirass/http.scm
@@ -3,6 +3,7 @@
;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
;;; Copyright © 2018 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2018 Clément Lassieur <clement@lassieur.org>
+;;; Copyright © 2018 Tatiana Sholokhova <tanja201396@gmail.com>
;;;
;;; This file is part of Cuirass.
;;;
@@ -20,11 +21,14 @@
;;; along with Cuirass. If not, see <http://www.gnu.org/licenses/>.
(define-module (cuirass http)
+ #:use-module (cuirass config)
#:use-module (cuirass database)
#:use-module (cuirass utils)
#:use-module (cuirass logging)
+ #:use-module (srfi srfi-1)
#:use-module (srfi srfi-11)
#:use-module (srfi srfi-26)
+ #:use-module (ice-9 binary-ports)
#:use-module (ice-9 match)
#:use-module (json)
#:use-module (web request)
@@ -33,8 +37,37 @@
#:use-module (web uri)
#:use-module (fibers)
#:use-module (fibers channels)
+ #:use-module (sxml simple)
+ #:use-module (cuirass templates)
+ #:use-module (guix utils)
+ #:use-module (guix build union)
#:export (run-cuirass-server))
+(define %static-directory
+ ;; Define to the static file directory.
+ (make-parameter (string-append
+ (or (getenv "CUIRASS_DATADIR")
+ (string-append %datadir "/" %package))
+ "/static")))
+
+(define %page-size 10)
+
+(define %file-mime-types
+ '(("css" . (text/css))
+ ("otf" . (font/otf))
+ ("woff" . (font/woff))
+ ("js" . (text/javascript))
+ ("png" . (image/png))
+ ("gif" . (image/gif))
+ ("html" . (text/html))))
+
+(define %file-white-list
+ '("css/bootstrap.css"
+ "css/open-iconic-bootstrap.css"
+ "fonts/open-iconic.otf"
+ "fonts/open-iconic.woff"
+ "images/logo.png"))
+
(define (build->hydra-build build)
"Convert BUILD to an assoc list matching hydra API format."
(define (bool->int bool)
@@ -70,19 +103,17 @@
(#:releasename . #nil)
(#:buildinputs_builds . #nil)))
-(define (handle-build-request db-channel build-id)
- "Retrieve build identified by BUILD-ID over DB-CHANNEL and convert it to
-hydra format. Return #f is not build was found."
- (let ((build (with-critical-section db-channel (db)
- (db-get-build db build-id))))
+(define (handle-build-request db build-id)
+ "Retrieve build identified by BUILD-ID over DB and convert it
+ to hydra format. Return #f is not build was found."
+ (let ((build (db-get-build db build-id)))
(and=> build build->hydra-build)))
-(define (handle-builds-request db-channel filters)
- "Retrieve all builds matched by FILTERS in DB-CHANNEL and convert them to
-Hydra format."
- (let ((builds (with-critical-section db-channel (db)
- (with-time-logging "builds request"
- (db-get-builds db filters)))))
+(define (handle-builds-request db filters)
+ "Retrieve all builds matched by FILTERS in DB and convert them
+ to Hydra format."
+ (let ((builds (with-time-logging "builds request"
+ (db-get-builds db filters))))
(map build->hydra-build builds)))
(define (request-parameters request)
@@ -136,6 +167,28 @@ Hydra format."
(object->json-string
`((error . ,message)))))
+ (define (respond-html body)
+ (respond '((content-type . (application/xhtml+xml)))
+ #:body
+ (lambda (port)
+ (format
+ port "<!DOCTYPE html PUBLIC ~s ~s>"
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd")
+ (sxml->xml body port))))
+
+ (define (respond-static-file path)
+ ;; PATH is a list of path components
+ (let ((file-name (string-join path "/"))
+ (file-path (string-join (cons* (%static-directory) path) "/")))
+ (if (and (member file-name %file-white-list)
+ (file-exists? file-path)
+ (not (file-is-directory? file-path)))
+ (respond `((content-type . ,(assoc-ref %file-mime-types
+ (file-extension file-path))))
+ #:body (call-with-input-file file-path get-bytevector-all))
+ (respond-not-found file-name))))
+
(define (respond-build-not-found build-id)
(respond-json-with-error
404
@@ -147,6 +200,11 @@ Hydra format."
404
(format #f "The build log of derivation ~a is not available." drv))))
+ (define (respond-not-found resource_name)
+ (respond (build-response #:code 404)
+ #:body (string-append "Resource not found: "
+ resource_name)))
+
(log-message "~a ~a" (request-method request)
(uri-path (request-uri request)))
@@ -159,8 +217,9 @@ Hydra format."
(with-critical-section db-channel (db)
(db-get-specifications db)))))
(("build" build-id)
- (let ((hydra-build (handle-build-request db-channel
- (string->number build-id))))
+ (let ((hydra-build
+ (with-critical-section db-channel (db)
+ (handle-build-request db (string->number build-id)))))
(if hydra-build
(respond-json (object->json-string hydra-build))
(respond-build-not-found build-id))))
@@ -203,11 +262,12 @@ Hydra format."
(valid-params? (assq-ref params 'nr)))
(if valid-params?
;; Limit results to builds that are "done".
- (respond-json (object->json-string
- (handle-builds-request db-channel
- `((status done)
- ,@params
- (order finish-time)))))
+ (respond-json
+ (object->json-string
+ (with-critical-section db-channel (db)
+ (handle-builds-request db `((status done)
+ ,@params
+ (order finish-time))))))
(respond-json-with-error 500 "Parameter not defined!"))))
(("api" "queue")
(let* ((params (request-parameters request))
@@ -218,18 +278,66 @@ Hydra format."
(object->json-string
;; Use the 'status+submission-time' order so that builds in
;; 'running' state appear before builds in 'scheduled' state.
- (handle-builds-request db-channel
- `((status pending)
- ,@params
- (order status+submission-time)))))
+ (with-critical-section db-channel (db)
+ (handle-builds-request db `((status pending)
+ ,@params
+ (order status+submission-time))))))
(respond-json-with-error 500 "Parameter not defined!"))))
+ ('()
+ (respond-html (html-page
+ "Cuirass"
+ (specifications-table
+ (with-critical-section db-channel (db)
+ (db-get-specifications db))))))
+
+ (("jobset" name)
+ (respond-html
+ (with-critical-section db-channel (db)
+ (let* ((evaluation-id-max (db-get-evaluations-id-max db name))
+ (evaluation-id-min (db-get-evaluations-id-min db name))
+ (params (request-parameters request))
+ (border-high (assqx-ref params 'border-high))
+ (border-low (assqx-ref params 'border-low))
+ (evaluations (db-get-evaluations-build-summary db
+ name
+ %page-size
+ border-low
+ border-high)))
+ (html-page name (evaluation-info-table name
+ evaluations
+ evaluation-id-min
+ evaluation-id-max))))))
+
+ (("eval" id)
+ (respond-html
+ (with-critical-section db-channel (db)
+ (let* ((builds-id-max (db-get-builds-max db id))
+ (builds-id-min (db-get-builds-min db id))
+ (params (request-parameters request))
+ (border-high-time (assqx-ref params 'border-high-time))
+ (border-low-time (assqx-ref params 'border-low-time))
+ (border-high-id (assqx-ref params 'border-high-id))
+ (border-low-id (assqx-ref params 'border-low-id)))
+ (html-page
+ "Evaluation"
+ (build-eval-table
+ (handle-builds-request db `((evaluation ,id)
+ (nr ,%page-size)
+ (order finish-time+build-id)
+ (border-high-time ,border-high-time)
+ (border-low-time ,border-low-time)
+ (border-high-id ,border-high-id)
+ (border-low-id ,border-low-id)))
+ builds-id-min
+ builds-id-max))))))
+
+ (("static" path ...)
+ (respond-static-file path))
('method-not-allowed
;; 405 "Method Not Allowed"
(values (build-response #:code 405) #f db-channel))
(_
- (respond (build-response #:code 404)
- #:body (string-append "Resource not found: "
- (uri->string (request-uri request)))))))
+ (respond-not-found (uri->string (request-uri request))))))
(define* (run-cuirass-server db #:key (host "localhost") (port 8080))
(let* ((host-info (gethostbyname host))