mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2024-12-25 05:48:07 -05:00
inferior: Add 'inferior-package-derivation'.
* guix/inferior.scm (read-inferior-response) (send-inferior-request): New procedures. (inferior-eval): Rewrite in terms of these. (proxy, inferior-package-derivation, inferior-package->derivation) (package-compiler): New procedures. * tests/inferior.scm ("inferior-package-derivation"): New test.
This commit is contained in:
parent
7e27393f82
commit
9daf046c5d
2 changed files with 141 additions and 6 deletions
|
@ -19,9 +19,21 @@
|
||||||
(define-module (guix inferior)
|
(define-module (guix inferior)
|
||||||
#:use-module (srfi srfi-9)
|
#:use-module (srfi srfi-9)
|
||||||
#:use-module (srfi srfi-9 gnu)
|
#:use-module (srfi srfi-9 gnu)
|
||||||
#:use-module ((guix utils) #:select (source-properties->location))
|
#:use-module ((guix utils)
|
||||||
|
#:select (%current-system
|
||||||
|
source-properties->location
|
||||||
|
call-with-temporary-directory))
|
||||||
|
#:use-module ((guix store)
|
||||||
|
#:select (nix-server-socket
|
||||||
|
nix-server-major-version
|
||||||
|
nix-server-minor-version
|
||||||
|
store-lift))
|
||||||
|
#:use-module ((guix derivations)
|
||||||
|
#:select (read-derivation-from-file))
|
||||||
|
#:use-module (guix gexp)
|
||||||
#:use-module (ice-9 match)
|
#:use-module (ice-9 match)
|
||||||
#:use-module (ice-9 popen)
|
#:use-module (ice-9 popen)
|
||||||
|
#:use-module (ice-9 binary-ports)
|
||||||
#:export (inferior?
|
#:export (inferior?
|
||||||
open-inferior
|
open-inferior
|
||||||
close-inferior
|
close-inferior
|
||||||
|
@ -36,7 +48,8 @@ (define-module (guix inferior)
|
||||||
inferior-package-synopsis
|
inferior-package-synopsis
|
||||||
inferior-package-description
|
inferior-package-description
|
||||||
inferior-package-home-page
|
inferior-package-home-page
|
||||||
inferior-package-location))
|
inferior-package-location
|
||||||
|
inferior-package-derivation))
|
||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
;;;
|
;;;
|
||||||
|
@ -123,8 +136,7 @@ (define (write-inferior-object object port)
|
||||||
|
|
||||||
(set-record-type-printer! <inferior-object> write-inferior-object)
|
(set-record-type-printer! <inferior-object> write-inferior-object)
|
||||||
|
|
||||||
(define (inferior-eval exp inferior)
|
(define (read-inferior-response inferior)
|
||||||
"Evaluate EXP in INFERIOR."
|
|
||||||
(define sexp->object
|
(define sexp->object
|
||||||
(match-lambda
|
(match-lambda
|
||||||
(('value value)
|
(('value value)
|
||||||
|
@ -132,14 +144,21 @@ (define sexp->object
|
||||||
(('non-self-quoting address string)
|
(('non-self-quoting address string)
|
||||||
(inferior-object address string))))
|
(inferior-object address string))))
|
||||||
|
|
||||||
(write exp (inferior-socket inferior))
|
|
||||||
(newline (inferior-socket inferior))
|
|
||||||
(match (read (inferior-socket inferior))
|
(match (read (inferior-socket inferior))
|
||||||
(('values objects ...)
|
(('values objects ...)
|
||||||
(apply values (map sexp->object objects)))
|
(apply values (map sexp->object objects)))
|
||||||
(('exception key objects ...)
|
(('exception key objects ...)
|
||||||
(apply throw key (map sexp->object objects)))))
|
(apply throw key (map sexp->object objects)))))
|
||||||
|
|
||||||
|
(define (send-inferior-request exp inferior)
|
||||||
|
(write exp (inferior-socket inferior))
|
||||||
|
(newline (inferior-socket inferior)))
|
||||||
|
|
||||||
|
(define (inferior-eval exp inferior)
|
||||||
|
"Evaluate EXP in INFERIOR."
|
||||||
|
(send-inferior-request exp inferior)
|
||||||
|
(read-inferior-response inferior))
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Inferior packages.
|
;;; Inferior packages.
|
||||||
|
@ -216,3 +235,97 @@ (define (inferior-package-location package)
|
||||||
(location->source-properties
|
(location->source-properties
|
||||||
loc)))
|
loc)))
|
||||||
package-location))))
|
package-location))))
|
||||||
|
|
||||||
|
(define (proxy client backend) ;adapted from (guix ssh)
|
||||||
|
"Proxy communication between CLIENT and BACKEND until CLIENT closes the
|
||||||
|
connection, at which point CLIENT is closed (both CLIENT and BACKEND must be
|
||||||
|
input/output ports.)"
|
||||||
|
(define (select* read write except)
|
||||||
|
;; This is a workaround for <https://bugs.gnu.org/30365> in Guile < 2.2.4:
|
||||||
|
;; since 'select' sometimes returns non-empty sets for no good reason,
|
||||||
|
;; call 'select' a second time with a zero timeout to filter out incorrect
|
||||||
|
;; replies.
|
||||||
|
(match (select read write except)
|
||||||
|
((read write except)
|
||||||
|
(select read write except 0))))
|
||||||
|
|
||||||
|
;; Use buffered ports so that 'get-bytevector-some' returns up to the
|
||||||
|
;; whole buffer like read(2) would--see <https://bugs.gnu.org/30066>.
|
||||||
|
(setvbuf client _IOFBF 65536)
|
||||||
|
(setvbuf backend _IOFBF 65536)
|
||||||
|
|
||||||
|
(let loop ()
|
||||||
|
(match (select* (list client backend) '() '())
|
||||||
|
((reads () ())
|
||||||
|
(when (memq client reads)
|
||||||
|
(match (get-bytevector-some client)
|
||||||
|
((? eof-object?)
|
||||||
|
(close-port client))
|
||||||
|
(bv
|
||||||
|
(put-bytevector backend bv)
|
||||||
|
(force-output backend))))
|
||||||
|
(when (memq backend reads)
|
||||||
|
(match (get-bytevector-some backend)
|
||||||
|
(bv
|
||||||
|
(put-bytevector client bv)
|
||||||
|
(force-output client))))
|
||||||
|
(unless (port-closed? client)
|
||||||
|
(loop))))))
|
||||||
|
|
||||||
|
(define* (inferior-package-derivation store package
|
||||||
|
#:optional
|
||||||
|
(system (%current-system))
|
||||||
|
#:key target)
|
||||||
|
"Return the derivation for PACKAGE, an inferior package, built for SYSTEM
|
||||||
|
and cross-built for TARGET if TARGET is true. The inferior corresponding to
|
||||||
|
PACKAGE must be live."
|
||||||
|
;; Create a named socket in /tmp and let the inferior of PACKAGE connect to
|
||||||
|
;; it and use it as its store. This ensures the inferior uses the same
|
||||||
|
;; store, with the same options, the same per-session GC roots, etc.
|
||||||
|
(call-with-temporary-directory
|
||||||
|
(lambda (directory)
|
||||||
|
(chmod directory #o700)
|
||||||
|
(let* ((name (string-append directory "/inferior"))
|
||||||
|
(socket (socket AF_UNIX SOCK_STREAM 0))
|
||||||
|
(inferior (inferior-package-inferior package))
|
||||||
|
(major (nix-server-major-version store))
|
||||||
|
(minor (nix-server-minor-version store))
|
||||||
|
(proto (logior major minor)))
|
||||||
|
(bind socket AF_UNIX name)
|
||||||
|
(listen socket 1024)
|
||||||
|
(send-inferior-request
|
||||||
|
`(let ((socket (socket AF_UNIX SOCK_STREAM 0)))
|
||||||
|
(connect socket AF_UNIX ,name)
|
||||||
|
|
||||||
|
;; 'port->connection' appeared in June 2018 and we can hardly
|
||||||
|
;; emulate it on older versions. Thus fall back to
|
||||||
|
;; 'open-connection', at the risk of talking to the wrong daemon or
|
||||||
|
;; having our build result reclaimed (XXX).
|
||||||
|
(let* ((store (if (defined? 'port->connection)
|
||||||
|
(port->connection socket #:version ,proto)
|
||||||
|
(open-connection)))
|
||||||
|
(package (hashv-ref %package-table
|
||||||
|
,(inferior-package-id package)))
|
||||||
|
(drv ,(if target
|
||||||
|
`(package-cross-derivation store package
|
||||||
|
,target
|
||||||
|
,system)
|
||||||
|
`(package-derivation store package
|
||||||
|
,system))))
|
||||||
|
(close-connection store)
|
||||||
|
(close-port socket)
|
||||||
|
(derivation-file-name drv)))
|
||||||
|
inferior)
|
||||||
|
(match (accept socket)
|
||||||
|
((client . address)
|
||||||
|
(proxy client (nix-server-socket store))))
|
||||||
|
(close-port socket)
|
||||||
|
(read-derivation-from-file (read-inferior-response inferior))))))
|
||||||
|
|
||||||
|
(define inferior-package->derivation
|
||||||
|
(store-lift inferior-package-derivation))
|
||||||
|
|
||||||
|
(define-gexp-compiler (package-compiler (package <inferior-package>) system
|
||||||
|
target)
|
||||||
|
;; Compile PACKAGE for SYSTEM, optionally cross-building for TARGET.
|
||||||
|
(inferior-package->derivation package system #:target target))
|
||||||
|
|
|
@ -17,9 +17,13 @@
|
||||||
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
|
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
(define-module (test-inferior)
|
(define-module (test-inferior)
|
||||||
|
#:use-module (guix tests)
|
||||||
#:use-module (guix inferior)
|
#:use-module (guix inferior)
|
||||||
#:use-module (guix packages)
|
#:use-module (guix packages)
|
||||||
|
#:use-module (guix store)
|
||||||
|
#:use-module (guix derivations)
|
||||||
#:use-module (gnu packages)
|
#:use-module (gnu packages)
|
||||||
|
#:use-module (gnu packages bootstrap)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (srfi srfi-64))
|
#:use-module (srfi srfi-64))
|
||||||
|
|
||||||
|
@ -29,6 +33,9 @@ (define %top-srcdir
|
||||||
(define %top-builddir
|
(define %top-builddir
|
||||||
(dirname (search-path %load-compiled-path "guix.go")))
|
(dirname (search-path %load-compiled-path "guix.go")))
|
||||||
|
|
||||||
|
(define %store
|
||||||
|
(open-connection-for-tests))
|
||||||
|
|
||||||
|
|
||||||
(test-begin "inferior")
|
(test-begin "inferior")
|
||||||
|
|
||||||
|
@ -72,4 +79,19 @@ (define result
|
||||||
(close-inferior inferior)
|
(close-inferior inferior)
|
||||||
result))))
|
result))))
|
||||||
|
|
||||||
|
(test-equal "inferior-package-derivation"
|
||||||
|
(map derivation-file-name
|
||||||
|
(list (package-derivation %store %bootstrap-guile "x86_64-linux")
|
||||||
|
(package-derivation %store %bootstrap-guile "armhf-linux")))
|
||||||
|
(let* ((inferior (open-inferior %top-builddir
|
||||||
|
#:command "scripts/guix"))
|
||||||
|
(packages (inferior-packages inferior))
|
||||||
|
(guile (find (lambda (package)
|
||||||
|
(string=? (package-name %bootstrap-guile)
|
||||||
|
(inferior-package-name package)))
|
||||||
|
packages)))
|
||||||
|
(map derivation-file-name
|
||||||
|
(list (inferior-package-derivation %store guile "x86_64-linux")
|
||||||
|
(inferior-package-derivation %store guile "armhf-linux")))))
|
||||||
|
|
||||||
(test-end "inferior")
|
(test-end "inferior")
|
||||||
|
|
Loading…
Reference in a new issue