diff options
-rw-r--r-- | gnu/tests.scm | 183 |
1 files changed, 104 insertions, 79 deletions
diff --git a/gnu/tests.scm b/gnu/tests.scm index ea779ed6f0..1821ac45c5 100644 --- a/gnu/tests.scm +++ b/gnu/tests.scm @@ -27,7 +27,13 @@ #:use-module (srfi srfi-1) #:use-module (srfi srfi-9 gnu) #:use-module (ice-9 match) - #:export (marionette-service-type + #:export (marionette-configuration + marionette-configuration? + marionette-configuration-device + marionette-configuration-imported-modules + marionette-configuration-requirements + + marionette-service-type marionette-operating-system define-os-with-source @@ -50,81 +56,93 @@ ;;; ;;; Code: -(define (marionette-shepherd-service imported-modules) +(define-record-type* <marionette-configuration> + marionette-configuration make-marionette-configuration + marionette-configuration? + (device marionette-configuration-device ;string + (default "/dev/hvc0")) + (imported-modules marionette-configuration-imported-modules + (default '())) + (requirements marionette-configuration-requirements ;list of symbols + (default '()))) + +(define (marionette-shepherd-service config) "Return the Shepherd service for the marionette REPL" - (define device - "/dev/hvc0") - - (list (shepherd-service - (provision '(marionette)) - (requirement '(udev)) ;so that DEVICE is available - (modules '((ice-9 match) - (srfi srfi-9 gnu) - (guix build syscalls) - (rnrs bytevectors))) - (imported-modules `((guix build syscalls) - ,@imported-modules)) - (start - #~(lambda () - (define (clear-echo termios) - (set-field termios (termios-local-flags) - (logand (lognot (local-flags ECHO)) - (termios-local-flags termios)))) - - (define (self-quoting? x) - (letrec-syntax ((one-of (syntax-rules () - ((_) #f) - ((_ pred rest ...) - (or (pred x) - (one-of rest ...)))))) - (one-of symbol? string? pair? null? vector? - bytevector? number? boolean?))) - - (match (primitive-fork) - (0 - (dynamic-wind - (const #t) - (lambda () - (let* ((repl (open-file #$device "r+0")) - (termios (tcgetattr (fileno repl))) - (console (open-file "/dev/console" "r+0"))) - ;; Don't echo input back. - (tcsetattr (fileno repl) (tcsetattr-action TCSANOW) - (clear-echo termios)) - - ;; Redirect output to the console. - (close-fdes 1) - (close-fdes 2) - (dup2 (fileno console) 1) - (dup2 (fileno console) 2) - (close-port console) - - (display 'ready repl) - (let loop () - (newline repl) - - (match (read repl) - ((? eof-object?) - (primitive-exit 0)) - (expr - (catch #t - (lambda () - (let ((result (primitive-eval expr))) - (write (if (self-quoting? result) - result - (object->string result)) - repl))) - (lambda (key . args) - (print-exception (current-error-port) - (stack-ref (make-stack #t) 1) - key args) - (write #f repl))))) - (loop)))) - (lambda () - (primitive-exit 1)))) - (pid - pid)))) - (stop #~(make-kill-destructor))))) + (match config + (($ <marionette-configuration> device imported-modules requirement) + (list (shepherd-service + (provision '(marionette)) + + ;; Always depend on UDEV so that DEVICE is available. + (requirement `(udev ,@requirement)) + + (modules '((ice-9 match) + (srfi srfi-9 gnu) + (guix build syscalls) + (rnrs bytevectors))) + (imported-modules `((guix build syscalls) + ,@imported-modules)) + (start + #~(lambda () + (define (clear-echo termios) + (set-field termios (termios-local-flags) + (logand (lognot (local-flags ECHO)) + (termios-local-flags termios)))) + + (define (self-quoting? x) + (letrec-syntax ((one-of (syntax-rules () + ((_) #f) + ((_ pred rest ...) + (or (pred x) + (one-of rest ...)))))) + (one-of symbol? string? pair? null? vector? + bytevector? number? boolean?))) + + (match (primitive-fork) + (0 + (dynamic-wind + (const #t) + (lambda () + (let* ((repl (open-file #$device "r+0")) + (termios (tcgetattr (fileno repl))) + (console (open-file "/dev/console" "r+0"))) + ;; Don't echo input back. + (tcsetattr (fileno repl) (tcsetattr-action TCSANOW) + (clear-echo termios)) + + ;; Redirect output to the console. + (close-fdes 1) + (close-fdes 2) + (dup2 (fileno console) 1) + (dup2 (fileno console) 2) + (close-port console) + + (display 'ready repl) + (let loop () + (newline repl) + + (match (read repl) + ((? eof-object?) + (primitive-exit 0)) + (expr + (catch #t + (lambda () + (let ((result (primitive-eval expr))) + (write (if (self-quoting? result) + result + (object->string result)) + repl))) + (lambda (key . args) + (print-exception (current-error-port) + (stack-ref (make-stack #t) 1) + key args) + (write #f repl))))) + (loop)))) + (lambda () + (primitive-exit 1)))) + (pid + pid)))) + (stop #~(make-kill-destructor))))))) (define marionette-service-type ;; This is the type of the "marionette" service, allowing a guest system to @@ -136,12 +154,19 @@ marionette-shepherd-service))))) (define* (marionette-operating-system os - #:key (imported-modules '())) - "Return a marionetteed variant of OS such that OS can be used as a marionette -in a virtual machine--i.e., controlled from the host system." + #:key + (imported-modules '()) + (requirements '())) + "Return a marionetteed variant of OS such that OS can be used as a +marionette in a virtual machine--i.e., controlled from the host system. The +marionette service in the guest is started after the Shepherd services listed +in REQUIREMENTS." (operating-system (inherit os) - (services (cons (service marionette-service-type imported-modules) + (services (cons (service marionette-service-type + (marionette-configuration + (requirements requirements) + (imported-modules imported-modules))) (operating-system-user-services os))))) (define-syntax define-os-with-source |