unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: John Kehayias <john.kehayias@protonmail.com>
To: "Ludovic Courtès" <ludo@gnu.org>
Cc: "guix-devel@gnu.org" <guix-devel@gnu.org>
Subject: Re: [WIP Patch] Adding an FHS container to guix shell
Date: Wed, 20 Jul 2022 21:22:02 +0000	[thread overview]
Message-ID: <MkbJBmKI5hWQRxxN5fT8DRe7sLPi7Hbj1gB4RP8YTUjHzsS-XytJaeFz1SXWg_v4G8dHfLa0p_kYa5IuBwwW2avKw7ZsyCy-mRI1MrTYco8=@protonmail.com> (raw)
In-Reply-To: <875yju1wev.fsf@gnu.org>

Hi Ludo’,

------- Original Message -------
On Monday, July 18th, 2022 at 7:40 AM, Ludovic Courtès wrote:

> Hello!
>
> John Kehayias 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.
>

I was thinking mostly of binaries, though I've also encountered code that wanted to read the ldcache (e.g. parsing ldconfig -p directly), for some reason. Is there any difficulty with having already some /etc/ld.so.cache from some package in the container profile? Perhaps that leads some programs to rely on the cache and then not continue searching for libraries? I'm not sure how that works, but only know that I've found the ldcache necessary (at least without modifying source) for things I would need the FHS container for.

My overall goal with this FHS option is to mimic both the standard and the typical expectations of distros that follow it (global ld cache, certain directories in PATH, etc). In my testing I didn't get very far without the modified glibc, though perhaps there are other ways around it. (There's patchelf, though hard to scale that I think.)

For example, lots of language build sytems/package managers will bring in some binaries, whether it is just to install (rustup does this) or because something like a web automation framework downloads browser binaries to use. My goal here was to make this all "just work," but I can understand wanting to keep it minimal.

I'll proceed with the glibc-for-fhs and ldcache for now, but open to discussing and hearing what everyone thinks. Overall, I find it necessary to enable the use-cases I'm thinking of.

> > + ;; 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?
>

Thanks, that's all a good idea for tidying up! I did so, further breaking down the FHS directories to ones we can map directly like this, others that need directory contents symlinked (because the container already has e.g. /bin not empty), and then creating the optional FHS directories to link to these. For example, /lib is mapped to profile/lib and /usr/lib is linked to /lib. Again, not strictly necessary, but I was trying to follow the structure of other distros here. And this way there is still "one" place where everything from the profile ends up, /lib, /bin, etc.

> > + ;; 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.
>

As discussed above, I'm finding this rather necessary and makes for a smooth FHS-container experience. I'm open to other options, maybe making this an additional option or hiding it away, though I think the design here fits the "pretend to be like another distro and just work" that I was going for.

> > + (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.
>

I'm not sure what you were showing here/I'm a bit confused. If I do just 'guix shell -C' for example, I can't just do 'sh' or 'exec sh' in this environment although /bin/sh exists (as a link to /gnu/store/...bash-.../bin/sh). While your example does indeed find sh (if I include the needed inputs to run the example), I'm not sure how that relates to running things directly. But maybe you just mean in terms of libc directly. Sorry, I don't know quite enough in this area.

In the container PATH only has profile/bin. Additionally, we frequently see hardcoded path assumptions like /bin or /usr/bin, or expectations of PATH being set with these. Adding, e.g. coreutils and which to the shell, which will happily find 'ls' but not 'sh', as which just searches PATH of course.

This could be worked around by the user, but again, I was going for "just works" as much as possible. Or at least as other distros "just work". (Side note: not that I think this is better! All this FHS stuff gives me even better appreciation for the design of Guix, despite the initial complications one sees as a new user.)

> 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.
>

Would this still be better if we do keep the ldcache being generated? I didn't see a quick way to just add in some setup commands to the container, though that could be a nice extension. Admittedly, my script here was the simplest hack I saw that worked, so I'm not married to it by any means. Again, the user could also generate the ldcache, but was trying to make it all automatic.

> Thanks,
> Ludo’.

Thanks for the constructive comments! It definitely helped me clean up the implementation, which I'll be sending shortly to the patches list. I'll followup on this thread as well to point people to a patch they can try.

For my testing I've been able to do work with web automations (uses binaries of browsers), tested that AppImages can work, built a Rust project, etc. A useful tool, even if it is one I hope I don't have to reach for too often.

John


  reply	other threads:[~2022-07-20 21:22 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-12 15:59 [WIP Patch] Adding an FHS container to guix shell John Kehayias
2022-07-12 17:34 ` Vagrant Cascadian
2022-07-15 15:41   ` John Kehayias
2022-07-13  2:11 ` Dominic Martinez
2022-07-13 23:27   ` Blake Shaw
2022-07-15 15:44   ` John Kehayias
2022-07-14 10:01 ` zimoun
2022-07-15 15:46   ` John Kehayias
2022-07-14 14:59 ` Liliana Marie Prikler
2022-07-15 16:00   ` John Kehayias
2022-07-15 13:43 ` Maxim Cournoyer
2022-07-15 16:35   ` John Kehayias
2022-07-15 13:45 ` Maxim Cournoyer
2022-07-18 11:40 ` Ludovic Courtès
2022-07-20 21:22   ` John Kehayias [this message]
2022-07-20 23:49     ` Maxime Devos
2022-07-21  3:15       ` John Kehayias
2022-07-21  0:20 ` debbugs irritation Was: " Csepp
2022-07-21  4:18   ` John Kehayias
2022-07-21 16:45   ` zimoun
2022-07-21 20:22     ` Csepp
2022-08-18 10:55       ` zimoun
2022-08-19 22:13         ` jbranso
2022-07-21  4:25 ` John Kehayias

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='MkbJBmKI5hWQRxxN5fT8DRe7sLPi7Hbj1gB4RP8YTUjHzsS-XytJaeFz1SXWg_v4G8dHfLa0p_kYa5IuBwwW2avKw7ZsyCy-mRI1MrTYco8=@protonmail.com' \
    --to=john.kehayias@protonmail.com \
    --cc=guix-devel@gnu.org \
    --cc=ludo@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).