From mboxrd@z Thu Jan 1 00:00:00 1970 From: David Thompson Subject: [PATCH 14/15] scripts: environment: Add --container option. Date: Mon, 6 Jul 2015 09:16:43 -0400 Message-ID: <1436188604-2813-14-git-send-email-dthompson2@worcester.edu> References: <1436188604-2813-1-git-send-email-dthompson2@worcester.edu> Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:47647) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZC6HC-0001aC-AD for guix-devel@gnu.org; Mon, 06 Jul 2015 09:17:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZC6HA-000726-DU for guix-devel@gnu.org; Mon, 06 Jul 2015 09:17:38 -0400 Received: from mail-qk0-f180.google.com ([209.85.220.180]:33898) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZC6HA-00071t-6l for guix-devel@gnu.org; Mon, 06 Jul 2015 09:17:36 -0400 Received: by qkeo142 with SMTP id o142so116532892qke.1 for ; Mon, 06 Jul 2015 06:17:36 -0700 (PDT) In-Reply-To: <1436188604-2813-1-git-send-email-dthompson2@worcester.edu> List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org Sender: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org To: guix-devel@gnu.org Cc: David Thompson From: David Thompson * guix/scripts/enviroment.scm (show-help): Show help for new option. (%options): Add --container option. (launch-environment, launch-environment/container): New procedures. (guix-environment): Spawn new process in a container when requested. * doc/guix.texi (Invoking guix environment): Document it. --- doc/guix.texi | 16 +++++++++++++++ guix/scripts/environment.scm | 48 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index d24f97e..57fc446 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -4191,6 +4191,15 @@ NumPy: guix environment --ad-hoc python2-numpy python-2.7 -E python @end example +Sometimes it is desirable to isolate the environment as much as +possible, for maximal purity and reproducibility. For example, the +following command spawns a Guile REPL in a ``container'' where only the +store and the current working directory are mounted: + +@example +guix environment --ad-hoc --container guile --exec=guile +@end example + The available options are summarized below. @table @code @@ -4256,6 +4265,13 @@ environment. @item --system=@var{system} @itemx -s @var{system} Attempt to build for @var{system}---e.g., @code{i686-linux}. + +@item --container +@itemx -C +Run command within an isolated container. The current working directory +outside the container is mapped to @file{/env} inside the container. +Additionally, the spawned process runs as the current user outside the +container, but has root privileges in the context of the container. @end table It also supports all of the common build options that @command{guix diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm index ecdbc7a..41d1554 100644 --- a/guix/scripts/environment.scm +++ b/guix/scripts/environment.scm @@ -28,6 +28,9 @@ #:use-module (guix monads) #:use-module ((guix gexp) #:select (lower-inputs)) #:use-module (guix scripts build) + #:use-module (gnu build linux-container) + #:use-module (gnu system linux-container) + #:use-module (gnu system file-systems) #:use-module (gnu packages) #:use-module (ice-9 format) #:use-module (ice-9 match) @@ -122,6 +125,8 @@ shell command in that environment.\n")) --search-paths display needed environment variable definitions")) (display (_ " -s, --system=SYSTEM attempt to build for SYSTEM--e.g., \"i686-linux\"")) + (display (_ " + -C, --container run command within an isolated container")) (newline) (show-build-options-help) (newline) @@ -174,6 +179,9 @@ shell command in that environment.\n")) (lambda (opt name arg result) (alist-cons 'system arg (alist-delete 'system result eq?)))) + (option '(#\C "container") #f #f + (lambda (opt name arg result) + (alist-cons 'container? #t result))) %standard-build-options)) (define (pick-all alist key) @@ -229,6 +237,38 @@ OUTPUT) tuples, using the build options in OPTS." (built-derivations derivations) (return derivations)))))))) +(define (launch-environment command inputs paths pure?) + "Run COMMAND in a new environment containing INPUTS, using the native search +paths defined by the list PATHS. When PURE?, pre-existing environment +variables are cleared before setting the new ones." + (create-environment inputs paths pure?) + (system command)) + +(define (launch-environment/container command inputs paths) + "Run COMMAND within a Linux container that includes INPUTS and the +environment variables defined by PATHS, a list of native search paths." + ;; Bind-mount the store and the current working directory within the + ;; container. + (let* ((mappings + (list (file-system-mapping + (source (%store-prefix)) + (target (%store-prefix)) + (writable? #f)) + (file-system-mapping + (source (getcwd)) + (target "/env") + (writable? #t)))) + (file-systems + (append %container-file-systems + (map mapping->file-system mappings))) + (status + (call-with-container (map file-system->spec file-systems) + (lambda () + (chdir "/env") + ;; A container's environment is already purified. + (launch-environment command inputs paths #f))))) + (status:exit-val status))) + ;; Entry point. (define (guix-environment . args) (define (handle-argument arg result) @@ -238,6 +278,7 @@ OUTPUT) tuples, using the build options in OPTS." (let* ((opts (parse-command-line args %options (list %default-options) #:argument-handler handle-argument)) (pure? (assoc-ref opts 'pure)) + (container? (assoc-ref opts 'container?)) (ad-hoc? (assoc-ref opts 'ad-hoc?)) (command (assoc-ref opts 'exec)) (packages (pick-all (options/resolve-packages opts) 'package)) @@ -279,6 +320,9 @@ OUTPUT) tuples, using the build options in OPTS." ((assoc-ref opts 'search-paths) (show-search-paths inputs paths pure?) (return #t)) + (container? + (return + (launch-environment/container command inputs paths))) (else - (create-environment inputs paths pure?) - (return (exit (status:exit-val (system command))))))))))))) + (return + (launch-environment command inputs paths pure?))))))))))) -- 2.4.3