diff --git a/gnu/build/linux-container.scm b/gnu/build/linux-container.scm index dd56a79232..95bfd92dde 100644 --- a/gnu/build/linux-container.scm +++ b/gnu/build/linux-container.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2015 David Thompson +;;; Copyright © 2017 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -32,7 +33,8 @@ %namespaces run-container call-with-container - container-excursion)) + container-excursion + container-excursion*)) (define (user-namespace-supported?) "Return #t if user namespaces are supported on this system." @@ -326,3 +328,21 @@ return the exit status." (match (waitpid pid) ((_ . status) (status:exit-val status)))))) + +(define (container-excursion* pid thunk) + "Like 'container-excursion', but return the return value of THUNK." + (match (pipe) + ((in . out) + (match (container-excursion pid + (lambda () + (close-port in) + (write (thunk) out))) + (0 + (close-port out) + (let ((result (read in))) + (close-port in) + result)) + (_ ;maybe PID died already + (close-port out) + (close-port in) + #f))))) diff --git a/tests/containers.scm b/tests/containers.scm index 745b56b710..0b3a4be12b 100644 --- a/tests/containers.scm +++ b/tests/containers.scm @@ -180,4 +180,31 @@ (lambda () (primitive-exit 42)))) +(skip-if-unsupported) +(test-assert "container-excursion*" + (call-with-temporary-directory + (lambda (root) + (define (namespaces pid) + (let ((pid (number->string pid))) + (map (lambda (ns) + (readlink (string-append "/proc/" pid "/ns/" ns))) + '("user" "ipc" "uts" "net" "pid" "mnt")))) + + (let* ((pid (run-container root '() + %namespaces 1 + (lambda () + (sleep 100)))) + (result (container-excursion* pid + (lambda () + (namespaces 1))))) + (kill pid SIGKILL) + (equal? result (namespaces pid)))))) + +(skip-if-unsupported) +(test-equal "container-excursion*, same namespaces" + 42 + (container-excursion* (getpid) + (lambda () + (* 6 7)))) + (test-end)