aboutsummaryrefslogtreecommitdiff
path: root/guix-build-coordinator/hooks.scm
diff options
context:
space:
mode:
Diffstat (limited to 'guix-build-coordinator/hooks.scm')
-rw-r--r--guix-build-coordinator/hooks.scm191
1 files changed, 144 insertions, 47 deletions
diff --git a/guix-build-coordinator/hooks.scm b/guix-build-coordinator/hooks.scm
index bc055c2..3cd1c59 100644
--- a/guix-build-coordinator/hooks.scm
+++ b/guix-build-coordinator/hooks.scm
@@ -26,14 +26,16 @@
#:use-module (gcrypt pk-crypto)
#:use-module (zlib)
#:use-module (lzlib)
+ #:use-module (knots timeout)
#:use-module (guix pki)
#:use-module (guix store)
#:use-module (guix base32)
#:use-module (guix config)
#:use-module (guix derivations)
#:use-module (guix serialization)
- #:use-module ((guix utils) #:select (default-keyword-arguments))
- #:use-module (guix build utils)
+ #:use-module ((guix utils) #:select (default-keyword-arguments
+ call-with-decompressed-port))
+ #:use-module ((guix build utils) #:select (dump-port mkdir-p))
#:use-module (guix-build-coordinator config)
#:use-module (guix-build-coordinator utils)
#:use-module (guix-build-coordinator datastore)
@@ -81,6 +83,20 @@
build-id agent-id)
(current-error-port))))
+(define* (default-nar-compressions #:key output-filename nar-size
+ source-compression source-size)
+ (define MiB (* (expt 2 20) 1.))
+
+ (if (eq? 'none source-compression)
+ ;; If the agent didn't compress the nar, don't change that here
+ (list 'none)
+ (let* ((compression-proportion
+ (/ source-size nar-size)))
+ (if (or (> compression-proportion 0.95)
+ (< nar-size (* 0.05 MiB)))
+ '(none)
+ (list source-compression)))))
+
(define* (build-success-publish-hook
publish-directory
#:key
@@ -94,7 +110,8 @@
post-publish-hook
combined-post-publish-hook
(publish-referenced-derivation-source-files? #t)
- derivation-substitute-urls)
+ derivation-substitute-urls
+ (nar-compressions-proc default-nar-compressions))
(mkdir-p (string-append publish-directory "/nar/lzip"))
(lambda (build-coordinator build-id)
@@ -140,7 +157,8 @@
(substitute-derivation store
drv-name
#:substitute-urls
- derivation-substitute-urls)))
+ derivation-substitute-urls))
+ #:timeout 120)
(add-temp-root store drv-name))
(let* ((drv (read-derivation-from-file* drv-name))
@@ -218,8 +236,7 @@
nar-filename))
#:unwind? #t))
- (cons narinfo-filename
- nar-filename)))))
+ narinfo-filename))))
referenced-source-files))))))
(define (process-output drv-name output)
@@ -230,12 +247,6 @@
(nar-location
(build-output-file-location datastore build-id
output-name))
- (nar-filename
- (string-append "nar/lzip/"
- (basename output-filename)))
- (nar-destination
- (string-append publish-directory "/"
- nar-filename))
(narinfo-filename
(string-append (string-take (basename output-filename) 32)
".narinfo"))
@@ -246,8 +257,78 @@
(if (skip-publishing-proc narinfo-filename narinfo-directory)
#f
- (begin
- (copy-file nar-location nar-destination)
+ (let ((compressions
+ (nar-compressions-proc
+ #:output-filename output-filename
+ #:nar-size (assq-ref output 'size)
+ ;; TODO Don't hardcode this
+ #:source-compression 'lzip
+ #:source-size (stat:size (stat nar-location #f)))))
+
+ (for-each
+ (lambda (compression)
+ (if (or (and (pair? compression)
+ (eq? (car compression) 'lzip))
+ (eq? compression 'lzip))
+ ;; TODO If the agents start uploading uncompressed files
+ ;; or files compressed differently, this might not be
+ ;; right
+ (let ((nar-destination
+ (string-append publish-directory "/"
+ "nar/lzip/"
+ (basename output-filename))))
+ (copy-file nar-location nar-destination))
+ (let* ((target-compression
+ (if (pair? compression)
+ (car compression)
+ compression))
+ ;; TODO This logic should sit elsewhere
+ (nar-destination
+ (string-append
+ publish-directory "/"
+ "nar/"
+ (if (eq? compression 'none)
+ ""
+ (string-append
+ (symbol->string target-compression) "/"))
+ (basename output-filename)))
+ (temporary-destination
+ (string-append nar-destination ".tmp")))
+ (mkdir-p (dirname temporary-destination))
+ (call-with-input-file nar-location
+ (lambda (source-port)
+ (call-with-decompressed-port
+ ;; TODO Don't assume the source compression
+ 'lzip
+ source-port
+ (lambda (decompressed-source-port)
+ (let ((call-with-compressed-output-port*
+ (match target-compression
+ ('gzip
+ (@ (zlib) call-with-gzip-output-port))
+ ('lzip
+ (@ (lzlib) call-with-lzip-output-port))
+ ('zstd
+ (@ (zstd) call-with-zstd-output-port))
+ ('none
+ (lambda (port proc)
+ (proc port)
+ (close-port port))))))
+ (when (file-exists? temporary-destination)
+ (delete-file temporary-destination))
+ (apply
+ call-with-compressed-output-port*
+ (open-output-file temporary-destination
+ #:binary #t)
+ (lambda (compressed-port)
+ (dump-port decompressed-source-port
+ compressed-port))
+ (if (pair? compression)
+ (cdr compression)
+ '())))))))
+ (rename-file temporary-destination
+ nar-destination))))
+ compressions)
(call-with-output-file narinfo-location
(lambda (port)
@@ -257,7 +338,23 @@
(assq-ref output 'size)
(vector->list
(assq-ref output 'references))
- `((lzip ,(stat:size (stat nar-location #f))))
+ (map
+ (lambda (compression-details)
+ (let* ((compression
+ (if (pair? compression-details)
+ (car compression-details)
+ compression-details))
+ ;; TODO This logic should sit elsewhere
+ (file (string-append
+ publish-directory "/"
+ "nar/"
+ (if (eq? compression 'none)
+ ""
+ (string-append
+ (symbol->string compression) "/"))
+ (basename output-filename))))
+ (list compression (stat:size (stat file #f)))))
+ compressions)
#:system (datastore-find-derivation-system
datastore
drv-name)
@@ -276,18 +373,16 @@
(raise-exception exn))
(lambda ()
(post-publish-hook publish-directory
- narinfo-filename
- nar-filename))
+ narinfo-filename))
#:unwind? #t))
- (cons narinfo-filename
- nar-filename)))))
+ narinfo-filename))))
(let* ((build-details
(datastore-find-build datastore build-id))
(drv-name
(assq-ref build-details 'derivation-name))
- (narinfos-and-nars
+ (narinfos
(append
(if publish-referenced-derivation-source-files?
(process-referenced-derivation-source-files drv-name)
@@ -297,23 +392,22 @@
(process-output drv-name output))
(datastore-list-build-outputs datastore build-id)))))
(when (and combined-post-publish-hook
- (not (null? narinfos-and-nars)))
+ (not (null? narinfos)))
(with-exception-handler
(lambda (exn)
;; Rollback narinfo creation, to make this more
;; transactional
(for-each
- (match-lambda
- ((narinfo-filename . _)
- (delete-file
- (string-append
- narinfo-directory "/" narinfo-filename))))
- narinfos-and-nars)
+ (lambda
+ (narinfo-filename)
+ (delete-file
+ (string-append
+ narinfo-directory "/" narinfo-filename)))
+ narinfos)
(raise-exception exn))
(lambda ()
- (combined-post-publish-hook publish-directory
- narinfos-and-nars))
+ (combined-post-publish-hook publish-directory narinfos))
#:unwind? #t)))))
(define* (build-success-s3-publish-hook
@@ -528,24 +622,27 @@
(unless (eq? source-compression recompress-to)
(when (file-exists? tmp-output-log-file)
(delete-file tmp-output-log-file))
- (with-port-timeouts
- (lambda ()
- (call-with-compressed-input-file
- source-log-file
- source-compression
- (lambda (input-port)
- (call-with-compressed-output-file
- tmp-output-log-file
- recompress-to
- (lambda (output-port)
- (dump-port input-port output-port))))))
- #:timeout timeout)
+ (call-with-compressed-input-file
+ source-log-file
+ source-compression
+ (lambda (input-port)
+ (call-with-compressed-output-file
+ tmp-output-log-file
+ recompress-to
+ (lambda (output-port)
+ (dump-port input-port output-port)))))
(rename-file tmp-output-log-file
output-log-file)
(delete-file source-log-file)))))
-(define (default-build-missing-inputs-hook build-coordinator
- build-id missing-inputs)
+(define* (default-build-missing-inputs-hook
+ build-coordinator
+ build-id missing-inputs
+ #:key (submit-build? (lambda* (missing-input
+ #:key successful-builds
+ pending-builds)
+ (and (null? successful-builds)
+ (null? pending-builds)))))
(define datastore
(build-coordinator-datastore build-coordinator))
@@ -579,8 +676,9 @@
(not (assq-ref build-details 'processed))
(not (assq-ref build-details 'canceled))))
builds-for-output)))
- (if (and (null? successful-builds)
- (null? pending-builds))
+ (if (submit-build? missing-input
+ #:successful-builds successful-builds
+ #:pending-builds pending-builds)
(begin
(simple-format #t
"submitting build for ~A\n"
@@ -590,8 +688,7 @@
#:tags (datastore-fetch-build-tags
datastore
build-id)))
- (simple-format #t "~A builds exist for ~A, skipping\n"
- (length builds-for-output)
+ (simple-format #t "skipping submitting build for ~A\n"
missing-input)))
(begin
(simple-format (current-error-port)