;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2020 Ludovic Courtès ;;; Copyright © 2017 Jan Nieuwenhuizen ;;; Copyright © 2018, 2019 Clément Lassieur ;;; Copyright © 2021 Mathieu Othacehe ;;; ;;; This file is part of GNU Guix. ;;; ;;; GNU Guix is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 3 of the License, or (at ;;; your option) any later version. ;;; ;;; GNU Guix is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with GNU Guix. If not, see . ;;; ;;; This file defines build jobs for the Cuirass continuation integration ;;; tool. ;;; (use-modules (guix inferior) (guix channels) (guix) (guix ui) (srfi srfi-1) (ice-9 match) (ice-9 threads)) ;; XXX: Debugging hack: since `hydra-eval-guile-jobs' redirects the output ;; port to the bit bucket, let us write to the error port instead. (setvbuf (current-error-port) 'line) (set-current-output-port (current-error-port)) (define (find-current-checkout arguments) "Find the first checkout of ARGUMENTS that provided the current file. Return #f if no such checkout is found." (let ((current-root (canonicalize-path (string-append (dirname (current-filename)) "/../..")))) (find (lambda (argument) (and=> (assq-ref argument 'file-name) (lambda (name) (string=? name current-root)))) arguments))) (define* (cuirass-jobs store arguments register) "Return a list of jobs where each job is a NAME/THUNK pair." (define checkout (find-current-checkout arguments)) (define commit (assq-ref checkout 'revision)) (define source (assq-ref checkout 'file-name)) (define instance (checkout->channel-instance source #:commit commit)) (define derivation ;; Compute the derivation of Guix for COMMIT. (run-with-store store (channel-instances->derivation (list instance)))) ;; TODO: Remove 'show-what-to-build' call when Cuirass' 'evaluate' scripts ;; uses 'with-build-handler'. (show-what-to-build store (list derivation)) (build-derivations store (list derivation)) ;; Open an inferior for the just-built Guix. (call-with-temporary-directory (lambda (directory) (let* ((name (string-append directory "/ci-inferior")) (socket (socket AF_UNIX SOCK_STREAM 0)) (inferior (open-inferior (derivation->output-path derivation)))) ;; XXX: The inferior cannot call directly the register procedure that ;; is declared in Cuirass. Use a socket to proxy the inferior ;; registration requests. (call-with-new-thread (lambda () (bind socket AF_UNIX name) (listen socket 1024) (match (select (list socket) '() '() 60) (((_) () ()) (match (accept socket) ((client . address) (setvbuf client 'block 1024) (let loop ((exp (read client))) (unless (eof-object? exp) (apply register exp) (loop (read client))))))) ((() () ()) #f)) (close-port socket))) (inferior-eval '(use-modules (gnu ci) (ice-9 match)) inferior) (inferior-eval-with-store inferior store `(lambda (store) (let* ((socket (socket AF_UNIX SOCK_STREAM 0)) (register (lambda args (write args socket)))) (connect socket AF_UNIX ,name) (setvbuf socket 'block 1024) (cuirass-jobs store '((superior-guix-checkout . ,checkout) ,@arguments) register) (close-port socket))))))))