GNU bug report logs - #30255
[PATCH 1/3] scripts: environment: Add --link-profile.

Previous Next

Package: guix-patches;

Reported by: Mike Gerwitz <mtg <at> gnu.org>

Date: Fri, 26 Jan 2018 03:31:02 UTC

Severity: normal

Tags: patch

Done: ludo <at> gnu.org (Ludovic Courtès)

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 30255 in the body.
You can then email your comments to 30255 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to guix-patches <at> gnu.org:
bug#30255; Package guix-patches. (Fri, 26 Jan 2018 03:31:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Mike Gerwitz <mtg <at> gnu.org>:
New bug report received and forwarded. Copy sent to guix-patches <at> gnu.org. (Fri, 26 Jan 2018 03:31:03 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Mike Gerwitz <mtg <at> gnu.org>
To: guix-patches <at> gnu.org
Subject: [PATCH 1/3] scripts: environment: Add --link-profile.
Date: Thu, 25 Jan 2018 22:29:15 -0500
[Message part 1 (text/plain, inline)]
This change is motivated by attempts to run programs (like GNU IceCat) within
containers.  The 'fontconfig' program, for example, is configured explicitly
to check ~/.guix-profile for additional fonts.

There were no existing container tests in 'tests/guix-environment.sh', but I
added one anyway for this change.

* doc/guix.texi (Invoking guix environment): Add '--link-profile'.
* guix/scripts/environment.scm (show-help): Add '--link-profile'.
(%options): Add 'link-profile' as '#\P', assigned to 'link-profile?'.
(lnk-environment): New procedure.
(launch-environment/container): Use it when 'link-profile?'.
[link-profile?]: New parameter.
(guix-environment): Leave when '--link-prof' but not '--container'.  Add
'#:link-profile?' argument to 'launch-environment/container' application.
* tests/guix-environment.sh: New '--link-profile' test.
---
 doc/guix.texi                | 17 +++++++++++++++++
 guix/scripts/environment.scm | 43 +++++++++++++++++++++++++++++++++++++------
 tests/guix-environment.sh    | 12 ++++++++++++
 3 files changed, 66 insertions(+), 6 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 1ecdcd218..3b6ae1ab9 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -46,6 +46,7 @@ Copyright @copyright{} 2017 Andy Wingo@*
 Copyright @copyright{} 2017 Arun Isaac@*
 Copyright @copyright{} 2017 nee@*
 Copyright @copyright{} 2018 Rutger Helling
+Copyright @copyright{} 2018 Mike Gerwitz
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -7166,6 +7167,22 @@ For containers, share the network namespace with the host system.
 Containers created without this flag only have access to the loopback
 device.
 
+@item --link-profile
+@itemx -P
+For containers, link the environment profile to
+@file{~/.guix-profile} within the container.  This is equivalent to
+running the command @command{ln -s $GUIX_ENVIRONMENT ~/.guix-profile}
+within the container.  Linking will fail and abort the environment if
+the directory already exists, which will certainly be the case if
+@command{guix environment} was invoked in the user's home directory.
+
+Certain packages are configured to look in
+@code{~/.guix-profile} for configuration files and data;@footnote{For
+example, the @code{fontconfig} package inspects
+@file{~/.guix-profile/share/fonts} for additional fonts.}
+@code{--link-profile} allows these programs to behave as expected within
+the environment.
+
 @item --expose=@var{source}[=@var{target}]
 For containers, expose the file system @var{source} from the host system
 as the read-only file system @var{target} within the container.  If
diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm
index d2568e6a7..771574c15 100644
--- a/guix/scripts/environment.scm
+++ b/guix/scripts/environment.scm
@@ -1,6 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014, 2015 David Thompson <davet <at> gnu.org>
 ;;; Copyright © 2015, 2016, 2017 Ludovic Courtès <ludo <at> gnu.org>
+;;; Copyright © 2018 Mike Gerwitz <mtg <at> gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -157,6 +158,9 @@ COMMAND or an interactive shell in that environment.\n"))
   -C, --container        run command within an isolated container"))
   (display (G_ "
   -N, --network          allow containers to access the network"))
+  (display (G_ "
+  -P, --link-profile     link environment profile to ~/.guix-profile within
+                         an isolated container"))
   (display (G_ "
       --share=SPEC       for containers, share writable host file system
                          according to SPEC"))
@@ -236,6 +240,9 @@ COMMAND or an interactive shell in that environment.\n"))
          (option '(#\N "network") #f #f
                  (lambda (opt name arg result)
                    (alist-cons 'network? #t result)))
+         (option '(#\P "link-profile") #f #f
+                 (lambda (opt name arg result)
+                   (alist-cons 'link-profile? #t result)))
          (option '("share") #t #f
                  (lambda (opt name arg result)
                    (alist-cons 'file-system-mapping
@@ -384,18 +391,20 @@ environment variables are cleared before setting the new ones."
            ((_ . status) status)))))
 
 (define* (launch-environment/container #:key command bash user-mappings
-                                       profile paths network?)
+                                       profile paths link-profile? network?)
   "Run COMMAND within a container that features the software in PROFILE.
 Environment variables are set according to PATHS, a list of native search
 paths.  The global shell is BASH, a file name for a GNU Bash binary in the
 store.  When NETWORK?, access to the host system network is permitted.
 USER-MAPPINGS, a list of file system mappings, contains the user-specified
-host file systems to mount inside the container."
+host file systems to mount inside the container.  LINK-PROFILE? creates a
+symbolic link from ~/.guix-profile to the environment profile."
   (mlet %store-monad ((reqs (inputs->requisites
                              (list (direct-store-path bash) profile))))
     (return
-     (let* ((cwd (getcwd))
-            (passwd (getpwuid (getuid)))
+     (let* ((cwd      (getcwd))
+            (passwd   (getpwuid (getuid)))
+            (home-dir (passwd:dir passwd))
             ;; Bind-mount all requisite store items, user-specified mappings,
             ;; /bin/sh, the current working directory, and possibly networking
             ;; configuration files within the container.
@@ -440,8 +449,13 @@ host file systems to mount inside the container."
 
             ;; Create a dummy home directory under the same name as on the
             ;; host.
-            (mkdir-p (passwd:dir passwd))
-            (setenv "HOME" (passwd:dir passwd))
+            (mkdir-p home-dir)
+            (setenv "HOME" home-dir)
+
+            ;; If requested, link $GUIX_ENVIRONMENT to $HOME/.guix-profile;
+            ;; this allows programs expecting that path to continue working as
+            ;; expected within a container.
+            (when link-profile? (link-environment profile home-dir))
 
             ;; Create a dummy /etc/passwd to satisfy applications that demand
             ;; to read it, such as 'git clone' over SSH, a valid use-case when
@@ -471,6 +485,18 @@ host file systems to mount inside the container."
                            (delq 'net %namespaces) ; share host network
                            %namespaces)))))))
 
+(define (link-environment profile home-dir)
+  "Create a symbolic link from HOME-DIR/.guix-profile to PROFILE."
+  (let ((profile-dir (string-append home-dir "/.guix-profile")))
+    (catch 'system-error
+      (lambda ()
+        (symlink profile profile-dir))
+      (lambda args
+        (if (= EEXIST (system-error-errno args))
+            (leave (G_ "cannot link profile: path '~a' already exists within container~%")
+                   profile-dir)
+            (apply throw args))))))
+
 (define (environment-bash container? bootstrap? system)
   "Return a monadic value in the store monad for the version of GNU Bash
 needed in the environment for SYSTEM, if any.  If CONTAINER? is #f, return #f.
@@ -544,6 +570,7 @@ message if any test fails."
     (let* ((opts       (parse-args args))
            (pure?      (assoc-ref opts 'pure))
            (container? (assoc-ref opts 'container?))
+           (link-prof? (assoc-ref opts 'link-profile?))
            (network?   (assoc-ref opts 'network?))
            (bootstrap? (assoc-ref opts 'bootstrap?))
            (system     (assoc-ref opts 'system))
@@ -577,6 +604,9 @@ message if any test fails."
 
       (when container? (assert-container-features))
 
+      (when (and (not container?) link-prof?)
+        (leave (G_ "--link-prof cannot be used without --container~%")))
+
       (with-store store
         (set-build-options-from-command-line store opts)
 
@@ -626,6 +656,7 @@ message if any test fails."
                                                   #:user-mappings mappings
                                                   #:profile profile
                                                   #:paths paths
+                                                  #:link-profile? link-prof?
                                                   #:network? network?)))
                  (else
                   (return
diff --git a/tests/guix-environment.sh b/tests/guix-environment.sh
index bf5ca17fa..e995636df 100644
--- a/tests/guix-environment.sh
+++ b/tests/guix-environment.sh
@@ -62,6 +62,18 @@ fi
 guix environment --bootstrap --ad-hoc guile-bootstrap --pure \
      -- "$SHELL" -c 'test -f "$GUIX_ENVIRONMENT/bin/guile"'
 
+# Make sure 'GUIX_ENVIRONMENT' is linked to '~/.guix-profile' when requested
+# within a container
+(
+  linktest='(exit (string=? (getenv "GUIX_ENVIRONMENT")
+(readlink (string-append (getenv "HOME") "/.guix-profile"))))'
+
+  cd "$tmpdir" \
+     && guix environment --bootstrap --container --link-profile \
+             --ad-hoc guile-bootstrap --pure \
+             -- guile -c "$linktest"
+)
+
 # Make sure '-r' works as expected.
 rm -f "$gcroot"
 expected="`guix environment --bootstrap --ad-hoc guile-bootstrap \
-- 
2.15.1

[signature.asc (application/pgp-signature, inline)]

Reply sent to ludo <at> gnu.org (Ludovic Courtès):
You have taken responsibility. (Fri, 02 Mar 2018 10:21:01 GMT) Full text and rfc822 format available.

Notification sent to Mike Gerwitz <mtg <at> gnu.org>:
bug acknowledged by developer. (Fri, 02 Mar 2018 10:21:02 GMT) Full text and rfc822 format available.

Message #10 received at 30255-done <at> debbugs.gnu.org (full text, mbox):

From: ludo <at> gnu.org (Ludovic Courtès)
To: Mike Gerwitz <mtg <at> gnu.org>
Cc: 30255-done <at> debbugs.gnu.org
Subject: Re: [bug#30255] [PATCH 1/3] scripts: environment: Add --link-profile.
Date: Fri, 02 Mar 2018 11:20:00 +0100
[Message part 1 (text/plain, inline)]
Hi Mike,

Mike Gerwitz <mtg <at> gnu.org> skribis:

> This change is motivated by attempts to run programs (like GNU IceCat) within
> containers.  The 'fontconfig' program, for example, is configured explicitly
> to check ~/.guix-profile for additional fonts.
>
> There were no existing container tests in 'tests/guix-environment.sh', but I
> added one anyway for this change.
>
> * doc/guix.texi (Invoking guix environment): Add '--link-profile'.
> * guix/scripts/environment.scm (show-help): Add '--link-profile'.
> (%options): Add 'link-profile' as '#\P', assigned to 'link-profile?'.
> (lnk-environment): New procedure.
> (launch-environment/container): Use it when 'link-profile?'.
> [link-profile?]: New parameter.
> (guix-environment): Leave when '--link-prof' but not '--container'.  Add
> '#:link-profile?' argument to 'launch-environment/container' application.
> * tests/guix-environment.sh: New '--link-profile' test.

Sorry for forgetting about this patch series.  It’s perfect, and
very useful!

I applied this one with the changes below.  The main change is moving
the test to guix-environment-container.sh, which is skipped when user
namespaces are not supported.

Thank you!

Ludo’.

[Message part 2 (text/x-patch, inline)]
diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm
index d86d30308..5c7d83881 100644
--- a/guix/scripts/environment.scm
+++ b/guix/scripts/environment.scm
@@ -513,7 +513,7 @@ symbolic link from ~/.guix-profile to the environment profile."
         (symlink profile profile-dir))
       (lambda args
         (if (= EEXIST (system-error-errno args))
-            (leave (G_ "cannot link profile: path '~a' already exists within container~%")
+            (leave (G_ "cannot link profile: '~a' already exists within container~%")
                    profile-dir)
             (apply throw args))))))
 
@@ -625,7 +625,7 @@ message if any test fails."
       (when container? (assert-container-features))
 
       (when (and (not container?) link-prof?)
-        (leave (G_ "--link-prof cannot be used without --container~%")))
+        (leave (G_ "'--link-profile' cannot be used without '--container'~%")))
 
       (with-store store
         (set-build-options-from-command-line store opts)
diff --git a/tests/guix-environment-container.sh b/tests/guix-environment-container.sh
index d7c1b7057..df40ce03e 100644
--- a/tests/guix-environment-container.sh
+++ b/tests/guix-environment-container.sh
@@ -97,6 +97,20 @@ grep -e "$NIX_STORE_DIR/.*-bash" $tmpdir/mounts # bootstrap bash
 
 rm $tmpdir/mounts
 
+# Make sure 'GUIX_ENVIRONMENT' is linked to '~/.guix-profile' when requested
+# within a container.
+(
+  linktest='(exit (string=? (getenv "GUIX_ENVIRONMENT")
+(readlink (string-append (getenv "HOME") "/.guix-profile"))))'
+
+  cd "$tmpdir" \
+     && guix environment --bootstrap --container --link-profile \
+             --ad-hoc guile-bootstrap --pure \
+             -- guile -c "$linktest"
+)
+
+# Check the exit code.
+
 abnormal_exit_code="
 (use-modules (system foreign))
 ;; Purposely make Guile crash with a segfault. :)
diff --git a/tests/guix-environment.sh b/tests/guix-environment.sh
index ba686816f..b44aca099 100644
--- a/tests/guix-environment.sh
+++ b/tests/guix-environment.sh
@@ -71,18 +71,6 @@ echo "(use-modules (guix profiles) (gnu packages bootstrap))
 guix environment --bootstrap --manifest=$tmpdir/manifest.scm --pure \
      -- "$SHELL" -c 'test -f "$GUIX_ENVIRONMENT/bin/guile"'
 
-# Make sure 'GUIX_ENVIRONMENT' is linked to '~/.guix-profile' when requested
-# within a container
-(
-  linktest='(exit (string=? (getenv "GUIX_ENVIRONMENT")
-(readlink (string-append (getenv "HOME") "/.guix-profile"))))'
-
-  cd "$tmpdir" \
-     && guix environment --bootstrap --container --link-profile \
-             --ad-hoc guile-bootstrap --pure \
-             -- guile -c "$linktest"
-)
-
 # Make sure '-r' works as expected.
 rm -f "$gcroot"
 expected="`guix environment --bootstrap --ad-hoc guile-bootstrap \

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Fri, 30 Mar 2018 11:24:05 GMT) Full text and rfc822 format available.

This bug report was last modified 7 years and 86 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.