From debbugs-submit-bounces@debbugs.gnu.org Mon May 04 17:44:25 2015 Received: (at 20255) by debbugs.gnu.org; 4 May 2015 21:44:25 +0000 Received: from localhost ([127.0.0.1]:34076 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YpOA4-0007Pi-Uj for submit@debbugs.gnu.org; Mon, 04 May 2015 17:44:25 -0400 Received: from fencepost.gnu.org ([208.118.235.10]:59998 ident=Debian-exim) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YpOA2-0007PY-Q7 for 20255@debbugs.gnu.org; Mon, 04 May 2015 17:44:23 -0400 Received: from reverse-83.fdn.fr ([80.67.176.83]:41243 helo=pluto) by fencepost.gnu.org with esmtpsa (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1YpOA1-0005ok-EX; Mon, 04 May 2015 17:44:22 -0400 From: ludo@gnu.org (Ludovic =?utf-8?Q?Court=C3=A8s?=) To: =?utf-8?B?5a6L5paH5q2m?= Subject: Re: bug#20255: 'search-paths' should respect both user and system profile. References: <877ftschjt.fsf@gmail.com> <87fv8fip01.fsf@gnu.org> <87d23j1bxk.fsf@gmail.com> Date: Mon, 04 May 2015 23:44:19 +0200 In-Reply-To: <87d23j1bxk.fsf@gmail.com> (=?utf-8?B?IuWui+aWh+atpiIncw==?= message of "Sun, 05 Apr 2015 11:39:03 +0800") Message-ID: <87lhh43tn0.fsf@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: -5.0 (-----) X-Debbugs-Envelope-To: 20255 Cc: 20255@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable =E5=AE=8B=E6=96=87=E6=AD=A6 skribis: > Or better to generate a 'profile' script for each manifest, and then > merged in shell level, so it can work out-of-the-box. How about: > - /etc/profile: > # configuration for the whole system goes here. > # shouldn't refer profile paths. > export LANG=3Den_US.utf8 > export SSL_CERT_DIR=3D/etc/ssl/certs > export LINUX_MODULE_DIRECTORY=3D/run/booted-system/kernel/lib/modules > [...] > > source /run/current-system/profile/etc/profile > > if [ -f $HOME/.guix-profile/etc/profile ]; then > source $HOME/.guix-profile/etc/profile > fi > > # honor setuid-programs > export PATH=3D/run/setuid-programs:$PATH > > - /run/current-system/profile/etc/profile: > export PATH=3D/run/current-system/profile/bin:/run/current-system/pro= file/sbin:$PATH > export MANPATH=3D/run/current-system/profile/share/man:$PATH > [...] >=20=20=20=20=20 > - ~/.guix-profile/etc/profile: > export PATH=3D~/.guix-profile/bin:~/.guix-profile/sbin:$PATH > [...] There=E2=80=99s a further complication here: =E2=80=98profile-derivation=E2= =80=99, which builds the profile, doesn=E2=80=99t know its user-visible name ~/.guix-profile. It just knows its store file name. However, we don=E2=80=99t want etc/profile= to read: export PATH=3D/gnu/store/...-profile/bin:$PATH because then, the user=E2=80=99s environment variables in a running session would keep pointing to a given profile generation. So we have to tell =E2=80=98profile-generation=E2=80=99 what the user-visib= le name of the profile is going to be. Attached is a very rough patch to do that. This is not so nice because all user interfaces will now have to pass that #:target parameter or etc/profile will be =E2=80=9Cwrong.=E2=80=9D Another option would be to simply run: eval `guix package -p ~/.guix-profile --search-paths` This has two downsides: 1. It takes ~200 ms to run on my laptop, which can maybe be noticeable; OTOH it=E2=80=99s only for interactive shells, so maybe th= at=E2=80=99s OK. 2. If there=E2=80=99s a manifest format change and /etc/profile calls a = =E2=80=98guix=E2=80=99 command that cannot handle the manifest format (because it=E2=80=99s o= lder than the =E2=80=98guix=E2=80=99 used to build the profile), then it do= esn=E2=80=99t work at all (that=E2=80=99s a bit contrived, but not completely impossible.) Thoughts? Ludo=E2=80=99. --=-=-= Content-Type: text/x-patch Content-Disposition: inline Modified guix/profiles.scm diff --git a/guix/profiles.scm b/guix/profiles.scm index 8445e00..308dc23 100644 --- a/guix/profiles.scm +++ b/guix/profiles.scm @@ -582,10 +582,15 @@ MANIFEST. Single-file bundles are required by programs such as Git and Lynx." (define* (profile-derivation manifest #:key + target (hooks %default-profile-hooks)) "Return a derivation that builds a profile (aka. 'user environment') with the given MANIFEST. The profile includes additional derivations returned by -the monadic procedures listed in HOOKS--such as an Info 'dir' file, etc." +the monadic procedures listed in HOOKS--such as an Info 'dir' file, etc. + +When TARGET is not #f, it must be a string denoting the file name under which +the profile will be available--e.g., \"/home/rms/.guix-profile\". This name +is used in the profile's 'etc/profile' file (read that again.)" (mlet %store-monad ((extras (if (null? (manifest-entries manifest)) (return '()) (sequence %store-monad @@ -598,20 +603,72 @@ the monadic procedures listed in HOOKS--such as an Info 'dir' file, etc." (define builder #~(begin - (use-modules (ice-9 pretty-print) - (guix build union)) + (use-modules (ice-9 match) + (ice-9 regex) + (ice-9 pretty-print) + (guix build union) + (guix build utils) + (guix search-paths)) + + (define target + '#$target) + + (define search-paths + (map sexp->search-path-specification + '#$(map search-path-specification->sexp + (append-map manifest-entry-search-paths + (manifest-entries manifest))))) + + (define (use-target value separator) + (let ((items ((@@ (guix search-paths) string-tokenize*) + value separator))) + (string-join (map (lambda (str) + (string-append target + (string-drop str + (string-length + #$output)))) + items) + separator))) + + (define write-environment-variable-definition + (match-lambda + ((spec . value) + (let ((variable (search-path-specification-variable spec)) + (sep (search-path-specification-separator spec))) + (display + (environment-variable-definition variable + (if target + (use-target value sep) + value) + #:separator sep + #:kind 'prefix)) + (newline))))) (setvbuf (current-output-port) _IOLBF) (setvbuf (current-error-port) _IOLBF) + ;; Make the symlinks. (union-build #$output '#$inputs #:log-port (%make-void-port "w")) + + ;; Store meta-data. (call-with-output-file (string-append #$output "/manifest") (lambda (p) - (pretty-print '#$(manifest->gexp manifest) p))))) + (pretty-print '#$(manifest->gexp manifest) p))) + + ;; Store a ready-to-use Bash profile. + (mkdir-p (string-append #$output "/etc")) + (with-output-to-file (string-append #$output "/etc/profile") + (lambda () + (let ((variables (evaluate-search-paths search-paths #$output))) + (for-each write-environment-variable-definition + variables)))))) (gexp->derivation "profile" builder - #:modules '((guix build union)) + #:modules '((guix build union) + (guix build utils) + (guix search-paths) + (guix records)) #:local-build? #t))) (define (profile-regexp profile) Modified guix/scripts/package.scm diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm index 7f53af7..38ec8ed 100644 --- a/guix/scripts/package.scm +++ b/guix/scripts/package.scm @@ -833,6 +833,7 @@ more information.~%")) (let* ((prof-drv (run-with-store (%store) (profile-derivation new + #:target (user-friendly-profile profile) #:hooks (if bootstrap? '() %default-profile-hooks)))) --=-=-=--