~ruther/guix-local

c90db25f4cf1f98f3f4f3af38d175a14ffb8c32a — Ludovic Courtès 9 years ago b9a5efa
linux-container: Add 'container-excursion*'.

* gnu/build/linux-container.scm (container-excursion*): New procedure.
* tests/containers.scm ("container-excursion*")
("container-excursion*, same namespaces"): New tests.
2 files changed, 48 insertions(+), 1 deletions(-)

M gnu/build/linux-container.scm
M tests/containers.scm
M gnu/build/linux-container.scm => gnu/build/linux-container.scm +21 -1
@@ 1,5 1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015 David Thompson <davet@gnu.org>
;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
;;;
;;; 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)))))

M tests/containers.scm => tests/containers.scm +27 -0
@@ 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)