From 29a686688674dc875775305312513405fa396a06 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Fri, 5 Jan 2018 17:15:41 +0100 Subject: daemon: Add gzip log compression. * nix/nix-daemon/guix-daemon.cc (GUIX_OPT_LOG_COMPRESSION): New macro. (options): Mark "disable-log-compression" as hidden and add "log-compression". (parse_opt): Handle GUIX_OPT_LOG_COMPRESSION. * nix/libstore/build.cc (DerivationGoal): Add 'gzLogFile'. (openLogFile): Initialize it when 'logCompression' is COMPRESSION_GZIP. (closeLogFile, handleChildOutput): Honor 'gzLogFile'. * nix/libstore/globals.hh (Settings)[compressLog]: Remove. [logCompression]: New field. (CompressionType): New enum. * nix/libstore/globals.cc (Settings::Settings): Initialize it. (update): Remove '_get' call for 'compressLog'. * nix/local.mk (guix_daemon_LDADD, guix_register_LDADD): Add -lz. * guix/store.scm (log-file): Handle '.gz' log files. * tests/guix-daemon.sh: Add test with '--log-compression=gzip'. * doc/guix.texi (Invoking guix-daemon): Adjust accordingly. * config-daemon.ac: Check for libz and zlib.h. --- tests/guix-daemon.sh | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/guix-daemon.sh b/tests/guix-daemon.sh index 7212e3eb68..6f91eb58bf 100644 --- a/tests/guix-daemon.sh +++ b/tests/guix-daemon.sh @@ -1,5 +1,5 @@ # GNU Guix --- Functional package management for GNU -# Copyright © 2012, 2014, 2015, 2016, 2017 Ludovic Courtès +# Copyright © 2012, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès # # This file is part of GNU Guix. # @@ -193,3 +193,39 @@ do GUIX_DAEMON_SOCKET="$socket" guile -c "$client_code" kill "$daemon_pid" done + +# Log compression. + +guix-daemon --listen="$socket" --disable-chroot --debug --log-compression=gzip & +daemon_pid=$! + +stamp="compressed-build-log-test-$$-`date +%H%M%S`" +client_code=" + (use-modules (guix) (gnu packages bootstrap)) + + (with-store store + (run-with-store store + (mlet %store-monad ((drv (lower-object + (computed-file \"compressed-log-test\" + #~(begin + (display \"$stamp\") + (newline) + (mkdir #\$output)) + #:guile %bootstrap-guile)))) + (display (derivation-file-name drv)) + (newline) + (return #t)))) +" + +GUIX_DAEMON_SOCKET="$socket" +export GUIX_DAEMON_SOCKET + +drv=`guile -c "$client_code"` +guix build "$drv" + +log=`guix build "$drv" --log-file` +test -f "$log" +case "$log" in + *.gz) test "`gunzip -c < "$log"`" = "$stamp" ;; + *) false ;; +esac -- cgit v1.2.3 From c04ffadbed7412545555b8be6b78f23eed150d26 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Fri, 5 Jan 2018 00:19:35 +0100 Subject: publish: Publish build logs. * guix/scripts/publish.scm (render-log-file): New procedure. (make-request-handler): Add "log" case. * tests/publish.scm ("/log/NAME") ("/log/NAME not found"): New tests. * doc/guix.texi (Invoking guix publish): Document /log URLs. --- doc/guix.texi | 17 +++++++++++++++++ guix/scripts/publish.scm | 29 +++++++++++++++++++++++++++++ tests/publish.scm | 28 ++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) (limited to 'tests') diff --git a/doc/guix.texi b/doc/guix.texi index 90d6f7665c..f51593ada1 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -5676,6 +5676,7 @@ collection as soon as the build completes. @xref{Invoking guix gc}, for more on GC roots. @item --log-file +@cindex build logs, access Return the build log file names or URLs for the given @var{package-or-derivation}, or raise an error if build logs are missing. @@ -7238,6 +7239,22 @@ http://example.org/file/hello-2.10.tar.gz/sha256/0ssi1@dots{}ndq1i Obviously, these URLs only work for files that are in the store; in other cases, they return 404 (``Not Found''). +@cindex build logs, publication +Build logs are available from @code{/log} URLs like: + +@example +http://example.org/log/gwspk@dots{}-guile-2.2.3 +@end example + +@noindent +When @command{guix-daemon} is configured to save compressed build logs, +as is the case by default (@pxref{Invoking guix-daemon}), @code{/log} +URLs return the compressed log as-is, with an appropriate +@code{Content-Type} and/or @code{Content-Encoding} header. We recommend +running @command{guix-daemon} with @code{--log-compression=gzip} since +Web browsers can automatically decompress it, which is not the case with +bzip2 compression. + The following options are available: @table @code diff --git a/guix/scripts/publish.scm b/guix/scripts/publish.scm index 3f73197239..6eb5397c8d 100644 --- a/guix/scripts/publish.scm +++ b/guix/scripts/publish.scm @@ -572,6 +572,31 @@ has the given HASH of type ALGO." (not-found request))) (not-found request))) +(define (render-log-file store request name) + "Render the log file for NAME, the base name of a store item. Don't attempt +to compress or decompress the log file; just return it as-is." + (define (response-headers file) + ;; XXX: We're not returning the actual contents, deferring instead to + ;; 'http-write'. This is a hack to work around + ;; . + (cond ((string-suffix? ".gz" file) + `((content-type . (text/plain (charset . "UTF-8"))) + (content-encoding . (gzip)) + (x-raw-file . ,file))) + ((string-suffix? ".bz2" file) + `((content-type . (application/x-bzip2 + (charset . "ISO-8859-1"))) + (x-raw-file . ,file))) + (else ;uncompressed + `((content-type . (text/plain (charset . "UTF-8"))) + (x-raw-file . ,file))))) + + (let ((log (log-file store + (string-append (%store-prefix) "/" name)))) + (if log + (values (response-headers log) log) + (not-found request)))) + (define (render-home-page request) "Render the home page." (values `((content-type . (text/html (charset . "UTF-8")))) @@ -772,6 +797,10 @@ blocking." (render-content-addressed-file store request name 'sha256 hash)))) + ;; /log/OUTPUT + (("log" name) + (render-log-file store request name)) + ;; Use different URLs depending on the compression type. This ;; guarantees that /nar URLs remain valid even when 'guix publish' ;; is restarted with different compression parameters. diff --git a/tests/publish.scm b/tests/publish.scm index 352caf5325..bd1a75cf00 100644 --- a/tests/publish.scm +++ b/tests/publish.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2015 David Thompson +;;; Copyright © 2016, 2017, 2018 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -439,4 +440,31 @@ FileSize: ~a~%" (assoc-ref narinfo "FileSize")) (response-code compressed)))))))))) +(test-equal "/log/NAME" + `(200 #t application/x-bzip2) + (let ((drv (run-with-store %store + (gexp->derivation "with-log" + #~(call-with-output-file #$output + (lambda (port) + (display "Hello, build log!" + (current-error-port)) + (display "" port))))))) + (build-derivations %store (list drv)) + (let* ((response (http-get + (publish-uri (string-append "/log/" + (basename (derivation->output-path drv)))) + #:decode-body? #f)) + (base (basename (derivation-file-name drv))) + (log (string-append (dirname %state-directory) + "/log/guix/drvs/" (string-take base 2) + "/" (string-drop base 2) ".bz2"))) + (list (response-code response) + (= (response-content-length response) (stat:size (stat log))) + (first (response-content-type response)))))) + +(test-equal "/log/NAME not found" + 404 + (let ((uri (publish-uri "/log/does-not-exist"))) + (response-code (http-get uri)))) + (test-end "publish") -- cgit v1.2.3