[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[WIP Patch] Adding an FHS container to guix shell
From: |
John Kehayias |
Subject: |
[WIP Patch] Adding an FHS container to guix shell |
Date: |
Tue, 12 Jul 2022 15:59:14 +0000 |
Hi Guixers,
Apologies for the long email, so let me start with the punchline: attached is a
diff which adds an '--fhs-container' (or -F) option to guix shell/environment
to set up an FHS-like container. This includes the usual /lib directory and a
glibc which loads (a generated in the container) /etc/ld.so.cache. This should
allow running most things that expect a more "typical" Linux environment. Give
it a try!
First, I wanted to ask how people feel about such a feature. Obviously, one use
is to run pre-built binaries (isolated!), but this is also handy for setting up
development environments when not able (or wanting) to with Guix packages only.
For example, using the rustup [0] scripts, pretty much anything JS, or just
following typical Readme instructions to try out something new before
packaging. I won't debate the details here other than to say this topic comes
up with Guix and I think it is yet another useful tool for guix shell and
containers.
Nix, which I know almost nothing about, does have some FHS
container/environment options as well.
Next, some technical points about implementation, which I hope will be informed
by the first question and what we want from this tool. There are two main
things needed for the FHS-container:
1. Set up directories like /lib. This is easy enough and can be done currently,
like in roptat's response here [1] by building the profile first to know where
to link to. Note that it is easier to do it within the environment code since
we have access to the profile even if it is being built for the first time.
There are some wrinkles with linking something like /bin since we currently add
a link for sh; see the comments in my diff.
Right now I did not handle a multi-arch setup, though that shouldn't be too
difficult. This would probably require an option to build either all or
specified packages for an additional arch, like 32bit in a 64bit system, and
make the libraries available (/lib32 or something). Though may run into a
union-build bug [2]?
2. Typically binaries will expect the ld loader to use /etc/ld.so.cache for
finding libraries. So, I made a glibc package that removes our dl cache patch
to restore this behavior. It seems enough to add this as a default package to
the container, though I commented out an option to automatically graft
everything with this glibc. Both worked for me, but grafting didn't seem
necessary.
The second step is to generate the ld cache, which is done with a simple
startup script in the container, after creating a temporary ld.so.conf (our
ldconfig doesn't use the usual default directories?). I'm sure I found the
hackiest way to do this, but it works :) Again, this could be possible without
modifying guix containers, but this is easier. (For example, you can see work
done by myself and others at a certain non-free channel to do exactly this.)
Some questions going forward, besides overall cleanup and tweaking of the code
(which I provided comments in for some details, please see there). It might be
nice to be able to extend containers more easily with setup scripts, though
again this can be done by making some Guile scripts to wrap a container and
making a package around that (e.g. from the non-free channel). What kind of
extensions would be useful to expose? I think I saw some talk on IRC recently
about how to manage env variables when using guix shell. Perhaps an extended
manifest format for shell?
Relatedly and more generally, perhaps it would be good to have somewhere
(cookbook?) some recipes of useful guix shell container incantations. Sharing
what you need from the host for graphical programs can be a little tricky to
figure out. We have the --network option, maybe others would be useful? Or some
base package lists for development: just like we have our various
-build-system's, a package list with typical library sets might be a nice
convenience.
What about other uses for this container, like providing an isolated
environment to build and run software we can't do fully with bootstrap and
sources (like JS)? Could this become some stop-gap to allow people to work with
these ecosystems in a more controlled way within Guix? Or an alternative build
environment? Not entirely sure what this could mean, just thinking out loud.
Okay, let me end by bringing it back to what we can currently do with this code
I whipped up (and many thanks to [1] and efforts in a non-free channel for
doing the work that I drew upon).
I don't know any Rust, so I figured trying out what I read on the internet
about "just use rustup" and follow a readme is a good test case. So I did that
and compiled something that looked hefty, a graphical widget system [3]. Here's
the command I used and everything just worked: the rustup script ran and
downloaded the rust tools, the cargo build command worked to build everything.
I couldn't run the actual widgets as I am within a pure shell for my guix
checkout (but have done this with similar code and it fully worked once sharing
the right host env variables/directories). I used a directory as my container
home to keep everything.
./pre-inst-env guix shell --network --fhs-container bash coreutils curl grep
nss-certs gcc:lib gcc-toolchain pkg-config glib cairo atk pango@1.48.10
gdk-pixbuf gtk+ --share=$HOME/temp/fhs-home=$HOME
On IRC, apteryx mentioned wanting to try buildroot [4] as a use-case. This
worked for me after setting TERM=xterm in the container (I think I run the
shell not quite correctly right now, or because it is already with in a guix
shell --pure). Unfortunately make failed with some broken URLs, but so far
didn't need any tweaks.
./pre-inst-env guix shell --network --fhs-container bash coreutils grep make
nss-certs diffutils findutils ncurses which sed unzip gzip bzip2 wget perl cpio
bc patch rsync tar file python gawk util-linux-with-udev gcc:lib pkg-config
gcc-toolchain --share=$HOME/temp/fhs-home=$HOME
So, things should work as long as you provide the necessary packages. There may
be some tweaks needed with some symlinks or env variables, but I think the
basics are there.
Happy to hear everyone's thoughts! And sorry for the long email, but the code
is pretty short and straightforward.
John
PS: Is there an easy way to use the modified environment scripts outside of a
guix checkout shell?
[0] https://rustup.rs/
[1]
https://unix.stackexchange.com/questions/600311/how-to-run-a-dynamically-compiled-32-bit-x86-binary-on-a-amd64-bit-guix-system
[2] https://issues.guix.gnu.org/53406
[3] https://github.com/elkowar/eww
[4] https://git.buildroot.net/buildroot/
fhs-container.diff
Description: Text Data
- [WIP Patch] Adding an FHS container to guix shell,
John Kehayias <=
- Re: [WIP Patch] Adding an FHS container to guix shell, Vagrant Cascadian, 2022/07/12
- Re: [WIP Patch] Adding an FHS container to guix shell, Dominic Martinez, 2022/07/12
- Re: [WIP Patch] Adding an FHS container to guix shell, zimoun, 2022/07/14
- Re: [WIP Patch] Adding an FHS container to guix shell, Liliana Marie Prikler, 2022/07/14
- Re: [WIP Patch] Adding an FHS container to guix shell, Maxim Cournoyer, 2022/07/15