Hello! John Kehayias <john.kehay...@protonmail.com> skribis:
> 2. Typically binaries will expect the ld loader to use > /etc/ld.so.cache for finding libraries. Not necessarily. /etc/ld.so.cache is an optimization, but it’s entirely possible to opt out: if that file is missing, things will work fine, but libc will ‘stat’ more to find files. That would make glibc-for-fhs unnecessary. > +(define* (launch-environment/container #:key command bash fhs-container? user > + user-mappings profile manifest > + link-profile? network? map-cwd? > + (white-list '())) > "Run COMMAND within a container that features the software in PROFILE. > Environment variables are set according to the search paths of MANIFEST. > The global shell is BASH, a file name for a GNU Bash binary in the > @@ -709,6 +718,49 @@ (define* (launch-environment/container #:key command > bash user user-mappings > (mkdir-p home-dir) > (setenv "HOME" home-dir) > > + ;; Set up an FHS container. > + (when fhs-container? > + ;; Set up the expected bin and library directories as symlinks > to > + ;; the profile lib directory. Note that this is assuming a > 64bit > + ;; architecture. > + (let ((lib-dir (string-append profile "/lib"))) > + (symlink lib-dir "/lib64") > + (symlink lib-dir "/lib") > + (mkdir-p "/usr") > + (symlink lib-dir "/usr/lib")) Instead of adding code here, maybe you could do in a more declarative fashion, like: (define fhs-mappings (list (file-system-mapping (source (string-append profile "/bin")) (target "/bin")) …)) and append that to the ‘mappings’ variable there. It’s not necessarily more compact, but maybe marginally easier to read? > + ;; Define an entry script to start the container: generate > + ;; ld.so.cache, supplement $PATH, and include command. I’d leave ld.so.cache generation out. > + (call-with-output-file "/tmp/fhs.sh" > + (lambda (port) > + (display "ldconfig -X -f /tmp/ld.so.conf" port) > + (newline port) > + (display "export PATH=/bin:/usr/bin:/sbin:/usr/sbin:$PATH" > port) I think the default value of PATH in our libc is the FHS one: --8<---------------cut here---------------start------------->8--- $ env -i $(type -P strace) -e execve -f $(type -P guile) -c '(system* "whatever")' execve("/gnu/store/lpcjxka7hx3ypv4nz47g08k4m2syqwlj-profile/bin/guile", ["/gnu/store/lpcjxka7hx3ypv4nz47g0"..., "-c", "(system* \"whatever\")"], 0x7ffede27ad38 /* 0 vars */) = 0 /home/ludo/.guix-home/profile/bin/strace: Process 9727 attached /home/ludo/.guix-home/profile/bin/strace: Process 9728 attached /home/ludo/.guix-home/profile/bin/strace: Process 9729 attached /home/ludo/.guix-home/profile/bin/strace: Process 9730 attached /home/ludo/.guix-home/profile/bin/strace: Process 9731 attached /home/ludo/.guix-home/profile/bin/strace: Process 9732 attached [pid 9732] execve("/bin/whatever", ["whatever"], 0x7ffed6d967c8 /* 0 vars */) = -1 ENOENT (No such file or directory) [pid 9732] execve("/usr/bin/whatever", ["whatever"], 0x7ffed6d967c8 /* 0 vars */) = -1 ENOENT (No such file or directory) In execvp of whatever: No such file or directory --8<---------------cut here---------------end--------------->8--- So you could leave it undefined, but ‘load-profile’ in ‘launch-environment’ will define it. Instead of the wrapper script, maybe you could extend ‘launch-environment’ so the caller can make it override certain variables? I would find it a bit clearer. Thanks, Ludo’.